transactd 3.5.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/bin/common/{tdclc_32_3_5.dll → tdclc_32_3_6.dll} +0 -0
  3. data/bin/common/tdclc_64_3_6.dll +0 -0
  4. data/build/swig/ruby/tdclrb_wrap.cpp +12524 -24430
  5. data/build/swig/tdcl.i +5 -0
  6. data/build/tdclc/tdclc.cbproj +1 -1
  7. data/build/tdclc/tdclc.rc +4 -4
  8. data/build/tdclcpp/tdclcpp.rc +4 -4
  9. data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
  10. data/build/tdclrb/tdclrb.rc +4 -4
  11. data/source/bzs/db/engine/mysql/database.cpp +210 -184
  12. data/source/bzs/db/engine/mysql/database.h +276 -105
  13. data/source/bzs/db/engine/mysql/mysqlInternal.h +37 -0
  14. data/source/bzs/db/engine/mysql/mysqlProtocol.cpp +1 -0
  15. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +4 -4
  16. data/source/bzs/db/protocol/tdap/client/activeTable.h +1 -1
  17. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +1 -0
  18. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +1 -1
  19. data/source/bzs/db/protocol/tdap/client/database.cpp +7 -4
  20. data/source/bzs/db/protocol/tdap/client/database.h +6 -1
  21. data/source/bzs/db/protocol/tdap/client/databaseManager.h +2 -2
  22. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +21 -9
  23. data/source/bzs/db/protocol/tdap/client/dbDef.h +1 -1
  24. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +10 -2
  25. data/source/bzs/db/protocol/tdap/client/field.cpp +29 -5
  26. data/source/bzs/db/protocol/tdap/client/field.h +3 -1
  27. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.cpp +5 -0
  28. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.h +1 -0
  29. data/source/bzs/db/protocol/tdap/client/fields.h +9 -2
  30. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +8 -4
  31. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +18 -5
  32. data/source/bzs/db/protocol/tdap/client/memRecord.h +2 -2
  33. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +46 -13
  34. data/source/bzs/db/protocol/tdap/client/nsTable.h +5 -0
  35. data/source/bzs/db/protocol/tdap/client/recordset.cpp +5 -0
  36. data/source/bzs/db/protocol/tdap/client/recordset.h +1 -0
  37. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +6 -2
  38. data/source/bzs/db/protocol/tdap/client/request.h +46 -38
  39. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +2 -3
  40. data/source/bzs/db/protocol/tdap/client/stringConverter.h +29 -13
  41. data/source/bzs/db/protocol/tdap/client/table.cpp +60 -10
  42. data/source/bzs/db/protocol/tdap/client/table.h +4 -1
  43. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +18 -1
  44. data/source/bzs/db/protocol/tdap/client/trdormapi.h +10 -4
  45. data/source/bzs/db/protocol/tdap/fieldComp.h +1 -1
  46. data/source/bzs/db/protocol/tdap/mysql/characterset.h +1 -0
  47. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +11 -4
  48. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +2 -1
  49. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +52 -94
  50. data/source/bzs/db/protocol/tdap/mysql/request.h +20 -13
  51. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +92 -60
  52. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +4 -4
  53. data/source/bzs/db/protocol/tdap/tdapRequest.h +11 -0
  54. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +83 -34
  55. data/source/bzs/db/protocol/tdap/tdapSchema.h +5 -1
  56. data/source/bzs/db/protocol/tdap/tdapcapi.h +7 -3
  57. data/source/bzs/example/ormap_c.cpp +2 -2
  58. data/source/bzs/netsvc/server/serverPipe.cpp +35 -1
  59. data/source/bzs/test/tdclatl/test_v3.js +48 -1
  60. data/source/bzs/test/tdclphp/bench.php +89 -76
  61. data/source/bzs/test/tdclphp/transactd_Test.php +691 -687
  62. data/source/bzs/test/tdclphp/transactd_blob_Test.php +46 -43
  63. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +46 -43
  64. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +33 -33
  65. data/source/bzs/test/tdclphp/transactd_pool_Test.php +29 -25
  66. data/source/bzs/test/tdclphp/transactd_v3_Test.php +653 -183
  67. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +40 -4
  68. data/source/bzs/test/tdclrb/transactd_fetch_spec.rb +785 -0
  69. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +21 -1
  70. data/source/bzs/test/tdclrb/transactd_setget_spec.rb +450 -0
  71. data/source/bzs/test/tdclrb/transactd_spec.rb +14 -2
  72. data/source/bzs/test/tdclrb/transactd_v3_spec.rb +1192 -11
  73. data/source/bzs/test/trdclengn/testField.h +522 -1
  74. data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +37 -1
  75. data/source/bzs/test/trdclengn/test_trdclengn.cpp +62 -4
  76. data/source/global/tdclatl/RecordsetQuery.cpp +2 -1
  77. data/source/global/tdclatl/RecordsetQuery.h +1 -1
  78. data/source/global/tdclatl/Table.cpp +17 -0
  79. data/source/global/tdclatl/Table.h +3 -1
  80. data/source/global/tdclatl/tdclatl.idl +7 -2
  81. data/transactd.gemspec +1 -1
  82. metadata +7 -5
  83. data/bin/common/tdclc_64_3_5.dll +0 -0
