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
@@ -21,6 +21,7 @@
21
21
 
22
22
  #include "request.h"
23
23
  #include <bzs/db/protocol/tdap/tdapSchema.h>
24
+ #include <bzs/db/protocol/tdap/fieldComp.h>
24
25
  #include <bzs/rtl/exception.h>
25
26
  #include <bzs/db/engine/mysql/IReadRecords.h>
26
27
  #include <bzs/db/engine/mysql/fieldAccess.h>
@@ -81,9 +82,23 @@ public:
81
82
  {
82
83
  return m_tb->fieldSizeByte(fieldNum);
83
84
  }
84
- inline ushort fieldPackCopy(unsigned char* dest, short fieldNum)
85
+ inline ushort fieldPackCopy(unsigned char* nullPtr, int& nullbit, unsigned char* dest, short fieldNum)
85
86
  {
86
- return m_tb->fieldPackCopy(dest, fieldNum);
87
+ return m_tb->fieldPackCopy(nullPtr, nullbit, dest, fieldNum);
88
+ }
89
+ inline bool isMysqlNull() const { return m_tb->isMysqlNull();}
90
+ inline bool isNullable(int index) const { return m_tb->field(index)->null_bit != 0; }
91
+ inline unsigned char nullbit(int index) const { return m_tb->field(index)->null_bit; }
92
+ inline unsigned char nullOffset(int index) const
93
+ {
94
+ Field* fd = m_tb->field(index);
95
+ unsigned char* null_ptr = (unsigned char*)cp_null_ptr(fd, (unsigned char*)m_tb->internalTable()->record[0]);
96
+ return (unsigned char)((unsigned char*)m_tb->fieldPos(0) - null_ptr);
97
+ }
98
+
99
+ bool isLegacyTimeFormat(int fieldNum) const
100
+ {
101
+ return m_tb->isLegacyTimeFormat(fieldNum);
87
102
  }
88
103
  };
89
104
 
@@ -136,134 +151,18 @@ inline unsigned short position::packLen(const resultField* rf) const
136
151
  return m_tb->fieldDataLen(rf->fieldNum);
137
152
  }
138
153
 
