transactd 2.4.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +1 -1
  3. data/README-JA.md +52 -529
  4. data/README.md +52 -523
  5. data/bin/common/tdclc_32_3_0.dll +0 -0
  6. data/bin/common/tdclc_64_3_0.dll +0 -0
  7. data/build/common/system.cmake +2 -1
  8. data/build/common/transactd_cl_common.cmake +3 -6
  9. data/build/swig/ruby/ruby.swg +85 -28
  10. data/build/swig/ruby/tdclrb_wrap.cpp +3195 -1578
  11. data/build/swig/tdcl.i +161 -5
  12. data/build/tdclc/CMakeLists.txt +1 -0
  13. data/build/tdclc/tdclc.cbproj +7 -1
  14. data/build/tdclc/tdclc.rc +4 -4
  15. data/build/tdclcpp/tdclcpp.rc +4 -4
  16. data/build/tdclcpp/tdclcpp_bc.cbproj +2 -5
  17. data/build/tdclrb/tdclrb.rc +4 -4
  18. data/source/bzs/db/blobStructs.h +1 -1
  19. data/source/bzs/db/engine/mysql/database.cpp +199 -74
  20. data/source/bzs/db/engine/mysql/database.h +47 -18
  21. data/source/bzs/db/engine/mysql/dbManager.cpp +1 -0
  22. data/source/bzs/db/engine/mysql/mysqlInternal.h +32 -8
  23. data/source/bzs/db/protocol/tdap/btrDate.cpp +110 -75
  24. data/source/bzs/db/protocol/tdap/btrDate.h +46 -21
  25. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +18 -18
  26. data/source/bzs/db/protocol/tdap/client/activeTable.h +25 -25
  27. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +10 -4
  28. data/source/bzs/db/protocol/tdap/client/client.cpp +6 -5
  29. data/source/bzs/db/protocol/tdap/client/client.h +82 -15
  30. data/source/bzs/db/protocol/tdap/client/database.cpp +531 -142
  31. data/source/bzs/db/protocol/tdap/client/database.h +19 -6
  32. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +461 -408
  33. data/source/bzs/db/protocol/tdap/client/dbDef.h +11 -17
  34. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +61 -13
  35. data/source/bzs/db/protocol/tdap/client/field.cpp +1592 -1398
  36. data/source/bzs/db/protocol/tdap/client/field.h +110 -121
  37. data/source/bzs/db/protocol/tdap/client/fields.h +40 -10
  38. data/source/bzs/db/protocol/tdap/client/filter.h +69 -55
  39. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +296 -164
  40. data/source/bzs/db/protocol/tdap/client/groupQuery.h +77 -25
  41. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +31 -13
  42. data/source/bzs/db/protocol/tdap/client/memRecord.h +31 -21
  43. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +1 -1
  44. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -1
  45. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +69 -24
  46. data/source/bzs/db/protocol/tdap/client/nsTable.h +3 -1
  47. data/source/bzs/db/protocol/tdap/client/recordset.cpp +1 -0
  48. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +46 -27
  49. data/source/bzs/db/protocol/tdap/client/request.h +2 -1
  50. data/source/bzs/db/protocol/tdap/client/serializer.cpp +44 -9
  51. data/source/bzs/db/protocol/tdap/client/serializer.h +1 -1
  52. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +182 -76
  53. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +23 -12
  54. data/source/bzs/db/protocol/tdap/client/stringConverter.h +8 -10
  55. data/source/bzs/db/protocol/tdap/client/table.cpp +172 -93
  56. data/source/bzs/db/protocol/tdap/client/table.h +112 -37
  57. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +17 -0
  58. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +0 -1
  59. data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +0 -2
  60. data/source/bzs/db/protocol/tdap/client/trdormapi.h +1 -1
  61. data/source/bzs/db/protocol/tdap/fieldComp.h +698 -14
  62. data/source/bzs/db/protocol/tdap/myDateTime.cpp +723 -307
  63. data/source/bzs/db/protocol/tdap/myDateTime.h +294 -0
  64. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +164 -54
  65. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +6 -3
  66. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +133 -550
  67. data/source/bzs/db/protocol/tdap/mysql/request.h +6 -5
  68. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +217 -82
  69. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +1 -1
  70. data/source/bzs/db/protocol/tdap/tdapRequest.h +4 -9
  71. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +808 -17
  72. data/source/bzs/db/protocol/tdap/tdapSchema.h +656 -164
  73. data/source/bzs/db/protocol/tdap/tdapcapi.h +130 -28
  74. data/source/bzs/db/protocol/tdap/uri.h +40 -32
  75. data/source/bzs/db/transactd/connManager.cpp +1 -1
  76. data/source/bzs/db/transactd/transactd.cpp +7 -0
  77. data/source/bzs/env/compiler.h +107 -94
  78. data/source/bzs/env/crosscompile.cpp +24 -12
  79. data/source/bzs/env/crosscompile.h +75 -6
  80. data/source/bzs/env/mbcswchrLinux.cpp +2 -2
  81. data/source/bzs/env/tcharMinGW.h +4 -0
  82. data/source/bzs/example/changeSchema.cpp +22 -17
  83. data/source/bzs/example/queryData.cpp +4 -0
  84. data/source/bzs/netsvc/client/iconnection.h +3 -1
  85. data/source/bzs/netsvc/client/tcpClient.h +10 -3
  86. data/source/bzs/rtl/stringBuffers.cpp +7 -0
  87. data/source/bzs/test/tdclatl/bench_query_atl.js +6 -0
  88. data/source/bzs/test/tdclatl/bench_tdclatl.js +8 -1
  89. data/source/bzs/test/tdclatl/test_query_atl.js +22 -2
  90. data/source/bzs/test/tdclatl/test_v3.js +1017 -0
  91. data/source/bzs/test/tdclphp/transactd_Test.php +55 -21
  92. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +0 -5
  93. data/source/bzs/test/tdclphp/transactd_pool_Test.php +2 -0
  94. data/source/bzs/test/tdclphp/transactd_v3_Test.php +743 -0
  95. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +0 -5
  96. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +2 -0
  97. data/source/bzs/test/tdclrb/transactd_spec.rb +39 -16
  98. data/source/bzs/test/tdclrb/transactd_v3_spec.rb +748 -0
  99. data/source/bzs/test/transactdBench/transactdBench.cpp +55 -58
  100. data/source/bzs/test/transactdBench/transactdBench2.cpp +1 -3
  101. data/source/bzs/test/trdclengn/testField.h +3305 -0
  102. data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +1050 -0
  103. data/source/bzs/test/trdclengn/test_trdclengn.cpp +112 -190
  104. data/source/bzs/test/trdclengn/testbase.h +137 -0
  105. data/source/global/ormsrcgen/srcgen.cpp +23 -12
  106. data/source/global/ormsrcgen/template/ormDataClass_template.h +2 -0
  107. data/source/global/querystmts/querystmts.cpp +2 -3
  108. data/source/global/tdclatl/Bitset.cpp +38 -0
  109. data/source/global/tdclatl/Bitset.h +63 -0
  110. data/source/global/tdclatl/Database.cpp +59 -18
  111. data/source/global/tdclatl/Database.h +7 -4
  112. data/source/global/tdclatl/DbDef.cpp +6 -6
  113. data/source/global/tdclatl/DbDef.h +2 -1
  114. data/source/global/tdclatl/Field.cpp +112 -0
  115. data/source/global/tdclatl/Field.h +19 -5
  116. data/source/global/tdclatl/FieldDef.cpp +137 -16
  117. data/source/global/tdclatl/FieldDef.h +18 -2
  118. data/source/global/tdclatl/FieldDefs.cpp +54 -1
  119. data/source/global/tdclatl/FieldDefs.h +3 -0
  120. data/source/global/tdclatl/GroupQuery.cpp +8 -8
  121. data/source/global/tdclatl/QueryBase.cpp +65 -0
  122. data/source/global/tdclatl/QueryBase.h +10 -0
  123. data/source/global/tdclatl/Record.cpp +33 -2
  124. data/source/global/tdclatl/Record.h +3 -1
  125. data/source/global/tdclatl/RecordsetQuery.cpp +42 -0
  126. data/source/global/tdclatl/RecordsetQuery.h +8 -0
  127. data/source/global/tdclatl/Table.cpp +127 -3
  128. data/source/global/tdclatl/Table.h +10 -1
  129. data/source/global/tdclatl/TableDef.cpp +41 -8
  130. data/source/global/tdclatl/TableDef.h +7 -2
  131. data/source/global/tdclatl/activeTable.cpp +40 -71
  132. data/source/global/tdclatl/resource.h +0 -0
  133. data/source/global/tdclatl/tdclatl.idl +222 -28
  134. data/source/linux/tchar.h +100 -96
  135. data/transactd.gemspec +2 -2
  136. metadata +13 -11
  137. data/BUILD_UNIX-JA.md +0 -161
  138. data/BUILD_WIN-JA.md +0 -326
  139. data/README_ORMSRCGEN-JA.md +0 -115
  140. data/README_ORMSRCGEN.md +0 -118
  141. data/RELEASE_NOTE-JA.md +0 -356
  142. data/RELEASE_NOTE.md +0 -360
  143. data/bin/common/tdclc_32_2_4.dll +0 -0
  144. data/bin/common/tdclc_64_2_4.dll +0 -0
  145. data/source/bzs/test/trdclengn/test_blob.cpp +0 -375