@@ -27,6 +27,7 @@
27
27
  #include <bzs/db/engine/mysql/fieldAccess.h>
28
28
  #include <boost/shared_ptr.hpp>
29
29
 
30
+
30
31
  #ifndef MAX_KEY_SEGMENT
31
32
  #define MAX_KEY_SEGMENT 8
32
33
  #endif
@@ -125,6 +126,17 @@ struct extResultDef
125
126
  {
126
127
  return 4 + (sizeof(resultField) * fieldCount);
127
128
  }
129
+
130
+ bool isFieldSelect(ulong clientRecordLen) const
131
+ {
132
+ return ((fieldCount > 1) ||
133
+ ((fieldCount == 1) && (field[0].len < clientRecordLen)));
134
+ }
135
+
136
+ bool isAllField(ulong clientRecordLen) const
137
+ {
138
+ return ((fieldCount == 1) && (field[0].len >= clientRecordLen));
139
+ }
128
140
  };
129
141
 
130
142
  inline position::position() : m_tb(NULL), m_record(NULL){};
@@ -287,7 +299,7 @@ public:
287
299
  m_sizeBytes = 0;
288
300
  m_judge = false;
289
301
  m_matched = false;
290
- m_placeHolderNum = 0;
302
+ m_placeHolderNum = 0xffff;
291
303
  m_nullOffset = 0;
292
304
  m_nullbit = 0;
293
305
  m_nullOffsetCompFd = 0;
@@ -541,12 +553,15 @@ public:
541
553
 
542
554
  void setNextPtr()
543
555
  {
544
- for (int i = 0; i < (int)m_fields.size() - 1; ++i)
556
+ if (m_fields.size())
545
557
  {
546
- m_fields[i].m_next = &m_fields[i + 1];
547
- m_fields[i].oprCache();
558
+ for (int i = 0; i < (int)m_fields.size() - 1; ++i)
559
+ {
560
+ m_fields[i].m_next = &m_fields[i + 1];
561
+ m_fields[i].oprCache();
562
+ }
563
+ m_fields[m_fields.size() - 1].oprCache();
548
564
  }
549
- m_fields[m_fields.size() - 1].oprCache();
550
565
  }
551
566
  };
552
567
 
@@ -556,39 +571,20 @@ class prepared : public engine::mysql::IPrepare
556
571
  public:
557
572
  fields* fds;
558
573
  extResultDef* rd;
559
- unsigned char* readMap;
574
+ std::bitset<256> bits;
560
575
  int blobs;
561
576
  unsigned short rejectCount;
562
- int readMapSize;
563
- prepared() : fds(NULL), rd(NULL), readMap(NULL), readMapSize(0){}
577
+ bool wholeRow;
578
+ prepared() : fds(NULL), rd(NULL), wholeRow(false){}
564
579
 
565
580
  ~prepared()
566
581
  {
567
582
  if (fds)
568
583
  delete fds;
569
- if (readMap)
570
- delete [] readMap;
571
584
  if (rd)
572
585
  free(rd);
573
586
  }
574
587
 
575
- void copyBitmapTo(MY_BITMAP* bm)
576
- {
577
- if (readMap)
578
- memcpy(bm->bitmap, readMap, readMapSize);
579
- }
580
-
581
- void assignBitmap(MY_BITMAP* bm)
582
- {
583
- if (bm)
584
- {
585
- assert(readMap == NULL);
586
- readMapSize = ((bm->n_bits + 7)/ 8);
587
- readMap = new unsigned char[readMapSize];
588
- memcpy(readMap, (unsigned char*)bm->bitmap, readMapSize);
589
- }
590
- }
591
-
592
588
  void assignResultDef(const extResultDef* src)
593
589
  {
594
590
  assert(rd == NULL);
@@ -602,7 +598,6 @@ public:
602
598
  fds = new fields();
603
599
  *(fds) = *src;
604
600
  fds->setNextPtr();
605
-
606
601
  }
607
602
 
608
603
  void release()
@@ -635,8 +630,7 @@ class resultWriter
635
630
  // in the client, fieldCount > 0 buf recLen=0 then this pattern
636
631
  if (pos)
