InfiniSQL  v0.1.2-alpha
Massive Scale Transaction Processing
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SubTransaction.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 
30 #include "SubTransaction.h"
31 #line 32 "SubTransaction.cc"
32 
34  int64_t transactionidarg, int64_t domainidarg,
35  class Engine *enginePtrarg) :
36  taAddr(taAddrarg), transactionid(transactionidarg), domainid(domainidarg),
37  enginePtr(enginePtrarg)
38 {
42 }
43 
45 {
47 }
48 
50 {
51  msgrcv = msgrcvarg;
52 
54  {
56  {
57  class MessageSubtransactionCmd &subtransactionCmdRef =
58  *((class MessageSubtransactionCmd *)msgrcv);
60  class MessageSubtransactionCmd &msgref = *msg;
61 
62  switch ((enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd)
63  {
64  case NEWROW:
65  {
67  newrow(subtransactionCmdRef.subtransactionStruct.tableid,
68  subtransactionCmdRef.row);
70  }
71  break;
72 
73  case UNIQUEINDEX:
74  {
76  uniqueIndex(subtransactionCmdRef.subtransactionStruct.tableid,
77  subtransactionCmdRef.subtransactionStruct.fieldid,
78  subtransactionCmdRef.subtransactionStruct.rowid,
79  subtransactionCmdRef.subtransactionStruct.engineid,
80  &subtransactionCmdRef.fieldVal);
82  subtransactionCmdRef.subtransactionStruct.tableid;
84  subtransactionCmdRef.subtransactionStruct.fieldid;
85  msgref.fieldVal = subtransactionCmdRef.fieldVal;
86  }
87  break;
88 
89  case UPDATEROW:
90  {
92  updaterow(subtransactionCmdRef.subtransactionStruct.tableid,
93  subtransactionCmdRef.subtransactionStruct.rowid,
94  &subtransactionCmdRef.row);
96  }
97  break;
98 
99  case DELETEROW:
100  {
101  msgref.subtransactionStruct.rowid =
102  subtransactionCmdRef.subtransactionStruct.rowid;
104  subtransactionCmdRef.subtransactionStruct.tableid;
106  subtransactionCmdRef.subtransactionStruct.engineid;
108  deleterow(subtransactionCmdRef.subtransactionStruct.tableid,
109  subtransactionCmdRef.subtransactionStruct.rowid);
110  }
111  break;
112 
113  case REPLACEDELETEROW:
114  {
116  deleterow(subtransactionCmdRef.subtransactionStruct.tableid,
117  subtransactionCmdRef.subtransactionStruct.rowid,
118  subtransactionCmdRef.subtransactionStruct.forward_rowid,
119  subtransactionCmdRef.subtransactionStruct.forward_engineid);
121  }
122  break;
123 
124  case INDEXSEARCH:
125  {
126  indexSearch(subtransactionCmdRef.subtransactionStruct.tableid,
127  subtransactionCmdRef.subtransactionStruct.fieldid,
128  &subtransactionCmdRef.searchParameters,
129  &msgref.indexHits);
130  }
131  break;
132 
133  case SELECTROWS:
134  {
135  selectrows(subtransactionCmdRef.subtransactionStruct.tableid,
136  &subtransactionCmdRef.rowids,
137  subtransactionCmdRef.subtransactionStruct.locktype,
138  subtransactionCmdRef.transactionStruct.transaction_pendingcmdid,
139  &msgref.returnRows);
140  }
141  break;
142 
143  case SEARCHRETURN1:
144  searchReturn1(subtransactionCmdRef.subtransactionStruct.tableid,
145  subtransactionCmdRef.subtransactionStruct.fieldid,
146  subtransactionCmdRef.subtransactionStruct.locktype,
147  subtransactionCmdRef.searchParameters,
148  msgref.returnRows);
149  break;
150 
151  default:
152  fprintf(logfile, "anomaly: %i %s %i\n",
153  subtransactionCmdRef.transactionStruct.transaction_enginecmd,
154  __FILE__, __LINE__);
155  }
156 
157  replyTransaction((void *)msg);
158  }
159  break;
160 
162  {
163  class MessageCommitRollback &subtransactionCmdRef =
164  *((class MessageCommitRollback *)msgrcv);
165  class Table *tablePtr;
166  class Index *indexPtr;
167 
168  for (size_t n=0; n<subtransactionCmdRef.rofs.size(); n++)
169  {
170  rowOrField_s &rowFieldRef = subtransactionCmdRef.rofs[n];
171 
172  if (!schemaPtr->tables.count(rowFieldRef.tableid))
173  {
174  printf("%s %i anomaly, barfing, tableid %i\n", __FILE__,
175  __LINE__, rowFieldRef.tableid);
176  abort();
177  }
178 
179  tablePtr = schemaPtr->tables[rowFieldRef.tableid];
180 
181  if (rowFieldRef.isrow==true)
182  {
183  tablePtr->commitRollbackUnlock(rowFieldRef.rowid,
185  (enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd);
186 
187  // drain lock queue if: sueccessful delete & commit, or insert &
188  // rollback is a non-existent row sufficient to infer?
189  // For now, yes,
190  // but later, maybe not, if there's some other flag. Figure it
191  // out at
192  // that point.
193  if (tablePtr->rows.count(rowFieldRef.rowid) &&
194  (enginecmd_e)subtransactionCmdRef.transactionStruct.transaction_enginecmd !=
195  REVERTCMD)
196  {
197  processRowLockQueue(rowFieldRef.tableid,
198  rowFieldRef.rowid);
199  }
200  else
201  {
202  drainRowLockQueue(rowFieldRef.tableid,
203  rowFieldRef.rowid);
204  }
205  }
206  else if (rowFieldRef.isnotaddunique==false)
207  {
208  indexPtr = &tablePtr->fields[rowFieldRef.fieldid].index;
209 
210  if (rowFieldRef.fieldVal.isnull==true)
211  {
212  printf("%s %i INSERTNULLENTRY unique index\n", __FILE__,
213  __LINE__);
214  indexPtr->insertNullEntry(rowFieldRef.rowid,
215  rowFieldRef.engineid);
216  }
217  else
218  {
219 
220  switch (indexPtr->fieldtype)
221  {
222  case INT:
223  indexPtr->commitRollback(rowFieldRef.fieldVal.value.integer,
225  (enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd);
226  break;
227 
228  case UINT:
229  indexPtr->commitRollback(rowFieldRef.fieldVal.value.uinteger,
231  (enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd);
232  break;
233 
234  case BOOL:
235  indexPtr->commitRollback(rowFieldRef.fieldVal.value.boolean,
237  (enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd);
238  break;
239 
240  case FLOAT:
241  indexPtr->commitRollback(rowFieldRef.fieldVal.value.floating,
243  (enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd);
244  break;
245 
246  case CHAR:
247  indexPtr->commitRollback(rowFieldRef.fieldVal.value.character,
249  (enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd);
250  break;
251 
252  case CHARX:
253  indexPtr->commitRollback(rowFieldRef.fieldVal.str,
255  (enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd);
256  break;
257 
258  case VARCHAR:
259  indexPtr->commitRollback(rowFieldRef.fieldVal.str,
261  (enginecmd_e) subtransactionCmdRef.transactionStruct.transaction_enginecmd);
262  break;
263 
264  default:
265  fprintf(logfile, "anomaly: %i %s %i\n",
266  indexPtr->fieldtype, __FILE__, __LINE__);
267  }
268  }
269 
270  if ((enginecmd_e)subtransactionCmdRef.transactionStruct.transaction_enginecmd == COMMITCMD)
271  {
272  drainIndexLockQueue(rowFieldRef.tableid, rowFieldRef.fieldid,
273  &rowFieldRef.fieldVal);
274  }
275  else if ((enginecmd_e)subtransactionCmdRef.transactionStruct.transaction_enginecmd == ROLLBACKCMD)
276  {
277  processIndexLockQueue(rowFieldRef.tableid,
278  rowFieldRef.fieldid,
279  &rowFieldRef.fieldVal);
280  }
281  }
282  else // is not addunique index
283  {
284  // possibilities are: add null, delete null,
285  // add nonunique, delete nonunique, delete unique, replace
286  indexPtr = &tablePtr->fields[rowFieldRef.fieldid].index;
287 
288  if (rowFieldRef.isreplace==true)
289  {
290  if (rowFieldRef.fieldVal.isnull==true)
291  {
292  indexPtr->replaceNull(rowFieldRef.rowid,
293  rowFieldRef.engineid,
294  rowFieldRef.newrowid,
295  rowFieldRef.engineid);
296  }
297  else
298  {
299  switch (indexPtr->fieldtype)
300  {
301  case INT:
302  if (indexPtr->isunique==true)
303  {
304  indexPtr->replaceUnique(rowFieldRef.newrowid,
305  rowFieldRef.newengineid,
306  rowFieldRef.fieldVal.value.integer);
307  }
308  else
309  {
310  indexPtr->replaceNonunique(rowFieldRef.rowid,
311  rowFieldRef.engineid,
312  rowFieldRef.newrowid,
313  rowFieldRef.newengineid,
314  rowFieldRef.fieldVal.value.integer);
315  }
316 
317  break;
318 
319  case UINT:
320  if (indexPtr->isunique==true)
321  {
322  indexPtr->replaceUnique(rowFieldRef.newrowid,
323  rowFieldRef.newengineid,
324  rowFieldRef.fieldVal.value.uinteger);
325  }
326  else
327  {
328  indexPtr->replaceNonunique(rowFieldRef.rowid,
329  rowFieldRef.engineid,
330  rowFieldRef.newrowid,
331  rowFieldRef.newengineid,
332  rowFieldRef.fieldVal.value.uinteger);
333  }
334 
335  break;
336 
337  case BOOL:
338  if (indexPtr->isunique==true)
339  {
340  indexPtr->replaceUnique(rowFieldRef.newrowid,
341  rowFieldRef.newengineid,
342  rowFieldRef.fieldVal.value.boolean);
343  }
344  else
345  {
346  indexPtr->replaceNonunique(rowFieldRef.rowid,
347  rowFieldRef.engineid,
348  rowFieldRef.newrowid,
349  rowFieldRef.newengineid,
350  rowFieldRef.fieldVal.value.boolean);
351  }
352 
353  break;
354 
355  case FLOAT:
356  if (indexPtr->isunique==true)
357  {
358  indexPtr->replaceUnique(rowFieldRef.newrowid,
359  rowFieldRef.newengineid,
360  rowFieldRef.fieldVal.value.floating);
361  }
362  else
363  {
364  indexPtr->replaceNonunique(rowFieldRef.rowid,
365  rowFieldRef.engineid,
366  rowFieldRef.newrowid,
367  rowFieldRef.newengineid,
368  rowFieldRef.fieldVal.value.floating);
369  }
370 
371  break;
372 
373  case CHAR:
374  if (indexPtr->isunique==true)
375  {
376  indexPtr->replaceUnique(rowFieldRef.newrowid,
377  rowFieldRef.newengineid,
378  rowFieldRef.fieldVal.value.character);
379  }
380  else
381  {
382  indexPtr->replaceNonunique(rowFieldRef.rowid,
383  rowFieldRef.engineid,
384  rowFieldRef.newrowid,
385  rowFieldRef.newengineid,
386  rowFieldRef.fieldVal.value.character);
387  }
388 
389  break;
390 
391  case CHARX:
392  if (indexPtr->isunique==true)
393  {
394  indexPtr->replaceUnique(rowFieldRef.newrowid,
395  rowFieldRef.newengineid,
396  rowFieldRef.fieldVal.str);
397  }
398  else
399  {
400  indexPtr->replaceNonunique(rowFieldRef.rowid,
401  rowFieldRef.engineid,
402  rowFieldRef.newrowid,
403  rowFieldRef.newengineid,
404  rowFieldRef.fieldVal.str);
405  }
406 
407  break;
408 
409  case VARCHAR:
410  if (indexPtr->isunique==true)
411  {
412  indexPtr->replaceUnique(rowFieldRef.newrowid,
413  rowFieldRef.newengineid,
414  rowFieldRef.fieldVal.str);
415  }
416  else
417  {
418  indexPtr->replaceNonunique(rowFieldRef.rowid,
419  rowFieldRef.engineid,
420  rowFieldRef.newrowid,
421  rowFieldRef.newengineid,
422  rowFieldRef.fieldVal.str);
423  }
424 
425  break;
426 
427  default:
428  fprintf(logfile, "anomaly: %i %s %i\n",
429  indexPtr->fieldtype, __FILE__, __LINE__);
430  }
431  }
432 
433  continue;
434  }
435 
436  if (rowFieldRef.fieldVal.isnull==true)
437  {
438  if (rowFieldRef.deleteindexentry==true)
439  {
440  indexPtr->deleteNullEntry(rowFieldRef.rowid,
441  rowFieldRef.engineid);
442  }
443  else
444  {
445  indexPtr->insertNullEntry(rowFieldRef.rowid,
446  rowFieldRef.engineid);
447  }
448 
449  continue;
450  }
451 
452  switch (indexPtr->fieldtype)
453  {
454  case INT:
455  if (indexPtr->isunique==true) // delete unique
456  {
457  indexPtr->deleteUniqueEntry(rowFieldRef.fieldVal.value.integer);
458  // process lock queue
459  processIndexLockQueue(rowFieldRef.tableid,
460  rowFieldRef.fieldid,
461  &rowFieldRef.fieldVal);
462  }
463  else if (rowFieldRef.deleteindexentry==true) // delete non-unique
464  {
465  indexPtr->deleteNonuniqueEntry(rowFieldRef.fieldVal.value.integer, rowFieldRef.rowid, rowFieldRef.engineid);
466  }
467  else // add non-unique
468  {
469  indexPtr->insertNonuniqueEntry(rowFieldRef.fieldVal.value.integer, rowFieldRef.rowid, rowFieldRef.engineid);
470  }
471 
472  break;
473 
474  case UINT:
475  if (indexPtr->isunique==true) // delete unique
476  {
477  indexPtr->deleteUniqueEntry(rowFieldRef.fieldVal.value.
478  uinteger);
479  // process lock queue
480  processIndexLockQueue(rowFieldRef.tableid,
481  rowFieldRef.fieldid,
482  &rowFieldRef.fieldVal);
483  }
484  else if (rowFieldRef.deleteindexentry==true) // delete non-unique
485  {
486  indexPtr->deleteNonuniqueEntry(rowFieldRef.fieldVal.value.uinteger, rowFieldRef.rowid, rowFieldRef.engineid);
487  }
488  else // add non-unique
489  {
490  indexPtr->insertNonuniqueEntry(rowFieldRef.fieldVal.value.uinteger, rowFieldRef.rowid, rowFieldRef.engineid);
491  }
492 
493  break;
494 
495  case BOOL:
496  if (indexPtr->isunique==true) // delete unique
497  {
498  indexPtr->deleteUniqueEntry(rowFieldRef.fieldVal.value.boolean);
499  // process lock queue
500  processIndexLockQueue(rowFieldRef.tableid,
501  rowFieldRef.fieldid,
502  &rowFieldRef.fieldVal);
503  }
504  else if (rowFieldRef.deleteindexentry==true) // delete non-unique
505  {
506  indexPtr->deleteNonuniqueEntry(rowFieldRef.fieldVal.value.boolean, rowFieldRef.rowid, rowFieldRef.engineid);
507  }
508  else // add non-unique
509  {
510  indexPtr->insertNonuniqueEntry(rowFieldRef.fieldVal.value.boolean, rowFieldRef.rowid, rowFieldRef.engineid);
511  }
512 
513  break;
514 
515  case FLOAT:
516  if (indexPtr->isunique==true) // delete unique
517  {
518  indexPtr->deleteUniqueEntry(rowFieldRef.fieldVal.value.
519  floating);
520  // process lock queue
521  processIndexLockQueue(rowFieldRef.tableid,
522  rowFieldRef.fieldid,
523  &rowFieldRef.fieldVal);
524  }
525  else if (rowFieldRef.deleteindexentry==true) // delete non-unique
526  {
527  indexPtr->deleteNonuniqueEntry(rowFieldRef.fieldVal.value.floating, rowFieldRef.rowid, rowFieldRef.engineid);
528  }
529  else // add non-unique
530  {
531  indexPtr->insertNonuniqueEntry(rowFieldRef.fieldVal.value.floating, rowFieldRef.rowid, rowFieldRef.engineid);
532  }
533 
534  break;
535 
536  case CHAR:
537  if (indexPtr->isunique==true) // delete unique
538  {
539  indexPtr->deleteUniqueEntry(rowFieldRef.fieldVal.value.character);
540  // process lock queue
541  processIndexLockQueue(rowFieldRef.tableid,
542  rowFieldRef.fieldid,
543  &rowFieldRef.fieldVal);
544  }
545  else if (rowFieldRef.deleteindexentry==true) // delete non-unique
546  {
547  indexPtr->deleteNonuniqueEntry(rowFieldRef.fieldVal.value.character, rowFieldRef.rowid, rowFieldRef.engineid);
548  }
549  else // add non-unique
550  {
551  indexPtr->insertNonuniqueEntry(rowFieldRef.fieldVal.value.character, rowFieldRef.rowid, rowFieldRef.engineid);
552  }
553 
554  break;
555 
556  case CHARX:
557  if (indexPtr->isunique==true) // delete unique
558  {
559  indexPtr->deleteUniqueEntry(&rowFieldRef.fieldVal.str);
560  // process lock queue
561  processIndexLockQueue(rowFieldRef.tableid,
562  rowFieldRef.fieldid,
563  &rowFieldRef.fieldVal);
564  }
565  else if (rowFieldRef.deleteindexentry==true) // delete non-unique
566  {
567  indexPtr->deleteNonuniqueEntry(&rowFieldRef.fieldVal.str,
568  rowFieldRef.rowid,
569  rowFieldRef.engineid);
570  }
571  else // add non-unique
572  {
573  indexPtr->insertNonuniqueEntry(&rowFieldRef.fieldVal.str,
574  rowFieldRef.rowid,
575  rowFieldRef.engineid);
576  }
577 
578  break;
579 
580  case VARCHAR:
581  if (indexPtr->isunique==true) // delete unique
582  {
583  indexPtr->deleteUniqueEntry(&rowFieldRef.fieldVal.str);
584  // process lock queue
585  processIndexLockQueue(rowFieldRef.tableid,
586  rowFieldRef.fieldid,
587  &rowFieldRef.fieldVal);
588  }
589  else if (rowFieldRef.deleteindexentry==true) // delete non-unique
590  {
591  indexPtr->deleteNonuniqueEntry(&rowFieldRef.fieldVal.str,
592  rowFieldRef.rowid,
593  rowFieldRef.engineid);
594  }
595  else // add non-unique
596  {
597  indexPtr->insertNonuniqueEntry(&rowFieldRef.fieldVal.str,
598  rowFieldRef.rowid,
599  rowFieldRef.engineid);
600  }
601 
602  break;
603 
604  default:
605  fprintf(logfile, "anomaly: %i %s %i\n", indexPtr->fieldtype,
606  __FILE__, __LINE__);
607  }
608  }
609  }
610 
611  // rollback & unlock are fire and forget
612  if ((enginecmd_e)subtransactionCmdRef.transactionStruct.transaction_enginecmd == COMMITCMD)
613  {
614  replyTransaction((void *) new class MessageCommitRollback);
615  }
616  }
617  break;
618 
619  default:
620  fprintf(logfile, "anomaly: %i %s %i\n",
621  msgrcv->messageStruct.payloadtype, __FILE__, __LINE__);
622  }
623 }
624 
625 locktype_e SubTransaction::uniqueIndex(int64_t tableid, int64_t fieldid,
626  int64_t rowid, int64_t engineid,
627  fieldValue_s *val)
628 {
629  class MessageSubtransactionCmd &subtransactionCmdRef =
630  *((class MessageSubtransactionCmd *)msgrcv);
631  lockQueueIndexEntry queueEntry = {};
632  queueEntry.pendingcmdid =
633  subtransactionCmdRef.transactionStruct.transaction_pendingcmdid;
634  queueEntry.tacmdentrypoint =
635  subtransactionCmdRef.transactionStruct.transaction_tacmdentrypoint;
636  queueEntry.entry.engineid = engineid;
637  queueEntry.entry.rowid = rowid;
639 
640  class Index &indexRef = schemaPtr->tables[tableid]->fields[fieldid].index;
641 
642  switch (indexRef.indexmaptype)
643  {
644  case uniqueint:
645  {
646  if (!indexRef.uniqueIntIndex->count(val->value.integer))
647  {
648  // there is no entry, so stage one and lock it
649  indexRef.uniqueIntIndex->operator [](val->value.integer) =
650  queueEntry.entry;
651  return INDEXLOCK;
652  }
653 
654  if (indexRef.uniqueIntIndex->at(val->value.integer).subtransactionid)
655  {
656  // there is already a staged, locked entry, so go into the lock queue
657  indexRef.intLockQueue->operator [](val->value.integer).push(queueEntry);
658  return INDEXPENDINGLOCK;
659  }
660 
661  // there is an entry that is not locked: constraint violation
662  return NOLOCK;
663  }
664  break;
665 
666  case unorderedint:
667  {
668  if (!indexRef.unorderedIntIndex->count(val->value.integer))
669  {
670  // there is no entry, so stage one and lock it
671  indexRef.unorderedIntIndex->operator [](val->value.integer) =
672  queueEntry.entry;
673  return INDEXLOCK;
674  }
675 
676  if (indexRef.unorderedIntIndex->at(val->value.integer).subtransactionid)
677  {
678  // there is already a staged, locked entry, so go into the lock queue
679  indexRef.intLockQueue->operator [](val->value.integer).push(queueEntry);
680  return INDEXPENDINGLOCK;
681  }
682 
683  // there is an entry that is not locked: constraint violation
684  return NOLOCK;
685  }
686  break;
687 
688  case uniqueuint:
689  {
690  if (!indexRef.uniqueUintIndex->count(val->value.uinteger))
691  {
692  // there is no entry, so stage one and lock it
693  indexRef.uniqueUintIndex->operator [](val->value.uinteger) =
694  queueEntry.entry;
695  return INDEXLOCK;
696  }
697 
698  if (indexRef.uniqueUintIndex->at(val->value.uinteger).subtransactionid)
699  {
700  // there is already a staged, locked entry, so go into the lock queue
701  indexRef.uintLockQueue->operator [](val->value.uinteger).
702  push(queueEntry);
703  return INDEXPENDINGLOCK;
704  }
705 
706  // there is an entry that is not locked, so that means constraint violation
707  return NOLOCK;
708  }
709  break;
710 
711  case unordereduint:
712  {
713  if (!indexRef.unorderedUintIndex->count(val->value.uinteger))
714  {
715  // there is no entry, so stage one and lock it
716  indexRef.unorderedUintIndex->operator [](val->value.uinteger) =
717  queueEntry.entry;
718  return INDEXLOCK;
719  }
720 
721  if (indexRef.unorderedUintIndex->at(val->value.uinteger).subtransactionid)
722  {
723  // there is already a staged, locked entry, so go into the lock queue
724  indexRef.uintLockQueue->operator [](val->value.uinteger).push(queueEntry);
725  return INDEXPENDINGLOCK;
726  }
727 
728  // there is an entry that is not locked: constraint violation
729  return NOLOCK;
730  }
731  break;
732 
733  case uniquebool:
734  {
735  if (!indexRef.uniqueBoolIndex->count(val->value.boolean))
736  {
737  // there is no entry, so stage one and lock it
738  indexRef.uniqueBoolIndex->operator [](val->value.boolean) =
739  queueEntry.entry;
740  return INDEXLOCK;
741  }
742 
743  if (indexRef.uniqueBoolIndex->at(val->value.boolean).subtransactionid)
744  {
745  // there is already a staged, locked entry, so go into the lock queue
746  indexRef.boolLockQueue->operator [](val->value.boolean).push(queueEntry);
747  return INDEXPENDINGLOCK;
748  }
749 
750  // there is an entry that is not locked: constraint violation
751  return NOLOCK;
752  }
753  break;
754 
755  case unorderedbool:
756  {
757  if (!indexRef.unorderedBoolIndex->count(val->value.boolean))
758  {
759  // there is no entry, so stage one and lock it
760  indexRef.unorderedBoolIndex->operator [](val->value.boolean) =
761  queueEntry.entry;
762  return INDEXLOCK;
763  }
764 
765  if (indexRef.unorderedBoolIndex->at(val->value.boolean).subtransactionid)
766  {
767  // there is already a staged, locked entry, so go into the lock queue
768  indexRef.boolLockQueue->operator [](val->value.boolean).
769  push(queueEntry);
770  return INDEXPENDINGLOCK;
771  }
772 
773  // there is an entry that is not locked, so that means constraint violation
774  return NOLOCK;
775  }
776  break;
777 
778  case uniquefloat:
779  {
780  if (!indexRef.uniqueFloatIndex->count(val->value.floating))
781  {
782  // there is no entry, so stage one and lock it
783  indexRef.uniqueFloatIndex->operator [](val->value.floating) =
784  queueEntry.entry;
785  return INDEXLOCK;
786  }
787 
788  if (indexRef.uniqueFloatIndex->at(val->value.floating).subtransactionid)
789  {
790  // there is already a staged, locked entry, so go into the lock queue
791  indexRef.floatLockQueue->operator [](val->value.floating).
792  push(queueEntry);
793  return INDEXPENDINGLOCK;
794  }
795 
796  // there is an entry that is not locked: constraint violation
797  printf("%s %i NOLOCK float %Lf\n", __FILE__, __LINE__,
798  val->value.floating);
799  return NOLOCK;
800  }
801  break;
802 
803  case unorderedfloat:
804  {
805  if (!indexRef.unorderedFloatIndex->count(val->value.floating))
806  {
807  // there is no entry, so stage one and lock it
808  indexRef.unorderedFloatIndex->operator [](val->value.floating) =
809  queueEntry.entry;
810  return INDEXLOCK;
811  }
812 
813  if (indexRef.unorderedFloatIndex->at(val->value.floating).
815  {
816  // there is already a staged, locked entry, so go into the lock queue
817  indexRef.floatLockQueue->operator [](val->value.floating).push(queueEntry);
818  return INDEXPENDINGLOCK;
819  }
820 
821  // there is an entry that is not locked: constraint violation
822  return NOLOCK;
823  }
824  break;
825 
826  case uniquechar:
827  {
828  if (!indexRef.uniqueCharIndex->count(val->value.character))
829  {
830  // there is no entry, so stage one and lock it
831  indexRef.uniqueCharIndex->operator [](val->value.character) =
832  queueEntry.entry;
833  return INDEXLOCK;
834  }
835 
836  if (indexRef.uniqueCharIndex->at(val->value.character).subtransactionid)
837  {
838  // there is already a staged, locked entry, so go into the lock queue
839  indexRef.charLockQueue->operator [](val->value.character).
840  push(queueEntry);
841  return INDEXPENDINGLOCK;
842  }
843 
844  // there is an entry that is not locked: constraint violation
845  printf("%s %i NOLOCK char %c\n", __FILE__, __LINE__,
846  val->value.character);
847  return NOLOCK;
848  }
849  break;
850 
851  case unorderedchar:
852  {
853  if (!indexRef.unorderedCharIndex->count(val->value.character))
854  {
855  // there is no entry, so stage one and lock it
856  indexRef.unorderedCharIndex->operator [](val->value.character) =
857  queueEntry.entry;
858  return INDEXLOCK;
859  }
860 
861  if (indexRef.unorderedCharIndex->at(val->value.character).
863  {
864  // there is already a staged, locked entry, so go into the lock queue
865  indexRef.charLockQueue->operator [](val->value.character).
866  push(queueEntry);
867  return INDEXPENDINGLOCK;
868  }
869 
870  // there is an entry that is not locked, so that means constraint
871  // violation
872  return NOLOCK;
873  }
874  break;
875 
876  case uniquecharx:
877  {
878  trimspace(val->str);
879 
880  if (!indexRef.uniqueStringIndex->count(val->str))
881  {
882  // there is no entry, so stage one and lock it
883  indexRef.uniqueStringIndex->operator [](val->str) =
884  queueEntry.entry;
885  return INDEXLOCK;
886  }
887 
888  if (indexRef.uniqueStringIndex->at(val->str).subtransactionid)
889  {
890  // there is already a staged, locked entry, so go into the lock queue
891  indexRef.stringLockQueue->operator [](val->str).push(queueEntry);
892  return INDEXPENDINGLOCK;
893  }
894 
895  // there is an entry that is not locked: constraint violation
896  printf("%s %i NOLOCK charx '%s'\n", __FILE__, __LINE__,
897  val->str.c_str());
898  return NOLOCK;
899  }
900  break;
901 
902  case unorderedcharx:
903  {
904  if (!indexRef.unorderedStringIndex->count(val->str))
905  {
906  // there is no entry, so stage one and lock it
907  indexRef.unorderedStringIndex->operator [](val->str) =
908  queueEntry.entry;
909  return INDEXLOCK;
910  }
911 
912  if (indexRef.unorderedStringIndex->at(val->str).subtransactionid)
913  {
914  // there is already a staged, locked entry, so go into the lock queue
915  indexRef.stringLockQueue->operator [](val->str).push(queueEntry);
916  return INDEXPENDINGLOCK;
917  }
918 
919  // there is an entry that is not locked, so that means constraint
920  // violation
921  return NOLOCK;
922  }
923  break;
924 
925  case uniquevarchar:
926  {
927  trimspace(val->str);
928 
929  if (!indexRef.uniqueStringIndex->count(val->str))
930  {
931  // there is no entry, so stage one and lock it
932  indexRef.uniqueStringIndex->operator [](val->str) =
933  queueEntry.entry;
934  return INDEXLOCK;
935  }
936 
937  if (indexRef.uniqueStringIndex->at(val->str).subtransactionid)
938  {
939  // there is already a staged, locked entry, so go into the lock queue
940  indexRef.stringLockQueue->operator [](val->str).push(queueEntry);
941  return INDEXPENDINGLOCK;
942  }
943 
944  // there is an entry that is not locked: constraint violation
945  printf("%s %i NOLOCK varchar '%s'\n", __FILE__, __LINE__,
946  val->str.c_str());
947  return NOLOCK;
948  }
949  break;
950 
951  case unorderedvarchar:
952  {
953  if (!indexRef.unorderedStringIndex->count(val->str))
954  {
955  // there is no entry, so stage one and lock it
956  indexRef.unorderedStringIndex->operator [](val->str) =
957  queueEntry.entry;
958  return INDEXLOCK;
959  }
960 
961  if (indexRef.unorderedStringIndex->at(val->str).subtransactionid)
962  {
963  // there is already a staged, locked entry, so go into the lock queue
964  indexRef.stringLockQueue->operator [](val->str).push(queueEntry);
965  return INDEXPENDINGLOCK;
966  }
967 
968  // there is an entry that is not locked, so that means constraint
969  // violation
970  return NOLOCK;
971  }
972  break;
973 
974  default:
975  printf("%s %i anomaly %i\n", __FILE__, __LINE__, indexRef.indexmaptype);
976  }
977 
978  return NOTFOUNDLOCK;
979 }
980 
981 void SubTransaction::indexSearch(int64_t tableid, int64_t fieldid,
982  searchParams_s *searchParameters,
983  vector<nonLockingIndexEntry_s> *indexHits)
984 {
985  class Index &indexRef = schemaPtr->tables[tableid]->fields[fieldid].index;
986  // for the various operation types, also field types. 11 ops, 7 field types
987 
988  switch (searchParameters->op)
989  {
990  case OPERATOR_EQ:
991  {
992  switch (indexRef.fieldtype)
993  {
994  case INT:
995  {
996  indexRef.getequal(searchParameters->values[0].value.integer,
997  indexHits);
998  }
999  break;
1000 
1001  case UINT:
1002  {
1003  indexRef.getequal(searchParameters->values[0].value.uinteger,
1004  indexHits);
1005  }
1006  break;
1007 
1008  case BOOL:
1009  {
1010  indexRef.getequal(searchParameters->values[0].value.boolean,
1011  indexHits);
1012  }
1013  break;
1014 
1015  case FLOAT:
1016  {
1017  indexRef.getequal(searchParameters->values[0].value.floating,
1018  indexHits);
1019  }
1020  break;
1021 
1022  case CHAR:
1023  {
1024  indexRef.getequal(searchParameters->values[0].value.character,
1025  indexHits);
1026  }
1027  break;
1028 
1029  case CHARX:
1030  {
1031  indexRef.getequal(searchParameters->values[0].str,
1032  indexHits);
1033  }
1034  break;
1035 
1036  case VARCHAR:
1037  {
1038  indexRef.getequal(searchParameters->values[0].str,
1039  indexHits);
1040  }
1041  break;
1042 
1043  default:
1044  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1045  __LINE__);
1046  }
1047 
1048  }
1049  break;
1050 
1051  case OPERATOR_NE:
1052  {
1053  switch (indexRef.fieldtype)
1054  {
1055  case INT:
1056  {
1057  indexRef.getnotequal(searchParameters->values[0].value.integer,
1058  indexHits);
1059  }
1060  break;
1061 
1062  case UINT:
1063  {
1064  indexRef.getnotequal(searchParameters->values[0].value.uinteger,
1065  indexHits);
1066  }
1067  break;
1068 
1069  case BOOL:
1070  {
1071  indexRef.getnotequal(searchParameters->values[0].value.boolean,
1072  indexHits);
1073  }
1074  break;
1075 
1076  case FLOAT:
1077  {
1078  indexRef.getnotequal(searchParameters->values[0].value.floating,
1079  indexHits);
1080  }
1081  break;
1082 
1083  case CHAR:
1084  {
1085  indexRef.getnotequal(searchParameters->values[0].value.character,
1086  indexHits);
1087  }
1088  break;
1089 
1090  case CHARX:
1091  {
1092  indexRef.getnotequal(searchParameters->values[0].str,
1093  indexHits);
1094  }
1095  break;
1096 
1097  case VARCHAR:
1098  {
1099  indexRef.getnotequal(searchParameters->values[0].str,
1100  indexHits);
1101  }
1102  break;
1103 
1104  default:
1105  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1106  __LINE__);
1107  }
1108  }
1109  break;
1110 
1111  case OPERATOR_GT:
1112  {
1113  switch (indexRef.fieldtype)
1114  {
1115  case INT:
1116  {
1117  indexRef.comparison(searchParameters->values[0].value.integer,
1118  searchParameters->op, indexHits);
1119  }
1120  break;
1121 
1122  case UINT:
1123  {
1124  indexRef.comparison(searchParameters->values[0].value.uinteger,
1125  searchParameters->op, indexHits);
1126  }
1127  break;
1128 
1129  case BOOL:
1130  {
1131  indexRef.comparison(searchParameters->values[0].value.boolean,
1132  searchParameters->op, indexHits);
1133  }
1134  break;
1135 
1136  case FLOAT:
1137  {
1138  indexRef.comparison(searchParameters->values[0].value.floating,
1139  searchParameters->op, indexHits);
1140  }
1141  break;
1142 
1143  case CHAR:
1144  {
1145  indexRef.comparison(searchParameters->values[0].value.character,
1146  searchParameters->op, indexHits);
1147  }
1148  break;
1149 
1150  case CHARX:
1151  {
1152  indexRef.comparison(&searchParameters->values[0].str,
1153  searchParameters->op, indexHits);
1154  }
1155  break;
1156 
1157  case VARCHAR:
1158  {
1159  indexRef.comparison(&searchParameters->values[0].str,
1160  searchParameters->op, indexHits);
1161  }
1162  break;
1163 
1164  default:
1165  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1166  __LINE__);
1167  }
1168 
1169  }
1170  break;
1171 
1172  case OPERATOR_LT:
1173  {
1174  switch (indexRef.fieldtype)
1175  {
1176  case INT:
1177  {
1178  indexRef.comparison(searchParameters->values[0].value.integer,
1179  searchParameters->op, indexHits);
1180  }
1181  break;
1182 
1183  case UINT:
1184  {
1185  indexRef.comparison(searchParameters->values[0].value.uinteger,
1186  searchParameters->op, indexHits);
1187  }
1188  break;
1189 
1190  case BOOL:
1191  {
1192  indexRef.comparison(searchParameters->values[0].value.boolean,
1193  searchParameters->op, indexHits);
1194  }
1195  break;
1196 
1197  case FLOAT:
1198  {
1199  indexRef.comparison(searchParameters->values[0].value.floating,
1200  searchParameters->op, indexHits);
1201  }
1202  break;
1203 
1204  case CHAR:
1205  {
1206  indexRef.comparison(searchParameters->values[0].value.character,
1207  searchParameters->op, indexHits);
1208  }
1209  break;
1210 
1211  case CHARX:
1212  {
1213  indexRef.comparison(&searchParameters->values[0].str,
1214  searchParameters->op, indexHits);
1215  }
1216  break;
1217 
1218  case VARCHAR:
1219  {
1220  indexRef.comparison(&searchParameters->values[0].str,
1221  searchParameters->op, indexHits);
1222  }
1223  break;
1224 
1225  default:
1226  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1227  __LINE__);
1228  }
1229 
1230  }
1231  break;
1232 
1233  case OPERATOR_GTE:
1234  {
1235  switch (indexRef.fieldtype)
1236  {
1237  case INT:
1238  {
1239  indexRef.comparison(searchParameters->values[0].value.integer,
1240  searchParameters->op, indexHits);
1241  }
1242  break;
1243 
1244  case UINT:
1245  {
1246  indexRef.comparison(searchParameters->values[0].value.uinteger,
1247  searchParameters->op, indexHits);
1248  }
1249  break;
1250 
1251  case BOOL:
1252  {
1253  indexRef.comparison(searchParameters->values[0].value.boolean,
1254  searchParameters->op, indexHits);
1255  }
1256  break;
1257 
1258  case FLOAT:
1259  {
1260  indexRef.comparison(searchParameters->values[0].value.floating,
1261  searchParameters->op, indexHits);
1262  }
1263  break;
1264 
1265  case CHAR:
1266  {
1267  indexRef.comparison(searchParameters->values[0].value.character,
1268  searchParameters->op, indexHits);
1269  }
1270  break;
1271 
1272  case CHARX:
1273  {
1274  indexRef.comparison(&searchParameters->values[0].str,
1275  searchParameters->op, indexHits);
1276  }
1277  break;
1278 
1279  case VARCHAR:
1280  {
1281  indexRef.comparison(&searchParameters->values[0].str,
1282  searchParameters->op, indexHits);
1283  }
1284  break;
1285 
1286  default:
1287  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1288  __LINE__);
1289  }
1290 
1291  }
1292  break;
1293 
1294  case OPERATOR_LTE:
1295  {
1296  switch (indexRef.fieldtype)
1297  {
1298  case INT:
1299  {
1300  indexRef.comparison(searchParameters->values[0].value.integer,
1301  searchParameters->op, indexHits);
1302  }
1303  break;
1304 
1305  case UINT:
1306  {
1307  indexRef.comparison(searchParameters->values[0].value.uinteger,
1308  searchParameters->op, indexHits);
1309  }
1310  break;
1311 
1312  case BOOL:
1313  {
1314  indexRef.comparison(searchParameters->values[0].value.boolean,
1315  searchParameters->op, indexHits);
1316  }
1317  break;
1318 
1319  case FLOAT:
1320  {
1321  indexRef.comparison(searchParameters->values[0].value.floating,
1322  searchParameters->op, indexHits);
1323  }
1324  break;
1325 
1326  case CHAR:
1327  {
1328  indexRef.comparison(searchParameters->values[0].value.character,
1329  searchParameters->op, indexHits);
1330  }
1331  break;
1332 
1333  case CHARX:
1334  {
1335  indexRef.comparison(&searchParameters->values[0].str,
1336  searchParameters->op, indexHits);
1337  }
1338  break;
1339 
1340  case VARCHAR:
1341  {
1342  indexRef.comparison(&searchParameters->values[0].str,
1343  searchParameters->op, indexHits);
1344  }
1345  break;
1346 
1347  default:
1348  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1349  __LINE__);
1350  }
1351 
1352  }
1353  break;
1354 
1355  case OPERATOR_IN:
1356  {
1357  switch (indexRef.fieldtype)
1358  {
1359  case INT:
1360  {
1361  vector<int64_t> v(searchParameters->values.size());
1362 
1363  for (size_t n=0; n < searchParameters->values.size(); n++)
1364  {
1365  v[n] = searchParameters->values[n].value.integer;
1366  }
1367 
1368  indexRef.getin(&v, indexHits);
1369  }
1370  break;
1371 
1372  case UINT:
1373  {
1374  vector<uint64_t> v(searchParameters->values.size());
1375 
1376  for (size_t n=0; n < searchParameters->values.size(); n++)
1377  {
1378  v[n] = searchParameters->values[n].value.uinteger;
1379  }
1380 
1381  indexRef.getin(&v, indexHits);
1382  }
1383  break;
1384 
1385  case BOOL:
1386  {
1387  vector<bool> v(searchParameters->values.size());
1388 
1389  for (size_t n=0; n < searchParameters->values.size(); n++)
1390  {
1391  v[n] = searchParameters->values[n].value.boolean;
1392  }
1393 
1394  indexRef.getin(&v, indexHits);
1395  }
1396  break;
1397 
1398  case FLOAT:
1399  {
1400  vector<long double> v(searchParameters->values.size());
1401 
1402  for (size_t n=0; n < searchParameters->values.size(); n++)
1403  {
1404  v[n] = searchParameters->values[n].value.floating;
1405  }
1406 
1407  indexRef.getin(&v, indexHits);
1408  }
1409  break;
1410 
1411  case CHAR:
1412  {
1413  vector<char> v(searchParameters->values.size());
1414 
1415  for (size_t n=0; n < searchParameters->values.size(); n++)
1416  {
1417  v[n] = searchParameters->values[n].value.character;
1418  }
1419 
1420  indexRef.getin(&v, indexHits);
1421  }
1422  break;
1423 
1424  case CHARX:
1425  {
1426  vector<string> v(searchParameters->values.size());
1427 
1428  for (size_t n=0; n < searchParameters->values.size(); n++)
1429  {
1430  v[n] = searchParameters->values[n].str;
1431  }
1432 
1433  indexRef.getin(&v, indexHits);
1434  }
1435  break;
1436 
1437  case VARCHAR:
1438  {
1439  vector<string> v(searchParameters->values.size());
1440 
1441  for (size_t n=0; n < searchParameters->values.size(); n++)
1442  {
1443  v[n] = searchParameters->values[n].str;
1444  }
1445 
1446  indexRef.getin(&v, indexHits);
1447  }
1448  break;
1449 
1450  default:
1451  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1452  __LINE__);
1453  }
1454  }
1455  break;
1456 
1457  case OPERATOR_NOTIN:
1458  {
1459  switch (indexRef.fieldtype)
1460  {
1461  case INT:
1462  {
1463  vector<int64_t> v(searchParameters->values.size());
1464 
1465  for (size_t n=0; n < searchParameters->values.size(); n++)
1466  {
1467  v[n] = searchParameters->values[n].value.integer;
1468  }
1469 
1470  indexRef.getnotin(v, indexHits);
1471  }
1472  break;
1473 
1474  case UINT:
1475  {
1476  vector<uint64_t> v(searchParameters->values.size());
1477 
1478  for (size_t n=0; n < searchParameters->values.size(); n++)
1479  {
1480  v[n] = searchParameters->values[n].value.uinteger;
1481  }
1482 
1483  indexRef.getnotin(v, indexHits);
1484  }
1485  break;
1486 
1487  case BOOL:
1488  {
1489  vector<bool> v(searchParameters->values.size());
1490 
1491  for (size_t n=0; n < searchParameters->values.size(); n++)
1492  {
1493  v[n] = searchParameters->values[n].value.boolean;
1494  }
1495 
1496  indexRef.getnotin(v, indexHits);
1497  }
1498  break;
1499 
1500  case FLOAT:
1501  {
1502  vector<long double> v(searchParameters->values.size());
1503 
1504  for (size_t n=0; n < searchParameters->values.size(); n++)
1505  {
1506  v[n] = searchParameters->values[n].value.floating;
1507  }
1508 
1509  indexRef.getnotin(v, indexHits);
1510  }
1511  break;
1512 
1513  case CHAR:
1514  {
1515  vector<char> v(searchParameters->values.size());
1516 
1517  for (size_t n=0; n < searchParameters->values.size(); n++)
1518  {
1519  v[n] = searchParameters->values[n].value.character;
1520  }
1521 
1522  indexRef.getnotin(v, indexHits);
1523  }
1524  break;
1525 
1526  case CHARX:
1527  {
1528  vector<string> v(searchParameters->values.size());
1529 
1530  for (size_t n=0; n < searchParameters->values.size(); n++)
1531  {
1532  v[n] = searchParameters->values[n].str;
1533  }
1534 
1535  indexRef.getnotin(v, indexHits);
1536  }
1537  break;
1538 
1539  case VARCHAR:
1540  {
1541  vector<string> v(searchParameters->values.size());
1542 
1543  for (size_t n=0; n < searchParameters->values.size(); n++)
1544  {
1545  v[n] = searchParameters->values[n].str;
1546  }
1547 
1548  indexRef.getnotin(v, indexHits);
1549  }
1550  break;
1551 
1552  default:
1553  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1554  __LINE__);
1555  }
1556  }
1557  break;
1558 
1559  case OPERATOR_BETWEEN:
1560  {
1561  switch (indexRef.fieldtype)
1562  {
1563  case INT:
1564  {
1565  indexRef.between(searchParameters->values[0].value.integer,
1566  searchParameters->values[1].value.integer,
1567  indexHits);
1568  }
1569  break;
1570 
1571  case UINT:
1572  {
1573  indexRef.between(searchParameters->values[0].value.uinteger,
1574  searchParameters->values[1].value.uinteger,
1575  indexHits);
1576  }
1577  break;
1578 
1579  case BOOL:
1580  {
1581  indexRef.between(searchParameters->values[0].value.boolean,
1582  searchParameters->values[1].value.boolean,
1583  indexHits);
1584  }
1585  break;
1586 
1587  case FLOAT:
1588  {
1589  indexRef.between(searchParameters->values[0].value.floating,
1590  searchParameters->values[1].value.floating,
1591  indexHits);
1592  }
1593  break;
1594 
1595  case CHAR:
1596  {
1597  indexRef.between(searchParameters->values[0].value.character,
1598  searchParameters->values[1].value.character,
1599  indexHits);
1600  }
1601  break;
1602 
1603  case CHARX:
1604  {
1605  indexRef.between(searchParameters->values[0].str,
1606  searchParameters->values[1].str,
1607  indexHits);
1608  }
1609  break;
1610 
1611  case VARCHAR:
1612  {
1613  indexRef.between(searchParameters->values[0].str,
1614  searchParameters->values[1].str, indexHits);
1615  }
1616  break;
1617 
1618  default:
1619  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1620  __LINE__);
1621  }
1622 
1623  }
1624  break;
1625 
1626  case OPERATOR_NOTBETWEEN:
1627  {
1628  switch (indexRef.fieldtype)
1629  {
1630  case INT:
1631  {
1632  indexRef.notbetween(searchParameters->values[0].value.integer,
1633  searchParameters->values[1].value.integer,
1634  indexHits);
1635  }
1636  break;
1637 
1638  case UINT:
1639  {
1640  indexRef.notbetween(searchParameters->values[0].value.uinteger,
1641  searchParameters->values[1].value.uinteger,
1642  indexHits);
1643  }
1644  break;
1645 
1646  case BOOL:
1647  {
1648  indexRef.notbetween(searchParameters->values[0].value.boolean,
1649  searchParameters->values[1].value.boolean,
1650  indexHits);
1651  }
1652  break;
1653 
1654  case FLOAT:
1655  {
1656  indexRef.notbetween(searchParameters->values[0].value.floating,
1657  searchParameters->values[1].value.floating,
1658  indexHits);
1659  }
1660  break;
1661 
1662  case CHAR:
1663  {
1664  indexRef.notbetween(searchParameters->values[0].value.character,
1665  searchParameters->values[1].value.character,
1666  indexHits);
1667  }
1668  break;
1669 
1670  case CHARX:
1671  {
1672  indexRef.notbetween(&searchParameters->values[0].str,
1673  &searchParameters->values[1].str, indexHits);
1674  }
1675  break;
1676 
1677  case VARCHAR:
1678  {
1679  indexRef.notbetween(&searchParameters->values[0].str,
1680  &searchParameters->values[1].str, indexHits);
1681  }
1682  break;
1683 
1684  default:
1685  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1686  __LINE__);
1687  }
1688 
1689  }
1690  break;
1691 
1692  case OPERATOR_ISNULL:
1693  indexRef.getnulls(indexHits);
1694  break;
1695 
1696  case OPERATOR_ISNOTNULL:
1697  indexRef.getnotnulls(indexHits);
1698  break;
1699 
1700  case OPERATOR_SELECTALL: // combination of nulls and not nulls
1701  indexRef.getall(indexHits);
1702  break;
1703 
1704  case OPERATOR_REGEX:
1705  indexRef.regex(&searchParameters->regexString, indexHits);
1706  break;
1707 
1708  case OPERATOR_LIKE:
1709  indexRef.like(searchParameters->values[0].str, indexHits);
1710  break;
1711 
1712  case OPERATOR_NOTLIKE:
1713  indexRef.notlike(searchParameters->values[0].str, indexHits);
1714  break;
1715 
1716  default:
1717  fprintf(logfile, "anomaly %i %s %i\n", searchParameters->op, __FILE__,
1718  __LINE__);
1719  }
1720 }
1721 
1722 void SubTransaction::commitRollbackUnlock(vector<rowOrField_s> *rowOrFields,
1723  enginecmd_e cmd)
1724 {
1725  // remember to process lock queue after each item
1726  for (size_t n=0; n<rowOrFields->size(); n++)
1727  {
1728  rowOrField_s &rowOrFieldRef = rowOrFields->at(n);
1729  class Table &tableRef = *schemaPtr->tables[rowOrFieldRef.tableid];
1730 
1731  if (rowOrFieldRef.isrow==true)
1732  {
1733  tableRef.commitRollbackUnlock(rowOrFieldRef.rowid, subtransactionid,
1734  COMMITCMD);
1735  }
1736  else
1737  {
1738  class Index &indexRef = tableRef.fields[rowOrFieldRef.fieldid].index;
1739 
1740  switch (indexRef.fieldtype)
1741  {
1742  case INT:
1743  indexRef.commitRollback(rowOrFieldRef.fieldVal.value.integer,
1744  subtransactionid, cmd);
1745 
1746  case UINT:
1747  indexRef.commitRollback(rowOrFieldRef.fieldVal.value.uinteger,
1748  subtransactionid, cmd);
1749 
1750  case BOOL:
1751  indexRef.commitRollback(rowOrFieldRef.fieldVal.value.boolean,
1752  subtransactionid, cmd);
1753 
1754  case FLOAT:
1755  indexRef.commitRollback(rowOrFieldRef.fieldVal.value.floating,
1756  subtransactionid, cmd);
1757 
1758  case CHAR:
1759  indexRef.commitRollback(rowOrFieldRef.fieldVal.value.character,
1760  subtransactionid, cmd);
1761 
1762  case CHARX:
1763  indexRef.commitRollback(rowOrFieldRef.fieldVal.str,
1764  subtransactionid, cmd);
1765 
1766  case VARCHAR:
1767  indexRef.commitRollback(rowOrFieldRef.fieldVal.str,
1768  subtransactionid, cmd);
1769  break;
1770 
1771  default:
1772  fprintf(logfile, "anomaly %i %s %i\n", indexRef.fieldtype, __FILE__,
1773  __LINE__);
1774  }
1775  }
1776  }
1777 }
1778 
1780 {
1781  class MessageTransaction &msgref = *(class MessageTransaction *)data;
1782  class MessageTransaction &msgrcvRef =
1783  *(class MessageTransaction *)msgrcv;
1787  msgrcvRef.transactionStruct.transactionid;
1794 
1796  *((class Message *)data));
1797 }
1798 
1799 // for drain queue old transactions
1801  class MessageTransaction &rcvRef)
1802 {
1814 
1816 }
1817 
1818 // to be called whenever the row is unlocked
1819 void SubTransaction::processRowLockQueue(int64_t tableid, int64_t rowid)
1820 {
1821  return;
1822  // class Table &tableRef = *schemaPtr->tables[tableid];
1823  // std::queue<lockQueueRowEntry> &qRef = tableRef.lockQueue[rowid];
1824  // // subtransactionCmd *subtransactionCmdPtr;
1825  // class MessageSubtransactionCmd *subtransactionCmdPtr;
1826 
1827  // bool readlockedflag=false;
1828 
1829  // while (!qRef.empty()) // remember to return when a WRITELOCK is processed
1830  // {
1831  // lockQueueRowEntry &entry = qRef.front();
1832 
1833  // if (enginePtr->SubTransactions.count(entry.subtransactionid))
1834  // {
1835  // // oh yeah gotta lock the row, but don't know how to stage the
1836  // // row itself
1837  // if (entry.locktype==WRITELOCK)
1838  // {
1839  // setwritelock(&tableRef.rows[rowid]->flags);
1840  // tableRef.rows[rowid]->writelockHolder = entry.subtransactionid;
1841 
1842  // subtransactionCmdPtr = new class MessageSubtransactionCmd();
1843  // returnRow_s returnRow= {};
1844  // returnRow.rowid=rowid;
1845  // returnRow.locktype=PENDINGTOWRITELOCK;
1846  // subtransactionCmdPtr->returnRows.push_back(returnRow);
1847  // }
1848  // else if (entry.locktype==READLOCK)
1849  // {
1850  // if (readlockedflag==false)
1851  // {
1852  // setreadlock(&tableRef.rows[rowid]->flags);
1853  // tableRef.rows[rowid]->readlockHolders =
1854  // new boost::unordered_set<int64_t>;
1855  // readlockedflag=true;
1856  // }
1857 
1858  // tableRef.rows[rowid]->readlockHolders->insert(entry.subtransactionid);
1859 
1860  // subtransactionCmdPtr = new class MessageSubtransactionCmd();
1861  // subtransactionCmdPtr->returnRows[0].locktype = PENDINGTOREADLOCK;
1862  // subtransactionCmdPtr->returnRows[0].rowid = rowid;
1863  // subtransactionCmdPtr->returnRows[0].row = tableRef.rows[rowid]->row;
1864  // }
1865  // else
1866  // {
1867  // qRef.pop();
1868  // fprintf(logfile, "anomaly: %i %s %i\n", entry.locktype, __FILE__,
1869  // __LINE__);
1870  // continue;
1871  // }
1872 
1873  // // ok gotta fake msgrcv for replyTransaction
1874  // class SubTransaction &subTransactionRef =
1875  // *enginePtr->SubTransactions[entry.subtransactionid];
1876  // class MessageSubtransactionCmd rcv;
1877  // rcv.transactionStruct.transactionid = subTransactionRef.transactionid;
1878  // rcv.transactionStruct.subtransactionid = entry.subtransactionid;
1879  // rcv.transactionStruct.engineinstance = enginePtr->partitionid;
1880  // rcv.transactionStruct.transaction_tacmdentrypoint = entry.tacmdentrypoint;
1881  // rcv.transactionStruct.transaction_pendingcmdid = entry.pendingcmdid;
1882  // rcv.messageStruct.payloadtype = PAYLOADSUBTRANSACTION;
1883 
1884  // subTransactionRef.replyTransaction(*subtransactionCmdPtr, rcv);
1885 
1886  // // there can only be 1 lock holder if it's a WRITELOCK
1887  // if (entry.locktype==WRITELOCK)
1888  // {
1889  // qRef.pop();
1890  // return;
1891  // }
1892  // }
1893 
1894  // qRef.pop();
1895  // }
1896 }
1897 
1898 void SubTransaction::drainRowLockQueue(int64_t tableid, int64_t rowid)
1899 {
1900  class Table &tableRef = *schemaPtr->tables[tableid];
1901  std::queue<lockQueueRowEntry> &qRef = tableRef.lockQueue[rowid];
1902 
1903  while (!qRef.empty())
1904  {
1905  lockQueueRowEntry &entry = qRef.front();
1906 
1907  if (enginePtr->SubTransactions.count(entry.subtransactionid))
1908  {
1909  class SubTransaction &subTransactionRef =
1911 
1912  class MessageSubtransactionCmd *subtransactionCmdPtr =
1914  subtransactionCmdPtr->returnRows[0].locktype = PENDINGTONOLOCK;
1915  subtransactionCmdPtr->returnRows[0].rowid = rowid;
1916  // ok gotta fake msgrcv for replyTransaction
1917  class MessageSubtransactionCmd rcv;
1919  subTransactionRef.transactionid;
1923  entry.tacmdentrypoint;
1926 
1927  subTransactionRef.replyTransaction(*subtransactionCmdPtr, rcv);
1928  }
1929 
1930  qRef.pop();
1931  }
1932 }
1933 
1934 void SubTransaction::processIndexLockQueue(int64_t tableid, int64_t fieldid,
1935  fieldValue_s *val)
1936 {
1937  return;
1938  // class Index &indexRef = schemaPtr->tables[tableid]->fields[fieldid].index;
1939  // std::queue<lockQueueIndexEntry> *lockQueuePtr = NULL;
1940 
1941  // switch (indexRef.fieldtype)
1942  // {
1943  // case INT:
1944  // if (indexRef.intLockQueue->count(val->value.integer))
1945  // {
1946  // lockQueuePtr = &indexRef.intLockQueue->at(val->value.integer);
1947  // }
1948 
1949  // break;
1950 
1951  // case UINT:
1952  // if (indexRef.uintLockQueue->count(val->value.uinteger))
1953  // {
1954  // lockQueuePtr = &indexRef.uintLockQueue->at(val->value.uinteger);
1955  // }
1956 
1957  // break;
1958 
1959  // case BOOL:
1960  // if (indexRef.boolLockQueue->count(val->value.boolean))
1961  // {
1962  // lockQueuePtr = &indexRef.boolLockQueue->at(val->value.boolean);
1963  // }
1964 
1965  // break;
1966 
1967  // case FLOAT:
1968  // if (indexRef.floatLockQueue->count(val->value.floating))
1969  // {
1970  // lockQueuePtr = &indexRef.floatLockQueue->at(val->value.floating);
1971  // }
1972 
1973  // break;
1974 
1975  // case CHAR:
1976  // if (indexRef.charLockQueue->count(val->value.character))
1977  // {
1978  // lockQueuePtr = &indexRef.charLockQueue->at(val->value.character);
1979  // }
1980 
1981  // break;
1982 
1983  // case CHARX:
1984  // if (indexRef.stringLockQueue->count(val->str))
1985  // {
1986  // lockQueuePtr = &indexRef.stringLockQueue->at(val->str);
1987  // }
1988 
1989  // break;
1990 
1991  // case VARCHAR:
1992  // if (indexRef.stringLockQueue->count(val->str))
1993  // {
1994  // lockQueuePtr = &indexRef.stringLockQueue->at(val->str);
1995  // }
1996 
1997  // break;
1998 
1999  // default:
2000  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.fieldtype, __FILE__,
2001  // __LINE__);
2002  // }
2003 
2004  // if (lockQueuePtr==NULL)
2005  // {
2006  // return;
2007  // }
2008 
2009  // std::queue<lockQueueIndexEntry> &lockQueueRef = *lockQueuePtr;
2010 
2011  // while (!lockQueueRef.empty())
2012  // {
2013  // lockQueueIndexEntry &entry = lockQueueRef.front();
2014 
2015  // if (enginePtr->SubTransactions.count(entry.entry.subtransactionid))
2016  // {
2017  // class SubTransaction &subTransactionRef =
2018  // *enginePtr->SubTransactions[entry.entry.subtransactionid];
2019 
2020  // // do stuff
2021  // switch (indexRef.fieldtype)
2022  // {
2023  // case INT:
2024  // if (indexRef.indexmaptype==unorderedint)
2025  // {
2026  // indexRef.unorderedIntIndex->at(val->value.integer) = entry.entry;
2027  // }
2028  // else if (indexRef.indexmaptype==uniqueint)
2029  // {
2030  // indexRef.uniqueIntIndex->at(val->value.integer) = entry.entry;
2031  // }
2032  // else
2033  // {
2034  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.indexmaptype,
2035  // __FILE__, __LINE__);
2036  // }
2037 
2038  // case UINT:
2039  // if (indexRef.indexmaptype==unordereduint)
2040  // {
2041  // indexRef.unorderedUintIndex->at(val->value.uinteger) = entry.entry;
2042  // }
2043  // else if (indexRef.indexmaptype==uniqueuint)
2044  // {
2045  // indexRef.uniqueUintIndex->at(val->value.uinteger) = entry.entry;
2046  // }
2047  // else
2048  // {
2049  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.indexmaptype,
2050  // __FILE__, __LINE__);
2051  // }
2052 
2053  // break;
2054 
2055  // case BOOL:
2056  // if (indexRef.indexmaptype==unorderedbool)
2057  // {
2058  // indexRef.unorderedBoolIndex->at(val->value.boolean) = entry.entry;
2059  // }
2060  // else if (indexRef.indexmaptype==uniquebool)
2061  // {
2062  // indexRef.uniqueBoolIndex->at(val->value.boolean) = entry.entry;
2063  // }
2064  // else
2065  // {
2066  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.indexmaptype,
2067  // __FILE__, __LINE__);
2068  // }
2069 
2070  // break;
2071 
2072  // case FLOAT:
2073  // if (indexRef.indexmaptype==unorderedfloat)
2074  // {
2075  // indexRef.unorderedFloatIndex->at(val->value.floating) = entry.entry;
2076  // }
2077  // else if (indexRef.indexmaptype==uniquefloat)
2078  // {
2079  // indexRef.uniqueFloatIndex->at(val->value.floating) = entry.entry;
2080  // }
2081  // else
2082  // {
2083  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.indexmaptype,
2084  // __FILE__, __LINE__);
2085  // }
2086 
2087  // break;
2088 
2089  // case CHAR:
2090  // if (indexRef.indexmaptype==unorderedchar)
2091  // {
2092  // indexRef.unorderedCharIndex->at(val->value.character) = entry.entry;
2093  // }
2094  // else if (indexRef.indexmaptype==uniquechar)
2095  // {
2096  // indexRef.uniqueCharIndex->at(val->value.character) = entry.entry;
2097  // }
2098  // else
2099  // {
2100  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.indexmaptype,
2101  // __FILE__, __LINE__);
2102  // }
2103 
2104  // break;
2105 
2106  // case CHARX:
2107  // if (indexRef.indexmaptype==unorderedcharx)
2108  // {
2109  // indexRef.unorderedStringIndex->at(val->str) = entry.entry;
2110  // }
2111  // else if (indexRef.indexmaptype==uniquecharx)
2112  // {
2113  // indexRef.uniqueStringIndex->at(val->str) = entry.entry;
2114  // }
2115  // else
2116  // {
2117  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.indexmaptype,
2118  // __FILE__, __LINE__);
2119  // }
2120 
2121  // break;
2122 
2123  // case VARCHAR:
2124  // if (indexRef.indexmaptype==unorderedvarchar)
2125  // {
2126  // indexRef.unorderedStringIndex->at(val->str) = entry.entry;
2127  // }
2128  // else if (indexRef.indexmaptype==uniquevarchar)
2129  // {
2130  // indexRef.uniqueStringIndex->at(val->str) = entry.entry;
2131  // }
2132  // else
2133  // {
2134  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.indexmaptype,
2135  // __FILE__, __LINE__);
2136  // }
2137 
2138  // break;
2139 
2140  // default:
2141  // fprintf(logfile, "anomaly: %i %s %i\n", indexRef.fieldtype, __FILE__,
2142  // __LINE__);
2143  // }
2144 
2145  // //reply
2146  // class MessageSubtransactionCmd *subtransactionCmdPtr =
2147  // new MessageSubtransactionCmd();
2148  // subtransactionCmdPtr->subtransactionStruct.locktype = PENDINGTOINDEXLOCK;
2149  // subtransactionCmdPtr->subtransactionStruct.tableid = tableid;
2150  // subtransactionCmdPtr->subtransactionStruct.fieldid = fieldid;
2151  // subtransactionCmdPtr->fieldVal = *val;
2152 
2153  // // ok gotta fake msgrcv for replyTransaction
2154  // class MessageSubtransactionCmd rcv;
2155  // rcv.transactionStruct.transactionid = subTransactionRef.transactionid;
2156  // rcv.transactionStruct.subtransactionid = entry.entry.subtransactionid;
2157  // rcv.transactionStruct.engineinstance = enginePtr->partitionid;
2158  // rcv.transactionStruct.transaction_tacmdentrypoint = entry.tacmdentrypoint;
2159  // rcv.transactionStruct.transaction_pendingcmdid = entry.pendingcmdid;
2160  // rcv.messageStruct.payloadtype = PAYLOADSUBTRANSACTION;
2161 
2162  // subTransactionRef.replyTransaction(*subtransactionCmdPtr, rcv);
2163 
2164  // lockQueueRef.pop();
2165  // }
2166 
2167  // lockQueueRef.pop();
2168  // }
2169 }
2170 
2171 void SubTransaction::drainIndexLockQueue(int64_t tableid, int64_t fieldid,
2172  fieldValue_s *val)
2173 {
2174  class Index &indexRef = schemaPtr->tables[tableid]->fields[fieldid].index;
2175  std::queue<lockQueueIndexEntry> *lockQueuePtr=NULL;
2176 
2177  switch (indexRef.fieldtype)
2178  {
2179  case INT:
2180  if (indexRef.intLockQueue->count(val->value.integer))
2181  {
2182  lockQueuePtr = &indexRef.intLockQueue->at(val->value.integer);
2183  }
2184 
2185  break;
2186 
2187  case UINT:
2188  if (indexRef.uintLockQueue->count(val->value.uinteger))
2189  {
2190  lockQueuePtr = &indexRef.uintLockQueue->at(val->value.uinteger);
2191  }
2192 
2193  break;
2194 
2195  case BOOL:
2196  if (indexRef.boolLockQueue->count(val->value.boolean))
2197  {
2198  lockQueuePtr = &indexRef.boolLockQueue->at(val->value.boolean);
2199  }
2200 
2201  break;
2202 
2203  case FLOAT:
2204  if (indexRef.floatLockQueue->count(val->value.floating))
2205  {
2206  lockQueuePtr = &indexRef.floatLockQueue->at(val->value.floating);
2207  }
2208 
2209  break;
2210 
2211  case CHAR:
2212  if (indexRef.charLockQueue->count(val->value.character))
2213  {
2214  lockQueuePtr = &indexRef.charLockQueue->at(val->value.character);
2215  }
2216 
2217  break;
2218 
2219  case CHARX:
2220  if (indexRef.stringLockQueue->count(val->str))
2221  {
2222  lockQueuePtr = &indexRef.stringLockQueue->at(val->str);
2223  }
2224 
2225  break;
2226 
2227  case VARCHAR:
2228  if (indexRef.stringLockQueue->count(val->str))
2229  {
2230  lockQueuePtr = &indexRef.stringLockQueue->at(val->str);
2231  }
2232 
2233  break;
2234 
2235  default:
2236  fprintf(logfile, "anomaly: %i %s %i\n", indexRef.fieldtype, __FILE__,
2237  __LINE__);
2238  }
2239 
2240  if (lockQueuePtr==NULL)
2241  {
2242  return;
2243  }
2244 
2245  std::queue<lockQueueIndexEntry> &lockQueueRef = *lockQueuePtr;
2246 
2247  while (!lockQueueRef.empty())
2248  {
2249  lockQueueIndexEntry &entry = lockQueueRef.front();
2250 
2251  if (enginePtr->SubTransactions.count(entry.entry.subtransactionid))
2252  {
2253  class SubTransaction &subTransactionRef =
2255  //reply
2256  class MessageSubtransactionCmd *subtransactionCmdPtr =
2258  subtransactionCmdPtr->subtransactionStruct.locktype =
2260  subtransactionCmdPtr->subtransactionStruct.tableid = tableid;
2261  subtransactionCmdPtr->subtransactionStruct.fieldid = fieldid;
2262  subtransactionCmdPtr->fieldVal = *val;
2263 
2264  // ok gotta fake msgrcv for replyTransaction
2265  // THIS HAS TO BE BUGGY 1/19/2013, fix when testing
2266  class MessageSubtransactionCmd rcv;
2268  subTransactionRef.transactionid;
2270  entry.entry.subtransactionid;
2273  entry.tacmdentrypoint;
2276  subTransactionRef.replyTransaction(*subtransactionCmdPtr, rcv);
2277  }
2278 
2279  lockQueueRef.pop();
2280  }
2281 }
2282 
2283 int64_t SubTransaction::newrow(int64_t tableid, string row)
2284 {
2285  class Table &tableRef = *schemaPtr->tables[tableid];
2286  int64_t newrowid = tableRef.getnextrowid();
2287  tableRef.newrow(newrowid, subtransactionid, row);
2288 
2289  return newrowid;
2290 }
2291 
2292 int64_t SubTransaction::updaterow(int64_t tableid, int64_t rowid, string *row)
2293 {
2294  class Table &tableRef = *schemaPtr->tables[tableid];
2295  return tableRef.updaterow(rowid, subtransactionid, row);
2296 }
2297 
2298 int64_t SubTransaction::deleterow(int64_t tableid, int64_t rowid)
2299 {
2300  class Table &tableRef = *schemaPtr->tables[tableid];
2301  return tableRef.deleterow(rowid, subtransactionid);
2302 }
2303 
2304 int64_t SubTransaction::deleterow(int64_t tableid, int64_t rowid,
2305  int64_t forward_rowid,
2306  int64_t forward_engineid)
2307 {
2308  class Table &tableRef = *schemaPtr->tables[tableid];
2309  return tableRef.deleterow(rowid, subtransactionid, forward_rowid,
2310  forward_engineid);
2311 }
2312 
2313 void SubTransaction::selectrows(int64_t tableid, vector<int64_t> *rowids,
2314  locktype_e locktype, int64_t pendingcmdid,
2315  vector<returnRow_s> *returnRows)
2316 {
2317  int64_t tacmd = ((class MessageTransaction *)msgrcv)->transactionStruct.transaction_tacmdentrypoint;
2318  class Table &tableRef = *schemaPtr->tables[tableid];
2319  tableRef.selectrows(rowids, locktype, subtransactionid, pendingcmdid,
2320  returnRows, tacmd);
2321 }
2322 
2323 void SubTransaction::searchReturn1(int64_t tableid, int64_t fieldid,
2324  locktype_e locktype,
2325  searchParams_s &searchParams,
2326  vector<returnRow_s> &returnRows)
2327 {
2328  vector<nonLockingIndexEntry_s> indexHits;
2329 
2330  indexSearch(tableid, fieldid, &searchParams, &indexHits);
2331 
2332  if (indexHits.size()==1)
2333  {
2334  nonLockingIndexEntry_s &hit = indexHits[0];
2335  class MessageSubtransactionCmd &msgrcvRef =
2336  *(class MessageSubtransactionCmd *)msgrcv;
2337  vector<int64_t> rowids(1, hit.rowid);
2338  selectrows(tableid, &rowids, locktype, msgrcvRef.transactionStruct.transaction_pendingcmdid,
2339  &returnRows);
2340  }
2341  else
2342  {
2343  // NOTFOUNDLOCK result
2344  returnRow_s returnRow = {};
2345  returnRow.locktype = NOTFOUNDLOCK;
2346  returnRows.push_back(returnRow);
2347  }
2348 }