139
- template <class T> inline
140
- int bitMask(const char* l, const char* r)
141
- {
142
- T v = *((T*)l) & *((T*)r);
143
- return (int)(*((T*)r) - v);
144
- }
145
-
146
- inline int bitMask24(const char* l, const char* r)
147
- {
148
- int lv = ((*((int*)l) & 0xFFFFFF) << 8) / 0x100;
149
- int rv = ((*((int*)r) & 0xFFFFFF) << 8) / 0x100;
150
- int v = lv & rv;
151
- return rv - v;
152
- }
153
-
154
- inline int compareUint24(const char* l, const char* r)
155
- {
156
- unsigned int lv = *((unsigned int*)l) & 0xFFFFFF;
157
- unsigned int rv = *((unsigned int*)r) & 0xFFFFFF;
158
- if (lv < rv)
159
- return -1;
160
- if (lv > rv)
161
- return 1;
162
- return 0;
163
- }
164
-
165
- inline int compareInt24(const char* l, const char* r)
166
- {
167
- int lv = ((*((int*)l) & 0xFFFFFF) << 8) / 0x100;
168
- int rv = ((*((int*)r) & 0xFFFFFF) << 8) / 0x100;
169
-
170
- if (lv < rv)
171
- return -1;
172
- else if (lv > rv)
173
- return 1;
174
- return 0;
175
- }
176
-
177
- template <class T> inline int compare(const char* l, const char* r)
178
- {
179
- if (*((T*)l) < *((T*)r))
180
- return -1;
181
- else if (*((T*)l) > *((T*)r))
182
- return 1;
183
- return 0;
184
- }
185
-
186
- template <class T> inline int compare(T l, T r)
187
- {
188
- if (l < r)
189
- return -1;
190
- else if (l > r)
191
- return 1;
192
- return 0;
193
- }
194
-
195
- template <class T>
196
- inline int compareVartype(const char* l, const char* r, bool bin, char logType)
197
- {
198
- int llen = (*(T*)l);
199
- int rlen = (*(T*)r);
200
- int tmp = std::min(llen, rlen);
201
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
202
- tmp = _strnicmp(l + sizeof(T), r + sizeof(T), tmp);
203
- else if (bin)
204
- tmp = memcmp(l + sizeof(T), r + sizeof(T), tmp);
205
- else
206
- tmp = strncmp(l + sizeof(T), r + sizeof(T), tmp);
207
-
208
- if (logType & CMPLOGICAL_VAR_COMP_ALL)
209
- return (tmp == 0) ? compare<int>(llen, rlen) : tmp; // match complete
210
- return (tmp == 0 && (llen < rlen)) ? -1 : tmp; // match a part
211
- }
212
-
213
- template <class T>
214
- inline int compareWvartype(const char* l, const char* r, bool bin, char logType)
215
- {
216
- int llen = (*(T*)l) / sizeof(char16_t);
217
- int rlen = (*(T*)r) / sizeof(char16_t);
218
- int tmp = std::min(llen, rlen);
219
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
220
- tmp = wcsnicmp16((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)),
221
- tmp);
222
- else if (bin)
223
- tmp =
224
- wmemcmp16((const char16_t*)(l + sizeof(T)), (const char16_t*)(r + sizeof(T)), tmp);
225
- else
226
- tmp = wcsncmp16((char16_t*)(l + sizeof(T)), (char16_t*)(r + sizeof(T)),
227
- tmp);
228
- if (logType & CMPLOGICAL_VAR_COMP_ALL)
229
- return (tmp == 0) ? compare<int>(llen, rlen) : tmp; // match complete
230
- return (tmp == 0 && (llen < rlen)) ? -1 : tmp; // match a part
231
- }
232
-
233
- inline int compareBlobType(const char* l, const char* r, bool bin, char logType,
234
- int sizeByte)
235
- {
236
- int llen = 0;
237
- int rlen = 0;
238
- memcpy(&llen, l, sizeByte);
239
- memcpy(&rlen, r, sizeByte);
240
- int tmp = std::min(llen, rlen);
241
- const char* lptr = *((const char**)(l + sizeByte));
242
- const char* rptr = r + sizeByte;
243
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
244
- tmp = _strnicmp(lptr, rptr, tmp);
245
- else if (bin)
246
- tmp = memcmp(lptr, rptr, tmp);
247
- else
248
- tmp = strncmp(lptr, rptr, tmp);
249
-
250
- if (logType & CMPLOGICAL_VAR_COMP_ALL)
251
- return (tmp == 0) ? compare<int>(llen, rlen) : tmp;
252
- return (tmp == 0 && (llen < rlen)) ? -1 : tmp;
253
- }
254
154
 
255
155
  #define REC_MACTH 0
256
156
  #define REC_NOMACTH 1
257
157
  #define REC_NOMACTH_NOMORE 2
258
158
 
259
- //#define COMP_USE_SWITCHCASE
260
- #ifndef COMP_USE_SWITCHCASE
261
- #define COMP_USE_FUNCTION_POINTER
262
- #endif
263
-
264
159
  struct seek
265
160
  {
266
- unsigned short len;
161
+ struct
162
+ {
163
+ unsigned short len : 15;
164
+ unsigned short null : 1;
165
+ };
267
166
  unsigned char ptr[1]; // variable
268
167
  seek* next() const
269
168
  {
@@ -279,9 +178,6 @@ struct seek
279
178
  }
280
179
  };
281
180
 
282
- struct logicalField;
283
- typedef int (logicalField::*compFunc)(const char* l, const char* r,
284
- int sizeByte) const;
285
181
  struct logicalField
286
182
  {
287
183
 
@@ -304,343 +200,12 @@ public:
304
200
  }
305
201
 
306
202
  public:
307
- #ifdef COMP_USE_SWITCHCASE
308
- int comp(const char* record, int sizeByte) const
309
- {
310
- const char* r = (const char*)ptr;
311
- if (logType & CMPLOGICAL_FIELD)
312
- r = record + offset;
313
- const char* l = record + pos;
314
- switch (type)
315
- {
316
- case ft_integer:
317
- case ft_autoinc:
318
- case ft_currency:
319
- {
320
- if (logType & 8)
321
- {
322
- switch (len)
323
- {
324
- case 1:
325
- return bitMask<char>(l, r);
326
- case 2:
327
- return bitMask<short>(l, r);
328
- case 3:
329
- return bitMask24(l, r);
330
- case 4:
331
- return bitMask<int>(l, r);
332
- case 8:
333
- return bitMask<__int64>(l, r);
334
- }
335
- }else
336
- {
337
- switch (len)
338
- {
339
- case 1:
340
- return compare<char>(l, r);
341
- case 2:
342
- return compare<short>(l, r);
343
- case 3:
344
- return compareInt24(l, r);
345
- case 4:
346
- return compare<int>(l, r);
347
- case 8:
348
- return compare<__int64>(l, r);
349
- }
350
- }
351
- }
352
- case ft_mychar:
353
- case ft_string:
354
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
355
- return _strnicmp(l, r, len);
356
- return memcmp(l, r, len);
357
- case ft_zstring:
358
- case ft_note:
359
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
360
- return _strnicmp(l, r, len);
361
- return strncmp(l, r, len);
362
- case ft_logical:
363
- case ft_uinteger:
364
- case ft_autoIncUnsigned:
365
- case ft_date:
366
- case ft_time:
367
- case ft_timestamp:
368
- case ft_mydate:
369
- {
370
- if (logType & 8)
371
- {
372
- switch (len)
373
- {
374
- case 1:
375
- return bitMask<char>(l, r);
376
- case 2:
377
- return bitMask<short>(l, r);
378
- case 3:
379
- return bitMask24(l, r);
380
- case 4:
381
- return bitMask<int>(l, r);
382
- case 8:
383
- return bitMask<__int64>(l, r);
384
- }
385
- }else
386
- {
387
- switch (len)
388
- {
389
- case 1:
390
- return compare<unsigned char>(l, r);
391
- case 2:
392
- return compare<unsigned short>(l, r);
393
- case 3:
394
- return compareUint24(l, r);
395
- case 4:
396
- return compare<unsigned int>(l, r);
397
- case 8:
398
- return compare<unsigned __int64>(l, r);
399
- }
400
- }
401
- }
402
-
403
- case ft_mytime:
404
- case ft_mydatetime:
405
- case ft_mytimestamp:
406
- return memcmp(l, r, len);
407
- case ft_float:
408
- switch (len)
409
- {
410
- case 4:
411
- return compare<float>(l, r);
412
- case 8:
413
- return compare<double>(l, r);
414
- }
415
- case ft_mywchar:
416
- case ft_wstring:
417
- case ft_wzstring:
418
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
419
- return wcsnicmp16((char16_t*)l, (char16_t*)r, len/sizeof(char16_t));
420
- if ((type == ft_wstring) || (type == ft_mywchar))
421
- return memcmp(l, r, len);
422
- return wcsncmp16((char16_t*)l, (char16_t*)r, len/sizeof(char16_t));
423
- case ft_lstring:
424
- case ft_myvarchar:
425
- case ft_myvarbinary:
426
- if (sizeByte == 1)
427
- return compareVartype<unsigned char>(
428
- l, r, type == ft_myvarbinary, logType);
429
- return compareVartype<unsigned short>(l, r, type == ft_myvarbinary,
430
- logType);
431
- case ft_mywvarchar:
432
- case ft_mywvarbinary:
433
- if (sizeByte == 1)
434
- return compareWvartype<unsigned char>(
435
- l, r, type == ft_mywvarbinary, logType);
436
- return compareWvartype<unsigned short>(
437
- l, r, type == ft_mywvarbinary, logType);
438
- case ft_mytext:
439
- case ft_myblob:
440
- return compareBlobType(l, r, type == ft_myblob, logType, sizeByte);
441
- }
442
- return 0;
443
- };
444
- #else // COMP_USE_FUNCTION_POINTER
445
- template <class T>
446
- inline int compBitAnd(const char* l, const char* r, int sizeByte) const
447
- {
448
- return bitMask<T>(l, r);
449
- }
450
-
451
- inline int compBitAnd24(const char* l, const char* r, int sizeByte) const
452
- {
453
- int lv = ((*((int*)l) & 0xFFFFFF) << 8) / 0x100;
454
- int rv = ((*((int*)r) & 0xFFFFFF) << 8) / 0x100;
455
- return bitMask<int>((const char*)&lv, (const char*)&rv);
456
- }
457
-
458
- template <class T>
459
- int compNumber(const char* l, const char* r, int sizeByte) const
460
- {
461
- return compare<T>(l, r);
462
- }
463
-
464
- int compNumber24(const char* l, const char* r, int sizeByte) const
465
- {
466
- return compareInt24(l, r);
467
- }
468
-
469
- int compNumberU24(const char* l, const char* r, int sizeByte) const
470
- {
471
- return compareUint24(l, r);
472
- }
473
203
 