637
632
  {
638
- if ((m_def->fieldCount == 1) &&
639
- (m_def->field[0].len >= pos->recordLenCl()))
633
+ if (m_def->isAllField(pos->recordLenCl()))
640
634
  { // write whole row
641
635
  int len = pos->recordPackCopy(m_nw->curPtr(),
642
636
  (uint)m_nw->bufferSpace());
@@ -725,15 +719,11 @@ class ReadRecordsHandler : public engine::mysql::IReadRecordsHandler
725
719
  position m_position;
726
720
  fields* m_fields;
727
721
  fields* m_defaultFields;
728
- engine::mysql::fieldBitmap bm;
729
722
  unsigned short m_maxRows;
730
723
  bool m_seeksMode;
731
724
 
732
725
  public:
733
- ReadRecordsHandler():m_defaultFields(new fields())
734
- {
735
-
736
- }
726
+ ReadRecordsHandler():m_defaultFields(new fields()){}
737
727
 
738
728
  ~ReadRecordsHandler()
739
729
  {
@@ -753,23 +743,16 @@ public:
753
743
  if (!m_fields->setSupplyValues(*req))
754
744
  return STATUS_INVALID_SUPPLYVALUES;
755
745
  }
756
-
757
- if(p->readMapSize)
758
- {
759
- bm.setTable(tb);
760
- if (m_seeksMode && !(req->itype & FILTER_TYPE_SEEKS_BOOKMARKS))
761
- addKeysegFieldMap(tb);
762
- if (p->readMapSize)
763
- p->copyBitmapTo(bm.getReadBitmap());
764
- }
765
-
766
- tb->indexInit();
746
+ engine::mysql::prepareHandler* ph = tb->getPrepareHandler();
747
+ ph->setReadBitmap(p->bits);
767
748
  tb->blobBuffer()->clear();
768
749
  tb->setBlobFieldCount(p->blobs);
769
750
  nw->beginExt(tb->blobFields() != 0);
770
751
  const extResultDef* rd = p->rd;
771
752
  m_writer.init(nw, rd, noBookmark, m_fields->nullbytes);
772
753
  m_maxRows = p->rd->maxRows;
754
+ ph->ready(p->wholeRow);
755
+
773
756
  return 0;
774
757
  }
775
758
 
@@ -778,14 +761,15 @@ public:
778
761
  {
779
762
  // Important! cache resultdef first.
780
763
  const extResultDef* srcRd = req->resultDef();
781
-
764
+
782
765
  short ret = begin(tb, req, fieldCache, nw, forword, noBookmark);
783
766
  p->assignResultDef(srcRd);
784
767
  p->assignFields(m_fields);
785
- if (bm.isUsing())
786
- p->assignBitmap(bm.getReadBitmap());
768
+ engine::mysql::prepareHandler* ph = tb->getPrepareHandler();
769
+ p->bits = ph->getReadBitmap();
787
770
  p->blobs = tb->getBlobFieldCount();
788
771
  p->rejectCount = m_req->rejectCount;
772
+ p->wholeRow = ph->isWholeRow();
789
773
  end();
790
774
  return ret;
791
775
  }
@@ -807,36 +791,25 @@ public:
807
791
  key = &tb->keyDef(tb->keyNum());
808
792
  m_fields->init(*m_req, m_position, key, forword);
809
793
  }
810
- if ((rd->fieldCount > 1) ||
811
- ((rd->fieldCount == 1) &&
812
- (rd->field[0].len < m_position.recordLenCl())))
794
+ bool whole_row = true;
795
+ if (rd->isFieldSelect(m_position.recordLenCl()))
796
+ {
813
797
  ret = convResultPosToFieldNum(tb, noBookmark, rd, m_seeksMode,
814
798
  (req->itype & FILTER_TYPE_SEEKS_BOOKMARKS) != 0);
815
-
799
+ if (ret) return ret;
800
+ whole_row = false;
801
+ }
802
+
816
803
  nw->beginExt(tb->blobFields() != 0);
817
804
  m_writer.init(nw, rd, noBookmark, m_fields->nullbytes);
818
805
  m_maxRows = rd->maxRows;
806
+
807
+ engine::mysql::prepareHandler* ph = tb->getPrepareHandler();
808
+ ph->ready(whole_row);
819
809
  // DEBUG_RECORDS_BEGIN(m_resultDef, m_req)
820
-
821
810
  return ret;
822
811
  }
823
-
824
- void addKeysegFieldMap(engine::mysql::table* tb)
825
- {
826
- const KEY* key = &tb->keyDef(tb->keyNum());
827
- if (key)
828
- {
829
- int sgi = 0;
830
- int segments = std::min<uint>(MAX_KEY_SEGMENT,
831
- key->user_defined_key_parts);
832
- while (sgi < segments)
833
- {
834
- bm.setReadBitmap(key->key_part[sgi].field->field_index);
835
- ++sgi;
836
- }
837
- }
838
- }
839
-
812
+
840
813
  // TODO This convert is move to client. but legacy app is need this
