InfiniSQL  v0.1.2-alpha
Massive Scale Transaction Processing
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Asts.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Mark Travis <mtravis15432+src@gmail.com>
3  * All rights reserved. No warranty, explicit or implicit, provided.
4  *
5  * This file is part of InfiniSQL(tm).
6 
7  * InfiniSQL is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 3
9  * as published by the Free Software Foundation.
10  *
11  * InfiniSQL is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with InfiniSQL. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
29 #include "gch.h"
30 #include "Asts.h"
31 #include "infinisql.h"
32 #include "Transaction.h"
33 #line 34 "Asts.cc"
34 
36 {
37 }
38 
39 Ast::Ast(class Ast *parentarg,
40  operatortypes_e operatortypearg) :
41  parent(parentarg), rightchild(NULL), leftchild(NULL), isoperator(true),
42  operatortype(operatortypearg)
43 {
44  // for unary operators, make left appear populated already
51  {
52  leftchild = this;
53  }
54 }
55 
56 Ast::Ast(class Ast *parentarg, string &operandarg) : parent(parentarg),
57  rightchild(NULL), leftchild(NULL),
58  isoperator(false),
59  operand(operandarg)
60 {
61 }
62 
63 Ast::Ast(const Ast &orig)
64 {
65  cp(orig);
66 }
67 
68 Ast &Ast::operator= (const Ast &orig)
69 {
70  cp(orig);
71  return *this;
72 }
73 
74 void Ast::cp(const Ast &orig)
75 {
76  parent = orig.parent;
77  isoperator = orig.isoperator;
79  operand = orig.operand;
81 
82  if (orig.leftchild != NULL)
83  {
84  leftchild = new class Ast;
85  *leftchild = *orig.leftchild;
86  }
87  else
88  {
89  leftchild=NULL;
90  }
91 
92  if (orig.rightchild != NULL)
93  {
94  rightchild = new class Ast;
95  *rightchild = *orig.rightchild;
96  }
97  else
98  {
99  rightchild=NULL;
100  }
101 }
102 
104 {
105  if (isoperator==true)
106  {
107  if (leftchild != NULL)
108  {
109  if (leftchild != this)
110  {
111  delete leftchild;
112  }
113  }
114 
115  if (rightchild != NULL)
116  {
117  delete rightchild;
118  }
119  }
120 }
121 
122 bool Ast::evaluate(class Ast **nextAstNode, class Statement *statementPtr)
123 {
124  if (isoperator==false)
125  {
126  if (operand[0]==OPERAND_PARAMETER)
127  {
128  int64_t paramnum;
129  memcpy(&paramnum, &operand[1], sizeof(paramnum));
130  operand = statementPtr->parameters[paramnum];
131  }
132 
133  *nextAstNode=parent;
134  return true;
135  }
136 
137  /* do left 1st, particularly for AND optimization */
138 
139  // unary operators ignore leftchild
146  {
147  if (leftchild->isoperator==true)
148  {
149  *nextAstNode=leftchild;
150  return false;
151  }
152 
154  {
155  int64_t paramnum;
156  memcpy(&paramnum, &leftchild->operand[1], sizeof(paramnum));
157  printf("%s %i paramnum %li\n", __FILE__, __LINE__, paramnum);
158  leftchild->operand = statementPtr->parameters[paramnum];
159  }
160  else if (leftchild->operand[0]==OPERAND_SUBQUERY)
161  {
162  statementPtr->subqueryScalar(this);
163  }
164  }
165 
166  if (rightchild->isoperator==true)
167  {
168  *nextAstNode=rightchild;
169  return false;
170  }
171 
173  {
174  int64_t paramnum;
175  memcpy(&paramnum, &rightchild->operand[1], sizeof(paramnum));
176  rightchild->operand = statementPtr->parameters[paramnum];
177  }
178  else if (rightchild->operand[0]==OPERAND_SUBQUERY)
179  {
180  statementPtr->subqueryScalar(this);
181  }
182 
183  // execute!
184  switch (operatortype)
185  {
187  {
188  if (leftchild->operand[0] != OPERAND_STRING ||
190  {
191  printf("%s %i bad operand %c\n", __FILE__, __LINE__, operand[0]);
192  return true;
193  }
194 
196  operand.append(leftchild->operand.substr(1, string::npos));
197  operand.append(rightchild->operand.substr(1, string::npos));
198  isoperator=false;
199  delete leftchild;
200  leftchild=NULL;
201  delete rightchild;
202  rightchild=NULL;
203  }
204  break;
205 
206  case OPERATOR_ADDITION:
207  if (leftchild->operand[0]==OPERAND_FLOAT ||
209  {
212  }
213 
214  switch (leftchild->operand[0])
215  {
216  case OPERAND_INTEGER:
217  {
219  {
220  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
222  return false;
223  }
224 
225  operand.resize(1+sizeof(int64_t), (char)0);
227  int64_t val = *(int64_t *)(leftchild->operand.c_str()+1) +
228  *(int64_t *)(rightchild->operand.c_str()+1);
229  memcpy(&operand[1], &val, sizeof(val));
230  isoperator=false;
231  }
232  break;
233 
234  case OPERAND_FLOAT:
235  {
236  if (rightchild->operand[0] != OPERAND_FLOAT)
237  {
238  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
240  return false;
241  }
242 
243  operand.resize(1+sizeof(long double), (char)0);
244  operand[0] = OPERAND_FLOAT;
245  int64_t val = *(long double *)(leftchild->operand.c_str()+1) +
246  *(long double *)(rightchild->operand.c_str()+1);
247  memcpy(&operand[1], &val, sizeof(val));
248  isoperator=false;
249  }
250  break;
251 
252  default:
253  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
254  leftchild->operand[0]);
255  return false;
256  }
257 
258  delete leftchild;
259  leftchild=NULL;
260  delete rightchild;
261  rightchild=NULL;
262  break;
263 
265  if (leftchild->operand[0]==OPERAND_FLOAT ||
267  {
270  }
271 
272  switch (leftchild->operand[0])
273  {
274  case OPERAND_INTEGER:
275  {
277  {
278  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
280  return false;
281  }
282 
283  operand.resize(1+sizeof(int64_t), (char)0);
285  int64_t val = *(int64_t *)(leftchild->operand.c_str()+1) -
286  *(int64_t *)(rightchild->operand.c_str()+1);
287  memcpy(&operand[1], &val, sizeof(val));
288  isoperator=false;
289  }
290  break;
291 
292  case OPERAND_FLOAT:
293  {
294  if (rightchild->operand[0] != OPERAND_FLOAT)
295  {
296  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
298  return false;
299  }
300 
301  operand.resize(1+sizeof(long double), (char)0);
302  operand[0] = OPERAND_FLOAT;
303  int64_t val = *(long double *)(leftchild->operand.c_str()+1) -
304  *(long double *)(rightchild->operand.c_str()+1);
305  memcpy(&operand[1], &val, sizeof(val));
306  isoperator=false;
307  }
308  break;
309 
310  default:
311  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
312  leftchild->operand[0]);
313  return false;
314  }
315 
316  delete leftchild;
317  leftchild=NULL;
318  delete rightchild;
319  rightchild=NULL;
320  break;
321 
323  if (leftchild->operand[0]==OPERAND_FLOAT ||
325  {
328  }
329 
330  switch (leftchild->operand[0])
331  {
332  case OPERAND_INTEGER:
333  {
335  {
336  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
338  return false;
339  }
340 
341  operand.resize(1+sizeof(int64_t), (char)0);
343  int64_t val = *(int64_t *)(leftchild->operand.c_str()+1) *
344  *(int64_t *)(rightchild->operand.c_str()+1);
345  memcpy(&operand[1], &val, sizeof(val));
346  isoperator=false;
347  }
348  break;
349 
350  case OPERAND_FLOAT:
351  {
352  if (rightchild->operand[0] != OPERAND_FLOAT)
353  {
354  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
356  return false;
357  }
358 
359  operand.resize(1+sizeof(long double), (char)0);
360  operand[0] = OPERAND_FLOAT;
361  int64_t val = *(long double *)(leftchild->operand.c_str()+1) *
362  *(long double *)(rightchild->operand.c_str()+1);
363  memcpy(&operand[1], &val, sizeof(val));
364  isoperator=false;
365  }
366  break;
367 
368  default:
369  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
370  leftchild->operand[0]);
371  return false;
372  }
373 
374  delete leftchild;
375  leftchild=NULL;
376  delete rightchild;
377  rightchild=NULL;
378  break;
379 
380  case OPERATOR_DIVISION:
381  if (leftchild->operand[0]==OPERAND_FLOAT ||
383  {
386  }
387 
388  switch (leftchild->operand[0])
389  {
390  case OPERAND_INTEGER:
391  {
393  {
394  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
396  return false;
397  }
398 
399  operand.resize(1+sizeof(int64_t), (char)0);
401  int64_t val = *(int64_t *)(leftchild->operand.c_str()+1) /
402  *(int64_t *)(rightchild->operand.c_str()+1);
403  memcpy(&operand[1], &val, sizeof(val));
404  isoperator=false;
405  }
406  break;
407 
408  case OPERAND_FLOAT:
409  {
410  if (rightchild->operand[0] != OPERAND_FLOAT)
411  {
412  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
414  return false;
415  }
416 
417  operand.resize(1+sizeof(long double), (char)0);
418  operand[0] = OPERAND_FLOAT;
419  int64_t val = *(long double *)(leftchild->operand.c_str()+1) /
420  *(long double *)(rightchild->operand.c_str()+1);
421  memcpy(&operand[1], &val, sizeof(val));
422  isoperator=false;
423  }
424  break;
425 
426  default:
427  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
428  leftchild->operand[0]);
429  return false;
430  }
431 
432  delete leftchild;
433  leftchild=NULL;
434  delete rightchild;
435  rightchild=NULL;
436  break;
437 
438  case OPERATOR_NEGATION:
440  {
442  }
443 
444  switch (rightchild->operand[0])
445  // switch (leftchild->operand[0])
446  {
447  case OPERAND_INTEGER:
448  {
450  {
451  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
453  return false;
454  }
455 
456  operand.resize(1+sizeof(int64_t), (char)0);
458  int64_t val = 0 - *(int64_t *)(rightchild->operand.c_str()+1);
459  memcpy(&operand[1], &val, sizeof(val));
460  isoperator=false;
461  }
462  break;
463 
464  case OPERAND_FLOAT:
465  {
466  if (rightchild->operand[0] != OPERAND_FLOAT)
467  {
468  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
470  return false;
471  }
472 
473  operand.resize(1+sizeof(long double), (char)0);
474  operand[0] = OPERAND_FLOAT;
475  int64_t val = 0 - *(long double *)(rightchild->operand.c_str()+1);
476  memcpy(&operand[1], &val, sizeof(val));
477  isoperator=false;
478  }
479  break;
480 
481  default:
482  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
483  leftchild->operand[0]);
484  return false;
485  }
486 
487  delete rightchild;
488  rightchild=NULL;
489  break;
490 
491  case OPERATOR_AND:
492  {
493  boost::unordered_map< int64_t, vector<int64_t> > enginerowids;
494 
495  boost::unordered_map<uuRecord_s, returnRow_s>::iterator it;
496 
497  for (it = leftchild->predicateResults.begin();
498  it != leftchild->predicateResults.end(); it++)
499  {
500  if (rightchild->predicateResults.count(it->first))
501  {
502  predicateResults[it->first] = it->second;
503  }
504  else
505  {
506  // unlock if it's not already staged in this transaction
507  if (!statementPtr->transactionPtr->stagedRows.count(it->first))
508  {
509  enginerowids[it->first.engineid].push_back(it->first.rowid);
510  }
511  }
512  }
513 
514  // send rollback messages
515  boost::unordered_map< int64_t, vector<int64_t> >::iterator it2;
516  rowOrField_s rowOrField = {};
517  rowOrField.isrow=true;
518  rowOrField.tableid=statementPtr->currentQuery->tableid;
519 
520  for (it2 = enginerowids.begin(); it2 != enginerowids.end(); it2++)
521  {
522  class MessageCommitRollback *msg = new class MessageCommitRollback();
523 
524  for (size_t n=0; n < it2->second.size(); n++)
525  {
526  rowOrField.rowid=it2->second[n];
527  msg->rofs.push_back(rowOrField);
528  }
529 
532  0, it2->first, msg);
533  }
534 
535  isoperator=false;
536  printf("%s %i this %p deleting leftchild %p rightchild %p\n", __FILE__,
537  __LINE__, this, leftchild, rightchild);
538  delete leftchild;
539  leftchild=NULL;
540  delete rightchild;
541  rightchild=NULL;
542  }
543  break;
544 
545  case OPERATOR_OR:
549  isoperator=false;
550  delete leftchild;
551  leftchild=NULL;
552  delete rightchild;
553  rightchild=NULL;
554  break;
555 
556  case OPERATOR_NOT:
557  /* NOT requires a call to retrieve all rows NOT in the
558  * operand's result set */
559  printf("%s %i operator %i not implemented.\n", __FILE__, __LINE__,
560  operatortype);
561  isoperator=false;
562  delete rightchild;
563  rightchild=NULL;
564  return false;
565 // break;
566 
567  case OPERATOR_TRUE:
568  /* IS TRUE is gratuitous*/
569  printf("%s %i operator %i not implemented.\n", __FILE__, __LINE__,
570  operatortype);
571  isoperator=false;
572  delete rightchild;
573  rightchild=NULL;
574  return false;
575 // break;
576 
577  case OPERATOR_FALSE:
578  /* IS FALSE requires a call to retrieve all rows like NOT, and
579  * all NOT NULL */
580  printf("%s %i operator %i not implemented.\n", __FILE__, __LINE__,
581  operatortype);
582  isoperator=false;
583  delete rightchild;
584  rightchild=NULL;
585  return false;
586 // break;
587 
588  case OPERATOR_UNKNOWN:
589  /* IS UNKNOWN is a variation on ISNULL predicates */
590  printf("%s %i operator %i not implemented.\n", __FILE__, __LINE__,
591  operatortype);
592  isoperator=false;
593  delete rightchild;
594  rightchild=NULL;
595  return false;
596 // break;
597 
598  case OPERATOR_EQ:
599  isoperator=false;
600 
601  if (statementPtr->stagedPredicate(operatortype,
602  statementPtr->currentQuery->tableid,
605  statementPtr->currentQuery->results.inValues,
606  statementPtr->transactionPtr->stagedRows,
607  predicateResults)==false)
608  {
609  /*
610  * if (parent != NULL && parent->operatortype==OPERATOR_AND &&
611  * this==parent->rightchild)
612  */
613  if (0) // revert this back when andPredicate is tested
614  {
615  statementPtr->andPredicate(operatortype,
616  statementPtr->currentQuery->tableid,
619  statementPtr->currentQuery->results.inValues,
621  delete leftchild;
622  leftchild=NULL;
623  delete rightchild;
624  rightchild=NULL;
625  }
626  else
627  {
628  statementPtr->transactionPtr->sqlPredicate(statementPtr,
629  operatortype,
630  statementPtr->currentQuery->tableid,
633  statementPtr->currentQuery->locktype,
634  statementPtr->currentQuery->results.inValues,
635  this,
637  *nextAstNode = NULL;
638  delete leftchild;
639  leftchild=NULL;
640  delete rightchild;
641  rightchild=NULL;
642  return false;
643  }
644  }
645  else
646  {
647  delete leftchild;
648  leftchild=NULL;
649  delete rightchild;
650  rightchild=NULL;
651  }
652  break;
653 
654  case OPERATOR_NE:
655  statementPtr->stagedPredicate(operatortype,
656  statementPtr->currentQuery->tableid,
659  statementPtr->currentQuery->results.inValues,
660  statementPtr->transactionPtr->stagedRows,
662 
663  isoperator=false;
664 
665  /*
666  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
667  this==parent->rightchild)
668  */
669  if (0) // revert this back when andPredicate is tested
670  {
671  statementPtr->andPredicate(operatortype,
672  statementPtr->currentQuery->tableid,
674  statementPtr->currentQuery->results.inValues,
676  delete leftchild;
677  leftchild=NULL;
678  delete rightchild;
679  rightchild=NULL;
680  }
681  else
682  {
683  statementPtr->transactionPtr->sqlPredicate(statementPtr,
684  operatortype,
685  statementPtr->currentQuery->tableid,
688  statementPtr->currentQuery->locktype,
689  statementPtr->currentQuery->results.inValues,
690  this, predicateResults);
691  *nextAstNode = NULL;
692  delete leftchild;
693  leftchild=NULL;
694  delete rightchild;
695  rightchild=NULL;
696  return false;
697  }
698 
699  break;
700 
701  case OPERATOR_LT:
702  statementPtr->stagedPredicate(operatortype,
703  statementPtr->currentQuery->tableid,
706  statementPtr->currentQuery->results.inValues,
707  statementPtr->transactionPtr->stagedRows,
709 
710  isoperator=false;
711 
712  /*
713  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
714  this==parent->rightchild)
715  */
716  if (0) // revert this back when andPredicate is tested
717  {
718  statementPtr->andPredicate(operatortype,
719  statementPtr->currentQuery->tableid,
721  statementPtr->currentQuery->results.inValues,
723  delete leftchild;
724  leftchild=NULL;
725  delete rightchild;
726  rightchild=NULL;
727  }
728  else
729  {
730  statementPtr->transactionPtr->sqlPredicate(statementPtr,
731  operatortype,
732  statementPtr->currentQuery->tableid,
735  statementPtr->currentQuery->locktype,
736  statementPtr->currentQuery->results.inValues,
737  this, predicateResults);
738  *nextAstNode = NULL;
739  delete leftchild;
740  leftchild=NULL;
741  delete rightchild;
742  rightchild=NULL;
743  return false;
744  }
745 
746  break;
747 
748  case OPERATOR_GT:
749  statementPtr->stagedPredicate(operatortype,
750  statementPtr->currentQuery->tableid,
753  statementPtr->currentQuery->results.inValues,
754  statementPtr->transactionPtr->stagedRows,
756 
757  isoperator=false;
758 
759  /*
760  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
761  this==parent->rightchild)
762  */
763  if (0) // revert this back when andPredicate is tested
764  {
765  statementPtr->andPredicate(operatortype,
766  statementPtr->currentQuery->tableid,
768  statementPtr->currentQuery->results.inValues,
771  delete leftchild;
772  leftchild=NULL;
773  delete rightchild;
774  rightchild=NULL;
775  }
776  else
777  {
778  statementPtr->transactionPtr->sqlPredicate(statementPtr,
779  operatortype,
780  statementPtr->currentQuery->tableid,
783  statementPtr->currentQuery->locktype,
784  statementPtr->currentQuery->results.inValues,
785  this, predicateResults);
786  *nextAstNode = NULL;
787  delete leftchild;
788  leftchild=NULL;
789  delete rightchild;
790  rightchild=NULL;
791  return false;
792  }
793 
794  break;
795 
796  case OPERATOR_LTE:
797  statementPtr->stagedPredicate(operatortype,
798  statementPtr->currentQuery->tableid,
801  statementPtr->currentQuery->results.inValues,
802  statementPtr->transactionPtr->stagedRows,
804 
805  isoperator=false;
806 
807  /*
808  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
809  this==parent->rightchild)
810  */
811  if (0) // revert this back when andPredicate is tested
812  {
813  statementPtr->andPredicate(operatortype,
814  statementPtr->currentQuery->tableid,
816  statementPtr->currentQuery->results.inValues,
818  delete leftchild;
819  leftchild=NULL;
820  delete rightchild;
821  rightchild=NULL;
822  }
823  else
824  {
825  statementPtr->transactionPtr->sqlPredicate(statementPtr,
826  operatortype,
827  statementPtr->currentQuery->tableid,
830  statementPtr->currentQuery->locktype,
831  statementPtr->currentQuery->results.inValues,
832  this, predicateResults);
833  *nextAstNode = NULL;
834  delete leftchild;
835  leftchild=NULL;
836  delete rightchild;
837  rightchild=NULL;
838  return false;
839  }
840 
841  break;
842 
843  case OPERATOR_GTE:
844  statementPtr->stagedPredicate(operatortype,
845  statementPtr->currentQuery->tableid,
847  statementPtr->currentQuery->results.inValues,
848  statementPtr->transactionPtr->stagedRows,
850 
851  isoperator=false;
852 
853  /*
854  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
855  this==parent->rightchild)
856  */
857  if (0) // revert this back when andPredicate is tested
858  {
859  statementPtr->andPredicate(operatortype,
860  statementPtr->currentQuery->tableid,
862  statementPtr->currentQuery->results.inValues,
864  delete leftchild;
865  leftchild=NULL;
866  delete rightchild;
867  rightchild=NULL;
868  }
869  else
870  {
871  statementPtr->transactionPtr->sqlPredicate(statementPtr,
872  operatortype,
873  statementPtr->currentQuery->tableid,
876  statementPtr->currentQuery->locktype,
877  statementPtr->currentQuery->results.inValues,
878  this, predicateResults);
879  *nextAstNode = NULL;
880  delete leftchild;
881  leftchild=NULL;
882  delete rightchild;
883  rightchild=NULL;
884  return false;
885  }
886 
887  break;
888 
889  case OPERATOR_BETWEEN:
890  statementPtr->stagedPredicate(operatortype,
891  statementPtr->currentQuery->tableid,
894  statementPtr->currentQuery->results.inValues,
895  statementPtr->transactionPtr->stagedRows,
897 
898  isoperator=false;
899 
900  /*
901  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
902  this==parent->rightchild)
903  */
904  if (0) // revert this back when andPredicate is tested
905  {
906  statementPtr->andPredicate(operatortype,
907  statementPtr->currentQuery->tableid,
909  statementPtr->currentQuery->results.inValues,
912  delete leftchild;
913  leftchild=NULL;
914  delete rightchild;
915  rightchild=NULL;
916  }
917  else
918  {
919  statementPtr->transactionPtr->sqlPredicate(statementPtr,
920  operatortype,
921  statementPtr->currentQuery->tableid,
924  statementPtr->currentQuery->locktype,
925  statementPtr->currentQuery->results.inValues,
926  this, predicateResults);
927  *nextAstNode = NULL;
928  delete leftchild;
929  leftchild=NULL;
930  delete rightchild;
931  rightchild=NULL;
932  return false;
933  }
934 
935  break;
936 
937  case OPERATOR_NOTBETWEEN:
938  statementPtr->stagedPredicate(operatortype,
939  statementPtr->currentQuery->tableid,
942  statementPtr->currentQuery->results.inValues,
943  statementPtr->transactionPtr->stagedRows,
945 
946  isoperator=false;
947 
948  /*
949  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
950  this==parent->rightchild)
951  */
952  if (0) // revert this back when andPredicate is tested
953  {
954  statementPtr->andPredicate(operatortype,
955  statementPtr->currentQuery->tableid,
957  statementPtr->currentQuery->results.inValues,
960  delete leftchild;
961  leftchild=NULL;
962  delete rightchild;
963  rightchild=NULL;
964  }
965  else
966  {
967  statementPtr->transactionPtr->sqlPredicate(statementPtr,
968  operatortype,
969  statementPtr->currentQuery->tableid,
972  statementPtr->currentQuery->locktype,
973  statementPtr->currentQuery->results.inValues,
974  this, predicateResults);
975  *nextAstNode = NULL;
976  delete leftchild;
977  leftchild=NULL;
978  delete rightchild;
979  rightchild=NULL;
980  return false;
981  }
982 
983  break;
984 
985  case OPERATOR_ISNULL: // unary operator
986  statementPtr->stagedPredicate(operatortype,
987  statementPtr->currentQuery->tableid,
990  statementPtr->currentQuery->results.inValues,
991  statementPtr->transactionPtr->stagedRows,
993 
994  isoperator=false;
995 
996  /*
997  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
998  this==parent->rightchild)
999  */
1000  if (0) // revert this back when andPredicate is tested
1001  {
1002  statementPtr->andPredicate(operatortype,
1003  statementPtr->currentQuery->tableid,
1005  statementPtr->currentQuery->results.inValues,
1007  delete rightchild;
1008  rightchild=NULL;
1009  }
1010  else
1011  {
1012  statementPtr->transactionPtr->sqlPredicate(statementPtr,
1013  operatortype,
1014  statementPtr->currentQuery->tableid,
1017  statementPtr->currentQuery->locktype,
1018  statementPtr->currentQuery->results.inValues,
1019  this, predicateResults);
1020  *nextAstNode = NULL;
1021  delete rightchild;
1022  rightchild=NULL;
1023  return false;
1024  }
1025 
1026  break;
1027 
1028  case OPERATOR_ISNOTNULL: // unary operator
1029  statementPtr->stagedPredicate(operatortype,
1030  statementPtr->currentQuery->tableid,
1031  leftchild->operand,
1033  statementPtr->currentQuery->results.inValues,
1034  statementPtr->transactionPtr->stagedRows,
1036 
1037  isoperator=false;
1038 
1039  /*
1040  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
1041  this==parent->rightchild)
1042  */
1043  if (0) // revert this back when andPredicate is tested
1044  {
1045  statementPtr->andPredicate(operatortype,
1046  statementPtr->currentQuery->tableid,
1048  statementPtr->currentQuery->results.inValues,
1050  delete rightchild;
1051  rightchild=NULL;
1052  }
1053  else
1054  {
1055  statementPtr->transactionPtr->sqlPredicate(statementPtr,
1056  operatortype,
1057  statementPtr->currentQuery->tableid,
1060  statementPtr->currentQuery->locktype,
1061  statementPtr->currentQuery->results.inValues,
1062  this, predicateResults);
1063  *nextAstNode = NULL;
1064  delete rightchild;
1065  rightchild=NULL;
1066  return false;
1067  }
1068 
1069  break;
1070 
1071  case OPERATOR_IN: // unary operator
1072  statementPtr->stagedPredicate(operatortype,
1073  statementPtr->currentQuery->tableid,
1074  leftchild->operand,
1076  statementPtr->currentQuery->results.inValues,
1077  statementPtr->transactionPtr->stagedRows,
1079 
1080  isoperator=false;
1081 
1082  // resolve inobject
1083  if (statementPtr->currentQuery->inobject.issubquery==true)
1084  {
1085  statementPtr->subqueryIn(this);
1086  }
1087  else
1088  {
1089  // fieldid is in the rightoperand, then get type
1090  int64_t fieldid;
1091  memcpy(&fieldid, &rightchild->operand[1], sizeof(fieldid));
1092  fieldtype_e fieldtype = statementPtr->schemaPtr->tables[statementPtr->currentQuery->tableid]->fields[fieldid].type;
1093 
1094  for (size_t n=0;
1095  n < statementPtr->currentQuery->inobject.expressionlist.size();
1096  n++)
1097  {
1098  fieldValue_s fieldValue = {};
1099  class Ast &astRef =
1100  *statementPtr->currentQuery->inobject.expressionlist[n];
1101  statementPtr->searchExpression(0, &astRef);
1102 
1103  if (astRef.operand[0]==OPERAND_NULL)
1104  {
1105  fieldValue.isnull=true;
1106  }
1107  else
1108  {
1109  switch (fieldtype)
1110  {
1111  case INT:
1112  memcpy(&fieldValue.value.integer, &astRef.operand[1],
1113  sizeof(int64_t));
1114  break;
1115 
1116  case UINT:
1117  memcpy(&fieldValue.value.uinteger, &astRef.operand[1],
1118  sizeof(int64_t));
1119  break;
1120 
1121  case BOOL:
1122  {
1123  int64_t torf;
1124  memcpy(&torf, &astRef.operand[1], sizeof(torf));
1125  fieldValue.value.boolean = (bool)torf;
1126  }
1127  break;
1128 
1129  case FLOAT:
1130  toFloat(astRef.operand, fieldValue);
1131  /*
1132  memcpy(&fieldValue.value.floating, &astRef.operand[1],
1133  sizeof(long double));
1134  */
1135  break;
1136 
1137  case CHAR:
1138  fieldValue.value.character = astRef.operand[1];
1139  break;
1140 
1141  case CHARX:
1142  fieldValue.str = astRef.operand.substr(1, string::npos);
1143  break;
1144 
1145  case VARCHAR:
1146  fieldValue.str = astRef.operand.substr(1, string::npos);
1147  break;
1148 
1149  default:
1150  printf("%s %i anomaly %i\n", __FILE__, __LINE__,
1151  fieldtype);
1152  }
1153  }
1154 
1155  statementPtr->currentQuery->results.inValues.push_back(fieldValue);
1156  delete &astRef;
1157  }
1158 
1159  statementPtr->currentQuery->inobject.expressionlist.clear();
1160  }
1161 
1162  /*
1163  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
1164  this==parent->rightchild)
1165  */
1166  if (0) // revert this back when andPredicate is tested
1167  {
1168  statementPtr->andPredicate(operatortype,
1169  statementPtr->currentQuery->tableid,
1171  statementPtr->currentQuery->results.inValues,
1174  delete rightchild;
1175  rightchild=NULL;
1176  }
1177  else
1178  {
1179  statementPtr->transactionPtr->sqlPredicate(statementPtr,
1180  operatortype,
1181  statementPtr->currentQuery->tableid,
1184  statementPtr->currentQuery->locktype,
1185  statementPtr->currentQuery->results.inValues,
1186  this, predicateResults);
1187  *nextAstNode = NULL;
1188  delete rightchild;
1189  rightchild=NULL;
1190  return false;
1191  }
1192 
1193  break;
1194 
1195  case OPERATOR_NOTIN: // unary operator
1196  statementPtr->stagedPredicate(operatortype,
1197  statementPtr->currentQuery->tableid,
1198  leftchild->operand,
1200  statementPtr->currentQuery->results.inValues,
1201  statementPtr->transactionPtr->stagedRows,
1203 
1204  isoperator=false;
1205 
1206  // resolve inobject
1207  if (statementPtr->currentQuery->inobject.issubquery==true)
1208  {
1209  statementPtr->subqueryIn(this);
1210  }
1211  else
1212  {
1213  // fieldid is in the rightoperand, then get type
1214  int64_t fieldid;
1215  memcpy(&fieldid, &rightchild->operand[1], sizeof(fieldid));
1216  fieldtype_e fieldtype =
1217  statementPtr->schemaPtr->tables[statementPtr->currentQuery->tableid]->fields[fieldid].type;
1218 
1219  for (size_t n=0;
1220  n < statementPtr->currentQuery->inobject.expressionlist.size();
1221  n++)
1222  {
1223  fieldValue_s fieldValue = {};
1224  class Ast &astRef =
1225  *statementPtr->currentQuery->inobject.expressionlist[n];
1226  statementPtr->searchExpression(0, &astRef);
1227 
1228  if (astRef.operand[0]==OPERAND_NULL)
1229  {
1230  fieldValue.isnull=true;
1231  }
1232  else
1233  {
1234  switch (fieldtype)
1235  {
1236  case INT:
1237  memcpy(&fieldValue.value.integer, &astRef.operand[1],
1238  sizeof(int64_t));
1239  break;
1240 
1241  case UINT:
1242  memcpy(&fieldValue.value.uinteger, &astRef.operand[1],
1243  sizeof(int64_t));
1244  break;
1245 
1246  case BOOL:
1247  {
1248  int64_t torf;
1249  memcpy(&torf, &astRef.operand[1], sizeof(torf));
1250  fieldValue.value.boolean = (bool)torf;
1251  }
1252  break;
1253 
1254  case FLOAT:
1255  toFloat(astRef.operand, fieldValue);
1256  break;
1257 
1258  case CHAR:
1259  fieldValue.value.character = astRef.operand[1];
1260  break;
1261 
1262  case CHARX:
1263  fieldValue.str = astRef.operand.substr(1, string::npos);
1264  break;
1265 
1266  case VARCHAR:
1267  fieldValue.str = astRef.operand.substr(1, string::npos);
1268  break;
1269 
1270  default:
1271  printf("%s %i anomaly %i\n", __FILE__, __LINE__,
1272  fieldtype);
1273  }
1274  }
1275 
1276  statementPtr->currentQuery->results.inValues.push_back(fieldValue);
1277  delete &astRef;
1278  }
1279 
1280  statementPtr->currentQuery->inobject.expressionlist.clear();
1281  }
1282 
1283  if (0) // revert this back when andPredicate is tested
1284  {
1285  statementPtr->andPredicate(operatortype,
1286  statementPtr->currentQuery->tableid,
1288  statementPtr->currentQuery->results.inValues,
1291  delete rightchild;
1292  rightchild=NULL;
1293  }
1294  else
1295  {
1296  statementPtr->transactionPtr->sqlPredicate(statementPtr,
1297  operatortype,
1298  statementPtr->currentQuery->tableid,
1301  statementPtr->currentQuery->locktype,
1302  statementPtr->currentQuery->results.inValues,
1303  this, predicateResults);
1304  *nextAstNode = NULL;
1305  delete rightchild;
1306  rightchild=NULL;
1307  return false;
1308  }
1309 
1310  break;
1311 
1312  case OPERATOR_LIKE:
1313  statementPtr->stagedPredicate(operatortype,
1314  statementPtr->currentQuery->tableid,
1315  leftchild->operand,
1317  statementPtr->currentQuery->results.inValues,
1318  statementPtr->transactionPtr->stagedRows,
1320 
1321  isoperator=false;
1322 
1323  if (0) // revert this back when andPredicate is tested
1324  {
1325  statementPtr->andPredicate(operatortype,
1326  statementPtr->currentQuery->tableid,
1327  leftchild->operand,
1329  statementPtr->currentQuery->results.inValues,
1332  delete leftchild;
1333  leftchild=NULL;
1334  delete rightchild;
1335  rightchild=NULL;
1336  }
1337  else
1338  {
1339  string str=rightchild->operand.substr(1, string::npos);
1340  statementPtr->transactionPtr->sqlPredicate(statementPtr,
1341  operatortype,
1342  statementPtr->currentQuery->tableid,
1343  leftchild->operand,
1345  statementPtr->currentQuery->locktype,
1346  statementPtr->currentQuery->results.inValues,
1347  this, predicateResults);
1348  *nextAstNode = NULL;
1349  delete leftchild;
1350  leftchild=NULL;
1351  delete rightchild;
1352  rightchild=NULL;
1353  return false;
1354  }
1355 
1356  break;
1357 
1358  case OPERATOR_NOTLIKE:
1359  statementPtr->stagedPredicate(operatortype,
1360  statementPtr->currentQuery->tableid,
1361  leftchild->operand,
1363  statementPtr->currentQuery->results.inValues,
1364  statementPtr->transactionPtr->stagedRows,
1366 
1367  isoperator=false;
1368 
1369  /*
1370  if (parent != NULL && parent->operatortype==OPERATOR_AND &&
1371  this==parent->rightchild)
1372  */
1373  if (0) // revert this back when andPredicate is tested
1374  {
1375  statementPtr->andPredicate(operatortype,
1376  statementPtr->currentQuery->tableid,
1378  statementPtr->currentQuery->results.inValues,
1381  delete leftchild;
1382  leftchild=NULL;
1383  delete rightchild;
1384  rightchild=NULL;
1385  }
1386  else
1387  {
1388  statementPtr->transactionPtr->sqlPredicate(statementPtr,
1389  operatortype,
1390  statementPtr->currentQuery->tableid,
1391  leftchild->operand,
1393  statementPtr->currentQuery->locktype,
1394  statementPtr->currentQuery->results.inValues,
1395  this, predicateResults);
1396  *nextAstNode = NULL;
1397  delete leftchild;
1398  leftchild=NULL;
1399  delete rightchild;
1400  rightchild=NULL;
1401  return false;
1402  }
1403 
1404  break;
1405 
1406  case OPERATOR_EXISTS: // unary operator
1407  {
1408  // need to process subqueries first
1409  statementPtr->stagedPredicate(operatortype,
1410  statementPtr->currentQuery->tableid,
1411  leftchild->operand,
1413  statementPtr->currentQuery->results.inValues,
1414  statementPtr->transactionPtr->stagedRows,
1416 
1417  statementPtr->subqueryExists(this);
1418  delete rightchild;
1419  rightchild=NULL;
1420  }
1421  break;
1422 
1423  case OPERATOR_UNIQUE: // unary operator
1424  {
1425  //need to process subqueries first
1426  statementPtr->stagedPredicate(operatortype,
1427  statementPtr->currentQuery->tableid,
1428  leftchild->operand,
1430  statementPtr->currentQuery->results.inValues,
1431  statementPtr->transactionPtr->stagedRows,
1433 
1434  statementPtr->subqueryUnique(this);
1435  delete rightchild;
1436  rightchild=NULL;
1437  }
1438  break;
1439 
1440  case OPERATOR_BETWEENAND:
1441  switch (leftchild->operand[0])
1442  {
1443  case OPERAND_INTEGER:
1444  {
1445  if (rightchild->operand[0] != OPERAND_INTEGER)
1446  {
1447  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1448  leftchild->operand[0], rightchild->operand[0]);
1449  return false;
1450  }
1451 
1452  operand.resize(1+2*sizeof(int64_t), (char)0);
1453  operand[0] = OPERAND_INTEGER;
1454  memcpy(&operand[1], &leftchild->operand[1], sizeof(int64_t));
1455  memcpy(&operand[1+sizeof(int64_t)], &rightchild->operand[1],
1456  sizeof(int64_t));
1457  isoperator=false;
1458  }
1459  break;
1460 
1461  case OPERAND_FLOAT:
1462  {
1463  if (rightchild->operand[0] != OPERAND_FLOAT)
1464  {
1465  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1466  leftchild->operand[0], rightchild->operand[0]);
1467  return false;
1468  }
1469 
1470  operand.resize(1+2*sizeof(long double), (char)0);
1471  operand[0] = OPERAND_FLOAT;
1472  memcpy(&operand[1], &leftchild->operand[1], sizeof(long double));
1473  memcpy(&operand[1+sizeof(long double)], &rightchild->operand[1],
1474  sizeof(long double));
1475  isoperator=false;
1476  }
1477  break;
1478 
1479  case OPERAND_STRING:
1480  {
1481  if (rightchild->operand[0] != OPERAND_STRING)
1482  {
1483  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1484  leftchild->operand[0], rightchild->operand[0]);
1485  return false;
1486  }
1487 
1488  operand.resize(1+sizeof(size_t)+(leftchild->operand.size()-1) +
1489  (rightchild->operand.size()-1), (char)0);
1490  operand[0] = OPERAND_STRING;
1491  size_t len = leftchild->operand.size()-1;
1492  memcpy(&operand[1], &len, sizeof(len));
1493  memcpy(&operand[1+sizeof(len)], &leftchild->operand[1], len);
1494  memcpy(&operand[1+sizeof(len)+len], &rightchild->operand[1],
1495  rightchild->operand.size()-1);
1496  isoperator=false;
1497  }
1498  break;
1499 
1500  default:
1501  printf("%s %i bad type %c\n", __FILE__, __LINE__,
1502  leftchild->operand[0]);
1503  return false;
1504  }
1505 
1506  delete leftchild;
1507  leftchild=NULL;
1508  delete rightchild;
1509  rightchild=NULL;
1510  break;
1511 
1512  default:
1513  printf("%s %i anomaly %i\n", __FILE__, __LINE__, operatortype);
1514  }
1515 
1516  *nextAstNode = parent;
1517  return true;
1518 }
1519 
1520 // to do updates like: set fieldA=fieldA+5
1521 void Ast::evaluateAssignment(vector<fieldValue_s> &fieldValues,
1522  class Statement *statementPtr)
1523 {
1524  if (isoperator==false)
1525  {
1526  normalizeSetAssignmentOperand(fieldValues, statementPtr);
1527  return;
1528  }
1529 
1530  if (operatortype != OPERATOR_NEGATION) // not unary operator
1531  {
1532  leftchild->evaluateAssignment(fieldValues, statementPtr);
1533  }
1534 
1535  rightchild->evaluateAssignment(fieldValues, statementPtr);
1536 
1537  switch (operatortype)
1538  {
1540  {
1541  if (leftchild->operand[0] != OPERAND_STRING ||
1543  {
1544  printf("%s %i bad operand %c\n", __FILE__, __LINE__, operand[0]);
1545  return;
1546  }
1547 
1549  operand.append(leftchild->operand.substr(1, string::npos));
1550  operand.append(rightchild->operand.substr(1, string::npos));
1551  isoperator=false;
1552  delete leftchild;
1553  leftchild=NULL;
1554  delete rightchild;
1555  rightchild=NULL;
1556  }
1557  break;
1558 
1559  case OPERATOR_ADDITION:
1560  if (leftchild->operand[0]==OPERAND_FLOAT ||
1562  {
1565  }
1566 
1567  switch (leftchild->operand[0])
1568  {
1569  case OPERAND_INTEGER:
1570  {
1571  if (rightchild->operand[0] != OPERAND_INTEGER)
1572  {
1573  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1574  leftchild->operand[0], rightchild->operand[0]);
1575  return;
1576  }
1577 
1578  operand.resize(1+sizeof(int64_t), (char)0);
1579  operand[0] = OPERAND_INTEGER;
1580  int64_t val = *(int64_t *)(leftchild->operand.c_str()+1) +
1581  *(int64_t *)(rightchild->operand.c_str()+1);
1582  memcpy(&operand[1], &val, sizeof(val));
1583  isoperator=false;
1584  }
1585  break;
1586 
1587  case OPERAND_FLOAT:
1588  {
1589  if (rightchild->operand[0] != OPERAND_FLOAT)
1590  {
1591  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1592  leftchild->operand[0], rightchild->operand[0]);
1593  return;
1594  }
1595 
1596  operand.resize(1+sizeof(long double), (char)0);
1597  operand[0] = OPERAND_FLOAT;
1598  int64_t val = *(long double *)(leftchild->operand.c_str()+1) +
1599  *(long double *)(rightchild->operand.c_str()+1);
1600  memcpy(&operand[1], &val, sizeof(val));
1601  isoperator=false;
1602  }
1603  break;
1604 
1605  default:
1606  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
1607  leftchild->operand[0]);
1608  return;
1609  }
1610 
1611  delete leftchild;
1612  leftchild=NULL;
1613  delete rightchild;
1614  rightchild=NULL;
1615  break;
1616 
1617  case OPERATOR_SUBTRACTION:
1618  if (leftchild->operand[0]==OPERAND_FLOAT ||
1620  {
1623  }
1624 
1625  switch (leftchild->operand[0])
1626  {
1627  case OPERAND_INTEGER:
1628  {
1629  if (rightchild->operand[0] != OPERAND_INTEGER)
1630  {
1631  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1632  leftchild->operand[0], rightchild->operand[0]);
1633  return;
1634  }
1635 
1636  operand.resize(1+sizeof(int64_t), (char)0);
1637  operand[0] = OPERAND_INTEGER;
1638  int64_t val = *(int64_t *)(leftchild->operand.c_str()+1) -
1639  *(int64_t *)(rightchild->operand.c_str()+1);
1640  memcpy(&operand[1], &val, sizeof(val));
1641  isoperator=false;
1642  }
1643  break;
1644 
1645  case OPERAND_FLOAT:
1646  {
1647  if (rightchild->operand[0] != OPERAND_FLOAT)
1648  {
1649  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1650  leftchild->operand[0], rightchild->operand[0]);
1651  return;
1652  }
1653 
1654  operand.resize(1+sizeof(long double), (char)0);
1655  operand[0] = OPERAND_FLOAT;
1656  int64_t val = *(long double *)(leftchild->operand.c_str()+1) -
1657  *(long double *)(rightchild->operand.c_str()+1);
1658  memcpy(&operand[1], &val, sizeof(val));
1659  isoperator=false;
1660  }
1661  break;
1662 
1663  default:
1664  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
1665  leftchild->operand[0]);
1666  return;
1667  }
1668 
1669  delete leftchild;
1670  leftchild=NULL;
1671  delete rightchild;
1672  rightchild=NULL;
1673  break;
1674 
1676  if (leftchild->operand[0]==OPERAND_FLOAT ||
1678  {
1681  }
1682 
1683  switch (leftchild->operand[0])
1684  {
1685  case OPERAND_INTEGER:
1686  {
1687  if (rightchild->operand[0] != OPERAND_INTEGER)
1688  {
1689  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1690  leftchild->operand[0], rightchild->operand[0]);
1691  return;
1692  }
1693 
1694  operand.resize(1+sizeof(int64_t), (char)0);
1695  operand[0] = OPERAND_INTEGER;
1696  int64_t val = *(int64_t *)(leftchild->operand.c_str()+1) *
1697  *(int64_t *)(rightchild->operand.c_str()+1);
1698  memcpy(&operand[1], &val, sizeof(val));
1699  isoperator=false;
1700  }
1701  break;
1702 
1703  case OPERAND_FLOAT:
1704  {
1705  if (rightchild->operand[0] != OPERAND_FLOAT)
1706  {
1707  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1708  leftchild->operand[0], rightchild->operand[0]);
1709  return;
1710  }
1711 
1712  operand.resize(1+sizeof(long double), (char)0);
1713  operand[0] = OPERAND_FLOAT;
1714  int64_t val = *(long double *)(leftchild->operand.c_str()+1) *
1715  *(long double *)(rightchild->operand.c_str()+1);
1716  memcpy(&operand[1], &val, sizeof(val));
1717  isoperator=false;
1718  }
1719  break;
1720 
1721  default:
1722  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
1723  leftchild->operand[0]);
1724  return;
1725  }
1726 
1727  delete leftchild;
1728  leftchild=NULL;
1729  delete rightchild;
1730  rightchild=NULL;
1731  break;
1732 
1733  case OPERATOR_DIVISION:
1734  if (leftchild->operand[0]==OPERAND_FLOAT ||
1736  {
1739  }
1740 
1741  switch (leftchild->operand[0])
1742  {
1743  case OPERAND_INTEGER:
1744  {
1745  if (rightchild->operand[0] != OPERAND_INTEGER)
1746  {
1747  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1748  leftchild->operand[0], rightchild->operand[0]);
1749  return;
1750  }
1751 
1752  operand.resize(1+sizeof(int64_t), (char)0);
1753  operand[0] = OPERAND_INTEGER;
1754  int64_t val = *(int64_t *)(leftchild->operand.c_str()+1) /
1755  *(int64_t *)(rightchild->operand.c_str()+1);
1756  memcpy(&operand[1], &val, sizeof(val));
1757  isoperator=false;
1758  }
1759  break;
1760 
1761  case OPERAND_FLOAT:
1762  {
1763  if (rightchild->operand[0] != OPERAND_FLOAT)
1764  {
1765  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1766  leftchild->operand[0], rightchild->operand[0]);
1767  return;
1768  }
1769 
1770  operand.resize(1+sizeof(long double), (char)0);
1771  operand[0] = OPERAND_FLOAT;
1772  int64_t val = *(long double *)(leftchild->operand.c_str()+1) /
1773  *(long double *)(rightchild->operand.c_str()+1);
1774  memcpy(&operand[1], &val, sizeof(val));
1775  isoperator=false;
1776  }
1777  break;
1778 
1779  default:
1780  printf("%s %i not an arithmetic type %c\n", __FILE__, __LINE__,
1781  leftchild->operand[0]);
1782  return;
1783  }
1784 
1785  delete leftchild;
1786  leftchild=NULL;
1787  delete rightchild;
1788  rightchild=NULL;
1789  break;
1790 
1791  case OPERATOR_NEGATION:
1792  if (rightchild->operand[0]==OPERAND_FLOAT)
1793  {
1795  }
1796 
1797  switch (rightchild->operand[0])
1798  {
1799  case OPERAND_INTEGER:
1800  {
1801  if (rightchild->operand[0] != OPERAND_INTEGER)
1802  {
1803  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1804  leftchild->operand[0], rightchild->operand[0]);
1805  return;
1806  }
1807 
1808  operand.resize(1+sizeof(int64_t), (char)0);
1809  operand[0] = OPERAND_INTEGER;
1810  int64_t val = 0 -
1811  *(int64_t *)(rightchild->operand.c_str()+1);
1812  memcpy(&operand[1], &val, sizeof(val));
1813  isoperator=false;
1814  }
1815  break;
1816 
1817  case OPERAND_FLOAT:
1818  {
1819  if (rightchild->operand[0] != OPERAND_FLOAT)
1820  {
1821  printf("%s %i operand mismatch %c %i\n", __FILE__, __LINE__,
1822  leftchild->operand[0], rightchild->operand[0]);
1823  return;
1824  }
1825 
1826  operand.resize(1+sizeof(long double), (char)0);
1827  operand[0] = OPERAND_FLOAT;
1828  int64_t val = 0 -
1829  *(long double *)(rightchild->operand.c_str()+1);
1830  memcpy(&operand[1], &val, sizeof(val));
1831  isoperator=false;
1832  }
1833  break;
1834 
1835  default:
1836  printf("%s %i not an arithmetic type '%c'\n", __FILE__, __LINE__,
1837  leftchild->operand[0]);
1838  return;
1839  }
1840 
1841  delete rightchild;
1842  rightchild=NULL;
1843  break;
1844 
1845  default:
1846  printf("%s %i can't evaluate %i in set assignment\n", __FILE__, __LINE__,
1847  operatortype);
1848  }
1849 }
1850 
1851 void Ast::normalizeSetAssignmentOperand(vector<fieldValue_s> &fieldValues,
1852  class Statement *statementPtr)
1853 {
1854  switch (operand[0])
1855  {
1856  case OPERAND_FIELDID:
1857  {
1858  int64_t fieldid;
1859  memcpy(&fieldid, &operand[1], sizeof(fieldid));
1860 
1861  switch (statementPtr->schemaPtr->tables[statementPtr->currentQuery->tableid]->fields[fieldid].type)
1862  {
1863  case INT:
1864  operand.resize(1+sizeof(int64_t), (char)0);
1865  operand[0] = OPERAND_INTEGER;
1866  memcpy(&operand[1], &fieldValues[fieldid].value.integer,
1867  sizeof(int64_t));
1868  break;
1869 
1870  case UINT:
1871  operand.resize(1+sizeof(int64_t), (char)0);
1872  operand[0] = OPERAND_INTEGER;
1873  memcpy(&operand[1], &fieldValues[fieldid].value.uinteger,
1874  sizeof(int64_t));
1875  break;
1876 
1877  case BOOL:
1878  operand.resize(1+sizeof(int64_t), (char)0);
1879  operand[0] = OPERAND_INTEGER;
1880  int64_t val;
1881 
1882  if (fieldValues[fieldid].value.boolean==true)
1883  {
1884  val=1;
1885  }
1886  else
1887  {
1888  val=0;
1889  }
1890 
1891  memcpy(&operand[1], &val, sizeof(int64_t));
1892  break;
1893 
1894  case FLOAT:
1895  operand.resize(1+sizeof(long double), (char)0);
1896  operand[0] = OPERAND_FLOAT;
1897  memcpy(&operand[1], &fieldValues[fieldid].value.floating,
1898  sizeof(int64_t));
1899  break;
1900 
1901  case CHAR:
1902  operand.resize(1+sizeof(char), (char)0);
1903  operand[0] = OPERAND_STRING;
1904  operand[1] = fieldValues[fieldid].value.character;
1905  break;
1906 
1907  case CHARX:
1908  operand.assign(1, OPERAND_STRING);
1909  operand.append(fieldValues[fieldid].str);
1910  break;
1911 
1912  case VARCHAR:
1913  operand.assign(1, OPERAND_STRING);
1914  operand.append(fieldValues[fieldid].str);
1915  break;
1916 
1917  default:
1918  printf("%s %i anomaly %i\n", __FILE__, __LINE__,
1919  statementPtr->schemaPtr->tables[statementPtr->currentQuery->tableid]->fields[fieldid].type);
1920  }
1921  }
1922  break;
1923 
1924  case OPERAND_SUBQUERY:
1925  statementPtr->subqueryScalar(this);
1926  break;
1927 
1928  case OPERAND_PARAMETER:
1929  {
1930  int64_t paramnum;
1931  memcpy(&paramnum, &operand[1], sizeof(paramnum));
1932  operand = statementPtr->parameters[paramnum];
1933  }
1934  break;
1935 
1936  default:
1937  return;
1938  }
1939 }
1940 
1941 void Ast::toFloat(const string &inoperand, fieldValue_s &outField)
1942 {
1943  switch (inoperand[0])
1944  {
1945  case OPERAND_INTEGER:
1946  {
1947  int64_t val;
1948  memcpy(&val, &inoperand[1], sizeof(val));
1949  outField.value.floating=(long double)val;
1950  }
1951  break;
1952 
1953  case OPERAND_FLOAT:
1954  memcpy(&outField.value.floating, &inoperand[1], sizeof(long double));
1955  break;
1956 
1957  default:
1958  outField.value.floating=0;
1959  }
1960 }
1961 
1962 void Ast::toFloat(const string &inoperand, string &outoperand)
1963 {
1964  string instr=inoperand;
1965 
1966  switch (instr[0])
1967  {
1968  case OPERAND_INTEGER:
1969  {
1970  outoperand.resize(1+sizeof(int64_t), OPERAND_FLOAT);
1971  int64_t val;
1972  memcpy(&val, &instr[1], sizeof(val));
1973  memcpy(&outoperand[1], &val, sizeof(val));
1974  }
1975  break;
1976 
1977  case OPERAND_FLOAT:
1978  outoperand=instr;
1979  break;
1980 
1981  default:
1982  outoperand.resize(1+sizeof(long double), OPERAND_FLOAT);
1983  long double val;
1984  memcpy(&val, &instr[1], sizeof(val));
1985  memcpy(&outoperand[1], &val, sizeof(val));
1986  }
1987 }
1988 
1990 {
1991 }
1992 
1994  class Schema *schemaPtrarg) :
1995  taPtr(taPtrarg), schemaPtr(schemaPtrarg), transactionPtr(NULL),
1996  currentQuery(NULL)
1997 {
1998  reentry = reentry_s();
1999 }
2000 
2002 {
2003  cp(orig);
2004 }
2005 
2007 {
2008  cp(orig);
2009  return *this;
2010 }
2011 
2012 /* copy of a statement should occur only prior to execution */
2013 void Statement::cp(const Statement &orig)
2014 {
2015  taPtr = orig.taPtr;
2016  schemaPtr = orig.schemaPtr;
2017  reentry = orig.reentry;
2019  currentQuery = orig.currentQuery;
2020 
2021  for (size_t n=0; n < orig.queries.size(); n++)
2022  {
2023  queries.push_back(cpquery(orig.queries[n]));
2024  }
2025 
2026  parameters = orig.parameters;
2027  queryindex = orig.queryindex;
2028 }
2029 
2031 {
2032  query_s newstmt;
2033 
2034  newstmt.instance = orig.instance;
2035  newstmt.type = orig.type;
2036  newstmt.isforupdate = orig.isforupdate;
2037  newstmt.hasnolock = orig.hasnolock;
2038  newstmt.haswhere = orig.haswhere;
2039  newstmt.hasgroupby= orig.hasgroupby;
2040  newstmt.hashaving = orig.hashaving;
2041  newstmt.hasorderby = orig.hasorderby;
2042  newstmt.table = orig.table;
2043  newstmt.tableid = orig.tableid;
2044  newstmt.locktype = orig.locktype;
2045  newstmt.groupByList = orig.groupByList;
2046  newstmt.fromColumns = orig.fromColumns;
2047  newstmt.fromColumnids = orig.fromColumnids;
2048  newstmt.orderbylist = orig.orderbylist;
2049 
2050  newstmt.inobject.issubquery = orig.inobject.issubquery;
2051  newstmt.inobject.subquery = orig.inobject.subquery;
2052  size_t siz = orig.inobject.expressionlist.size();
2053  newstmt.inobject.expressionlist.resize(siz, NULL);
2054 
2055  for (size_t n=0; n < siz; n++)
2056  {
2057  newstmt.inobject.expressionlist[n] = new class Ast;
2058  *newstmt.inobject.expressionlist[n] = *orig.inobject.expressionlist[n];
2059  }
2060 
2061  if (orig.searchCondition != NULL)
2062  {
2063  newstmt.searchCondition = new class Ast;
2064  *newstmt.searchCondition = *orig.searchCondition;
2065  }
2066  else
2067  {
2068  newstmt.searchCondition=NULL;
2069  }
2070 
2071  /* don't copy assignments, as fieldid assumedly has already been
2072  * resolved, and it makes keeping track of new Ast * objects difficult
2073  */
2074 
2075  boost::unordered_map<int64_t, class Ast *>::const_iterator it;
2076 
2077  for (it = orig.fieldidAssignments.begin();
2078  it != orig.fieldidAssignments.end(); it++)
2079  {
2080 
2081  newstmt.fieldidAssignments[it->first] = new class Ast;
2082  *newstmt.fieldidAssignments[it->first] = *it->second;
2083  }
2084 
2085  for (size_t n=0; n < orig.insertColumns.size(); n++)
2086  {
2087  newstmt.insertColumns.push_back(new class Ast);
2088  *newstmt.insertColumns[n] = *orig.insertColumns[n];
2089  }
2090 
2091  /* results should not need to be copied, as they are created only by
2092  * an executing statement
2093  */
2094  return newstmt;
2095 }
2096 
2098 {
2099  for (size_t n=0; n < queries.size(); n++)
2100  {
2101  query_s &queryRef = queries[n];
2102 
2103  if (queryRef.searchCondition != NULL)
2104  {
2105  delete queryRef.searchCondition;
2106  }
2107 
2108  for (size_t m=0; m < queryRef.inobject.expressionlist.size(); m++)
2109  {
2110  delete queryRef.inobject.expressionlist[m];
2111  }
2112 
2113  boost::unordered_map<int64_t, class Ast *>::iterator it;
2114 
2115  for (it = queryRef.fieldidAssignments.begin();
2116  it != queryRef.fieldidAssignments.end(); it++)
2117  {
2118  delete it->second;
2119  }
2120 
2121  for (size_t m=0; m < queryRef.insertColumns.size(); m++)
2122  {
2123  delete queryRef.insertColumns[m];
2124  }
2125  }
2126 }
2127 
2129 {
2130  for (size_t n=0; n < queries.size(); n++)
2131  {
2132  currentQuery=&queries[n];
2133 
2134  switch (currentQuery->type)
2135  {
2136  case CMD_SELECT:
2137  break;
2138 
2139  case CMD_INSERT:
2140  break;
2141 
2142  case CMD_UPDATE:
2143  break;
2144 
2145  case CMD_DELETE:
2146  break;
2147 
2148  default: // noop, must be BEGIN, COMMIT, etc.
2149  return true;
2150  }
2151 
2152  if (resolveTableFields2()==false)
2153  {
2154  return false;
2155  }
2156  }
2157 
2158  return true;
2159 }
2160 
2162 {
2163  // resolve tableid
2165  {
2168  }
2169  else
2170  {
2171  return false;
2172  }
2173 
2174  class Table &tableRef = *schemaPtr->tables[currentQuery->tableid];
2175 
2176  // resolve fieldids in select columns
2178  {
2179  for (ssize_t n=currentQuery->fromColumns.size()-1; n >= 0; n--)
2180  {
2181  string &fromColumnRef = currentQuery->fromColumns[n];
2182 
2183  switch (fromColumnRef[0])
2184  {
2185  case '*':
2186  {
2187  for (size_t n=0;
2188  n < tableRef.fields.size();
2189  n++)
2190  {
2192  (int64_t)n, tableRef.fields[n].name
2193  });
2194  }
2195  }
2196  break;
2197 
2198  case OPERAND_IDENTIFIER: // regular identifier
2199  {
2200  string fname = fromColumnRef.substr(1, string::npos);
2201  int64_t fid = getfieldid(currentQuery->tableid, fname);
2202 
2203  if (fid==-1)
2204  {
2205  printf("%s %i tableid field not found %li %s\n", __FILE__,
2206  __LINE__, currentQuery->tableid, fname.c_str());
2207  return false;
2208  }
2209  else
2210  {
2211  currentQuery->fromColumnids.push_back({OPERAND_FIELDID, fid,
2212  tableRef.fields[fid].name
2213  });
2214  }
2215  }
2216  break;
2217 
2218  case OPERAND_AGGREGATE: // aggregate
2219  {
2220  string fname = fromColumnRef.substr(2, string::npos);
2221  int64_t fid = getfieldid(currentQuery->tableid, fname);
2222 
2223  if (fid==-1)
2224  {
2225  printf("%s %i tableid field not found %li %s\n", __FILE__,
2226  __LINE__, currentQuery->tableid, fname.c_str());
2227  return false;
2228  }
2229  else
2230  {
2231  currentQuery->fromColumnids.push_back({fromColumnRef[1], fid,
2232  tableRef.fields[fid].name
2233  });
2234  }
2235  }
2236  break;
2237 
2238  default:
2239  printf("%s %i anomaly %c\n", __FILE__, __LINE__,
2240  fromColumnRef[0]);
2241  return false;
2242  }
2243  }
2244  }
2245  else if (currentQuery->type==CMD_UPDATE)
2246  {
2247  boost::unordered_map<string, class Ast *>::iterator it;
2248 
2249  for (it = currentQuery->assignments.begin();
2250  it != currentQuery->assignments.end(); it++)
2251  {
2252  int64_t fid = getfieldid(currentQuery->tableid, it->first);
2253 
2254  if (fid==-1)
2255  {
2256  printf("%s %i tableid field not found %li %s\n", __FILE__,
2257  __LINE__, currentQuery->tableid, it->first.c_str());
2258  return false;
2259  }
2260  else
2261  {
2262  currentQuery->fieldidAssignments[fid] = it->second;
2263  }
2264 
2265  if (resolveFieldNames(it->second)==false)
2266  {
2267  return false;
2268  }
2269  }
2270  }
2271 
2272  if (currentQuery->haswhere==true)
2273  {
2275  {
2276  return false;
2277  }
2278  }
2279 
2280  return true;
2281 }
2282 
2283 bool Statement::resolveFieldNames(class Ast *myPosition)
2284 {
2285  direction_e direction = FROM_ABOVE;
2286  bool isbreakout=false;
2287 
2288  while (1)
2289  {
2290  if (myPosition->isoperator==false &&
2291  myPosition->operand[0]==OPERAND_IDENTIFIER)
2292  {
2293  // CONVERT
2294  string fname = myPosition->operand.substr(1, string::npos);
2295  int64_t fid = getfieldid(currentQuery->tableid, fname);
2296 
2297  if (fid==-1)
2298  {
2299  printf("%s %i tableid field not found %li %s\n", __FILE__,
2300  __LINE__, currentQuery->tableid, fname.c_str());
2301  return false;
2302  }
2303  else
2304  {
2305  myPosition->operand.assign(1 + sizeof(fid), char(0));
2306  myPosition->operand[0] = OPERAND_FIELDID;
2307  memcpy(&myPosition->operand[1], &fid, sizeof(fid));
2308  }
2309 
2310  direction=FROM_RIGHT;
2311  }
2312 
2313  switch (direction)
2314  {
2315  case FROM_ABOVE:
2316  if (myPosition->leftchild==NULL || myPosition==myPosition->leftchild)
2317  {
2318  direction=FROM_LEFT;
2319  }
2320  else
2321  {
2322  myPosition=myPosition->leftchild;
2323  // direction=FROM_ABOVE; already set
2324  }
2325 
2326  break;
2327 
2328  case FROM_LEFT:
2329  if (myPosition->rightchild==NULL)
2330  {
2331  direction=FROM_RIGHT;
2332  }
2333  else
2334  {
2335  myPosition=myPosition->rightchild;
2336  direction=FROM_ABOVE;
2337  }
2338 
2339  break;
2340 
2341  case FROM_RIGHT:
2342  if (myPosition->parent==NULL)
2343  {
2344  isbreakout=true;
2345  }
2346  else
2347  {
2348  if (myPosition==myPosition->parent->leftchild)
2349  {
2350  direction=FROM_LEFT;
2351  }
2352  else // i am parent's right child
2353  {
2354  direction=FROM_RIGHT;
2355  }
2356 
2357  myPosition=myPosition->parent;
2358  }
2359 
2360  break;
2361 
2362  default:
2363  printf("%s %i anomaly %i\n", __FILE__, __LINE__, direction);
2364  return false;
2365  }
2366 
2367  if (isbreakout==true)
2368  {
2369  return true;
2370  // break;
2371  }
2372  }
2373 }
2374 
2375 int64_t Statement::getfieldid(int64_t tableid, const string &fieldName)
2376 {
2377  if (!schemaPtr->fieldNameToId.count(tableid))
2378  {
2379  return -1;
2380  }
2381 
2382  boost::unordered_map<string, int64_t> &ref =
2383  schemaPtr->fieldNameToId[tableid];
2384  boost::unordered_map<string, int64_t>::iterator it;
2385  it = ref.find(fieldName);
2386 
2387  if (it==ref.end())
2388  {
2389  return -1;
2390  }
2391 
2392  return ref[fieldName];
2393 }
2394 
2396  string &leftoperand, string &rightoperand,
2397  vector<fieldValue_s> &inValues,
2398  const boost::unordered_map<uuRecord_s, stagedRow_s> &stagedRows,
2399  boost::unordered_map<uuRecord_s, returnRow_s> &results)
2400 {
2401  bool equalhit=false;
2402 
2403  if (op != OPERATOR_IN && op != OPERATOR_NOTIN && op != OPERATOR_ISNULL &&
2404  op != OPERATOR_ISNOTNULL)
2405  {
2406  if (leftoperand[0] != OPERAND_FIELDID)
2407  {
2408  printf("%s %i left operand is not fieldid, it is '%c'\n",
2409  __FILE__, __LINE__, leftoperand[0]);
2410  return equalhit;
2411  }
2412  }
2413 
2414  int64_t fieldid;
2415  memcpy(&fieldid, &leftoperand[1], sizeof(fieldid));
2416 
2417  class Table &tableRef = *schemaPtr->tables[tableid];
2418  vector<fieldValue_s> fieldValues;
2419 
2420  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
2421 
2422  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
2423  {
2424  const uuRecord_s &uurRef = it->first;
2425 
2426  if (uurRef.tableid != tableid)
2427  {
2428  continue;
2429  }
2430 
2431  const stagedRow_s &stagedRowRef = it->second;
2432  returnRow_s returnRow;
2433  stagedRow2ReturnRow(stagedRowRef, returnRow);
2434 
2435  tableRef.unmakerow((string *)&returnRow.row, &fieldValues);
2436  fieldValue_s &lhs = fieldValues[fieldid];
2437 
2438  switch (tableRef.fields[fieldid].type)
2439  {
2440  case INT:
2441  {
2442  switch (op)
2443  {
2444  case OPERATOR_EQ:
2445  {
2446  // indexRef.getequal
2447  int64_t rhsval;
2448  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2449 
2450  if (lhs.value.integer==rhsval)
2451  {
2452  results[uurRef] = returnRow;
2453  equalhit=true;
2454  }
2455  }
2456  break;
2457 
2458  case OPERATOR_NE:
2459  {
2460  int64_t rhsval;
2461  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2462 
2463  if (lhs.value.integer!=rhsval)
2464  {
2465  results[uurRef] = returnRow;
2466  }
2467  }
2468  break;
2469 
2470  case OPERATOR_GT:
2471  {
2472  int64_t rhsval;
2473  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2474 
2475  if (lhs.value.integer>rhsval)
2476  {
2477  results[uurRef] = returnRow;
2478  }
2479  }
2480  break;
2481 
2482  case OPERATOR_LT:
2483  {
2484  int64_t rhsval;
2485  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2486 
2487  if (lhs.value.integer<rhsval)
2488  {
2489  results[uurRef] = returnRow;
2490  }
2491  }
2492  break;
2493 
2494  case OPERATOR_GTE:
2495  {
2496  int64_t rhsval;
2497  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2498 
2499  if (lhs.value.integer>=rhsval)
2500  {
2501  results[uurRef] = returnRow;
2502  }
2503  }
2504  break;
2505 
2506  case OPERATOR_LTE:
2507  {
2508  int64_t rhsval;
2509  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2510 
2511  if (lhs.value.integer<=rhsval)
2512  {
2513  results[uurRef] = returnRow;
2514  }
2515  }
2516  break;
2517 
2518  case OPERATOR_BETWEEN:
2519  {
2520  int64_t rhsval;
2521  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2522  int64_t rhsval2;
2523  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
2524  sizeof(rhsval2));
2525 
2526  if (lhs.value.integer >= rhsval && lhs.value.integer <= rhsval2)
2527  {
2528  results[uurRef] = returnRow;
2529  }
2530  }
2531  break;
2532 
2533  case OPERATOR_NOTBETWEEN:
2534  {
2535  int64_t rhsval;
2536  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2537  int64_t rhsval2;
2538  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
2539  sizeof(rhsval2));
2540 
2541  if (lhs.value.integer < rhsval || lhs.value.integer > rhsval2)
2542  {
2543  results[uurRef] = returnRow;
2544  }
2545  }
2546  break;
2547 
2548  case OPERATOR_IN:
2549  {
2550  int64_t fieldid;
2551  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
2552  vector<fieldValue_s> fieldValues;
2553  class Table &tableRef = *schemaPtr->tables[tableid];
2554  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
2555  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
2556 
2557  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
2558  {
2559  const uuRecord_s &uurRef = it->first;
2560  const stagedRow_s &sRowRef = it->second;
2561  returnRow_s rRow;
2562  stagedRow2ReturnRow(sRowRef, rRow);
2563  tableRef.unmakerow(&rRow.row, &fieldValues);
2564 
2565  for (size_t n=0; inValues.size(); n++)
2566  {
2567  if (compareFields(fieldtype, fieldValues[fieldid],
2568  inValues[n])==true)
2569  {
2570  results[uurRef] = rRow;
2571  }
2572  }
2573  }
2574  }
2575  break;
2576 
2577  case OPERATOR_NOTIN:
2578  {
2579  int64_t fieldid;
2580  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
2581  vector<fieldValue_s> fieldValues;
2582  class Table &tableRef = *schemaPtr->tables[tableid];
2583  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
2584  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
2585 
2586  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
2587  {
2588  const uuRecord_s &uurRef = it->first;
2589  const stagedRow_s &sRowRef = it->second;
2590  returnRow_s rRow;
2591  stagedRow2ReturnRow(sRowRef, rRow);
2592  tableRef.unmakerow(&rRow.row, &fieldValues);
2593  bool notin=true;
2594 
2595  for (size_t n=0; inValues.size(); n++)
2596  {
2597  if (compareFields(fieldtype, fieldValues[fieldid],
2598  inValues[n])==true)
2599  {
2600  notin=false;
2601  break;
2602  }
2603  }
2604 
2605  if (notin==true)
2606  {
2607  results[uurRef] = rRow;
2608  }
2609  }
2610  }
2611  break;
2612 
2613  case OPERATOR_ISNULL:
2614  {
2615  if (lhs.isnull==true)
2616  {
2617  results[uurRef] = returnRow;
2618  }
2619  }
2620  break;
2621 
2622  case OPERATOR_ISNOTNULL:
2623  {
2624  if (lhs.isnull==false)
2625  {
2626  results[uurRef] = returnRow;
2627  }
2628  }
2629  break;
2630 
2631  default:
2632  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
2633  return equalhit;
2634  }
2635  }
2636  break;
2637 
2638  case BOOL:
2639  {
2640  switch (op)
2641  {
2642  case OPERATOR_EQ:
2643  {
2644  // indexRef.getequal
2645  bool rhsval;
2646  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2647 
2648  if (lhs.value.boolean==rhsval)
2649  {
2650  results[uurRef] = returnRow;
2651  }
2652  }
2653  break;
2654 
2655  case OPERATOR_NE:
2656  {
2657  bool rhsval;
2658  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2659 
2660  if (lhs.value.boolean!=rhsval)
2661  {
2662  results[uurRef] = returnRow;
2663  }
2664  }
2665  break;
2666 
2667  case OPERATOR_GT:
2668  {
2669  bool rhsval;
2670  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2671 
2672  if (lhs.value.boolean>rhsval)
2673  {
2674  results[uurRef] = returnRow;
2675  }
2676  }
2677  break;
2678 
2679  case OPERATOR_LT:
2680  {
2681  bool rhsval;
2682  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2683 
2684  if (lhs.value.boolean<rhsval)
2685  {
2686  results[uurRef] = returnRow;
2687  }
2688  }
2689  break;
2690 
2691  case OPERATOR_GTE:
2692  {
2693  bool rhsval;
2694  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2695 
2696  if (lhs.value.boolean>=rhsval)
2697  {
2698  results[uurRef] = returnRow;
2699  }
2700  }
2701  break;
2702 
2703  case OPERATOR_LTE:
2704  {
2705  bool rhsval;
2706  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2707 
2708  if (lhs.value.boolean<=rhsval)
2709  {
2710  results[uurRef] = returnRow;
2711  }
2712  }
2713  break;
2714 
2715  case OPERATOR_BETWEEN:
2716  {
2717  bool rhsval;
2718  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2719  bool rhsval2;
2720  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
2721  sizeof(rhsval2));
2722 
2723  if (lhs.value.boolean >= rhsval && lhs.value.boolean <= rhsval2)
2724  {
2725  results[uurRef] = returnRow;
2726  }
2727  }
2728  break;
2729 
2730  case OPERATOR_NOTBETWEEN:
2731  {
2732  bool rhsval;
2733  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2734  bool rhsval2;
2735  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
2736  sizeof(rhsval2));
2737 
2738  if (lhs.value.boolean < rhsval || lhs.value.boolean > rhsval2)
2739  {
2740  results[uurRef] = returnRow;
2741  }
2742  }
2743  break;
2744 
2745  case OPERATOR_IN:
2746  {
2747  int64_t fieldid;
2748  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
2749  vector<fieldValue_s> fieldValues;
2750  class Table &tableRef = *schemaPtr->tables[tableid];
2751  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
2752  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
2753 
2754  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
2755  {
2756  const uuRecord_s &uurRef = it->first;
2757  const stagedRow_s &sRowRef = it->second;
2758  returnRow_s rRow;
2759  stagedRow2ReturnRow(sRowRef, rRow);
2760  tableRef.unmakerow(&rRow.row, &fieldValues);
2761 
2762  for (size_t n=0; inValues.size(); n++)
2763  {
2764  if (compareFields(fieldtype, fieldValues[fieldid],
2765  inValues[n])==true)
2766  {
2767  results[uurRef] = rRow;
2768  }
2769  }
2770  }
2771  }
2772  break;
2773 
2774  case OPERATOR_NOTIN:
2775  {
2776  int64_t fieldid;
2777  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
2778  vector<fieldValue_s> fieldValues;
2779  class Table &tableRef = *schemaPtr->tables[tableid];
2780  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
2781  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
2782 
2783  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
2784  {
2785  const uuRecord_s &uurRef = it->first;
2786  const stagedRow_s &sRowRef = it->second;
2787  returnRow_s rRow;
2788  stagedRow2ReturnRow(sRowRef, rRow);
2789  tableRef.unmakerow(&rRow.row, &fieldValues);
2790  bool notin=true;
2791 
2792  for (size_t n=0; inValues.size(); n++)
2793  {
2794  if (compareFields(fieldtype, fieldValues[fieldid],
2795  inValues[n])==true)
2796  {
2797  notin=false;
2798  break;
2799  }
2800  }
2801 
2802  if (notin==true)
2803  {
2804  results[uurRef] = rRow;
2805  }
2806  }
2807  }
2808  break;
2809 
2810  case OPERATOR_ISNULL:
2811  {
2812  if (lhs.isnull==true)
2813  {
2814  results[uurRef] = returnRow;
2815  }
2816  }
2817  break;
2818 
2819  case OPERATOR_ISNOTNULL:
2820  {
2821  if (lhs.isnull==false)
2822  {
2823  results[uurRef] = returnRow;
2824  }
2825  }
2826  break;
2827 
2828  default:
2829  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
2830  return equalhit;
2831  }
2832  }
2833  break;
2834 
2835  case FLOAT:
2836  {
2837  switch (op)
2838  {
2839  case OPERATOR_EQ:
2840  {
2841  // indexRef.getequal
2842  Ast::toFloat(rightoperand, rightoperand);
2843  long double rhsval;
2844  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2845 
2846  if (lhs.value.floating==rhsval)
2847  {
2848  results[uurRef] = returnRow;
2849  }
2850  }
2851  break;
2852 
2853  case OPERATOR_NE:
2854  {
2855  Ast::toFloat(rightoperand, rightoperand);
2856  long double rhsval;
2857  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2858 
2859  if (lhs.value.floating!=rhsval)
2860  {
2861  results[uurRef] = returnRow;
2862  }
2863  }
2864  break;
2865 
2866  case OPERATOR_GT:
2867  {
2868  Ast::toFloat(rightoperand, rightoperand);
2869  long double rhsval;
2870  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2871 
2872  if (lhs.value.floating>rhsval)
2873  {
2874  results[uurRef] = returnRow;
2875  }
2876  }
2877  break;
2878 
2879  case OPERATOR_LT:
2880  {
2881  Ast::toFloat(rightoperand, rightoperand);
2882  long double rhsval;
2883  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2884 
2885  if (lhs.value.floating<rhsval)
2886  {
2887  results[uurRef] = returnRow;
2888  }
2889  }
2890  break;
2891 
2892  case OPERATOR_GTE:
2893  {
2894  Ast::toFloat(rightoperand, rightoperand);
2895  long double rhsval;
2896  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2897 
2898  if (lhs.value.floating>=rhsval)
2899  {
2900  results[uurRef] = returnRow;
2901  }
2902  }
2903  break;
2904 
2905  case OPERATOR_LTE:
2906  {
2907  Ast::toFloat(rightoperand, rightoperand);
2908  long double rhsval;
2909  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2910 
2911  if (lhs.value.floating<=rhsval)
2912  {
2913  results[uurRef] = returnRow;
2914  }
2915  }
2916  break;
2917 
2918  case OPERATOR_BETWEEN:
2919  {
2920  long double rhsval;
2921  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2922  long double rhsval2;
2923  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
2924  sizeof(rhsval2));
2925 
2926  if (lhs.value.floating >= rhsval && lhs.value.floating <=
2927  rhsval2)
2928  {
2929  results[uurRef] = returnRow;
2930  }
2931  }
2932  break;
2933 
2934  case OPERATOR_NOTBETWEEN:
2935  {
2936  long double rhsval;
2937  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
2938  long double rhsval2;
2939  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
2940  sizeof(rhsval2));
2941 
2942  if (lhs.value.floating < rhsval || lhs.value.floating > rhsval2)
2943  {
2944  results[uurRef] = returnRow;
2945  }
2946  }
2947  break;
2948 
2949  case OPERATOR_IN:
2950  {
2951  int64_t fieldid;
2952  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
2953  vector<fieldValue_s> fieldValues;
2954  class Table &tableRef = *schemaPtr->tables[tableid];
2955  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
2956  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
2957 
2958  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
2959  {
2960  const uuRecord_s &uurRef = it->first;
2961  const stagedRow_s &sRowRef = it->second;
2962  returnRow_s rRow;
2963  stagedRow2ReturnRow(sRowRef, rRow);
2964  tableRef.unmakerow(&rRow.row, &fieldValues);
2965 
2966  for (size_t n=0; inValues.size(); n++)
2967  {
2968  if (compareFields(fieldtype, fieldValues[fieldid],
2969  inValues[n])==true)
2970  {
2971  results[uurRef] = rRow;
2972  }
2973  }
2974  }
2975  }
2976  break;
2977 
2978  case OPERATOR_NOTIN:
2979  {
2980  int64_t fieldid;
2981  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
2982  vector<fieldValue_s> fieldValues;
2983  class Table &tableRef = *schemaPtr->tables[tableid];
2984  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
2985  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
2986 
2987  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
2988  {
2989  const uuRecord_s &uurRef = it->first;
2990  const stagedRow_s &sRowRef = it->second;
2991  returnRow_s rRow;
2992  stagedRow2ReturnRow(sRowRef, rRow);
2993  tableRef.unmakerow(&rRow.row, &fieldValues);
2994  bool notin=true;
2995 
2996  for (size_t n=0; inValues.size(); n++)
2997  {
2998  if (compareFields(fieldtype, fieldValues[fieldid],
2999  inValues[n])==true)
3000  {
3001  notin=false;
3002  break;
3003  }
3004  }
3005 
3006  if (notin==true)
3007  {
3008  results[uurRef] = rRow;
3009  }
3010  }
3011  }
3012  break;
3013 
3014  case OPERATOR_ISNULL:
3015  {
3016  if (lhs.isnull==true)
3017  {
3018  results[uurRef] = returnRow;
3019  }
3020  }
3021  break;
3022 
3023  case OPERATOR_ISNOTNULL:
3024  {
3025  if (lhs.isnull==false)
3026  {
3027  results[uurRef] = returnRow;
3028  }
3029  }
3030  break;
3031 
3032  default:
3033  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
3034  return equalhit;
3035  }
3036  }
3037  break;
3038 
3039  case CHAR:
3040  {
3041  switch (op)
3042  {
3043  case OPERATOR_EQ:
3044  {
3045  // indexRef.getequal
3046  char rhsval=rightoperand[1];
3047 
3048  if (lhs.value.character==rhsval)
3049  {
3050  results[uurRef] = returnRow;
3051  }
3052  }
3053  break;
3054 
3055  case OPERATOR_NE:
3056  {
3057  char rhsval=rightoperand[1];
3058 
3059  if (lhs.value.character!=rhsval)
3060  {
3061  results[uurRef] = returnRow;
3062  }
3063  }
3064  break;
3065 
3066  case OPERATOR_GT:
3067  {
3068  char rhsval=rightoperand[1];
3069 
3070  if (lhs.value.character>rhsval)
3071  {
3072  results[uurRef] = returnRow;
3073  }
3074  }
3075  break;
3076 
3077  case OPERATOR_LT:
3078  {
3079  char rhsval=rightoperand[1];
3080 
3081  if (lhs.value.character<rhsval)
3082  {
3083  results[uurRef] = returnRow;
3084  }
3085  }
3086  break;
3087 
3088  case OPERATOR_GTE:
3089  {
3090  char rhsval=rightoperand[1];
3091 
3092  if (lhs.value.character>=rhsval)
3093  {
3094  results[uurRef] = returnRow;
3095  }
3096  }
3097  break;
3098 
3099  case OPERATOR_LTE:
3100  {
3101  char rhsval=rightoperand[1];
3102 
3103  if (lhs.value.character<=rhsval)
3104  {
3105  results[uurRef] = returnRow;
3106  }
3107  }
3108  break;
3109 
3110  case OPERATOR_BETWEEN:
3111  {
3112  char rhsval=rightoperand[1+sizeof(int64_t)];
3113  char rhsval2=rightoperand[1+sizeof(int64_t)+1];
3114 
3115  if (lhs.value.character >= rhsval && lhs.value.character <=
3116  rhsval2)
3117  {
3118  results[uurRef] = returnRow;
3119  }
3120  }
3121  break;
3122 
3123  case OPERATOR_NOTBETWEEN:
3124  {
3125  char rhsval=rightoperand[1+sizeof(int64_t)];
3126  char rhsval2=rightoperand[1+sizeof(int64_t)+1];
3127 
3128  if (lhs.value.character < rhsval || lhs.value.character >
3129  rhsval2)
3130  {
3131  results[uurRef] = returnRow;
3132  }
3133  }
3134  break;
3135 
3136  case OPERATOR_IN:
3137  {
3138  int64_t fieldid;
3139  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3140  vector<fieldValue_s> fieldValues;
3141  class Table &tableRef = *schemaPtr->tables[tableid];
3142  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3143  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
3144 
3145  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
3146  {
3147  const uuRecord_s &uurRef = it->first;
3148  const stagedRow_s &sRowRef = it->second;
3149  returnRow_s rRow;
3150  stagedRow2ReturnRow(sRowRef, rRow);
3151  tableRef.unmakerow(&rRow.row, &fieldValues);
3152 
3153  for (size_t n=0; inValues.size(); n++)
3154  {
3155  if (compareFields(fieldtype, fieldValues[fieldid],
3156  inValues[n])==true)
3157  {
3158  results[uurRef] = rRow;
3159  }
3160  }
3161  }
3162  }
3163  break;
3164 
3165  case OPERATOR_NOTIN:
3166  {
3167  int64_t fieldid;
3168  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3169  vector<fieldValue_s> fieldValues;
3170  class Table &tableRef = *schemaPtr->tables[tableid];
3171  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3172  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
3173 
3174  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
3175  {
3176  const uuRecord_s &uurRef = it->first;
3177  const stagedRow_s &sRowRef = it->second;
3178  returnRow_s rRow;
3179  stagedRow2ReturnRow(sRowRef, rRow);
3180  tableRef.unmakerow(&rRow.row, &fieldValues);
3181  bool notin=true;
3182 
3183  for (size_t n=0; inValues.size(); n++)
3184  {
3185  if (compareFields(fieldtype, fieldValues[fieldid],
3186  inValues[n])==true)
3187  {
3188  notin=false;
3189  break;
3190  }
3191  }
3192 
3193  if (notin==true)
3194  {
3195  results[uurRef] = rRow;
3196  }
3197  }
3198  }
3199  break;
3200 
3201  case OPERATOR_ISNULL:
3202  {
3203  if (lhs.isnull==true)
3204  {
3205  results[uurRef] = returnRow;
3206  }
3207  }
3208  break;
3209 
3210  case OPERATOR_ISNOTNULL:
3211  {
3212  if (lhs.isnull==false)
3213  {
3214  results[uurRef] = returnRow;
3215  }
3216  }
3217  break;
3218 
3219  default:
3220  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
3221  return equalhit;
3222  }
3223  }
3224  break;
3225 
3226  case CHARX:
3227  {
3228  switch (op)
3229  {
3230  case OPERATOR_EQ:
3231  {
3232  // indexRef.getequal
3233  string rhsval=rightoperand.substr(1, string::npos);
3234 
3235  if (!lhs.str.compare(rhsval))
3236  {
3237  results[uurRef] = returnRow;
3238  }
3239  }
3240  break;
3241 
3242  case OPERATOR_NE:
3243  {
3244  string rhsval=rightoperand.substr(1, string::npos);
3245 
3246  if (lhs.str.compare(rhsval))
3247  {
3248  results[uurRef] = returnRow;
3249  }
3250  }
3251  break;
3252 
3253  case OPERATOR_IN:
3254  {
3255  int64_t fieldid;
3256  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3257  vector<fieldValue_s> fieldValues;
3258  class Table &tableRef = *schemaPtr->tables[tableid];
3259  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3260  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
3261 
3262  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
3263  {
3264  const uuRecord_s &uurRef = it->first;
3265  const stagedRow_s &sRowRef = it->second;
3266  returnRow_s rRow;
3267  stagedRow2ReturnRow(sRowRef, rRow);
3268  tableRef.unmakerow(&rRow.row, &fieldValues);
3269 
3270  for (size_t n=0; inValues.size(); n++)
3271  {
3272  if (compareFields(fieldtype, fieldValues[fieldid],
3273  inValues[n])==true)
3274  {
3275  results[uurRef] = rRow;
3276  }
3277  }
3278  }
3279  }
3280  break;
3281 
3282  case OPERATOR_NOTIN:
3283  {
3284  int64_t fieldid;
3285  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3286  vector<fieldValue_s> fieldValues;
3287  class Table &tableRef = *schemaPtr->tables[tableid];
3288  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3289  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
3290 
3291  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
3292  {
3293  const uuRecord_s &uurRef = it->first;
3294  const stagedRow_s &sRowRef = it->second;
3295  returnRow_s rRow;
3296  stagedRow2ReturnRow(sRowRef, rRow);
3297  tableRef.unmakerow(&rRow.row, &fieldValues);
3298  bool notin=true;
3299 
3300  for (size_t n=0; inValues.size(); n++)
3301  {
3302  if (compareFields(fieldtype, fieldValues[fieldid],
3303  inValues[n])==true)
3304  {
3305  notin=false;
3306  break;
3307  }
3308  }
3309 
3310  if (notin==true)
3311  {
3312  results[uurRef] = rRow;
3313  }
3314  }
3315  }
3316  break;
3317 
3318  case OPERATOR_ISNULL:
3319  {
3320  if (lhs.isnull==true)
3321  {
3322  results[uurRef] = returnRow;
3323  }
3324  }
3325  break;
3326 
3327  case OPERATOR_ISNOTNULL:
3328  {
3329  if (lhs.isnull==false)
3330  {
3331  results[uurRef] = returnRow;
3332  }
3333  }
3334  break;
3335 
3336  default:
3337  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
3338  return equalhit;
3339  }
3340  }
3341  break;
3342 
3343  case VARCHAR:
3344  {
3345  switch (op)
3346  {
3347  case OPERATOR_EQ:
3348  {
3349  // indexRef.getequal
3350  string rhsval=rightoperand.substr(1, string::npos);
3351 
3352  if (!lhs.str.compare(rhsval))
3353  {
3354  results[uurRef] = returnRow;
3355  }
3356  }
3357  break;
3358 
3359  case OPERATOR_NE:
3360  {
3361  string rhsval=rightoperand.substr(1, string::npos);
3362 
3363  if (lhs.str.compare(rhsval))
3364  {
3365  results[uurRef] = returnRow;
3366  }
3367  }
3368  break;
3369 
3370  case OPERATOR_IN:
3371  {
3372  int64_t fieldid;
3373  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3374  vector<fieldValue_s> fieldValues;
3375  class Table &tableRef = *schemaPtr->tables[tableid];
3376  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3377  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
3378 
3379  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
3380  {
3381  const uuRecord_s &uurRef = it->first;
3382  const stagedRow_s &sRowRef = it->second;
3383  returnRow_s rRow;
3384  stagedRow2ReturnRow(sRowRef, rRow);
3385  tableRef.unmakerow(&rRow.row, &fieldValues);
3386 
3387  for (size_t n=0; inValues.size(); n++)
3388  {
3389  if (compareFields(fieldtype, fieldValues[fieldid],
3390  inValues[n])==true)
3391  {
3392  results[uurRef] = rRow;
3393  }
3394  }
3395  }
3396  }
3397  break;
3398 
3399  case OPERATOR_NOTIN:
3400  {
3401  int64_t fieldid;
3402  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3403  vector<fieldValue_s> fieldValues;
3404  class Table &tableRef = *schemaPtr->tables[tableid];
3405  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3406  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
3407 
3408  for (it = stagedRows.begin(); it != stagedRows.end(); it++)
3409  {
3410  const uuRecord_s &uurRef = it->first;
3411  const stagedRow_s &sRowRef = it->second;
3412  returnRow_s rRow;
3413  stagedRow2ReturnRow(sRowRef, rRow);
3414  tableRef.unmakerow(&rRow.row, &fieldValues);
3415  bool notin=true;
3416 
3417  for (size_t n=0; inValues.size(); n++)
3418  {
3419  if (compareFields(fieldtype, fieldValues[fieldid],
3420  inValues[n])==true)
3421  {
3422  notin=false;
3423  break;
3424  }
3425  }
3426 
3427  if (notin==true)
3428  {
3429  results[uurRef] = rRow;
3430  }
3431  }
3432  }
3433  break;
3434 
3435  case OPERATOR_ISNULL:
3436  {
3437  if (lhs.isnull==true)
3438  {
3439  results[uurRef] = returnRow;
3440  }
3441  }
3442  break;
3443 
3444  case OPERATOR_ISNOTNULL:
3445  {
3446  if (lhs.isnull==false)
3447  {
3448  results[uurRef] = returnRow;
3449  }
3450  }
3451  break;
3452 
3453  default:
3454  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
3455  return equalhit;
3456  }
3457  }
3458  break;
3459 
3460  default:
3461  printf("%s %i anomaly %i\n", __FILE__, __LINE__,
3462  tableRef.fields[fieldid].type);
3463  return equalhit;
3464  }
3465  }
3466 
3467  return equalhit;
3468 }
3469 
3470 /* to be called for predicates ANDed with results of other predicates
3471  * this avoids traffic to engines */
3472 void Statement::andPredicate(operatortypes_e op, int64_t tableid,
3473  string &leftoperand, string &rightoperand,
3474  vector<fieldValue_s> &inValues,
3475  const boost::unordered_map<uuRecord_s,
3476  returnRow_s> &andResults,
3477  boost::unordered_map<uuRecord_s,
3478  returnRow_s> &results)
3479 {
3480  if (leftoperand[0] != OPERAND_FIELDID)
3481  {
3482  printf("%s %i left operand is not fieldid, it is %c\n", __FILE__,
3483  __LINE__, leftoperand[0]);
3484  return;
3485  }
3486 
3487  int64_t fieldid;
3488  memcpy(&fieldid, &leftoperand[1], sizeof(fieldid));
3489 
3490  class Table &tableRef = *schemaPtr->tables[tableid];
3491  vector<fieldValue_s> fieldValues;
3492 
3493  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
3494 
3495  for (it = andResults.begin(); it != andResults.end(); it++)
3496  {
3497  const uuRecord_s &uurRef = it->first;
3498  const returnRow_s &returnRowRef = it->second;
3499  tableRef.unmakerow((string *)&returnRowRef.row, &fieldValues);
3500  fieldValue_s &lhs = fieldValues[fieldid];
3501 
3502  switch (tableRef.fields[fieldid].type)
3503  {
3504  case INT:
3505  {
3506  switch (op)
3507  {
3508  case OPERATOR_EQ:
3509  {
3510  int64_t rhsval;
3511  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3512 
3513  if (lhs.value.integer==rhsval)
3514  {
3515  results[uurRef] = returnRowRef;
3516  }
3517  }
3518  break;
3519 
3520  case OPERATOR_NE:
3521  {
3522  int64_t rhsval;
3523  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3524 
3525  if (lhs.value.integer!=rhsval)
3526  {
3527  results[uurRef] = returnRowRef;
3528  }
3529  }
3530  break;
3531 
3532  case OPERATOR_GT:
3533  {
3534  int64_t rhsval;
3535  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3536 
3537  if (lhs.value.integer>rhsval)
3538  {
3539  results[uurRef] = returnRowRef;
3540  }
3541  }
3542  break;
3543 
3544  case OPERATOR_LT:
3545  {
3546  int64_t rhsval;
3547  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3548 
3549  if (lhs.value.integer<rhsval)
3550  {
3551  results[uurRef] = returnRowRef;
3552  }
3553  }
3554  break;
3555 
3556  case OPERATOR_GTE:
3557  {
3558  int64_t rhsval;
3559  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3560 
3561  if (lhs.value.integer>=rhsval)
3562  {
3563  results[uurRef] = returnRowRef;
3564  }
3565  }
3566  break;
3567 
3568  case OPERATOR_LTE:
3569  {
3570  int64_t rhsval;
3571  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3572 
3573  if (lhs.value.integer<=rhsval)
3574  {
3575  results[uurRef] = returnRowRef;
3576  }
3577  }
3578  break;
3579 
3580  case OPERATOR_BETWEEN:
3581  {
3582  int64_t rhsval;
3583  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3584  int64_t rhsval2;
3585  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
3586  sizeof(rhsval2));
3587 
3588  if (lhs.value.integer >= rhsval && lhs.value.integer <= rhsval2)
3589  {
3590  results[uurRef] = returnRowRef;
3591  }
3592  }
3593  break;
3594 
3595  case OPERATOR_NOTBETWEEN:
3596  {
3597  int64_t rhsval;
3598  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3599  int64_t rhsval2;
3600  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
3601  sizeof(rhsval2));
3602 
3603  if (lhs.value.integer < rhsval || lhs.value.integer > rhsval2)
3604  {
3605  results[uurRef] = returnRowRef;
3606  }
3607  }
3608  break;
3609 
3610  case OPERATOR_IN:
3611  {
3612  /* do after AST is walkable since inobject contains a
3613  * vector of Ast */
3614  int64_t fieldid;
3615  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3616  vector<fieldValue_s> fieldValues;
3617  class Table &tableRef = *schemaPtr->tables[tableid];
3618  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3619  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
3620 
3621  for (it = andResults.begin(); it != andResults.end(); it++)
3622  {
3623  const uuRecord_s &uurRef = it->first;
3624  const returnRow_s &returnRowRef = it->second;
3625  tableRef.unmakerow((string *)&returnRowRef.row,
3626  &fieldValues);
3627 
3628  for (size_t n=0; inValues.size(); n++)
3629  {
3630  if (compareFields(fieldtype, fieldValues[fieldid],
3631  inValues[n])==true)
3632  {
3633  results[uurRef] = returnRowRef;
3634  }
3635  }
3636  }
3637  }
3638  break;
3639 
3640  case OPERATOR_NOTIN:
3641  {
3642  // do after AST is walkable since inobject contains a vector of Ast *
3643  int64_t fieldid;
3644  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3645  vector<fieldValue_s> fieldValues;
3646  class Table &tableRef = *schemaPtr->tables[tableid];
3647  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3648  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
3649 
3650  for (it = andResults.begin(); it != andResults.end(); it++)
3651  {
3652  const uuRecord_s &uurRef = it->first;
3653  const returnRow_s &returnRowRef = it->second;
3654  tableRef.unmakerow((string *)&returnRowRef.row,
3655  &fieldValues);
3656  bool notin=true;
3657 
3658  for (size_t n=0; inValues.size(); n++)
3659  {
3660  if (compareFields(fieldtype, fieldValues[fieldid],
3661  inValues[n])==true)
3662  {
3663  notin=false;
3664  break;
3665  }
3666  }
3667 
3668  if (notin==true)
3669  {
3670  results[uurRef] = returnRowRef;
3671  }
3672  }
3673  }
3674  break;
3675 
3676  case OPERATOR_ISNULL:
3677  {
3678  if (lhs.isnull==true)
3679  {
3680  results[uurRef] = returnRowRef;
3681  }
3682  }
3683  break;
3684 
3685  case OPERATOR_ISNOTNULL:
3686  {
3687  if (lhs.isnull==false)
3688  {
3689  results[uurRef] = returnRowRef;
3690  }
3691  }
3692  break;
3693 
3694  default:
3695  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
3696  }
3697  }
3698  break;
3699 
3700  case UINT:
3701  {
3702  switch (op)
3703  {
3704  case OPERATOR_EQ:
3705  {
3706  uint64_t rhsval;
3707  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3708 
3709  if (lhs.value.uinteger==rhsval)
3710  {
3711  results[uurRef] = returnRowRef;
3712  }
3713  }
3714  break;
3715 
3716  case OPERATOR_NE:
3717  {
3718  uint64_t rhsval;
3719  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3720 
3721  if (lhs.value.uinteger!=rhsval)
3722  {
3723  results[uurRef] = returnRowRef;
3724  }
3725  }
3726  break;
3727 
3728  case OPERATOR_GT:
3729  {
3730  uint64_t rhsval;
3731  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3732 
3733  if (lhs.value.uinteger>rhsval)
3734  {
3735  results[uurRef] = returnRowRef;
3736  }
3737  }
3738  break;
3739 
3740  case OPERATOR_LT:
3741  {
3742  uint64_t rhsval;
3743  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3744 
3745  if (lhs.value.uinteger<rhsval)
3746  {
3747  results[uurRef] = returnRowRef;
3748  }
3749  }
3750  break;
3751 
3752  case OPERATOR_GTE:
3753  {
3754  uint64_t rhsval;
3755  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3756 
3757  if (lhs.value.uinteger>=rhsval)
3758  {
3759  results[uurRef] = returnRowRef;
3760  }
3761  }
3762  break;
3763 
3764  case OPERATOR_LTE:
3765  {
3766  uint64_t rhsval;
3767  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3768 
3769  if (lhs.value.uinteger<=rhsval)
3770  {
3771  results[uurRef] = returnRowRef;
3772  }
3773  }
3774  break;
3775 
3776  case OPERATOR_BETWEEN:
3777  {
3778  uint64_t rhsval;
3779  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3780  uint64_t rhsval2;
3781  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
3782  sizeof(rhsval2));
3783 
3784  if (lhs.value.uinteger >= rhsval && lhs.value.uinteger <=
3785  rhsval2)
3786  {
3787  results[uurRef] = returnRowRef;
3788  }
3789  }
3790  break;
3791 
3792  case OPERATOR_NOTBETWEEN:
3793  {
3794  uint64_t rhsval;
3795  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3796  uint64_t rhsval2;
3797  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
3798  sizeof(rhsval2));
3799 
3800  if (lhs.value.uinteger < rhsval || lhs.value.uinteger > rhsval2)
3801  {
3802  results[uurRef] = returnRowRef;
3803  }
3804  }
3805  break;
3806 
3807  case OPERATOR_IN:
3808  {
3809  /* do after AST is walkable since inobject contains a vector
3810  * of Ast */
3811  int64_t fieldid;
3812  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3813  vector<fieldValue_s> fieldValues;
3814  class Table &tableRef = *schemaPtr->tables[tableid];
3815  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3816  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
3817 
3818  for (it = andResults.begin(); it != andResults.end(); it++)
3819  {
3820  const uuRecord_s &uurRef = it->first;
3821  const returnRow_s &returnRowRef = it->second;
3822  tableRef.unmakerow((string *)&returnRowRef.row,
3823  &fieldValues);
3824 
3825  for (size_t n=0; inValues.size(); n++)
3826  {
3827  if (compareFields(fieldtype, fieldValues[fieldid],
3828  inValues[n])==true)
3829  {
3830  results[uurRef] = returnRowRef;
3831  }
3832  }
3833  }
3834  }
3835  break;
3836 
3837  case OPERATOR_NOTIN:
3838  {
3839  // do after AST is walkable since inobject contains a vector of Ast *
3840  int64_t fieldid;
3841  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
3842  vector<fieldValue_s> fieldValues;
3843  class Table &tableRef = *schemaPtr->tables[tableid];
3844  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
3845  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
3846 
3847  for (it = andResults.begin(); it != andResults.end(); it++)
3848  {
3849  const uuRecord_s &uurRef = it->first;
3850  const returnRow_s &returnRowRef = it->second;
3851  tableRef.unmakerow((string *)&returnRowRef.row,
3852  &fieldValues);
3853  bool notin=true;
3854 
3855  for (size_t n=0; inValues.size(); n++)
3856  {
3857  if (compareFields(fieldtype, fieldValues[fieldid],
3858  inValues[n])==true)
3859  {
3860  notin=false;
3861  break;
3862  }
3863  }
3864 
3865  if (notin==true)
3866  {
3867  results[uurRef] = returnRowRef;
3868  }
3869  }
3870  }
3871  break;
3872 
3873  case OPERATOR_ISNULL:
3874  {
3875  if (lhs.isnull==true)
3876  {
3877  results[uurRef] = returnRowRef;
3878  }
3879  }
3880  break;
3881 
3882  case OPERATOR_ISNOTNULL:
3883  {
3884  if (lhs.isnull==false)
3885  {
3886  results[uurRef] = returnRowRef;
3887  }
3888  }
3889  break;
3890 
3891  default:
3892  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
3893  }
3894  }
3895  break;
3896 
3897  case BOOL:
3898  {
3899  switch (op)
3900  {
3901  case OPERATOR_EQ:
3902  {
3903  bool rhsval;
3904  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3905 
3906  if (lhs.value.boolean==rhsval)
3907  {
3908  results[uurRef] = returnRowRef;
3909  }
3910  }
3911  break;
3912 
3913  case OPERATOR_NE:
3914  {
3915  bool rhsval;
3916  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3917 
3918  if (lhs.value.boolean!=rhsval)
3919  {
3920  results[uurRef] = returnRowRef;
3921  }
3922  }
3923  break;
3924 
3925  case OPERATOR_GT:
3926  {
3927  bool rhsval;
3928  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3929 
3930  if (lhs.value.boolean>rhsval)
3931  {
3932  results[uurRef] = returnRowRef;
3933  }
3934  }
3935  break;
3936 
3937  case OPERATOR_LT:
3938  {
3939  bool rhsval;
3940  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3941 
3942  if (lhs.value.boolean<rhsval)
3943  {
3944  results[uurRef] = returnRowRef;
3945  }
3946  }
3947  break;
3948 
3949  case OPERATOR_GTE:
3950  {
3951  bool rhsval;
3952  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3953 
3954  if (lhs.value.boolean>=rhsval)
3955  {
3956  results[uurRef] = returnRowRef;
3957  }
3958  }
3959  break;
3960 
3961  case OPERATOR_LTE:
3962  {
3963  bool rhsval;
3964  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3965 
3966  if (lhs.value.boolean<=rhsval)
3967  {
3968  results[uurRef] = returnRowRef;
3969  }
3970  }
3971  break;
3972 
3973  case OPERATOR_BETWEEN:
3974  {
3975  bool rhsval;
3976  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3977  bool rhsval2;
3978  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
3979  sizeof(rhsval2));
3980 
3981  if (lhs.value.boolean >= rhsval && lhs.value.boolean <= rhsval2)
3982  {
3983  results[uurRef] = returnRowRef;
3984  }
3985  }
3986  break;
3987 
3988  case OPERATOR_NOTBETWEEN:
3989  {
3990  bool rhsval;
3991  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
3992  bool rhsval2;
3993  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
3994  sizeof(rhsval2));
3995 
3996  if (lhs.value.boolean < rhsval || lhs.value.boolean > rhsval2)
3997  {
3998  results[uurRef] = returnRowRef;
3999  }
4000  }
4001  break;
4002 
4003  case OPERATOR_IN:
4004  {
4005  // why do IN on a bool field?
4006  int64_t fieldid;
4007  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4008  vector<fieldValue_s> fieldValues;
4009  class Table &tableRef = *schemaPtr->tables[tableid];
4010  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4011  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4012 
4013  for (it = andResults.begin(); it != andResults.end(); it++)
4014  {
4015  const uuRecord_s &uurRef = it->first;
4016  const returnRow_s &returnRowRef = it->second;
4017  tableRef.unmakerow((string *)&returnRowRef.row,
4018  &fieldValues);
4019 
4020  for (size_t n=0; inValues.size(); n++)
4021  {
4022  if (compareFields(fieldtype, fieldValues[fieldid],
4023  inValues[n])==true)
4024  {
4025  results[uurRef] = returnRowRef;
4026  }
4027  }
4028  }
4029  }
4030  break;
4031 
4032  case OPERATOR_NOTIN:
4033  {
4034  // why do NOT IN on a bool field?
4035  int64_t fieldid;
4036  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4037  vector<fieldValue_s> fieldValues;
4038  class Table &tableRef = *schemaPtr->tables[tableid];
4039  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4040  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4041 
4042  for (it = andResults.begin(); it != andResults.end(); it++)
4043  {
4044  const uuRecord_s &uurRef = it->first;
4045  const returnRow_s &returnRowRef = it->second;
4046  tableRef.unmakerow((string *)&returnRowRef.row,
4047  &fieldValues);
4048  bool notin=true;
4049 
4050  for (size_t n=0; inValues.size(); n++)
4051  {
4052  if (compareFields(fieldtype, fieldValues[fieldid],
4053  inValues[n])==true)
4054  {
4055  notin=false;
4056  break;
4057  }
4058  }
4059 
4060  if (notin==true)
4061  {
4062  results[uurRef] = returnRowRef;
4063  }
4064  }
4065  }
4066  break;
4067 
4068  case OPERATOR_ISNULL:
4069  {
4070  if (lhs.isnull==true)
4071  {
4072  results[uurRef] = returnRowRef;
4073  }
4074  }
4075  break;
4076 
4077  case OPERATOR_ISNOTNULL:
4078  {
4079  if (lhs.isnull==false)
4080  {
4081  results[uurRef] = returnRowRef;
4082  }
4083  }
4084  break;
4085 
4086  default:
4087  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
4088  }
4089  }
4090  break;
4091 
4092  case FLOAT:
4093  {
4094  switch (op)
4095  {
4096  case OPERATOR_EQ:
4097  {
4098  Ast::toFloat(rightoperand, rightoperand);
4099  long double rhsval;
4100  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
4101 
4102  if (lhs.value.floating==rhsval)
4103  {
4104  results[uurRef] = returnRowRef;
4105  }
4106  }
4107  break;
4108 
4109  case OPERATOR_NE:
4110  {
4111  Ast::toFloat(rightoperand, rightoperand);
4112  long double rhsval;
4113  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
4114 
4115  if (lhs.value.floating!=rhsval)
4116  {
4117  results[uurRef] = returnRowRef;
4118  }
4119  }
4120  break;
4121 
4122  case OPERATOR_GT:
4123  {
4124  Ast::toFloat(rightoperand, rightoperand);
4125  long double rhsval;
4126  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
4127 
4128  if (lhs.value.floating>rhsval)
4129  {
4130  results[uurRef] = returnRowRef;
4131  }
4132  }
4133  break;
4134 
4135  case OPERATOR_LT:
4136  {
4137  Ast::toFloat(rightoperand, rightoperand);
4138  long double rhsval;
4139  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
4140 
4141  if (lhs.value.floating<rhsval)
4142  {
4143  results[uurRef] = returnRowRef;
4144  }
4145  }
4146  break;
4147 
4148  case OPERATOR_GTE:
4149  {
4150  Ast::toFloat(rightoperand, rightoperand);
4151  long double rhsval;
4152  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
4153 
4154  if (lhs.value.floating>=rhsval)
4155  {
4156  results[uurRef] = returnRowRef;
4157  }
4158  }
4159  break;
4160 
4161  case OPERATOR_LTE:
4162  {
4163  Ast::toFloat(rightoperand, rightoperand);
4164  long double rhsval;
4165  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
4166 
4167  if (lhs.value.floating<=rhsval)
4168  {
4169  results[uurRef] = returnRowRef;
4170  }
4171  }
4172  break;
4173 
4174  case OPERATOR_BETWEEN:
4175  {
4176  long double rhsval;
4177  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
4178  long double rhsval2;
4179  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
4180  sizeof(rhsval2));
4181 
4182  if (lhs.value.floating >= rhsval && lhs.value.floating <=
4183  rhsval2)
4184  {
4185  results[uurRef] = returnRowRef;
4186  }
4187  }
4188  break;
4189 
4190  case OPERATOR_NOTBETWEEN:
4191  {
4192  long double rhsval;
4193  memcpy(&rhsval, &rightoperand[1], sizeof(rhsval));
4194  long double rhsval2;
4195  memcpy(&rhsval2, &rightoperand[1+sizeof(rhsval)],
4196  sizeof(rhsval2));
4197 
4198  if (lhs.value.floating < rhsval || lhs.value.floating > rhsval2)
4199  {
4200  results[uurRef] = returnRowRef;
4201  }
4202  }
4203  break;
4204 
4205  case OPERATOR_IN:
4206  {
4207  /* do after AST is walkable since inobject contains a vector
4208  * of Ast */
4209  int64_t fieldid;
4210  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4211  vector<fieldValue_s> fieldValues;
4212  class Table &tableRef = *schemaPtr->tables[tableid];
4213  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4214  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4215 
4216  for (it = andResults.begin(); it != andResults.end(); it++)
4217  {
4218  const uuRecord_s &uurRef = it->first;
4219  const returnRow_s &returnRowRef = it->second;
4220  tableRef.unmakerow((string *)&returnRowRef.row,
4221  &fieldValues);
4222 
4223  for (size_t n=0; inValues.size(); n++)
4224  {
4225  if (compareFields(fieldtype, fieldValues[fieldid],
4226  inValues[n])==true)
4227  {
4228  results[uurRef] = returnRowRef;
4229  }
4230  }
4231  }
4232  }
4233  break;
4234 
4235  case OPERATOR_NOTIN:
4236  {
4237  /* do after AST is walkable since inobject contains a vector
4238  * of Ast */
4239  int64_t fieldid;
4240  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4241  vector<fieldValue_s> fieldValues;
4242  class Table &tableRef = *schemaPtr->tables[tableid];
4243  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4244  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4245 
4246  for (it = andResults.begin(); it != andResults.end(); it++)
4247  {
4248  const uuRecord_s &uurRef = it->first;
4249  const returnRow_s &returnRowRef = it->second;
4250  tableRef.unmakerow((string *)&returnRowRef.row,
4251  &fieldValues);
4252  bool notin=true;
4253 
4254  for (size_t n=0; inValues.size(); n++)
4255  {
4256  if (compareFields(fieldtype, fieldValues[fieldid],
4257  inValues[n])==true)
4258  {
4259  notin=false;
4260  break;
4261  }
4262  }
4263 
4264  if (notin==true)
4265  {
4266  results[uurRef] = returnRowRef;
4267  }
4268  }
4269  }
4270  break;
4271 
4272  case OPERATOR_ISNULL:
4273  {
4274  if (lhs.isnull==true)
4275  {
4276  results[uurRef] = returnRowRef;
4277  }
4278  }
4279  break;
4280 
4281  case OPERATOR_ISNOTNULL:
4282  {
4283  if (lhs.isnull==false)
4284  {
4285  results[uurRef] = returnRowRef;
4286  }
4287  }
4288  break;
4289 
4290  default:
4291  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
4292  }
4293  }
4294  break;
4295 
4296  case CHAR:
4297  {
4298  switch (op)
4299  {
4300  case OPERATOR_EQ:
4301  {
4302  char rhsval=rightoperand[1];
4303 
4304  if (lhs.value.character==rhsval)
4305  {
4306  results[uurRef] = returnRowRef;
4307  }
4308  }
4309  break;
4310 
4311  case OPERATOR_NE:
4312  {
4313  char rhsval=rightoperand[1];
4314 
4315  if (lhs.value.character!=rhsval)
4316  {
4317  results[uurRef] = returnRowRef;
4318  }
4319  }
4320  break;
4321 
4322  case OPERATOR_GT:
4323  {
4324  char rhsval=rightoperand[1];
4325 
4326  if (lhs.value.character>rhsval)
4327  {
4328  results[uurRef] = returnRowRef;
4329  }
4330  }
4331  break;
4332 
4333  case OPERATOR_LT:
4334  {
4335  char rhsval=rightoperand[1];
4336 
4337  if (lhs.value.character<rhsval)
4338  {
4339  results[uurRef] = returnRowRef;
4340  }
4341  }
4342  break;
4343 
4344  case OPERATOR_GTE:
4345  {
4346  char rhsval=rightoperand[1];
4347 
4348  if (lhs.value.character>=rhsval)
4349  {
4350  results[uurRef] = returnRowRef;
4351  }
4352  }
4353  break;
4354 
4355  case OPERATOR_LTE:
4356  {
4357  char rhsval=rightoperand[1];
4358 
4359  if (lhs.value.character<=rhsval)
4360  {
4361  results[uurRef] = returnRowRef;
4362  }
4363  }
4364  break;
4365 
4366  case OPERATOR_BETWEEN:
4367  {
4368  char rhsval=rightoperand[1+sizeof(int64_t)];
4369  char rhsval2=rightoperand[1+sizeof(int64_t)+1];
4370 
4371  if (lhs.value.character >= rhsval && lhs.value.character <=
4372  rhsval2)
4373  {
4374  results[uurRef] = returnRowRef;
4375  }
4376  }
4377  break;
4378 
4379  case OPERATOR_NOTBETWEEN:
4380  {
4381  char rhsval=rightoperand[1+sizeof(int64_t)];
4382  char rhsval2=rightoperand[1+sizeof(int64_t)+1];
4383 
4384  if (lhs.value.character < rhsval || lhs.value.character >
4385  rhsval2)
4386  {
4387  results[uurRef] = returnRowRef;
4388  }
4389  }
4390  break;
4391 
4392  case OPERATOR_IN:
4393  {
4394  /* do after AST is walkable since inobject contains a vector
4395  * of Ast */
4396  int64_t fieldid;
4397  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4398  vector<fieldValue_s> fieldValues;
4399  class Table &tableRef = *schemaPtr->tables[tableid];
4400  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4401  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4402 
4403  for (it = andResults.begin(); it != andResults.end(); it++)
4404  {
4405  const uuRecord_s &uurRef = it->first;
4406  const returnRow_s &returnRowRef = it->second;
4407  tableRef.unmakerow((string *)&returnRowRef.row,
4408  &fieldValues);
4409 
4410  for (size_t n=0; inValues.size(); n++)
4411  {
4412  if (compareFields(fieldtype, fieldValues[fieldid],
4413  inValues[n])==true)
4414  {
4415  results[uurRef] = returnRowRef;
4416  }
4417  }
4418  }
4419  }
4420  break;
4421 
4422  case OPERATOR_NOTIN:
4423  {
4424  /* do after AST is walkable since inobject contains a vector
4425  * of Ast */
4426  int64_t fieldid;
4427  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4428  vector<fieldValue_s> fieldValues;
4429  class Table &tableRef = *schemaPtr->tables[tableid];
4430  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4431  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4432 
4433  for (it = andResults.begin(); it != andResults.end(); it++)
4434  {
4435  const uuRecord_s &uurRef = it->first;
4436  const returnRow_s &returnRowRef = it->second;
4437  tableRef.unmakerow((string *)&returnRowRef.row,
4438  &fieldValues);
4439  bool notin=true;
4440 
4441  for (size_t n=0; inValues.size(); n++)
4442  {
4443  if (compareFields(fieldtype, fieldValues[fieldid],
4444  inValues[n])==true)
4445  {
4446  notin=false;
4447  break;
4448  }
4449  }
4450 
4451  if (notin==true)
4452  {
4453  results[uurRef] = returnRowRef;
4454  }
4455  }
4456  }
4457  break;
4458 
4459  case OPERATOR_ISNULL:
4460  {
4461  if (lhs.isnull==true)
4462  {
4463  results[uurRef] = returnRowRef;
4464  }
4465  }
4466  break;
4467 
4468  case OPERATOR_ISNOTNULL:
4469  {
4470  if (lhs.isnull==false)
4471  {
4472  results[uurRef] = returnRowRef;
4473  }
4474  }
4475  break;
4476 
4477  default:
4478  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
4479  }
4480  }
4481  break;
4482 
4483  case CHARX:
4484  {
4485  switch (op)
4486  {
4487  case OPERATOR_EQ:
4488  {
4489  string rhsval=rightoperand.substr(1, string::npos);
4490 
4491  if (!lhs.str.compare(rhsval))
4492  {
4493  results[uurRef] = returnRowRef;
4494  }
4495  }
4496  break;
4497 
4498  case OPERATOR_NE:
4499  {
4500  string rhsval=rightoperand.substr(1, string::npos);
4501 
4502  if (lhs.str.compare(rhsval))
4503  {
4504  results[uurRef] = returnRowRef;
4505  }
4506  }
4507  break;
4508 
4509  case OPERATOR_IN:
4510  {
4511  /* do after AST is walkable since inobject contains a vector
4512  * of Ast */
4513  int64_t fieldid;
4514  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4515  vector<fieldValue_s> fieldValues;
4516  class Table &tableRef = *schemaPtr->tables[tableid];
4517  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4518  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4519 
4520  for (it = andResults.begin(); it != andResults.end(); it++)
4521  {
4522  const uuRecord_s &uurRef = it->first;
4523  const returnRow_s &returnRowRef = it->second;
4524  tableRef.unmakerow((string *)&returnRowRef.row,
4525  &fieldValues);
4526 
4527  for (size_t n=0; inValues.size(); n++)
4528  {
4529  if (compareFields(fieldtype, fieldValues[fieldid],
4530  inValues[n])==true)
4531  {
4532  results[uurRef] = returnRowRef;
4533  }
4534  }
4535  }
4536  }
4537  break;
4538 
4539  case OPERATOR_NOTIN:
4540  {
4541  /* do after AST is walkable since inobject contains a vector
4542  * of Ast */
4543  int64_t fieldid;
4544  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4545  vector<fieldValue_s> fieldValues;
4546  class Table &tableRef = *schemaPtr->tables[tableid];
4547  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4548  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4549 
4550  for (it = andResults.begin(); it != andResults.end(); it++)
4551  {
4552  const uuRecord_s &uurRef = it->first;
4553  const returnRow_s &returnRowRef = it->second;
4554  tableRef.unmakerow((string *)&returnRowRef.row,
4555  &fieldValues);
4556  bool notin=true;
4557 
4558  for (size_t n=0; inValues.size(); n++)
4559  {
4560  if (compareFields(fieldtype, fieldValues[fieldid],
4561  inValues[n])==true)
4562  {
4563  notin=false;
4564  break;
4565  }
4566  }
4567 
4568  if (notin==true)
4569  {
4570  results[uurRef] = returnRowRef;
4571  }
4572  }
4573  }
4574  break;
4575 
4576  case OPERATOR_ISNULL:
4577  {
4578  if (lhs.isnull==true)
4579  {
4580  results[uurRef] = returnRowRef;
4581  }
4582  }
4583  break;
4584 
4585  case OPERATOR_ISNOTNULL:
4586  {
4587  if (lhs.isnull==false)
4588  {
4589  results[uurRef] = returnRowRef;
4590  }
4591  }
4592  break;
4593 
4594  case OPERATOR_LIKE:
4595  {
4596  string rhsval=rightoperand.substr(1, string::npos);
4597  like2Regex(rhsval);
4598  pcrecpp::RE re(rhsval);
4599 
4600  if (re.FullMatch(lhs.str)==true)
4601  {
4602  results[uurRef] = returnRowRef;
4603  }
4604  }
4605  break;
4606 
4607  case OPERATOR_NOTLIKE:
4608  {
4609  string rhsval=rightoperand.substr(1, string::npos);
4610  like2Regex(rhsval);
4611  pcrecpp::RE re(rhsval);
4612  rhsval.insert(0, "^((?!");
4613  rhsval.append(").)*$");
4614 
4615  if (re.FullMatch(lhs.str)==true)
4616  {
4617  results[uurRef] = returnRowRef;
4618  }
4619  }
4620  break;
4621 
4622  default:
4623  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
4624  }
4625  }
4626  break;
4627 
4628  case VARCHAR:
4629  {
4630  switch (op)
4631  {
4632  case OPERATOR_EQ:
4633  {
4634  string rhsval=rightoperand.substr(1, string::npos);
4635 
4636  if (!lhs.str.compare(rhsval))
4637  {
4638  results[uurRef] = returnRowRef;
4639  }
4640  }
4641  break;
4642 
4643  case OPERATOR_NE:
4644  {
4645  string rhsval=rightoperand.substr(1, string::npos);
4646 
4647  if (lhs.str.compare(rhsval))
4648  {
4649  results[uurRef] = returnRowRef;
4650  }
4651  }
4652  break;
4653 
4654  case OPERATOR_IN:
4655  {
4656  /* do after AST is walkable since inobject contains a vector
4657  * of Ast */
4658  int64_t fieldid;
4659  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4660  vector<fieldValue_s> fieldValues;
4661  class Table &tableRef = *schemaPtr->tables[tableid];
4662  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4663  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4664 
4665  for (it = andResults.begin(); it != andResults.end(); it++)
4666  {
4667  const uuRecord_s &uurRef = it->first;
4668  const returnRow_s &returnRowRef = it->second;
4669  tableRef.unmakerow((string *)&returnRowRef.row,
4670  &fieldValues);
4671 
4672  for (size_t n=0; inValues.size(); n++)
4673  {
4674  if (compareFields(fieldtype, fieldValues[fieldid],
4675  inValues[n])==true)
4676  {
4677  results[uurRef] = returnRowRef;
4678  }
4679  }
4680  }
4681  }
4682  break;
4683 
4684  case OPERATOR_NOTIN:
4685  {
4686  /* do after AST is walkable since inobject contains a vector
4687  * of Ast */
4688  int64_t fieldid;
4689  memcpy(&fieldid, &rightoperand[1], sizeof(fieldid));
4690  vector<fieldValue_s> fieldValues;
4691  class Table &tableRef = *schemaPtr->tables[tableid];
4692  fieldtype_e fieldtype = tableRef.fields[fieldid].type;
4693  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
4694 
4695  for (it = andResults.begin(); it != andResults.end(); it++)
4696  {
4697  const uuRecord_s &uurRef = it->first;
4698  const returnRow_s &returnRowRef = it->second;
4699  tableRef.unmakerow((string *)&returnRowRef.row,
4700  &fieldValues);
4701  bool notin=true;
4702 
4703  for (size_t n=0; inValues.size(); n++)
4704  {
4705  if (compareFields(fieldtype, fieldValues[fieldid],
4706  inValues[n])==true)
4707  {
4708  notin=false;
4709  break;
4710  }
4711  }
4712 
4713  if (notin==true)
4714  {
4715  results[uurRef] = returnRowRef;
4716  }
4717  }
4718  }
4719  break;
4720 
4721  case OPERATOR_ISNULL:
4722  {
4723  if (lhs.isnull==true)
4724  {
4725  results[uurRef] = returnRowRef;
4726  }
4727  }
4728  break;
4729 
4730  case OPERATOR_ISNOTNULL:
4731  {
4732  if (lhs.isnull==false)
4733  {
4734  results[uurRef] = returnRowRef;
4735  }
4736  }
4737  break;
4738 
4739  case OPERATOR_LIKE:
4740  {
4741  string rhsval=rightoperand.substr(1, string::npos);
4742  like2Regex(rhsval);
4743  pcrecpp::RE re(rhsval);
4744 
4745  if (re.FullMatch(lhs.str)==true)
4746  {
4747  results[uurRef] = returnRowRef;
4748  }
4749  }
4750  break;
4751 
4752  case OPERATOR_NOTLIKE:
4753  {
4754  string rhsval=rightoperand.substr(1, string::npos);
4755  like2Regex(rhsval);
4756  pcrecpp::RE re(rhsval);
4757  rhsval.insert(0, "^((?!");
4758  rhsval.append(").)*$");
4759 
4760  if (re.FullMatch(lhs.str)==true)
4761  {
4762  results[uurRef] = returnRowRef;
4763  }
4764  }
4765  break;
4766 
4767  default:
4768  printf("%s %i anomaly %i\n", __FILE__, __LINE__, op);
4769  }
4770  }
4771  break;
4772 
4773  default:
4774  fprintf(logfile, "anomaly: %i %s %i\n",
4775  tableRef.fields[fieldid].type, __FILE__, __LINE__);
4776  }
4777  }
4778 }
4779 
4780 /* create new transaction if transactionPtrarg is NULL return transactionPtr
4781  * Pg will probably need to have another version of this function
4782  */
4783 void Statement::execute(class ApiInterface *reentryObject, apifPtr reentryfptr,
4784  int64_t reentrypoint, void *reentrydata,
4785  class Transaction *transactionPtrarg,
4786  const vector<string> &parametersarg)
4787 {
4788  reentry.reentryObject=reentryObject;
4789  reentry.reentryfptr=reentryfptr;
4790  reentry.reentrypoint=reentrypoint;
4791  reentry.reentrydata=reentrydata;
4792 
4793  reentryObject->results.cmdtype=queries[0].type;
4794 
4795  switch (reentryObject->results.cmdtype)
4796  {
4797  case CMD_SELECT:
4798  if (transactionPtrarg==NULL)
4799  {
4800  transactionPtr = new class Transaction(taPtr, schemaPtr->domainid);
4801  }
4802  else
4803  {
4804  transactionPtr = transactionPtrarg;
4805  }
4806 
4807  break;
4808 
4809  case CMD_INSERT:
4810  if (transactionPtrarg==NULL)
4811  {
4812  transactionPtr = new class Transaction(taPtr, schemaPtr->domainid);
4813  }
4814  else
4815  {
4816  transactionPtr = transactionPtrarg;
4817  }
4818 
4819  break;
4820 
4821  case CMD_UPDATE:
4822  if (transactionPtrarg==NULL)
4823  {
4824  transactionPtr = new class Transaction(taPtr, schemaPtr->domainid);
4825  }
4826  else
4827  {
4828  transactionPtr = transactionPtrarg;
4829  }
4830 
4831  break;
4832 
4833  case CMD_DELETE:
4834  if (transactionPtrarg==NULL)
4835  {
4836  transactionPtr = new class Transaction(taPtr, schemaPtr->domainid);
4837  }
4838  else
4839  {
4840  transactionPtr = transactionPtrarg;
4841  }
4842 
4843  break;
4844 
4845  default:
4846  transactionPtr = transactionPtrarg;
4847  }
4848 
4849  parameters = parametersarg;
4850  queryindex = queries.size()-1;
4851  startQuery();
4852 }
4853 
4854 /* entrypoint=1, from a select, =2 for evaluating INSERT values. otherwise,
4855  * from IN & NOTIN or INSERT, =0
4856  */
4857 void Statement::searchExpression(int64_t entrypoint, class Ast *astNode)
4858 {
4859  class Ast *nextAstNode=NULL;
4860 
4861  while (1)
4862  {
4863  if (astNode->evaluate(&nextAstNode, this)==true)
4864  {
4865  // node evaluated successfully
4866  if (nextAstNode==NULL) // rootnode evaluated, carry on with statement
4867  {
4868  switch (entrypoint)
4869  if (entrypoint==1)
4870  {
4871  case 1:
4874  delete currentQuery->searchCondition;
4876  branchtotype();
4877  break;
4878 
4879  case 2:
4880  branchtotype();
4881  break;
4882 
4883  default:
4884  ;
4885  }
4886 
4887  return;
4888  }
4889 
4890  // non-rootnode evaluated, so set up for the next
4891  astNode=nextAstNode;
4892  }
4893  else
4894  {
4895  // node not evaluated successfully
4896  if (nextAstNode==NULL)
4897  {
4898  /* backgrounded query, will continue */
4899  return;
4900  }
4901 
4902  // evaluate a child
4903  astNode=nextAstNode;
4904  }
4905  }
4906 }
4907 
4909 {
4910  switch (currentQuery->type)
4911  {
4912  case CMD_SELECT:
4913  {
4914  if (currentQuery->haswhere==false)
4915  {
4916  /* select everything, checking existing staged rows first */
4917  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
4918 
4919  for (it = transactionPtr->stagedRows.begin();
4920  it != transactionPtr->stagedRows.end(); it++)
4921  {
4922  const uuRecord_s &uurRef = it->first;
4923  const stagedRow_s &stagedRowRef = it->second;
4924  returnRow_s returnRow;
4925  stagedRow2ReturnRow(stagedRowRef, returnRow);
4926  currentQuery->results.searchResults[uurRef]=returnRow;
4927  }
4928 
4933  }
4934  else
4935  {
4936  continueSelect(1, NULL);
4937  }
4938  }
4939  break;
4940 
4941  case CMD_INSERT:
4942  {
4943  class Table &tableRef = *schemaPtr->tables[currentQuery->tableid];
4944 
4945  size_t numfields = currentQuery->insertColumns.size();
4946  currentQuery->results.insertValues.reserve(numfields);
4947 
4948  for (size_t n=0; n < numfields; n++)
4949  {
4950  fieldValue_s fieldValue = {};
4951  class Ast &astRef = *currentQuery->insertColumns[numfields-1-n];
4952  searchExpression(0, &astRef);
4953 
4954  if (astRef.operand[0]==OPERAND_NULL)
4955  {
4956  class Field &fieldRef =
4957  tableRef.fields[n];
4958 
4959  if (fieldRef.indextype==UNIQUENOTNULL ||
4960  fieldRef.indextype==NONUNIQUENOTNULL ||
4961  fieldRef.indextype==UNORDEREDNOTNULL)
4962  {
4964  return;
4965  }
4966 
4967  fieldValue.isnull=true;
4968  currentQuery->results.insertValues.push_back(fieldValue);
4969  }
4970  else
4971  {
4972  switch (tableRef.fields[n].type)
4973  {
4974  case INT:
4975  memcpy(&fieldValue.value.integer, &astRef.operand[1],
4976  sizeof(int64_t));
4977  currentQuery->results.insertValues.push_back(fieldValue);
4978  break;
4979 
4980  case UINT:
4981  memcpy(&fieldValue.value.uinteger, &astRef.operand[1],
4982  sizeof(int64_t));
4983  currentQuery->results.insertValues.push_back(fieldValue);
4984  break;
4985 
4986  case BOOL:
4987  if (astRef.operand[1]=='t')
4988  {
4989  fieldValue.value.boolean=true;
4990  }
4991  else
4992  {
4993  fieldValue.value.boolean=false;
4994  }
4995 
4996  currentQuery->results.insertValues.push_back(fieldValue);
4997  break;
4998 
4999  case FLOAT:
5000  Ast::toFloat(astRef.operand, fieldValue);
5001  currentQuery->results.insertValues.push_back(fieldValue);
5002  break;
5003 
5004  case CHAR:
5005  fieldValue.value.character=astRef.operand[1];
5006  currentQuery->results.insertValues.push_back(fieldValue);
5007  break;
5008 
5009  case CHARX:
5010  fieldValue.str=astRef.operand.substr(1, string::npos);
5011  currentQuery->results.insertValues.push_back(fieldValue);
5012  break;
5013 
5014  case VARCHAR:
5015  fieldValue.str=astRef.operand.substr(1, string::npos);
5016  currentQuery->results.insertValues.push_back(fieldValue);
5017  break;
5018 
5019  default:
5020  printf("%s %i anomaly %i\n", __FILE__, __LINE__,
5021  tableRef.fields[n].type);
5022  }
5023  }
5024  }
5025 
5026  if (tableRef.makerow(&currentQuery->results.insertValues,
5027  &currentQuery->results.newrow)==false)
5028  {
5030  }
5031 
5033  tableRef.fields[0].type, currentQuery->results.insertValues[0]);
5034 
5036  {
5038  return;
5039  }
5040 
5044  {
5045  0
5046  };
5049 
5050  class MessageSubtransactionCmd *msg =
5051  new class MessageSubtransactionCmd();
5052  class MessageSubtransactionCmd &msgref = *msg;
5054  msgref.row = currentQuery->results.newrow;
5057  msg);
5058  }
5059  break;
5060 
5061  case CMD_UPDATE:
5062  {
5063  if (currentQuery->haswhere==false)
5064  {
5065  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
5066 
5067  for (it = transactionPtr->stagedRows.begin();
5068  it != transactionPtr->stagedRows.end(); it++)
5069  {
5070  const uuRecord_s &uurRef = it->first;
5071  const stagedRow_s &stagedRowRef = it->second;
5072  returnRow_s returnRow;
5073  stagedRow2ReturnRow(stagedRowRef, returnRow);
5074  currentQuery->results.searchResults[uurRef]=returnRow;
5075  }
5076 
5080  return;
5081  }
5082  else
5083  {
5084  continueUpdate(1, NULL);
5085  }
5086  }
5087  break;
5088 
5089  case CMD_DELETE:
5090  {
5091  if (currentQuery->haswhere==false)
5092  {
5093  boost::unordered_map<uuRecord_s, stagedRow_s>::const_iterator it;
5094 
5095  for (it = transactionPtr->stagedRows.begin();
5096  it != transactionPtr->stagedRows.end(); it++)
5097  {
5098  const uuRecord_s &uurRef = it->first;
5099  const stagedRow_s &stagedRowRef = it->second;
5100  returnRow_s returnRow;
5101  stagedRow2ReturnRow(stagedRowRef, returnRow);
5102  currentQuery->results.searchResults[uurRef]=returnRow;
5103  }
5104 
5108  }
5109  else
5110  {
5111  continueDelete(1, NULL);
5112  }
5113  }
5114  break;
5115 
5116  case CMD_STOREDPROCEDURE:
5117  {
5119 
5121  {
5122  domainProceduresMap &procsMapRef =
5124 
5125  if (procsMapRef.count(currentQuery->storedProcedure))
5126  {
5127  procedures_s &proceduresRef =
5128  procsMapRef[currentQuery->storedProcedure];
5129  spclasscreate spC =
5130  (spclasscreate)proceduresRef.procedurecreator;
5131  spclasscreate spD =
5132  (spclasscreate)proceduresRef.proceduredestroyer;
5133  // make sure to delete this statement in the procedure!
5134  spC(NULL, reentry.reentryObject, (void *)spD);
5135  }
5136  else
5137  {
5139  return;
5140  }
5141  }
5142  else
5143  {
5145  return;
5146  }
5147  }
5148  break;
5149 
5150  case CMD_BEGIN:
5151  startQuery();
5152  break;
5153 
5154  case CMD_COMMIT:
5155  startQuery();
5156  break;
5157 
5158  case CMD_ROLLBACK:
5159  startQuery();
5160  break;
5161 
5162  default:
5163  printf("%s %i unhandled statement type %i\n", __FILE__, __LINE__,
5164  currentQuery->type);
5166  return;
5167  }
5168 }
5169 
5170 void Statement::reenter(int64_t status)
5171 {
5172  class ApiInterface *reentryObject=reentry.reentryObject;
5173  apifPtr reentryfptr=reentry.reentryfptr;
5174  int64_t reentrypoint=reentry.reentrypoint;
5175  void *reentrydata=reentry.reentrydata;
5176 
5177  if (transactionPtr != NULL)
5178  {
5181  }
5182 
5183  delete this;
5184  reentryObject->statementPtr=NULL;
5185  reentryObject->results.statementStatus=status;
5186  reentryObject->results.transactionPtr=transactionPtr;
5187  (*reentryObject.*reentryfptr)(reentrypoint, reentrydata);
5188 }
5189 
5190 void Statement::continueSelect(int64_t entrypoint, class Ast *ignorethis)
5191 {
5192  /* there should be nothing special to do for selectall vs predicate search
5193  * because the searchResults have already been populated
5194  */
5195  class Table &tableRef = *schemaPtr->tables[currentQuery->tableid];
5196 
5197  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
5198 
5199  for (it = currentQuery->results.searchResults.begin();
5200  it != currentQuery->results.searchResults.end(); it++)
5201  {
5202  const uuRecord_s &uurRef = it->first;
5203  const returnRow_s &returnRowRef = it->second;
5204  vector<fieldValue_s> foundFields;
5205  tableRef.unmakerow((string *)&returnRowRef.row, &foundFields);
5206  vector<fieldValue_s> returnFields;
5207 
5208  for (size_t n=0; n < currentQuery->fromColumnids.size(); n++)
5209  {
5210  returnFields.push_back(foundFields[currentQuery->fromColumnids[n].fieldid]);
5211  }
5212 
5213  currentQuery->results.selectResults[uurRef] = returnFields;
5214 
5215  if (!transactionPtr->stagedRows.count(uurRef))
5216  {
5217  stagedRow_s srow = {};
5218  srow.cmd=NOCOMMAND;
5219  srow.locktype=returnRowRef.locktype;
5220  srow.originalRow=returnRowRef.row;
5221  srow.originalrowid=returnRowRef.rowid;
5222 
5223  transactionPtr->stagedRows[uurRef]=srow;
5224  }
5225  }
5226 
5227  startQuery();
5228 }
5229 
5230 void Statement::continueDelete(int64_t entrypoint, class Ast *ignorethis)
5231 {
5232  switch (entrypoint)
5233  {
5234  case 1:
5235  {
5237  {
5238  0
5239  };
5243 
5244  boost::unordered_map<uuRecord_s, returnRow_s>::const_iterator it;
5245 
5246  for (it = currentQuery->results.searchResults.begin();
5247  it != currentQuery->results.searchResults.end(); it++)
5248  {
5249  const uuRecord_s &uurRef = it->first;
5250  const returnRow_s &returnRowRef = it->second;
5251  class MessageSubtransactionCmd *msg =
5252  new class MessageSubtransactionCmd();
5253  msg->subtransactionStruct.tableid = uurRef.tableid;
5254  msg->subtransactionStruct.rowid = uurRef.rowid;
5255  msg->subtransactionStruct.engineid = uurRef.engineid;
5257  uurRef.engineid, msg);
5258  stagedRow_s &stagedRowRef = transactionPtr->stagedRows[uurRef];
5259  stagedRowRef.cmd=DELETE;
5260  stagedRowRef.originalRow=returnRowRef.row;
5261  transactionPtr->stagedRows[uurRef].cmd=DELETE;
5262  }
5263 
5266  }
5267  break;
5268 
5269  case 2:
5270  startQuery();
5271  break;
5272 
5273  default:
5274  printf("%s %i anomaly %li\n", __FILE__, __LINE__, entrypoint);
5275  }
5276 }
5277 
5278 void Statement::continueUpdate(int64_t entrypoint, class Ast *ignorethis)
5279 {
5280  switch (entrypoint)
5281  {
5282  case 1:
5283  {
5284  /* walk through each search result, doing update on each one
5285  * and calling Ast::evaluateAssignment(fieldValues) for each
5286  * field to modify
5287  */
5290  }
5291 
5292  // break; fall right through
5293 
5294  case 2:
5295  {
5296  /* walk through each search result, doing update on each one
5297  * and calling Ast::evaluateAssignment(fieldValues) for each
5298  * field to modify
5299  */
5301  {
5302  printf("%s %i APISTATUS_PENDING pendingcmd %i\n", __FILE__, __LINE__, transactionPtr->pendingcmd);
5304  return;
5305  }
5306 
5309  {
5310  0
5311  };
5313 
5314  class Table &tableRef = *schemaPtr->tables[currentQuery->tableid];
5315 
5318  {
5319  vector<fieldValue_s> fieldValues;
5320  const returnRow_s &returnRowRef=
5322  tableRef.unmakerow((string *)&returnRowRef.row, &fieldValues);
5323 
5324  // do update stuff
5325  // boost::unordered_map<int64_t, class Ast *> fieldidAssignments
5326  boost::unordered_map<int64_t, class Ast *>::iterator it;
5327 
5328  for (it = currentQuery->fieldidAssignments.begin();
5329  it != currentQuery->fieldidAssignments.end(); it++)
5330  {
5331  it->second->evaluateAssignment(fieldValues, this);
5332  // fieldid is it->first; class Ast * is it->second;
5333  class Field &fieldRef = tableRef.fields[it->first];
5334  fieldValue_s fieldValue = {};
5335 
5336  if (it->second->operand[0]==OPERAND_NULL)
5337  {
5338  fieldValue.isnull=true;
5339  }
5340  else
5341  {
5342  switch (fieldRef.type)
5343  {
5344  case INT:
5345  memcpy(&fieldValue.value.integer,
5346  &it->second->operand[1],
5347  sizeof(int64_t));
5348  break;
5349 
5350  case UINT:
5351  memcpy(&fieldValue.value.uinteger,
5352  &it->second->operand[1],
5353  sizeof(int64_t));
5354  break;
5355 
5356  case BOOL:
5357  {
5358  int64_t boolval;
5359  memcpy(&boolval, &it->second->operand[1],
5360  sizeof(int64_t));
5361  fieldValue.value.boolean = (bool)boolval;
5362  }
5363  break;
5364 
5365  case FLOAT:
5366  Ast::toFloat(it->second->operand, fieldValue);
5367  break;
5368 
5369  case CHAR:
5370  fieldValue.value.character=it->second->operand[1];
5371  break;
5372 
5373  case CHARX:
5374  fieldValue.str=it->second->operand.substr(1,
5375  string::npos);
5376  break;
5377 
5378  case VARCHAR:
5379  fieldValue.str=it->second->operand.substr(1,
5380  string::npos);
5381  break;
5382 
5383  default:
5384  printf("%s %i anomaly %i\n", __FILE__, __LINE__,
5385  tableRef.fields[it->first].type);
5386  return;
5387  }
5388  }
5389 
5390  currentQuery->results.setFields[it->first]=fieldValue;
5391  }
5392 
5393  const uuRecord_s &uurRef=
5395 
5396  if (!currentQuery->results.setFields.count(0))
5397  {
5398  // update
5400  stagedRow_s stagedRow= {};
5401  vector<fieldValue_s> fieldValues;
5402  tableRef.unmakerow((string *)&returnRowRef.row, &fieldValues);
5403 
5404  for (size_t n=0; n < fieldValues.size(); n++)
5405  {
5406  class Field &fieldRef = tableRef.fields[n];
5407 
5408  if (currentQuery->results.setFields.count(n))
5409  {
5410  fieldValues[n] = currentQuery->results.setFields[n];
5411 
5412  // index stuff
5413  if (fieldRef.index.isunique==true)
5414  {
5415  lockFieldValue_s lockFieldValue = {};
5416  lockFieldValue.engineid =
5417  transactionPtr->getengine(fieldRef.type,
5418  fieldValues[n]);
5419  // locktype could potentially change
5420  lockFieldValue.locktype = INDEXLOCK;
5421  lockFieldValue.fieldVal = fieldValues[n];
5422  stagedRow.uniqueIndices[n]=lockFieldValue;
5423 
5425  class MessageSubtransactionCmd *msg =
5426  new class MessageSubtransactionCmd();
5427  msg->subtransactionStruct.isrow = false;
5428  msg->subtransactionStruct.tableid = uurRef.tableid;
5429  msg->subtransactionStruct.rowid = uurRef.rowid;
5430  msg->subtransactionStruct.engineid = uurRef.engineid;
5431  msg->subtransactionStruct.fieldid = n;
5432  msg->fieldVal = lockFieldValue.fieldVal;
5435  1,
5436  lockFieldValue.engineid,
5437  msg);
5438  }
5439  }
5440  }
5441 
5442  stagedRow.originalRow=returnRowRef.row;
5443  stagedRow.originalrowid=uurRef.rowid;
5444  stagedRow.newrowid=uurRef.rowid;
5445  stagedRow.previoussubtransactionid=
5446  returnRowRef.previoussubtransactionid;
5447  stagedRow.locktype=WRITELOCK;
5448  stagedRow.originalengineid=uurRef.engineid;
5449  stagedRow.newengineid=uurRef.engineid;
5450  tableRef.makerow(&fieldValues, &stagedRow.newRow);
5451  stagedRow.cmd=UPDATE;
5452  transactionPtr->stagedRows[uurRef]=stagedRow;
5453 
5455  class MessageSubtransactionCmd *msg =
5456  new class MessageSubtransactionCmd();
5457  msg->subtransactionStruct.tableid = uurRef.tableid;
5458  msg->subtransactionStruct.rowid = uurRef.rowid;
5459  msg->row = stagedRow.newRow;
5461  1, uurRef.engineid, msg);
5462  }
5463  else
5464  {
5465  //replace
5466  stagedRow_s &stagedRowRef = transactionPtr->stagedRows[uurRef];
5467  stagedRowRef.cmd=UPDATE;
5468  stagedRowRef.originalRow=returnRowRef.row;
5469  stagedRowRef.originalrowid=uurRef.rowid;
5470  stagedRowRef.originalengineid=uurRef.engineid;
5471  stagedRowRef.previoussubtransactionid=
5472  returnRowRef.previoussubtransactionid;
5473  stagedRowRef.locktype=WRITELOCK;
5474 
5477  vector<fieldValue_s> fieldValues;
5478  tableRef.unmakerow((string *)&returnRowRef.row, &fieldValues);
5479 
5480  for (size_t n=0; n < fieldValues.size(); n++)
5481  {
5482  if (currentQuery->results.setFields.count(n))
5483  {
5484  fieldValues[n] = currentQuery->results.setFields[n];
5485  }
5486  }
5487 
5488  tableRef.makerow(&fieldValues, &stagedRowRef.newRow);
5490  transactionPtr->getengine(tableRef.fields[0].type,
5491  fieldValues[0]);
5493 
5494  class MessageSubtransactionCmd *msg =
5495  new class MessageSubtransactionCmd();
5496  class MessageSubtransactionCmd &msgref = *msg;
5498  msgref.row = stagedRowRef.newRow;
5500  stagedRowRef.newengineid, msg);
5501  }
5502 
5504 
5505  return;
5506  }
5507 
5508  startQuery();
5509  }
5510  break;
5511 
5512  default:
5513  printf("%s %i anomaly %li\n", __FILE__, __LINE__, entrypoint);
5514  }
5515 }
5516 
5517 void Statement::continueInsert(int64_t entrypoint, class Ast *ignorethis)
5518 {
5519  startQuery();
5520 }
5521 
5523 {
5524  if (queryindex >= 0)
5525  {
5527 
5528  if (currentQuery->haswhere==true)
5529  {
5531  }
5532  else
5533  {
5534  branchtotype();
5535  }
5536  }
5537  else
5538  {
5539  // reenter
5540  /* put the final query results somewhere, like staged rows,
5541  * locking every row in every query, then put the results
5542  * somewhere the user can find them */
5543  switch (currentQuery->type)
5544  {
5545  case CMD_SELECT:
5546  {
5548  reentry.reentryObject->results.statementStatus = STATUS_OK;
5551  class Table &tableRef = *schemaPtr->tables[currentQuery->tableid];
5552 
5553  for (size_t n=0; n < currentQuery->fromColumnids.size(); n++)
5554  {
5555  reentry.reentryObject->results.selectFields.push_back(
5556  {tableRef.fields[currentQuery->fromColumnids[n].fieldid].type, currentQuery->fromColumnids[n].name});
5557  }
5558  }
5559  break;
5560 
5561  case CMD_INSERT:
5562  {
5564  reentry.reentryObject->results.statementStatus = STATUS_OK;
5565  returnRow_s returnRow;
5566  returnRow.rowid = currentQuery->results.newrowuur.rowid;
5567  returnRow.previoussubtransactionid = 0;
5568  returnRow.locktype = WRITELOCK;
5569  returnRow.row = currentQuery->results.newrow;
5571  returnRow;
5572  }
5573  break;
5574 
5575  case CMD_UPDATE:
5577  reentry.reentryObject->results.statementStatus = STATUS_OK;
5578  reentry.reentryObject->results.statementResults =
5580  break;
5581 
5582  case CMD_DELETE:
5584  reentry.reentryObject->results.statementStatus = STATUS_OK;
5585  reentry.reentryObject->results.statementResults =
5587  break;
5588 
5589  case CMD_BEGIN:
5591  reentry.reentryObject->results.statementStatus = STATUS_OK;
5592  break;
5593 
5594  case CMD_COMMIT:
5596  reentry.reentryObject->results.statementStatus = STATUS_OK;
5597  break;
5598 
5599  case CMD_ROLLBACK:
5601  reentry.reentryObject->results.statementStatus = STATUS_OK;
5602  break;
5603 
5604  default:
5605  printf("%s %i anomaly %i\n", __FILE__, __LINE__, currentQuery->type);
5606  return;
5607  }
5608 
5609  reenter(STATUS_OK);
5610  }
5611 }
5612 
5613 void Statement::subqueryScalar(class Ast *astnode)
5614 {
5615  if (astnode->operand[0] != OPERAND_SUBQUERY)
5616  {
5617  return;
5618  }
5619 
5620  int64_t queryinstance;
5621  memcpy(&queryinstance, &astnode->operand[1], sizeof(queryinstance));
5622 
5623  query_s &queryRef = queries[queryinstance];
5624  boost::unordered_map< uuRecord_s, vector<fieldValue_s> > &selectResultsRef =
5625  queryRef.results.selectResults;
5626 
5627  switch (selectResultsRef.size())
5628  {
5629  case 0:
5630  astnode->operand.assign(1, OPERAND_NULL);
5631  break;
5632 
5633  case 1:
5634  {
5635  boost::unordered_map< uuRecord_s,
5636  vector<fieldValue_s> >::const_iterator it;
5637  it = selectResultsRef.begin();
5638  const vector<fieldValue_s> &fieldValuesRef = it->second;
5639 
5640  if (fieldValuesRef.size()==1)
5641  {
5642  // get the field type table.fields[0].type fieldtype_e
5643  switch (schemaPtr->tables[queryRef.tableid]->fields[0].type)
5644  {
5645  case INT:
5646  astnode->operand.resize(1+sizeof(int64_t), (char)0);
5647  astnode->operand[0] = OPERAND_INTEGER;
5648  memcpy(&astnode->operand[1], &fieldValuesRef[0].value.integer,
5649  sizeof(int64_t));
5650  break;
5651 
5652  case UINT:
5653  astnode->operand.resize(1+sizeof(int64_t), (char)0);
5654  astnode->operand[0] = OPERAND_INTEGER;
5655  memcpy(&astnode->operand[1], &fieldValuesRef[0].value.uinteger,
5656  sizeof(int64_t));
5657  break;
5658 
5659  case BOOL:
5660  astnode->operand.resize(2, OPERAND_BOOLEAN);
5661 
5662  if (fieldValuesRef[0].value.boolean==true)
5663  {
5664  astnode->operand[1]='t';
5665  }
5666  else
5667  {
5668  astnode->operand[1]='f';
5669  }
5670 
5671  break;
5672 
5673  case FLOAT:
5674  astnode->operand.resize(1+sizeof(long double), (char)0);
5675  astnode->operand[0] = OPERAND_FLOAT;
5676  memcpy(&astnode->operand[1], &fieldValuesRef[0].value.floating,
5677  sizeof(int64_t));
5678  break;
5679 
5680  case CHAR:
5681  astnode->operand.resize(1+sizeof(char), (char)0);
5682  astnode->operand[0] = OPERAND_STRING;
5683  astnode->operand[1] = fieldValuesRef[0].value.character;
5684  break;
5685 
5686  case CHARX:
5687  astnode->operand.assign(1, OPERAND_STRING);
5688  astnode->operand.append(fieldValuesRef[0].str);
5689  break;
5690 
5691  case VARCHAR:
5692  astnode->operand.assign(1, OPERAND_STRING);
5693  astnode->operand.append(fieldValuesRef[0].str);
5694  break;
5695 
5696  default:
5697  printf("%s %i anomaly %i\n", __FILE__, __LINE__,
5698  schemaPtr->tables[queryRef.tableid]->fields[0].type);
5699  }
5700 
5701  return;
5702  }
5703  else
5704  {
5705  printf("%s %i too many columns in scalar subquery %lu\n", __FILE__,
5706  __LINE__, fieldValuesRef.size());
5707  }
5708  }
5709  break;
5710 
5711  default:
5712  printf("%s %i too many returned rows in scalar subquery %lu\n", __FILE__,
5713  __LINE__, selectResultsRef.size());
5714  }
5715 }
5716 
5717 void Statement::subqueryUnique(class Ast *astnode)
5718 {
5719  int64_t queryinstance;
5720  memcpy(&queryinstance, &astnode->operand[1], sizeof(queryinstance));
5721  query_s &queryRef = queries[queryinstance];
5722  size_t numfields = queryRef.fromColumnids.size();
5723  class Table &tableRef = *schemaPtr->tables[queryRef.tableid];
5724 
5725  boost::unordered_map< uuRecord_s, vector<fieldValue_s> >::iterator it;
5726  boost::unordered_map< uuRecord_s, vector<fieldValue_s> >::iterator it2;
5727 
5728  for (it = queryRef.results.selectResults.begin();
5729  it != queryRef.results.selectResults.end(); it++)
5730  {
5731  const uuRecord_s &uurRef1 = it->first;
5732  const vector<fieldValue_s> &fieldValues = it->second;
5733 
5734  for (it2 = queryRef.results.selectResults.begin();
5735  it2 != queryRef.results.selectResults.end(); it++)
5736  {
5737  const uuRecord_s &uurRef2 = it2->first;
5738  const vector<fieldValue_s> &fieldValues2 = it->second;
5739 
5740  if (uurRef1==uurRef2)
5741  {
5742  continue;
5743  }
5744 
5745  bool ismatch=true;
5746 
5747  for (size_t n=0; n < numfields; n++)
5748  {
5749  if (compareFields(
5750  tableRef.fields[queryRef.fromColumnids[n].fieldid].type,
5751  fieldValues[n], fieldValues2[n])==false)
5752  {
5753  ismatch=false;
5754  break;
5755  }
5756  }
5757 
5758  if (ismatch==true)
5759  {
5760  astnode->operand.resize(OPERAND_BOOLEAN, 2);
5761  astnode->operand[1]='f';
5762  return;
5763  }
5764  }
5765  }
5766 
5767  astnode->operand.resize(OPERAND_BOOLEAN, 2);
5768  astnode->operand[1] = 't';
5769 }
5770 
5771 void Statement::subqueryExists(class Ast *astnode)
5772 {
5773  int64_t queryinstance;
5774  memcpy(&queryinstance, &astnode->operand[1], sizeof(queryinstance));
5775 
5776  astnode->operand.resize(OPERAND_BOOLEAN, 2);
5777 
5778  if (queries[queryinstance].results.selectResults.size())
5779  {
5780  astnode->operand[1]='t';
5781  }
5782  else
5783  {
5784  astnode->operand[1]='f';
5785  }
5786 }
5787 
5788 void Statement::subqueryIn(class Ast *astnode)
5789 {
5790  int64_t queryinstance;
5791  memcpy(&queryinstance, &astnode->operand[1], sizeof(queryinstance));
5792  query_s &queryRef = queries[queryinstance];
5793 
5794  boost::unordered_map< uuRecord_s, vector<fieldValue_s> >::iterator it;
5795 
5796  for (it = queryRef.results.selectResults.begin();
5797  it != queryRef.results.selectResults.end(); it++)
5798  {
5799  queryRef.results.inValues.push_back(it->second[0]);
5800  }
5801 }
5802 
5803 void Statement::abortQuery(int64_t status)
5804 {
5805  // entire transaction should be rolled back if non-zero status
5806  reenter(status);
5807 }