474
- int compMem(const char* l, const char* r, int sizeByte) const
204
+ comp1Func getCompFunc(int sizeByte) const
475
205
  {
476
- return memcmp(l, r, len);
206
+ return ::getCompFunc(type, len, logType, sizeByte);
477
207
  }
478
208
 
479
- int compString(const char* l, const char* r, int sizeByte) const
480
- {
481
- return strncmp(l, r, len);
482
- }
483
-
484
- int compiString(const char* l, const char* r, int sizeByte) const
485
- {
486
- return _strnicmp(l, r, len);
487
- }
488
-
489
- int compWString(const char* l, const char* r, int sizeByte) const
490
- {
491
- return wcsncmp16((char16_t*)l, (char16_t*)r, len);
492
- }
493
-
494
- int compiWString(const char* l, const char* r, int sizeByte) const
495
- {
496
- return wcsnicmp16((char16_t*)l, (char16_t*)r, len);
497
- }
498
-
499
- template <class T>
500
- int compVarString(const char* l, const char* r, int sizeByte) const
501
- {
502
- return compareVartype<T>(l, r, type == ft_myvarbinary, logType);
503
- }
504
-
505
- template <class T>
506
- int compWVarString(const char* l, const char* r, int sizeByte) const
507
- {
508
- return compareWvartype<T>(l, r, type == ft_mywvarbinary, logType);
509
- }
510
-
511
- int compBlob(const char* l, const char* r, int sizeByte) const
512
- {
513
- return compareBlobType(l, r, type == ft_myblob, logType, sizeByte);
514
- }
515
-
516
- compFunc getCompFunc(int sizeByte, char opr) const
517
- {
518
- switch (type)
519
- {
520
- case ft_integer:
521
- case ft_autoinc:
522
- case ft_currency:
523
- {
524
- if (opr & 8)
525
- {
526
- switch (len)
527
- {
528
- case 1:
529
- return &logicalField::compBitAnd<char>;
530
- case 2:
531
- return &logicalField::compBitAnd<short>;
532
- case 3:
533
- return &logicalField::compBitAnd24;
534
- case 4:
535
- return &logicalField::compBitAnd<int>;
536
- case 8:
537
- return &logicalField::compBitAnd<__int64>;
538
- }
539
- }else
540
- {
541
- switch (len)
542
- {
543
- case 1:
544
- return &logicalField::compNumber<char>;
545
- case 2:
546
- return &logicalField::compNumber<short>;
547
- case 3:
548
- return &logicalField::compNumber24;
549
- case 4:
550
- return &logicalField::compNumber<int>;
551
- case 8:
552
- return &logicalField::compNumber<__int64>;
553
- }
554
- }
555
- }
556
- case ft_mychar:
557
- case ft_string:
558
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
559
- return &logicalField::compiString;
560
- return &logicalField::compMem;
561
- case ft_zstring:
562
- case ft_note:
563
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
564
- return &logicalField::compiString;
565
- return &logicalField::compString;
566
- case ft_logical:
567
- case ft_uinteger:
568
- case ft_autoIncUnsigned:
569
- case ft_date:
570
- case ft_time:
571
- case ft_timestamp:
572
- case ft_mydate:
573
- {
574
- if (opr & 8)
575
- {
576
- switch (len)
577
- {
578
- case 1:
579
- return &logicalField::compBitAnd<char>;
580
- case 2:
581
- return &logicalField::compBitAnd<short>;
582
- case 3:
583
- return &logicalField::compBitAnd24;
584
- case 4:
585
- return &logicalField::compBitAnd<int>;
586
- case 8:
587
- return &logicalField::compBitAnd<__int64>;
588
- }
589
- }else
590
- {
591
- switch (len)
592
- {
593
- case 1:
594
- return &logicalField::compNumber<unsigned char>;
595
- case 2:
596
- return &logicalField::compNumber<unsigned short>;
597
- case 3:
598
- return &logicalField::compNumberU24;
599
- case 4:
600
- return &logicalField::compNumber<unsigned int>;
601
- case 8:
602
- return &logicalField::compNumber<unsigned __int64>;
603
- }
604
- }
605
- }
606
- case ft_mytime:
607
- case ft_mydatetime:
608
- case ft_mytimestamp:
609
- return &logicalField::compMem;
610
- case ft_float:
611
- switch (len)
612
- {
613
- case 4:
614
- return &logicalField::compNumber<float>;
615
- case 8:
616
- return &logicalField::compNumber<double>;
617
- }
618
- case ft_mywchar:
619
- case ft_wstring:
620
- case ft_wzstring:
621
- if (logType & CMPLOGICAL_CASEINSENSITIVE)
622
- return &logicalField::compiWString;
623
- if ((type == ft_wstring) || (type == ft_mywchar))
624
- return &logicalField::compMem;
625
- return &logicalField::compWString;
626
- case ft_lstring:
627
- case ft_myvarchar:
628
- case ft_myvarbinary:
629
- if (sizeByte == 1)
630
- return &logicalField::compVarString<unsigned char>;
631
- return &logicalField::compVarString<unsigned short>;
632
- case ft_mywvarchar:
633
- case ft_mywvarbinary:
634
- if (sizeByte == 1)
635
- return &logicalField::compWVarString<unsigned char>;
636
- return &logicalField::compWVarString<unsigned short>;
637
- case ft_mytext:
638
- case ft_myblob:
639
- return &logicalField::compBlob;
640
- }
641
- return NULL;
642
- }
643
- #endif
644
209
  extResultDef* resultDef() const