841
814
  short convResultPosToFieldNum(engine::mysql::table* tb, bool noBookmark,
842
815
  const extResultDef* rd, bool seeksMode, bool seekBookmark)
@@ -844,7 +817,8 @@ public:
844
817
  int blobs = 0;
845
818
  int nullfields = 0;
846
819
  m_fields->nullbytes = 0;
847
- bm.setTable(tb);
820
+ engine::mysql::prepareHandler* ph = tb->getPrepareHandler();
821
+ ph->clearReadBitmap();
848
822
  for (int i = 0; i < rd->fieldCount; i++)
849
823
  {
850
824
  const resultField& fd = rd->field[i];
@@ -852,7 +826,7 @@ public:
852
826
  if (num == -1)
853
827
  return STATUS_INVALID_FIELD_OFFSET;
854
828
  const_cast<resultField&>(fd).fieldNum = num;
855
- bm.setReadBitmap(num);
829
+ ph->setReadBitmap(num);
856
830
  if (m_position.isBlobField(&fd))
857
831
  ++blobs;
858
832
  if (m_position.isNullable(num) && m_position.isMysqlNull())
@@ -866,31 +840,17 @@ public:
866
840
  const logicalField* fd = &m_req->field;
867
841
  for (int i = 0; i < m_req->logicalCount; ++i)
868
842
  {
869
- bm.setReadBitmap(m_position.getFieldNumByPos(fd->pos));
843
+ ph->setReadBitmap(m_position.getFieldNumByPos(fd->pos));
870
844
  fd = fd->next();
871
845
  }
872
846
  }
873
847
  else if (!seekBookmark)
874
- addKeysegFieldMap(tb);
848
+ ph->makeCurrentKeyFieldBitmap();
875
849
 
876
850
  // if need bookmark , add primary key fields
877
851
  if (!noBookmark)
878
- {
879
- const KEY* key = tb->primaryKey();
880
- if (key)
881
- {
882
- int sgi = 0;
883
- int segments = std::min<uint>(MAX_KEY_SEGMENT,
884
- key->user_defined_key_parts);
885
- while (sgi < segments)
886
- {
887
- bm.setReadBitmap(key->key_part[sgi].field->field_index);
888
- ++sgi;
889
- }
890
- }
891
- }
892
- if (tb->keyNum() >= 0)
893
- tb->indexInit();
852
+ ph->makePrimaryKeyFieldBitmap();
853
+
894
854
  tb->blobBuffer()->clear();
895
855
  tb->setBlobFieldCount(blobs);
896
856
  return 0;
@@ -898,10 +858,8 @@ public:
898
858
 
899
859
  unsigned int end()
900
860
  {
901
- unsigned int len = m_writer.end();
902
861
  // DEBUG_RECORDS_END(m_writer.get())
903
- bm.setTable(NULL);
904
- return len;
862
+ return m_writer.end();
905
863
  }
906
864
 
907
865
  int match(bool typeNext) const
@@ -116,24 +116,31 @@ public:
116
116
  }
117
117
  }
118
118
 
119
- if (P_MASK_DATALEN & paramMask)
119
+ if (P_MASK_DB_AINC_VAL & paramMask)
120
120
  {
121
- datalenPtr = p;
122
- p += sizeof(uint_td);
121
+ memcpy(p, (const char*)datalen, sizeof(autoIncPackInfo));
122
+ p += sizeof(autoIncPackInfo);
123
123
  }
124
-
125
- if (P_MASK_DATA & paramMask)
124
+ else
126
125
  {
127
- if (tb && (data == tb->record()))
128
- resultLen = tb->recordPackCopy(p, 0);
129
- else
130
- memcpy(p, (const char*)data, resultLen);
131
- p += resultLen;
132
- }
126
+ if (P_MASK_DATALEN & paramMask)
127
+ {
128
+ datalenPtr = p;
129
+ p += sizeof(uint_td);
130
+ }
133
131
 
134
- if (P_MASK_DATALEN & paramMask)
135
- memcpy(datalenPtr, (const char*)&resultLen, sizeof(uint_td));
132
+ if (P_MASK_DATA & paramMask)
133
+ {
134
+ if (tb && (data == tb->record()))
135
+ resultLen = tb->recordPackCopy(p, 0);
136
+ else
137
+ memcpy(p, (const char*)data, resultLen);
138
+ p += resultLen;
139
+ }
136
140
 
141
+ if (P_MASK_DATALEN & paramMask)
142
+ memcpy(datalenPtr, (const char*)&resultLen, sizeof(uint_td));
143
+ }
137
144
  if (P_MASK_KEYBUF & paramMask)
