transactd 2.4.5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CMakeLists.txt +1 -1
- data/README-JA.md +52 -529
- data/README.md +52 -523
- data/bin/common/tdclc_32_3_0.dll +0 -0
- data/bin/common/tdclc_64_3_0.dll +0 -0
- data/build/common/system.cmake +2 -1
- data/build/common/transactd_cl_common.cmake +3 -6
- data/build/swig/ruby/ruby.swg +85 -28
- data/build/swig/ruby/tdclrb_wrap.cpp +3195 -1578
- data/build/swig/tdcl.i +161 -5
- data/build/tdclc/CMakeLists.txt +1 -0
- data/build/tdclc/tdclc.cbproj +7 -1
- data/build/tdclc/tdclc.rc +4 -4
- data/build/tdclcpp/tdclcpp.rc +4 -4
- data/build/tdclcpp/tdclcpp_bc.cbproj +2 -5
- data/build/tdclrb/tdclrb.rc +4 -4
- data/source/bzs/db/blobStructs.h +1 -1
- data/source/bzs/db/engine/mysql/database.cpp +199 -74
- data/source/bzs/db/engine/mysql/database.h +47 -18
- data/source/bzs/db/engine/mysql/dbManager.cpp +1 -0
- data/source/bzs/db/engine/mysql/mysqlInternal.h +32 -8
- data/source/bzs/db/protocol/tdap/btrDate.cpp +110 -75
- data/source/bzs/db/protocol/tdap/btrDate.h +46 -21
- data/source/bzs/db/protocol/tdap/client/activeTable.cpp +18 -18
- data/source/bzs/db/protocol/tdap/client/activeTable.h +25 -25
- data/source/bzs/db/protocol/tdap/client/activeTableImple.h +10 -4
- data/source/bzs/db/protocol/tdap/client/client.cpp +6 -5
- data/source/bzs/db/protocol/tdap/client/client.h +82 -15
- data/source/bzs/db/protocol/tdap/client/database.cpp +531 -142
- data/source/bzs/db/protocol/tdap/client/database.h +19 -6
- data/source/bzs/db/protocol/tdap/client/dbDef.cpp +461 -408
- data/source/bzs/db/protocol/tdap/client/dbDef.h +11 -17
- data/source/bzs/db/protocol/tdap/client/dllmain.cpp +61 -13
- data/source/bzs/db/protocol/tdap/client/field.cpp +1592 -1398
- data/source/bzs/db/protocol/tdap/client/field.h +110 -121
- data/source/bzs/db/protocol/tdap/client/fields.h +40 -10
- data/source/bzs/db/protocol/tdap/client/filter.h +69 -55
- data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +296 -164
- data/source/bzs/db/protocol/tdap/client/groupQuery.h +77 -25
- data/source/bzs/db/protocol/tdap/client/memRecord.cpp +31 -13
- data/source/bzs/db/protocol/tdap/client/memRecord.h +31 -21
- data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -1
- data/source/bzs/db/protocol/tdap/client/nsTable.cpp +69 -24
- data/source/bzs/db/protocol/tdap/client/nsTable.h +3 -1
- data/source/bzs/db/protocol/tdap/client/recordset.cpp +1 -0
- data/source/bzs/db/protocol/tdap/client/recordsetImple.h +46 -27
- data/source/bzs/db/protocol/tdap/client/request.h +2 -1
- data/source/bzs/db/protocol/tdap/client/serializer.cpp +44 -9
- data/source/bzs/db/protocol/tdap/client/serializer.h +1 -1
- data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +182 -76
- data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +23 -12
- data/source/bzs/db/protocol/tdap/client/stringConverter.h +8 -10
- data/source/bzs/db/protocol/tdap/client/table.cpp +172 -93
- data/source/bzs/db/protocol/tdap/client/table.h +112 -37
- data/source/bzs/db/protocol/tdap/client/trdboostapi.h +17 -0
- data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +0 -1
- data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +0 -2
- data/source/bzs/db/protocol/tdap/client/trdormapi.h +1 -1
- data/source/bzs/db/protocol/tdap/fieldComp.h +698 -14
- data/source/bzs/db/protocol/tdap/myDateTime.cpp +723 -307
- data/source/bzs/db/protocol/tdap/myDateTime.h +294 -0
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +164 -54
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +6 -3
- data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +133 -550
- data/source/bzs/db/protocol/tdap/mysql/request.h +6 -5
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +217 -82
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +1 -1
- data/source/bzs/db/protocol/tdap/tdapRequest.h +4 -9
- data/source/bzs/db/protocol/tdap/tdapSchema.cpp +808 -17
- data/source/bzs/db/protocol/tdap/tdapSchema.h +656 -164
- data/source/bzs/db/protocol/tdap/tdapcapi.h +130 -28
- data/source/bzs/db/protocol/tdap/uri.h +40 -32
- data/source/bzs/db/transactd/connManager.cpp +1 -1
- data/source/bzs/db/transactd/transactd.cpp +7 -0
- data/source/bzs/env/compiler.h +107 -94
- data/source/bzs/env/crosscompile.cpp +24 -12
- data/source/bzs/env/crosscompile.h +75 -6
- data/source/bzs/env/mbcswchrLinux.cpp +2 -2
- data/source/bzs/env/tcharMinGW.h +4 -0
- data/source/bzs/example/changeSchema.cpp +22 -17
- data/source/bzs/example/queryData.cpp +4 -0
- data/source/bzs/netsvc/client/iconnection.h +3 -1
- data/source/bzs/netsvc/client/tcpClient.h +10 -3
- data/source/bzs/rtl/stringBuffers.cpp +7 -0
- data/source/bzs/test/tdclatl/bench_query_atl.js +6 -0
- data/source/bzs/test/tdclatl/bench_tdclatl.js +8 -1
- data/source/bzs/test/tdclatl/test_query_atl.js +22 -2
- data/source/bzs/test/tdclatl/test_v3.js +1017 -0
- data/source/bzs/test/tdclphp/transactd_Test.php +55 -21
- data/source/bzs/test/tdclphp/transactd_datetime_Test.php +0 -5
- data/source/bzs/test/tdclphp/transactd_pool_Test.php +2 -0
- data/source/bzs/test/tdclphp/transactd_v3_Test.php +743 -0
- data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +0 -5
- data/source/bzs/test/tdclrb/transactd_pool_spec.rb +2 -0
- data/source/bzs/test/tdclrb/transactd_spec.rb +39 -16
- data/source/bzs/test/tdclrb/transactd_v3_spec.rb +748 -0
- data/source/bzs/test/transactdBench/transactdBench.cpp +55 -58
- data/source/bzs/test/transactdBench/transactdBench2.cpp +1 -3
- data/source/bzs/test/trdclengn/testField.h +3305 -0
- data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +1050 -0
- data/source/bzs/test/trdclengn/test_trdclengn.cpp +112 -190
- data/source/bzs/test/trdclengn/testbase.h +137 -0
- data/source/global/ormsrcgen/srcgen.cpp +23 -12
- data/source/global/ormsrcgen/template/ormDataClass_template.h +2 -0
- data/source/global/querystmts/querystmts.cpp +2 -3
- data/source/global/tdclatl/Bitset.cpp +38 -0
- data/source/global/tdclatl/Bitset.h +63 -0
- data/source/global/tdclatl/Database.cpp +59 -18
- data/source/global/tdclatl/Database.h +7 -4
- data/source/global/tdclatl/DbDef.cpp +6 -6
- data/source/global/tdclatl/DbDef.h +2 -1
- data/source/global/tdclatl/Field.cpp +112 -0
- data/source/global/tdclatl/Field.h +19 -5
- data/source/global/tdclatl/FieldDef.cpp +137 -16
- data/source/global/tdclatl/FieldDef.h +18 -2
- data/source/global/tdclatl/FieldDefs.cpp +54 -1
- data/source/global/tdclatl/FieldDefs.h +3 -0
- data/source/global/tdclatl/GroupQuery.cpp +8 -8
- data/source/global/tdclatl/QueryBase.cpp +65 -0
- data/source/global/tdclatl/QueryBase.h +10 -0
- data/source/global/tdclatl/Record.cpp +33 -2
- data/source/global/tdclatl/Record.h +3 -1
- data/source/global/tdclatl/RecordsetQuery.cpp +42 -0
- data/source/global/tdclatl/RecordsetQuery.h +8 -0
- data/source/global/tdclatl/Table.cpp +127 -3
- data/source/global/tdclatl/Table.h +10 -1
- data/source/global/tdclatl/TableDef.cpp +41 -8
- data/source/global/tdclatl/TableDef.h +7 -2
- data/source/global/tdclatl/activeTable.cpp +40 -71
- data/source/global/tdclatl/resource.h +0 -0
- data/source/global/tdclatl/tdclatl.idl +222 -28
- data/source/linux/tchar.h +100 -96
- data/transactd.gemspec +2 -2
- metadata +13 -11
- data/BUILD_UNIX-JA.md +0 -161
- data/BUILD_WIN-JA.md +0 -326
- data/README_ORMSRCGEN-JA.md +0 -115
- data/README_ORMSRCGEN.md +0 -118
- data/RELEASE_NOTE-JA.md +0 -356
- data/RELEASE_NOTE.md +0 -360
- data/bin/common/tdclc_32_2_4.dll +0 -0
- data/bin/common/tdclc_64_2_4.dll +0 -0
- 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
|
-
|
191
|
-
|
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
|
-
|
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
|
-
|
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 (
|
977
|
+
if (m_nisNullFields)
|
970
978
|
m_recordFormatType |= RF_INCLUDE_NIS;
|
971
|
-
|
972
|
-
|
973
|
-
|
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->
|
993
|
-
fd->unireg_check == Field::TIMESTAMP_DNUN_FIELD ||
|
994
|
-
fd->unireg_check == Field::TIMESTAMP_DN_FIELD)
|
985
|
+
if (fd->null_bit)
|
995
986
|
{
|
996
|
-
|
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
|
-
|
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(
|
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
|
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 =
|
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
|
-
|
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
|
-
|
1353
|
-
if (isVarType(fd->type()))
|
1399
|
+
if (!isNull)
|
1354
1400
|
{
|
1355
|
-
len =
|
1356
|
-
if (
|
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
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
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,
|
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 (
|
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::
|
2254
|
+
void table::setFieldNullFlags()
|
2168
2255
|
{
|
2169
|
-
std::vector<Field*>::iterator it =
|
2170
|
-
while (it !=
|
2256
|
+
std::vector<Field*>::iterator it = m_noNullModeNullFieldList.begin();
|
2257
|
+
while (it != m_noNullModeNullFieldList.end())
|
2171
2258
|
{
|
2172
|
-
if (
|
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
|
-
|
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 (
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
272
|
-
std::vector<Field*>
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
786
|
+
inline unsigned int delCount() const { return m_delCount; }
|
758
787
|
|
759
|
-
inline
|
788
|
+
inline unsigned int insCount() const { return m_insCount; }
|
760
789
|
|
761
|
-
inline
|
790
|
+
inline void setTimestampAlways(bool v) { m_timestampAlways = v;}
|
762
791
|
};
|
763
792
|
|
764
793
|
class fieldBitmap
|