645
210
  {
646
211
  if ((opr == 0) || (opr == FILTER_COMBINE_PREPARE))
@@ -651,8 +216,8 @@ public:
651
216
 
652
217
  struct extRequest
653
218
  {
654
- int ilen : 28;
655
- int itype : 4;
219
+ unsigned int ilen : 28;
220
+ unsigned int itype : 4;
656
221
  union
657
222
  {
658
223
  unsigned short rejectCount;
@@ -688,60 +253,30 @@ struct extRequestSeeks
688
253
  #pragma pack(pop)
689
254
  pragma_pop;
690
255
 
691
- bool isMatch1(int v)
692
- {
693
- return (v == 0);
694
- }
695
- bool isMatch2(int v)
696
- {
697
- return (v > 0);
698
- }
699
- bool isMatch3(int v)
700
- {
701
- return (v < 0);
702
- }
703
- bool isMatch4(int v)
704
- {
705
- return (v != 0);
706
- }
707
- bool isMatch5(int v)
708
- {
709
- return (v >= 0);
710
- }
711
- bool isMatch6(int v)
712
- {
713
- return (v <= 0);
714
- }
715
-
716
256
  class fields;
717
257
  class fieldAdapter
718
258
  {
719
259
  const logicalField* m_fd;
720
260
  fieldAdapter* m_next;
721
- bool (*m_isMatchFunc)(int);
722
- #ifdef COMP_USE_FUNCTION_POINTER
723
- compFunc m_compFunc;
724
- #endif
261
+ judgeFunc m_isMatchFunc;
262
+ comp1Func m_compFunc;
725
263
  unsigned short m_placeHolderNum;
726
264
  unsigned char m_keySeg;
727
265
  char m_judgeType;
728
266
  char m_sizeBytes;
729
267
  char opr;
268
+ unsigned char m_nullOffset;
269
+ unsigned char m_nullbit;
270
+ unsigned char m_nullOffsetCompFd;
271
+ unsigned char m_nullbitCompFd;
730
272
  struct
731
273
  {
732
274
  mutable bool m_judge : 1;
733
275
  mutable bool m_matched : 1;
276
+ mutable bool m_mysqlnull : 1;
277
+ mutable bool m_nulllog : 1;
734
278
  };
735
- #ifdef COMP_USE_FUNCTION_POINTER
736
- void setWstringCompLen()
737
- {
738
- if ((m_compFunc == &logicalField::compiWString) ||
739
- (m_compFunc == &logicalField::compWString))
740
- const_cast<logicalField*>(m_fd)->len /= sizeof(char16_t);
741
- }
742
- #else
743
- void setWstringCompLen(){};
744
- #endif
279
+
745
280
  public:
746
281
  friend class fields;
747
282
 
@@ -753,23 +288,53 @@ public:
753
288
  m_judge = false;
754
289
  m_matched = false;
755
290
  m_placeHolderNum = 0;
291
+ m_nullOffset = 0;
292
+ m_nullbit = 0;
293
+ m_nullOffsetCompFd = 0;
294
+ m_nullbitCompFd = 0;
756
295
  }
757
296
 
758
297
  int init(const logicalField* fd, position& position, const KEY* key, bool forword)
759
298
  {
760
299
  reset();
761
300
  m_fd = fd;
301
+ m_mysqlnull = position.isMysqlNull();
762
302
  int num = position.getFieldNumByPos(fd->pos);
763
303
  if (num == -1)
764
304
  return STATUS_INVALID_FIELD_OFFSET;
305
+
306
+ if (position.isNullable(num))
307
+ {
308
+ m_nullOffset = position.nullOffset(num);
309
+ m_nullbit = position.nullbit(num);
310
+ if (fd->logType & CMPLOGICAL_FIELD)
311
+ {
312
+ int fnum = position.getFieldNumByPos(fd->offset);
313
+ m_nullOffsetCompFd = position.nullOffset(fnum);
314
+ m_nullbitCompFd = position.nullbit(fnum);
315
+ }
316
+ }
317
+
318
+ // Chnage compare type
319
+ if (fd->type == ft_mytime || fd->type == ft_mydatetime || fd->type == ft_mytimestamp)
320
+ {
321
+ bool regacy = position.isLegacyTimeFormat(num);
322
+ if (regacy)
323
+ {
324
+ if (fd->type == ft_mytime) const_cast<logicalField*>(fd)->type = ft_mytime_num_cmp;
325
+ if (fd->type == ft_mydatetime) const_cast<logicalField*>(fd)->type = ft_mydatetime_num_cmp;
326
+ if (fd->type == ft_mytimestamp) const_cast<logicalField*>(fd)->type = ft_mytimestamp_num_cmp;
327
+ }
328
+ }
329
+ // Cacheing compare isNull ?
330
+ eCompType log = (eCompType)(m_fd->logType & 0xf);
331
+ m_nulllog = ((log == eIsNull) || (log == eIsNotNull));
332
+
765
333
  m_sizeBytes = (char)position.fieldSizeByte(num);
766
334
  m_placeHolderNum = fd->opr & FILTER_COMBINE_PREPARE;// temporary marking
767
335
  if (m_placeHolderNum)
768
336
  const_cast<logicalField*>(fd)->opr &= ~FILTER_COMBINE_PREPARE;
769
- #ifdef COMP_USE_FUNCTION_POINTER
770
- m_compFunc = fd->getCompFunc(m_sizeBytes, fd->opr);
771
- setWstringCompLen();
772
- #endif
337
+ m_compFunc = fd->getCompFunc(m_sizeBytes);
773
338
  if (fd->opr == 2)
774
339
  {
775
340
  m_judgeType = 0;
@@ -810,7 +375,7 @@ public:
810
375
  {
811
376
  const_cast<logicalField*>(p)->opr = opr;
812
377
  m_fd = p;
813
- setWstringCompLen();
378
+ m_compFunc = m_fd->getCompFunc(m_sizeBytes);
814
379
  }
815
380
 
816
381
  inline int checkNomore(bool typeNext, eCompType log) const
@@ -827,18 +392,44 @@ public:
827
392
  return REC_NOMACTH;
828
393
  }
829
394
 
395
+ /* nullComp
396
+ @result 1 true
397
+ -1 false
398
+ 0 no judge
399
+
400
+ */
401
+ int nullComp(const char* record, eCompType log) const
402
+ {
403
+ if (m_nullbitCompFd)
404
+ {
405
+ // (? = NULL) return false, ? <> NULL return false, ? > NULL return false
406
+ if ((*(record - m_nullOffsetCompFd) & m_nullbitCompFd) != 0)
407
+ return -1;
408
+ }
409
+ bool rnull = m_nulllog;
410
+ bool lnull = (*(record - m_nullOffset) & m_nullbit) != 0;
411
+ return ::nullComp(lnull, rnull, log);
412
+ }
413
+
830
414
  int match(const char* record, bool typeNext) const
831
415
  {
832
- #ifdef COMP_USE_SWITCHCASE
833
- int v = m_fd->comp(record, m_sizeBytes);
834
- #else // COMP_USE_FUNCTION_POINTER
835
- const char* r = (const char*)m_fd->ptr;
836
- if (m_fd->logType & CMPLOGICAL_FIELD)
837
- r = record + m_fd->offset;
838
- const char* l = record + m_fd->pos;
839
- int v = (m_fd->*m_compFunc)(l, r, m_sizeBytes);
840
- #endif
841
- bool ret = m_isMatchFunc(v);
416
+ bool ret;
417
+ int v = 2;
418
+
419
+ if (m_mysqlnull && (m_nullbit || m_nullbitCompFd || m_nulllog))
420
+ v = nullComp(record, (eCompType)(m_fd->logType & 0xf));
421
+ if (v < 2)
422
+ ret = (v == 0) ? true : false;
423
+ else
424
+ {
425
+ const char* r = (const char*)m_fd->ptr;
426
+ const char* l = record + m_fd->pos;
427
+ if (m_fd->logType & CMPLOGICAL_FIELD)
428
+ r = record + m_fd->offset;
429
+ v = (m_compFunc)(l, r, m_fd->len);
430
+ ret = m_isMatchFunc(v);
431
+ }
432
+
842
433
  if (ret && m_judgeType)
843
434
  {
844
435
  m_matched = true;
@@ -847,8 +438,7 @@ public:
847
438
  if ((m_fd->opr != 0) && m_judge && (v == 0) && m_next->m_judgeType)
848
439
  m_next->m_judge = true;
849
440
  }
850
- bool end = (m_fd->opr == 0) || (!ret && (m_fd->opr == 1)) ||
851
- (ret && (m_fd->opr == 2));
441
+ bool end = isEndComp(m_fd->opr, ret);
852
442
  if (!end)
853
443
  return m_next->match(record, typeNext);
854
444
  return ret ? REC_MACTH
@@ -871,9 +461,11 @@ class fields
871
461
  std::vector<fieldAdapter> m_fields;
872
462
 
873
463
  public:
464
+ unsigned char nullbytes;
874
465
 
875
466
  void init(const extRequest& req, position& position, const KEY* key, bool forword)
876
467
  {
468
+ nullbytes = 0;
877
469
  if (req.logicalCount == 0)
878
470
  return ;
879
471
 
@@ -886,34 +478,8 @@ public:
886
478
  {
887
479
  fieldAdapter& fda = m_fields[i];
888
480
  fda.init(fd, position, key, forword);
889
-
890
481
  fda.m_placeHolderNum = i;
891
-
892
- eCompType log = (eCompType)(fd->logType & 0xF);
893
- switch (log)
894
- {
895
- case 1:
896
- case 8:
897
- fda.m_isMatchFunc = isMatch1;
898
- break;
899
- case 2:
900
- fda.m_isMatchFunc = isMatch2;
901
- break;
902
- case 3:
903
- fda.m_isMatchFunc = isMatch3;
904
- break;
905
- case 4:
906
- case 9:
907
- fda.m_isMatchFunc = isMatch4;
908
- break;
909
- case 5:
910
- fda.m_isMatchFunc = isMatch5;
911
- break;
912
- case 6:
913
- fda.m_isMatchFunc = isMatch6;
914
- break;
915
- }
916
-
482
+ fda.m_isMatchFunc = getJudgeFunc((eCompType)fd->logType);
917
483
  fd = fd->next();
918
484
  if (fda.m_fd->opr == 2 && (lastIndex == req.logicalCount))
919
485
  lastIndex = i; // the first 'or' index
@@ -982,7 +548,6 @@ public:
982
548
  }
983
549
  m_fields[m_fields.size() - 1].oprCache();
984
550
  }
985
-
986
551
  };
987
552
 
988
553
 
@@ -1051,6 +616,7 @@ class resultWriter
1051
616
  netsvc::server::netWriter* m_nw;
1052
617
  const extResultDef* m_def;
1053
618
  bool m_noBookmark;
619
+ unsigned char m_nullbytes;
1054
620
 
1055
621
  short doWrite(position* pos, const unsigned char* bookmark, int bmlen)
1056
622
  {
@@ -1083,13 +649,23 @@ class resultWriter
1083
649
  }
1084
650
  else
1085
651
  {
652
+ //null support
653
+ unsigned char* nullPtr = NULL;
654
+ int nullbit = 0;
655
+ if (m_nullbytes)
656
+ {
657
+ nullPtr = (unsigned char*)m_nw->curPtr();
658
+ memset(nullPtr, 0, m_nullbytes);
659
+ m_nw->asyncWrite(NULL, m_nullbytes, netsvc::server::netWriter::curSeekOnly);
660
+ recLen += m_nullbytes;
661
+ }
1086
662
  // write each fields by field num.
1087
663
  for (int i = 0; i < m_def->fieldCount; i++)
1088
664
  {
1089
665
  const resultField& fd = m_def->field[i];
1090
666
  if (m_nw->bufferSpace() > fd.len)
1091
667
  {
1092
- uint len = pos->fieldPackCopy(
668
+ uint len = pos->fieldPackCopy(nullPtr, nullbit,
1093
669
  (unsigned char*)m_nw->curPtr(), fd.fieldNum);
1094
670
  m_nw->asyncWrite(
1095
671
  NULL, len, netsvc::server::netWriter::curSeekOnly);
@@ -1112,14 +688,15 @@ class resultWriter
1112
688
  }
1113
689
 
1114
690
  public:
1115
- resultWriter() : m_nw(NULL), m_def(NULL){}
691
+ resultWriter() : m_nw(NULL), m_def(NULL), m_noBookmark(false), m_nullbytes(0){}
1116
692
 
1117
693
  void init(netsvc::server::netWriter* nw, const extResultDef* def,
1118
- bool noBookmark)
694
+ bool noBookmark, unsigned char nullbytes)
1119
695
  {
1120
696
  m_nw = nw;
1121
697
  m_def = def;
1122
698
  m_noBookmark = noBookmark;
699
+ m_nullbytes = nullbytes;
1123
700
  }
1124
701
 
1125
702
  short write(position* pos, const unsigned char* bookmark, int len)
@@ -1191,7 +768,7 @@ public:
1191
768
  tb->setBlobFieldCount(p->blobs);
1192
769
  nw->beginExt(tb->blobFields() != 0);
1193
770
  const extResultDef* rd = p->rd;
1194
- m_writer.init(nw, rd, noBookmark);
771
+ m_writer.init(nw, rd, noBookmark, m_fields->nullbytes);
1195
772
  m_maxRows = p->rd->maxRows;
1196
773
  return 0;
1197
774
  }
@@ -1237,7 +814,7 @@ public:
1237
814
  (req->itype & FILTER_TYPE_SEEKS_BOOKMARKS) != 0);
1238
815
 
1239
816
  nw->beginExt(tb->blobFields() != 0);
1240
- m_writer.init(nw, rd, noBookmark);
817
+ m_writer.init(nw, rd, noBookmark, m_fields->nullbytes);
1241
818
  m_maxRows = rd->maxRows;
1242
819
  // DEBUG_RECORDS_BEGIN(m_resultDef, m_req)
1243
820
 
@@ -1265,6 +842,8 @@ public:
1265
842
  const extResultDef* rd, bool seeksMode, bool seekBookmark)
1266
843
  {
1267
844
  int blobs = 0;
845
+ int nullfields = 0;
846
+ m_fields->nullbytes = 0;
1268
847
  bm.setTable(tb);
1269
848
  for (int i = 0; i < rd->fieldCount; i++)
1270
849
  {
@@ -1276,7 +855,11 @@ public:
1276
855
  bm.setReadBitmap(num);
1277
856
  if (m_position.isBlobField(&fd))
1278
857
  ++blobs;
858
+ if (m_position.isNullable(num))
859
+ ++nullfields;
860
+
1279
861
  }
862
+ m_fields->nullbytes = (nullfields + 7)/8;
1280
863
 
1281
864
  if (!seeksMode)
1282
865
  {