transactd 3.5.0 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
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);