transactd 2.4.5 → 3.0.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 (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