138
145
  {
139
146
  if (tb)
@@ -194,7 +194,7 @@ void dumpStdErr(int op, request& req, table* tb)
194
194
  sprintf_s(msg.get(), 1024,
195
195
  "[Transactd] Exception:op=%d Handle=%d tablename=%s datalen=%d"
196
196
  " keynum=%d keylen=%d \n",
197
- op, req.pbk->handle, tb ? tb->name().c_str() : "", *req.datalen,
197
+ op, req.pbk ? req.pbk->handle : -1, tb ? tb->name().c_str() : "", *req.datalen,
198
198
  req.keyNum, req.keylen);
199
199
  sql_print_error("%s", msg.get());
200
200
  // dump Keybuf
@@ -505,6 +505,7 @@ inline bool dbExecuter::doOpenTable(request& req, char* buf, bool reconnect)
505
505
  if (getschema)
506
506
  mode -= TD_OPEN_MASK_GETSHCHEMA;
507
507
  bool getDefaultImage = IS_MODE_GETDEFAULTIMAGE(mode);
508
+ bool bin_str = IS_MODE_BIN_STR(mode);
508
509
  if (getDefaultImage)
509
510
  mode -= TD_OPEN_MASK_GETDEFAULTIMAGE;
510
511
  table* tb = NULL;
@@ -574,7 +575,7 @@ inline bool dbExecuter::doOpenTable(request& req, char* buf, bool reconnect)
574
575
  if (getschema)
575
576
  {
576
577
  p += len;
577
- len = m_tb->writeSchemaImage(p , *req.datalen - req.resultLen);
578
+ len = m_tb->writeSchemaImage(p , *req.datalen - req.resultLen, bin_str);
578
579
  if (len == sizeof(ushort_td))
579
580
  {
580
581
  req.result = STATUS_BUFFERTOOSMALL;
@@ -688,32 +689,19 @@ inline int dbExecuter::doReadMultiWithSeek(request& req, int op,
688
689
  int ret = 1;
689
690
  m_tb = getTable(req.pbk->handle);
690
691
  char keynum = m_tb->keyNumByMakeOrder(req.keyNum);
691
- if (keynum == -1 && (op == TD_KEY_GE_NEXT_MULTI))
692
- {
693
- m_tb->setNonKey(true);
694
- op = TD_POS_NEXT_MULTI;
695
- }
696
- else
697
- {
698
- if (!m_tb->setKeyNum(keynum))
699
- {
700
- req.result = m_tb->stat();
701
- return ret;
702
- }
703
-
704
- m_tb->setKeyValuesPacked((const uchar*)req.keybuf, req.keylen);
705
- m_tb->seekKey((op == TD_KEY_GE_NEXT_MULTI) ? HA_READ_KEY_OR_NEXT
706
- : HA_READ_KEY_OR_PREV,
707
- m_tb->keymap());
708
- }
709
-
692
+ if (keynum < 0) keynum = -2;
710
693
  extRequest* ereq = (extRequest*)req.data;
711
694
  bool noBookmark = (ereq->itype & FILTER_CURRENT_TYPE_NOBOOKMARK) != 0;
712
695
  bool execPrepared = (ereq->itype & FILTER_TYPE_SUPPLYVALUE) != 0;
696
+ if (!m_tb->setKeyNumForMultiRead(keynum))
697
+ {
698
+ req.result = m_tb->stat();
699
+ return ret;
700
+ }
701
+
713
702
  // smartReadRecordsHandler scope
714
703
  {
715
704
  smartReadRecordsHandler srrh(m_readHandler);
716
-
717
705
  if (execPrepared)
718
706
  {
719
707
  if (m_tb->preparedStatements.size() < ereq->preparedId)
@@ -729,6 +717,20 @@ inline int dbExecuter::doReadMultiWithSeek(request& req, int op,
729
717
  noBookmark);
730
718
  if (req.result != 0)
731
719
  return ret;
720
+ if (keynum < 0)
721
+ {
722
+ if (op == TD_KEY_GE_NEXT_MULTI)
723
+ op = TD_POS_NEXT_MULTI;
724
+ else if (op == TD_KEY_LE_PREV_MULTI)
725
+ op = TD_POS_PREV_MULTI;
726
+ }
727
+ else
728
+ {
729
+ m_tb->setKeyValuesPacked((const uchar*)req.keybuf, req.keylen);
730
+ m_tb->seekKey(
731
+ (op == TD_KEY_GE_NEXT_MULTI) ? HA_READ_KEY_OR_NEXT : HA_READ_KEY_OR_PREV,
732
+ m_tb->keymap());
733
+ }
732
734
  if (m_tb->stat() == 0)
733
735
  {
734
736
  if (op == TD_KEY_GE_NEXT_MULTI)
@@ -778,7 +780,16 @@ inline int dbExecuter::doReadMulti(request& req, int op,
778
780
  if (op == TD_KEY_SEEK_MULTI && !(ereq->itype & FILTER_TYPE_SEEKS_BOOKMARKS))
779
781
  {
780
782
  char keynum = m_tb->keyNumByMakeOrder(req.keyNum);
781
- if (!m_tb->setKeyNum(keynum))
783
+ if (keynum < 0)
784
+ {
785
+ if (op != TD_POS_NEXT_MULTI && op != TD_POS_PREV_MULTI)
786
+ {
787
+ req.result = STATUS_INVALID_KEYNUM;
788
+ return ret;
789
+ }
790
+ keynum = -2;
791
+ }
792
+ if (!m_tb->setKeyNumForMultiRead(keynum))
782
793
  {
783
794
  req.result = m_tb->stat();
784
795
  return ret;
@@ -994,26 +1005,29 @@ inline void dbExecuter::doInsert(request& req)
994
1005
  }
995
1006
  }
996
1007
  m_tb->clearBuffer();
1008
+ autoIncPackInfo ai;
997
1009
  m_tb->setRecordFromPacked((const uchar*)req.data, *(req.datalen),
998
- req.blobHeader);
999
- __int64 aincValue = m_tb->insert(ncc);
1010
+ req.blobHeader, &ai);
1011
+ ai.value = m_tb->insert(ncc);
1000
1012
  req.result = errorCodeSht(m_tb->stat());
1001
1013
  if (m_tb->stat() == 0)
1002
1014
  {
1003
- if (aincValue)
1015
+ if (ai.value && ai.len && *req.datalen >= ai.len)
1004
1016
  {
1005
- req.paramMask = P_MASK_INS_AUTOINC;
1006
- req.data = m_tb->record();
1017
+ req.paramMask = P_MASK_DB_AINC_VAL | P_MASK_POSBLK | P_MASK_KEYBUF;
1018
+ memcpy(req.datalen, &ai, sizeof(autoIncPackInfo));
1007
1019
  }
1008
1020
  else
1009
1021
  req.paramMask = P_MASK_POSBLK | P_MASK_KEYBUF;
1010
- }
1022
+ }else
1023
+ req.paramMask = 0;
1011
1024
  if (!m_tb->cursor())
1012
1025
  req.paramMask |= P_MASK_PB_ERASE_BM;
1013
1026
  }
1014
1027
 
1015
- inline void dbExecuter::doUpdateKey(request& req)
1028
+ inline void dbExecuter::doUpdateKey(request& req, bool confrictCheck)
1016
1029
  {
1030
+
1017
1031
  m_tb = getTable(req.pbk->handle, SQLCOM_UPDATE);
1018
1032
  char keynum = m_tb->keyNumByMakeOrder(req.keyNum);
1019
1033
  if (m_tb->setKeyNum(keynum))
@@ -1022,12 +1036,12 @@ inline void dbExecuter::doUpdateKey(request& req)
1022
1036
  m_tb->seekKey(HA_READ_KEY_EXACT, m_tb->keymap());
1023
1037
  if (m_tb->stat() == 0)
1024
1038
  {
1025
- m_tb->beginUpdate(keynum);
1039
+ double updateAtBefore = m_tb->beginUpdate(keynum, confrictCheck ? 2 : 0);
1026
1040
  if (m_tb->stat() == 0)
1027
1041
  {
1028
1042
  m_tb->setRecordFromPacked((const uchar*)req.data,
1029
- *(req.datalen), req.blobHeader);
1030
- m_tb->update(true);
1043
+ *(req.datalen), req.blobHeader, NULL);
1044
+ m_tb->update(true, updateAtBefore);
1031
1045
  }
1032
1046
  }
1033
1047
  }
@@ -1037,16 +1051,17 @@ inline void dbExecuter::doUpdateKey(request& req)
1037
1051
  req.paramMask |= P_MASK_PB_ERASE_BM;
1038
1052
  }
1039
1053
 
1040
- inline void dbExecuter::doUpdate(request& req)
1054
+ inline void dbExecuter::doUpdate(request& req, bool confrictCheck)
1041
1055
  {
1056
+
1042
1057
  m_tb = getTable(req.pbk->handle, SQLCOM_UPDATE);
1043
1058
  bool ncc = (req.keyNum == -1);
1044
- m_tb->beginUpdate(req.keyNum);
1059
+ double updateAtBefore = m_tb->beginUpdate(req.keyNum, confrictCheck ? 1 : 0);
1045
1060
  if (m_tb->stat() == 0)
1046
1061
  {
1047
1062
  m_tb->setRecordFromPacked((const uchar*)req.data, *(req.datalen),
1048
- req.blobHeader);
1049
- m_tb->update(ncc);
1063
+ req.blobHeader, NULL);
1064
+ m_tb->update(ncc, updateAtBefore);
1050
1065
  }
1051
1066
  req.result = errorCodeSht(m_tb->stat());
1052
1067
  req.paramMask = P_MASK_POSBLK | P_MASK_KEYBUF;
@@ -1054,7 +1069,7 @@ inline void dbExecuter::doUpdate(request& req)
1054
1069
  req.paramMask |= P_MASK_PB_ERASE_BM;
1055
1070
  }
1056
1071
 
1057
- inline void dbExecuter::doDeleteKey(request& req)
1072
+ inline void dbExecuter::doDeleteKey(request& req, bool confrictCheck)
1058
1073
  {
1059
1074
  m_tb = getTable(req.pbk->handle, SQLCOM_DELETE);
1060
1075
  char keynum = m_tb->keyNumByMakeOrder(req.keyNum);
@@ -1064,9 +1079,13 @@ inline void dbExecuter::doDeleteKey(request& req)
1064
1079
  m_tb->seekKey(HA_READ_KEY_EXACT, m_tb->keymap());
1065
1080
  if (m_tb->stat() == 0)
1066
1081
  {
1067
- m_tb->beginDel();
1082
+ double updateAtBefore = m_tb->beginDel(confrictCheck ? 2 : 0);
1068
1083
  if (m_tb->stat() == 0)
1069
- m_tb->del();
1084
+ {
1085
+ if (confrictCheck)
1086
+ m_tb->setUpdateTimeValue(req.data);
1087
+ m_tb->del(updateAtBefore);
1088
+ }
1070
1089
  }
1071
1090
  }
1072
1091
  req.result = errorCodeSht(m_tb->stat());
@@ -1075,12 +1094,16 @@ inline void dbExecuter::doDeleteKey(request& req)
1075
1094
  req.paramMask |= P_MASK_PB_ERASE_BM;
1076
1095
  }
1077
1096
 
1078
- inline void dbExecuter::doDelete(request& req)
1097
+ inline void dbExecuter::doDelete(request& req, bool confrictCheck)
1079
1098
  {
1080
1099
  m_tb = getTable(req.pbk->handle, SQLCOM_DELETE);
1081
- m_tb->beginDel();
1100
+ double updateAtBefore = m_tb->beginDel(confrictCheck ? 1 : 0);
1082
1101
  if (m_tb->stat() == 0)
1083
- m_tb->del();
1102
+ {
1103
+ if (confrictCheck)
1104
+ m_tb->setUpdateTimeValue(req.data);
1105
+ m_tb->del(updateAtBefore);
1106
+ }
1084
1107
  req.result = errorCodeSht(m_tb->stat());
1085
1108
  req.paramMask = P_MASK_POSBLK;
1086
1109
  if (!m_tb->cursor())
@@ -1111,7 +1134,7 @@ inline void dbExecuter::doInsertBulk(request& req)
1111
1134
  {
1112
1135
  m_tb->clearBuffer();
1113
1136
  m_tb->setRecordFromPacked(pos + sizeof(ushort_td), len,
1114
- req.blobHeader);
1137
+ req.blobHeader, NULL);
1115
1138
  if (i == *n - 1)
1116
1139
  m_tb->insert((req.keyNum != -1));
1117
1140
  else
@@ -1143,7 +1166,7 @@ inline void dbExecuter::doGetSchema(request& req, netsvc::server::netWriter* nw)
1143
1166
  char* p = nw->curPtr() - sizeof(unsigned short);// orver write row space
1144
1167
  if (req.keyNum == SC_SUBOP_VIEW_BY_SQL)
1145
1168
  {// Return SQL statement as show create view.
1146
- TABLE_LIST tables; char key[256];
1169
+ TABLE_LIST tables; char key[256]={0};
1147
1170
  const char* keyPtr = key;
1148
1171
  database* db = getDatabaseCid(req.cid);
1149
1172
  THD* thd = db->thd();
@@ -1190,7 +1213,9 @@ inline void dbExecuter::doGetSchema(request& req, netsvc::server::netWriter* nw)
1190
1213
  {// Return tabledef image binary.
1191
1214
  database* db = getDatabaseCid(req.cid);
1192
1215
  std::string name = getTableName(req);
1193
- schemaBuilder sb;
1216
+ unsigned char bin_char_index =
1217
+ (req.keyNum == SC_SUBOP_TABLEDEF_BIN_STR) ? 0 : CHARSET_BIN;
1218
+ schemaBuilder sb(bin_char_index);
1194
1219
  protocol::tdap::tabledef* td = sb.getTabledef(db, name.c_str(),
1195
1220
  (unsigned char*)p, *req.datalen);
1196
1221
  if (td)
@@ -1334,16 +1359,16 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1334
1359
  doInsert(req);
1335
1360
  break;
1336
1361
  case TD_REC_UPDATEATKEY:
1337
- doUpdateKey(req);
1362
+ doUpdateKey(req, opTrn > 100);
1338
1363
  break;
1339
1364
  case TD_REC_UPDATE:
1340
- doUpdate(req);
1365
+ doUpdate(req, opTrn > 100);
1341
1366
  break;
1342
1367
  case TD_REC_DELLETEATKEY:
1343
- doDeleteKey(req);
1368
+ doDeleteKey(req, opTrn > 100);
1344
1369
  break;
1345
1370
  case TD_REC_DELETE:
1346
- doDelete(req);
1371
+ doDelete(req, opTrn > 100);
1347
1372
  break;
1348
1373
  case TD_BEGIN_TRANSACTION:
1349
1374
  {
@@ -1526,14 +1551,18 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1526
1551
  break;
1527
1552
  case TD_GET_PER:
1528
1553
  m_tb = getTable(req.pbk->handle);
1529
- m_tb->calcPercentage();
1530
- req.result = errorCodeSht(m_tb->stat());
1531
- if (m_tb->stat() == 0)
1554
+ if (m_tb->setKeyNum(m_tb->keyNumByMakeOrder(req.keyNum)))
1532
1555
  {
1533
- req.paramMask = P_MASK_DATA | P_MASK_DATALEN ;
1534
- req.data = m_tb->percentResult();
1535
- req.resultLen = sizeof(int);
1536
- }
1556
+ m_tb->calcPercentage();
1557
+ req.result = errorCodeSht(m_tb->stat());
1558
+ if (m_tb->stat() == 0)
1559
+ {
1560
+ req.paramMask = P_MASK_DATA | P_MASK_DATALEN ;
1561
+ req.data = m_tb->percentResult();
1562
+ req.resultLen = sizeof(int);
1563
+ }
1564
+ }else
1565
+ req.result = m_tb->stat();
1537
1566
  break;
1538
1567
  case TD_INSERT_BULK:
1539
1568
  doInsertBulk(req);
@@ -1574,9 +1603,12 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1574
1603
  releaseDatabase(req, op);
1575
1604
  break;
1576
1605
  case TD_AUTOMEKE_SCHEMA:
1606
+ {
1577
1607
  m_tb = getTable(req.pbk->handle, SQLCOM_INSERT);
1578
- req.result = schemaBuilder().execute(getDatabaseCid(req.cid), m_tb, (req.keyNum==1));
1608
+ unsigned char bin_char_index = (req.keyNum & 2) ? 0 : CHARSET_BIN;
1609
+ req.result = schemaBuilder(bin_char_index).execute(getDatabaseCid(req.cid), m_tb, (req.keyNum & 1));
1579
1610
  break;
1611
+ }
1580
1612
  case TD_CREATETABLE:
1581
1613
  doCreateTable(req);
1582
1614
  break;
@@ -1681,7 +1713,7 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1681
1713
  {
1682
1714
  m_tb = getTable(req.pbk->handle, SQLCOM_UPDATE);
1683
1715
  bool ncc = (req.keyNum == -1);
1684
- m_tb->beginUpdate(req.keyNum);
1716
+ double v = m_tb->beginUpdate(req.keyNum, opTrn > 100);
1685
1717
  if (m_tb->stat() == 0)
1686
1718
  {
1687
1719
  std::vector<std::string> ss;
@@ -1691,7 +1723,7 @@ int dbExecuter::commandExec(request& req, netsvc::server::netWriter* nw)
1691
1723
  {
1692
1724
  for (int i = 0; i < (int)ss.size() ; i+=2)
1693
1725
  m_tb->setValue((short)atol(ss[i].c_str()), ss[i + 1], 0);
1694
- m_tb->update(ncc);
1726
+ m_tb->update(ncc, v);
1695
1727
  req.result = errorCodeSht(m_tb->stat());
1696
1728
  req.paramMask = P_MASK_POSBLK | P_MASK_KEYBUF;
1697
1729
  if (!m_tb->cursor())
@@ -80,10 +80,10 @@ class dbExecuter : public engine::mysql::dbManager
80
80
  inline void doStepRead(request& req, int op, engine::mysql::rowLockMode* lock);
81
81
 
82
82
  inline void doInsert(request& req);
83
- inline void doUpdate(request& req);
84
- inline void doUpdateKey(request& req);
85
- inline void doDelete(request& req);
86
- inline void doDeleteKey(request& req);
83
+ inline void doUpdate(request& req, bool confrictCheck);
84
+ inline void doUpdateKey(request& req, bool confrictCheck);
85
+ inline void doDelete(request& req, bool confrictCheck);
86
+ inline void doDeleteKey(request& req, bool confrictCheck);
87
87
  inline void doInsertBulk(request& req);
88
88
  inline void doGetSchema(request& req, netsvc::server::netWriter* nw);
89
89
  inline void doStat(request& req);