@@ -26,6 +26,10 @@
26
26
  #include "bookmark.h"
27
27
  #include <bzs/rtl/stl_uty.h>
28
28
  #include <boost/shared_array.hpp>
29
+ #include <bzs/db/protocol/tdap/mysql/databaseSchema.h>
30
+
31
+
32
+ extern unsigned int g_timestamp_always;
29
33
 
30
34
  namespace bzs
31
35
  {
@@ -186,11 +190,11 @@ bool unlockTables(bool releaseStatementLock, THD* thd, bool rollback, database::
186
190
  tableCacheCounter database::tableRef;
187
191
 
188
192
  database::database(const char* name, short cid)
189
- : m_dbname(name), m_thd(createThdForThread()),
190
- m_inTransaction(0), m_inSnapshot(0), m_stat(0), m_usingExclusive(false),
191
- m_inAutoTransaction(NULL), m_trnType(0), m_cid(cid), m_privilege(0xFFFF)
193
+ : m_dbname(name), m_thd(createThdForThread()),m_inAutoTransaction(NULL),
194
+ m_privilege(0xFFFF), m_inTransaction(0), m_inSnapshot(0), m_stat(0),
195
+ m_usingExclusive(false), m_trnType(0), m_cid(cid)
192
196
  {
193
- cp_security_ctx(m_thd)->skip_grants();
197
+ cp_security_ctx(m_thd)->skip_grants();
194
198
  }
195
199
 
196
200
  #ifdef _MSC_VER
@@ -770,11 +774,14 @@ table* database::openTable(const std::string& name, short mode,
770
774
  m_stat = STATUS_ALREADY_INTRANSACTION;
771
775
  return NULL;
772
776
  }
777
+ bool mysql_null = IS_MODE_MYSQL_NULL(mode);
778
+ if (mysql_null)
779
+ mode -= TD_OPEN_MASK_MYSQL_NULL;
773
780
  TABLE* t = doOpenTable(name, mode, ownerName);
774
781
  if (t)
775
782
  {
776
783
  boost::shared_ptr<table> tb(
777
- new table(t, *this, name, mode, (int)m_tables.size()));
784
+ new table(t, *this, name, mode, (int)m_tables.size(), mysql_null));
778
785
  {
779
786
  boost::mutex::scoped_lock lck(tableRef.mutex());
780
787
  m_tables.push_back(tb);
@@ -929,7 +936,7 @@ unsigned short nisFieldNum(TABLE* tb)
929
936
  bool table::noKeybufResult = true;
930
937
 
931
938
  table::table(TABLE* myTable, database& db, const std::string& name, short mode,
932
- int id)
939
+ int id, bool mysqlnull)
933
940
  : m_table(myTable), m_name(name), m_mode(mode), m_id(id), m_db(db),
934
941
  m_keybuf(new unsigned char[MAX_KEYLEN]),
935
942
  m_stat(0),
@@ -937,7 +944,8 @@ table::table(TABLE* myTable, database& db, const std::string& name, short mode,
937
944
  m_readCount(0), m_updCount(0), m_delCount(0), m_insCount(0),
938
945
  m_keyNum(-1), m_nonNcc(false), m_validCursor(true), m_cursor(false),
939
946
  m_locked(false), m_changed(false), m_nounlock(false), m_bulkInserting(false),
940
- m_delayAutoCommit(false),m_forceConsistentRead(false)
947
+ m_delayAutoCommit(false),m_forceConsistentRead(false), m_mysqlNull(mysqlnull),
948
+ m_timestampAlways(g_timestamp_always != 0)
941
949
  {
942
950
 
943
951
  m_table->read_set = &m_table->s->all_set;
@@ -947,7 +955,7 @@ table::table(TABLE* myTable, database& db, const std::string& name, short mode,
947
955
  m_lastVarLenBytes = 0;
948
956
  #endif
949
957
  // Is the Nis field included or not?
950
- m_nullFields = nisFieldNum(m_table);
958
+ m_nisNullFields = nisFieldNum(m_table);
951
959
 
952
960
  if (m_table->s->varchar_fields + m_table->s->blob_fields == 0)
953
961
  m_recordFormatType = RF_FIXED_LEN;
@@ -966,36 +974,41 @@ table::table(TABLE* myTable, database& db, const std::string& name, short mode,
966
974
  }
967
975
  }
968
976
  #endif
969
- if (m_nullFields)
977
+ if (m_nisNullFields)
970
978
  m_recordFormatType |= RF_INCLUDE_NIS;
971
- #ifdef USE_BTRV_VARIABLE_LEN
972
- m_recordLenCl = (uint)(m_table->s->reclength - m_table->s->null_bytes -
973
- m_nullFields - m_lastVarLenBytes);
974
- #else
975
- m_recordLenCl =
976
- (uint)(m_table->s->reclength - m_table->s->null_bytes - m_nullFields);
977
- #endif
978
- // Chash null field
979
- if (m_table->s->null_fields)
980
- {
981
- for (int i = 0; i < (int)m_table->s->fields; ++i)
982
- {
983
- Field* fd = m_table->field[i];
984
- if (fd->null_bit && fd->part_of_key.is_clear_all())
985
- m_nonKeySegNullFields.push_back(fd);
986
- }
987
- }
988
- // Chash timestamp field
979
+
980
+ // Cache null fields ,timestamp fields and no null mode null fields lists
981
+ int nullbits = 0;
989
982
  for (int i = 0; i < (int)m_table->s->fields; ++i)
990
983
  {
991
984
  Field* fd = m_table->field[i];
992
- if (fd->unireg_check == Field::TIMESTAMP_UN_FIELD ||
993
- fd->unireg_check == Field::TIMESTAMP_DNUN_FIELD ||
994
- fd->unireg_check == Field::TIMESTAMP_DN_FIELD)
985
+ if (fd->null_bit)
995
986
  {
996
- m_timeStampFields.push_back(fd);
987
+ if (m_mysqlNull)
988
+ ++nullbits;
989
+ else if (fd->part_of_key.is_clear_all())
990
+ m_noNullModeNullFieldList.push_back(fd);
997
991
  }
992
+
993
+ if (fd->unireg_check == Field::TIMESTAMP_UN_FIELD ||
994
+ fd->unireg_check == Field::TIMESTAMP_DNUN_FIELD ||
995
+ fd->unireg_check == Field::TIMESTAMP_DN_FIELD)
996
+ m_timeStampFields.push_back(fd);
998
997
  }
998
+ m_nullBytesCl = (nullbits + 7) / 8;
999
+
1000
+ #ifdef USE_BTRV_VARIABLE_LEN
1001
+ m_recordLenCl = (uint)(m_table->s->reclength - m_table->s->null_bytes -
1002
+ m_nisNullFields - m_lastVarLenBytes);
1003
+ #else
1004
+ m_recordLenCl =
1005
+ (uint)(m_table->s->reclength - m_table->s->null_bytes - m_nisNullFields);
1006
+ #endif
1007
+
1008
+ #if (MYSQL_VERSION_ID < 50600)
1009
+ m_table->timestamp_field_type = TIMESTAMP_NO_AUTO_SET;
1010
+ #endif
1011
+
999
1012
  }
1000
1013
 
1001
1014
  table::~table()
@@ -1127,18 +1140,19 @@ short table::setKeyValuesPacked(const uchar* ptr, int size)
1127
1140
  for (int j = 0; j < (int)key.user_defined_key_parts; j++)
1128
1141
  {
1129
1142
  KEY_PART_INFO& seg = key.key_part[j];
1130
- if (seg.null_bit)
1131
- {
1132
- m_keybuf[to++] = 0x00; // set null to mysql null indicator.
1133
- seg.field->set_notnull();// Ignore null for read.
1134
- }
1135
1143
  if (seg.null_bit && isNisField(seg.field->field_name))
1136
1144
  {
1137
- m_keybuf[to++] = 0x00; // set null to nis field.
1145
+ m_keybuf[to++] = 0x00; // set not null to nis field.
1146
+ m_keybuf[to++] = 0x00; // set value to nis field.
1138
1147
  //continue next segment
1139
1148
  }
1140
1149
  else
1141
1150
  {
1151
+ if (seg.null_bit)
1152
+ {
1153
+ m_keybuf[to++] = *from;
1154
+ ++from;
1155
+ }
1142
1156
  unsigned short copylen = seg.length; // length = store_len - varlen
1143
1157
  unsigned short copyspace = copylen;
1144
1158
  if (seg.key_part_flag & HA_BLOB_PART ||
@@ -1221,7 +1235,17 @@ void* table::record() const
1221
1235
  void table::setRecord(void* ptr, unsigned short size, int offset)
1222
1236
  {
1223
1237
  m_cursor = false;
1224
- Field* fd = m_table->field[0]; // remove null flag segment
1238
+ unsigned char* p;
1239
+ /*if (m_mysqlNull && m_table->s->null_fields)
1240
+ {
1241
+ p = m_table->record[0];
1242
+ size = std::min(size, (unsigned short)recordLen());
1243
+ }
1244
+ else*/
1245
+ {
1246
+ p = (unsigned char*)record();
1247
+ size = std::min(size, (unsigned short)recordLenCl());
1248
+ }
1225
1249
  #ifdef USE_BTRV_VARIABLE_LEN
1226
1250
  if (offset + size <=
1227
1251
  (unsigned short)m_table->s->reclength + lastVarLenBytes())
@@ -1233,13 +1257,13 @@ void table::setRecord(void* ptr, unsigned short size, int offset)
1233
1257
  #endif
1234
1258
 
1235
1259
  if (size > 0)
1236
- memcpy(fd->ptr + offset, ptr, size);
1260
+ memcpy(p + offset, ptr, size);
1237
1261
  }
1238
1262
  else
1239
1263
  THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_DATASIZE, "");
1240
1264
  }
1241
1265
 
1242
- inline bool isNull(Field* fd)
1266
+ inline bool isNullValue(Field* fd)
1243
1267
  {
1244
1268
  if (isVarType(fd->type()))
1245
1269
  {
@@ -1271,7 +1295,7 @@ inline bool isNullNis(KEY& key, bool all)
1271
1295
  Field* fd = key.key_part[j].field;
1272
1296
  if (key.key_part[j].null_bit)
1273
1297
  {
1274
- bool v = isNull(fd);
1298
+ bool v = isNullValue(fd);
1275
1299
  v ? fd->set_null() : fd->set_notnull();
1276
1300
  if (all && !v)
1277
1301
  return false;
@@ -1311,7 +1335,7 @@ void table::setRecordFromPacked(const uchar* packedPtr, uint size,
1311
1335
  const bzs::db::blobHeader* hd)
1312
1336
  {
1313
1337
  const uchar* p = packedPtr;
1314
-
1338
+ bool nullable = (m_mysqlNull && m_table->s->null_fields);
1315
1339
  #ifdef USE_BTRV_VARIABLE_LEN
1316
1340
  if (recordFormatType() & RF_FIXED_PLUS_VALIABLE_LEN)
1317
1341
  {
@@ -1337,39 +1361,66 @@ void table::setRecordFromPacked(const uchar* packedPtr, uint size,
1337
1361
  (recordFormatType() & RF_INCLUDE_NIS))
1338
1362
  {
1339
1363
  #else
1340
- if ((recordFormatType() & RF_VALIABLE_LEN) ||
1364
+ if (nullable || (recordFormatType() & RF_VALIABLE_LEN) ||
1341
1365
  (recordFormatType() & RF_INCLUDE_NIS))
1342
1366
  {
1343
1367
  #endif
1368
+ //copy null bits
1369
+
1370
+
1344
1371
  // It copies for every field.
1345
- for (uint i = 0; i < m_table->s->fields; i++)
1372
+ // But if null then not recived field image
1373
+ unsigned char* null_ptr = (unsigned char*)p;
1374
+ unsigned char null_bit = 1;
1375
+ p += m_nullBytesCl;
1376
+ for (uint i = 0; i < m_table->s->fields; ++i)
1346
1377
  {
1347
1378
  Field* fd = m_table->field[i];
1379
+ bool isNull = false;
1380
+ if (fd->null_bit && nullable)
1381
+ {
1382
+ isNull = (*null_ptr & null_bit) != 0;
1383
+ if (isNull)
1384
+ fd->set_null();
1385
+ else
1386
+ fd->set_notnull();
1387
+ if (null_bit == (uchar)128)
1388
+ {
1389
+ ++null_ptr;
1390
+ null_bit = 1;
1391
+ }else
1392
+ null_bit = null_bit << 1;
1393
+ }
1394
+
1348
1395
  if (isNisField(fd->field_name))
1349
1396
  fd->ptr[0] = 0x00; // The Nis field is not sent from a client.
1350
1397
  else
1351
1398
  {
1352
- int len = fd->pack_length();
1353
- if (isVarType(fd->type()))
1399
+ if (!isNull)
1354
1400
  {
1355
- len = var_total_len(p, var_bytes(fd));
1356
- if (len > (int)fd->pack_length())
1401
+ int len = fd->pack_length();
1402
+ if (isVarType(fd->type()))
1403
+ {
1404
+ len = var_total_len(p, var_bytes(fd));
1405
+ if (len > (int)fd->pack_length())
1406
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_BUFFERTOOSMALL,
1407
+ "setRecordFromPacked");
1408
+ }
1409
+ else if (size < (uint)len)
1357
1410
  THROW_BZS_ERROR_WITH_CODEMSG(STATUS_BUFFERTOOSMALL,
1358
- "setRecordFromPacked");
1359
- }
1360
- else if (size < (uint)len)
1361
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_BUFFERTOOSMALL,
1362
- "setRecordFromPacked");
1363
- memcpy(fd->ptr, p, len);
1364
- p += len;
1365
- size -= len;
1411
+ "setRecordFromPacked");
1412
+ memcpy(fd->ptr, p, len);
1413
+ p += len;
1414
+ size -= len;
1415
+ }else
1416
+ memset(fd->ptr, 0, fd->pack_length());
1366
1417
  }
1367
1418
  }
1368
1419
  if (m_table->s->blob_fields)
1369
1420
  setBlobFieldPointer(hd);
1370
1421
  }
1371
1422
  else
1372
- setRecord((void*)p, std::min(size, recordLenCl()));
1423
+ setRecord((void*)p, size);
1373
1424
  }
1374
1425
 
1375
1426
  /** A record image is packed, and is copied to the specified buffer, and length
@@ -1381,6 +1432,7 @@ void table::setRecordFromPacked(const uchar* packedPtr, uint size,
1381
1432
  uint table::recordPackCopy(char* buf, uint maxsize)
1382
1433
  {
1383
1434
  char* p = buf;
1435
+ bool nullable = (m_mysqlNull && m_table->s->null_fields);
1384
1436
  #ifdef USE_BTRV_VARIABLE_LEN
1385
1437
  if (recordFormatType() & RF_FIXED_PLUS_VALIABLE_LEN)
1386
1438
  {
@@ -1408,18 +1460,40 @@ uint table::recordPackCopy(char* buf, uint maxsize)
1408
1460
  (recordFormatType() & RF_INCLUDE_NIS))
1409
1461
  {
1410
1462
  #else
1411
- if ((recordFormatType() & RF_VALIABLE_LEN) ||
1463
+ if (nullable || (recordFormatType() & RF_VALIABLE_LEN) ||
1412
1464
  (recordFormatType() & RF_INCLUDE_NIS))
1413
1465
  {
1414
1466
  #endif
1415
1467
  int blobs = 0;
1468
+ p = buf + m_nullBytesCl;
1469
+ unsigned char* null_ptr = (unsigned char*)buf;//m_table->record[0];
1470
+ *null_ptr = 0x00;
1471
+ unsigned char null_bit = 1;
1416
1472
  for (uint i = 0; i < m_table->s->fields; i++)
1417
1473
  {
1418
1474
  Field* fd = m_table->field[i];
1475
+ bool isNull = false;
1476
+ if (fd->null_bit && nullable)
1477
+ {
1478
+ //copy null bit
1479
+ isNull = fd->is_null();
1480
+ if (isNull)
1481
+ {
1482
+ if (null_bit == 1)
1483
+ *null_ptr = 0x00;
1484
+ *null_ptr |= null_bit;
1485
+ }
1486
+ if (null_bit == (uchar)128)
1487
+ {
1488
+ ++null_ptr;
1489
+ null_bit = 1;
1490
+ }else
1491
+ null_bit = null_bit << 1;
1492
+ }
1419
1493
  if (isNisField(fd->field_name))
1420
1494
  ;
1421
1495
  // The Nis field is not sent to a client.
1422
- else
1496
+ else if (!isNull)
1423
1497
  {
1424
1498
  uint len = fd->pack_length();
1425
1499
  if (isVarType(fd->type()))
@@ -1447,7 +1521,7 @@ uint table::recordPackCopy(char* buf, uint maxsize)
1447
1521
  return (uint)(p - buf);
1448
1522
  }
1449
1523
 
1450
- ushort table::fieldPackCopy(unsigned char* dest, short fieldNum)
1524
+ ushort table::fieldPackCopy(unsigned char* nullPtr, int& nullbit, unsigned char* dest, short fieldNum)
1451
1525
  {
1452
1526
  Field* fd = m_table->field[fieldNum];
1453
1527
  uint len = fd->pack_length();
@@ -1461,7 +1535,19 @@ ushort table::fieldPackCopy(unsigned char* dest, short fieldNum)
1461
1535
  }
1462
1536
  else
1463
1537
  #endif
1538
+ {
1464
1539
  memcpy(dest, fd->ptr, len);
1540
+ if (m_mysqlNull && nullPtr)
1541
+ {
1542
+ if (fd->is_null())
1543
+ {
1544
+ nullPtr += (nullbit / 8);
1545
+ (*nullPtr) |= (unsigned char)(1L << (nullbit % 8));
1546
+ }
1547
+ if (fd->null_bit)
1548
+ ++nullbit;
1549
+ }
1550
+ }
1465
1551
  return (ushort)len;
1466
1552
  }
1467
1553
 
@@ -2106,7 +2192,7 @@ bool table::isNisKey(char num) const
2106
2192
  return false;
2107
2193
  }
2108
2194
 
2109
- bool setNullIf(KEY& key)
2195
+ bool setNullIf(KEY& key, bool mysqlNull)
2110
2196
  {
2111
2197
  bool nullkey = false;
2112
2198
  Field* fd = key.key_part[0].field; // Nis is only in a head segment.
@@ -2120,14 +2206,14 @@ bool setNullIf(KEY& key)
2120
2206
  else
2121
2207
  fd->set_notnull();
2122
2208
  }
2123
- else
2209
+ else if (!mysqlNull)
2124
2210
  {
2125
2211
  for (int j = 0; j < (int)key.user_defined_key_parts; j++)
2126
2212
  {
2127
2213
  fd = key.key_part[j].field;
2128
2214
  if (key.key_part[j].null_bit && fd->ptr)
2129
2215
  {
2130
- if (isNull(fd))
2216
+ if (isNullValue(fd))
2131
2217
  {
2132
2218
  fd->set_null();
2133
2219
  nullkey = true;
@@ -2153,7 +2239,7 @@ int table::setKeyNullFlags()
2153
2239
  KEY& key = m_table->key_info[i];
2154
2240
  if (key.flags & HA_NULL_PART_KEY)
2155
2241
  {
2156
- bool nullKey = setNullIf(key);
2242
+ bool nullKey = setNullIf(key, m_mysqlNull);
2157
2243
  if (nullKey && (i == m_keyNum))
2158
2244
  ++setCount;
2159
2245
  }
@@ -2163,13 +2249,14 @@ int table::setKeyNullFlags()
2163
2249
  }
2164
2250
 
2165
2251
  /** Sets null value for all null able fields
2252
+ This method effect only !mysqlNull
2166
2253
  */
2167
- void table::setFiledNullFlags()
2254
+ void table::setFieldNullFlags()
2168
2255
  {
2169
- std::vector<Field*>::iterator it = m_nonKeySegNullFields.begin();
2170
- while (it != m_nonKeySegNullFields.end())
2256
+ std::vector<Field*>::iterator it = m_noNullModeNullFieldList.begin();
2257
+ while (it != m_noNullModeNullFieldList.end())
2171
2258
  {
2172
- if (isNull(*it))
2259
+ if (isNullValue(*it))
2173
2260
  (*it)->set_null();
2174
2261
  else
2175
2262
  (*it)->set_notnull();
@@ -2184,13 +2271,13 @@ void table::setTimeStamp(bool insert)
2184
2271
  std::vector<Field*>::iterator it = m_timeStampFields.begin();
2185
2272
  while (it != m_timeStampFields.end())
2186
2273
  {
2187
- /*if (g_timestamp_always)
2274
+ if (m_timestampAlways)
2188
2275
  {
2189
2276
  if ((insert && cp_has_insert_default_function((*it))) ||
2190
2277
  (!insert && cp_has_update_default_function((*it))))
2191
2278
  (*it)->store(0.0f);
2192
- }*/
2193
- if (/*!(*it)->is_null() &&*/ ((*it)->val_real() == 0))
2279
+ }
2280
+ if (!(*it)->is_null() && ((*it)->val_real() == 0))
2194
2281
  {
2195
2282
  if (insert)
2196
2283
  cp_evaluate_insert_default_function((*it));
@@ -2213,9 +2300,9 @@ __int64 table::insert(bool ncc)
2213
2300
  {
2214
2301
  autoincSetup setup(m_table);
2215
2302
  setKeyNullFlags();
2216
- setFiledNullFlags();
2303
+ if (!m_mysqlNull) setFieldNullFlags();
2217
2304
  setTimeStamp(true /* insert */);
2218
-
2305
+ cp_setup_rpl_bitmap(m_table);
2219
2306
  m_stat = m_table->file->ha_write_row(m_table->record[0]);
2220
2307
  autoincValue = m_table->file->insert_id_for_cur_row;
2221
2308
 
@@ -2308,8 +2395,10 @@ void table::update(bool ncc)
2308
2395
  if (m_stat == 0)
2309
2396
  {
2310
2397
  int nullFieldsOfCurrentKey = setKeyNullFlags();
2311
- setFiledNullFlags();
2398
+ if (!m_mysqlNull) setFieldNullFlags();
2312
2399
  setTimeStamp(false /* update */);
2400
+ cp_setup_rpl_bitmap(m_table);
2401
+
2313
2402
  m_stat = m_table->file->ha_update_row(m_table->record[1],
2314
2403
  m_table->record[0]);
2315
2404
  if (m_stat == 0 || (m_stat == HA_ERR_RECORD_IS_THE_SAME))
@@ -2489,6 +2578,41 @@ void table::setKeyValues(const std::vector<std::string>& values, int keypart,
2489
2578
  key_copy(&m_keybuf[0], m_table->record[0], &key, KEYLEN_ALLCOPY);
2490
2579
  }
2491
2580
 
2581
+ unsigned int table::writeDefaultImage(unsigned char* p, size_t size)
2582
+ {
2583
+ unsigned short cllen = (unsigned short)recordLenCl();
2584
+ unsigned short len = cllen + m_nullBytesCl;
2585
+ int offset = m_table->s->null_bytes;
2586
+ memcpy(p, &len, sizeof(unsigned short));
2587
+ p += sizeof(ushort_td);
2588
+ if (size - 2 >= len)
2589
+ memcpy(p + m_nullBytesCl, m_table->s->default_values + offset, cllen);
2590
+
2591
+ unsigned char* src = m_table->s->default_values;
2592
+ for (int i = 0 ; i < m_nullBytesCl; ++i)
2593
+ {
2594
+ *p = *src;
2595
+ if (!(m_table->s->db_create_options & HA_OPTION_PACK_RECORD))
2596
+ {
2597
+ *p = *p >> 1;
2598
+ *p |= (*(src + 1) & 1) ? 0xf0 : 0;
2599
+ }
2600
+ ++p; ++src;
2601
+ }
2602
+ return len + sizeof(unsigned short);
2603
+ }
2604
+
2605
+ unsigned int table::writeSchemaImage(unsigned char* p, size_t size)
2606
+ {
2607
+ protocol::tdap::tabledef* td = schemaBuilder().getTabledef(this, 0, m_mysqlNull, p + 2, size - 2);
2608
+ unsigned short len = 0;
2609
+ if (td)
2610
+ len = td->varSize + 4;
2611
+ memcpy(p, &len, sizeof(unsigned short));
2612
+ return len + sizeof(unsigned short);
2613
+ }
2614
+
2615
+
2492
2616
  #ifdef USE_HANDLERSOCKET
2493
2617
 
2494
2618
  int table::fieldIndexByName(const char* name) const
@@ -2545,6 +2669,7 @@ void table::checkFiledIndex(int index)
2545
2669
  assert(index >= 0);
2546
2670
  }
2547
2671
 
2672
+
2548
2673
  #endif // USE_HANDLERSOCKET
2549
2674
 
2550
2675
  } // namespace mysql
@@ -112,16 +112,16 @@ public:
112
112
  private:
113
113
  std::string m_dbname;
114
114
  mutable THD* m_thd;
115
+ table* m_inAutoTransaction;
116
+ tableList m_tables;
117
+ ulong m_privilege;
115
118
  int m_inTransaction;
116
119
  int m_inSnapshot;
117
120
  int m_stat;
118
121
  int m_usingExclusive;
119
- table* m_inAutoTransaction;
120
122
  short m_trnType;
121
123
  short m_cid;
122
124
  enum_tx_isolation m_iso;
123
- tableList m_tables;
124
- ulong m_privilege;
125
125
 
126
126
  TABLE* doOpenTable(const std::string& name, short mode,
127
127
  const char* ownerName);
@@ -217,13 +217,13 @@ class bookmarks;
217
217
  */
218
218
  class keynumConvert
219
219
  {
220
- KEY* m_key;
220
+ const KEY* m_key;
221
221
  int m_keyCount;
222
222
  char m_keyNum;
223
223
  char m_convNum;
224
224
 
225
225
  public:
226
- keynumConvert(KEY* key, int count)
226
+ keynumConvert(const KEY* key, int count)
227
227
  : m_key(key), m_keyCount(count), m_keyNum(-1), m_convNum(-1)
228
228
  {
229
229
  }
@@ -241,6 +241,16 @@ public:
241
241
  return m_convNum = i;
242
242
  return m_convNum = num; // If not found, a value as it is returned.
243
243
  }
244
+
245
+ char clientKeynum(char num)
246
+ {
247
+ if (num < m_keyCount)
248
+ {
249
+ if (strstr(m_key[num].name, "key"))
250
+ return m_key[num].name[3] - '0';
251
+ }
252
+ return -1;
253
+ }
244
254
  };
245
255
 
246
256
  class table : private boost::noncopyable
@@ -252,7 +262,7 @@ class table : private boost::noncopyable
252
262
  std::string m_name;
253
263
 
254
264
  short m_mode;
255
- unsigned short m_nullFields;
265
+ unsigned short m_nisNullFields;
256
266
  int m_id;
257
267
  uint m_recordLenCl;
258
268
  int m_recordFormatType;
@@ -268,13 +278,14 @@ class table : private boost::noncopyable
268
278
  String m_str;
269
279
  keynumConvert m_keyconv;
270
280
  IblobBuffer* m_blobBuffer;
271
- std::vector<Field*> m_timeStampFields;
272
- std::vector<Field*> m_nonKeySegNullFields;
281
+ std::vector<Field*> m_noNullModeNullFieldList;
282
+ std::vector<Field*> m_timeStampFields;
273
283
  unsigned int m_readCount;
274
284
  unsigned int m_updCount;
275
285
  unsigned int m_delCount;
276
286
  unsigned int m_insCount;
277
287
  char m_keyNum;
288
+ unsigned char m_nullBytesCl;
278
289
  struct
279
290
  {
280
291
  bool m_nonNcc : 1;
@@ -289,10 +300,12 @@ class table : private boost::noncopyable
289
300
  struct
290
301
  {
291
302
  bool m_forceConsistentRead : 1;
303
+ bool m_mysqlNull : 1;
304
+ bool m_timestampAlways : 1;
292
305
  };
293
306
 
294
307
  table(TABLE* table, database& db, const std::string& name, short mode,
295
- int id);
308
+ int id, bool mysqlnull);
296
309
  void moveKey(boost::function<int()> func);
297
310
  void readRecords(IReadRecordsHandler* handler, bool includeCurrent,
298
311
  int type, bool noBookmark);
@@ -301,7 +314,7 @@ class table : private boost::noncopyable
301
314
  void preBuildPercent(uchar* first, uchar* last);
302
315
  void seekPos(const uchar* pos);
303
316
  int setKeyNullFlags();
304
- void setFiledNullFlags();
317
+ void setFieldNullFlags();
305
318
  void setTimeStamp(bool insert);
306
319
 
307
320
  bookmarks* bms();
@@ -550,7 +563,7 @@ public:
550
563
  const bzs::db::blobHeader* hd);
551
564
  uint recordPackCopy(char* buf, uint maxsize = 0);
552
565
 
553
- ushort fieldPackCopy(unsigned char* dest, short fieldNum);
566
+ ushort fieldPackCopy(unsigned char* nullPtr, int& nullbit, unsigned char* dest, short fieldNum);
554
567
 
555
568
  inline uint fieldSizeByte(int fieldNum)
556
569
  {
@@ -587,10 +600,17 @@ public:
587
600
  {
588
601
  return m_table->field[fieldNum]->flags;
589
602
  }
603
+
604
+ inline bool isLegacyTimeFormat(int fieldNum) const
605
+ {
606
+ return m_table->field[fieldNum]->key_type() != HA_KEYTYPE_BINARY;
607
+ }
590
608
 
591
609
  inline unsigned short fields() const { return m_table->s->fields; }
592
610
 
593
- inline unsigned int nisFields() const { return m_nullFields; }
611
+ inline bool isMysqlNull() const { return m_mysqlNull; }
612
+
613
+ inline unsigned int nisFields() const { return m_nisNullFields; }
594
614
 
595
615
  inline const char* fieldName(int fieldNum) const
596
616
  {
@@ -612,14 +632,14 @@ public:
612
632
 
613
633
  inline const KEY* primaryKey() const
614
634
  {
615
- return (m_table->s->primary_key != MAX_KEY)
635
+ return (m_table->s->primary_key <= MAX_KEY)
616
636
  ? &m_table->key_info[m_table->s->primary_key]
617
637
  : NULL;
618
638
  }
619
639
 
620
640
  inline Field* field(int fieldNum) const { return m_table->field[fieldNum]; }
621
641
 
622
- inline char primarykey() const { return m_table->s->primary_key; }
642
+ inline char primarykeyNum() const { return m_table->s->primary_key; }
623
643
 
624
644
  /** is this view. not table */
625
645
  inline bool isView() const { return m_table->s->is_view; }
@@ -752,13 +772,22 @@ public:
752
772
  void setKeyValues(const std::vector<std::string>& values, int keypart,
753
773
  const std::string* inValue = NULL);
754
774
 
755
- inline unsigned int readCount() const { return m_readCount; }
775
+ unsigned int writeDefaultImage(unsigned char* p, size_t size);
776
+
777
+ unsigned int writeSchemaImage(unsigned char* p, size_t size);
778
+
779
+
780
+ void restoreRecord() { restore_record(m_table, s->default_values);}
781
+
782
+ inline unsigned int readCount() const { return m_readCount; }
783
+
784
+ inline unsigned int updCount() const { return m_updCount; }
756
785
 
757
- inline unsigned int updCount() const { return m_updCount; }
786
+ inline unsigned int delCount() const { return m_delCount; }
758
787
 
759
- inline unsigned int delCount() const { return m_delCount; }
788
+ inline unsigned int insCount() const { return m_insCount; }
760
789
 
761
- inline unsigned int insCount() const { return m_insCount; }
790
+ inline void setTimestampAlways(bool v) { m_timestampAlways = v;}
762
791
  };
763
792
 
764
793
  class fieldBitmap
@@ -229,6 +229,7 @@ int dbManager::ddl_execSql(THD* thd, const std::string& sql_stmt)
229
229
  // result = 1;
230
230
  if (thd->is_error())
231
231
  result = errorCode(thd->cp_get_sql_error());
232
+ cp_lex_clear(thd); // reset values for insert
232
233
  return result;
233
234
  }
234
235