transactd 2.4.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +1 -1
  3. data/README-JA.md +52 -529
  4. data/README.md +52 -523
  5. data/bin/common/tdclc_32_3_0.dll +0 -0
  6. data/bin/common/tdclc_64_3_0.dll +0 -0
  7. data/build/common/system.cmake +2 -1
  8. data/build/common/transactd_cl_common.cmake +3 -6
  9. data/build/swig/ruby/ruby.swg +85 -28
  10. data/build/swig/ruby/tdclrb_wrap.cpp +3195 -1578
  11. data/build/swig/tdcl.i +161 -5
  12. data/build/tdclc/CMakeLists.txt +1 -0
  13. data/build/tdclc/tdclc.cbproj +7 -1
  14. data/build/tdclc/tdclc.rc +4 -4
  15. data/build/tdclcpp/tdclcpp.rc +4 -4
  16. data/build/tdclcpp/tdclcpp_bc.cbproj +2 -5
  17. data/build/tdclrb/tdclrb.rc +4 -4
  18. data/source/bzs/db/blobStructs.h +1 -1
  19. data/source/bzs/db/engine/mysql/database.cpp +199 -74
  20. data/source/bzs/db/engine/mysql/database.h +47 -18
  21. data/source/bzs/db/engine/mysql/dbManager.cpp +1 -0
  22. data/source/bzs/db/engine/mysql/mysqlInternal.h +32 -8
  23. data/source/bzs/db/protocol/tdap/btrDate.cpp +110 -75
  24. data/source/bzs/db/protocol/tdap/btrDate.h +46 -21
  25. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +18 -18
  26. data/source/bzs/db/protocol/tdap/client/activeTable.h +25 -25
  27. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +10 -4
  28. data/source/bzs/db/protocol/tdap/client/client.cpp +6 -5
  29. data/source/bzs/db/protocol/tdap/client/client.h +82 -15
  30. data/source/bzs/db/protocol/tdap/client/database.cpp +531 -142
  31. data/source/bzs/db/protocol/tdap/client/database.h +19 -6
  32. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +461 -408
  33. data/source/bzs/db/protocol/tdap/client/dbDef.h +11 -17
  34. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +61 -13
  35. data/source/bzs/db/protocol/tdap/client/field.cpp +1592 -1398
  36. data/source/bzs/db/protocol/tdap/client/field.h +110 -121
  37. data/source/bzs/db/protocol/tdap/client/fields.h +40 -10
  38. data/source/bzs/db/protocol/tdap/client/filter.h +69 -55
  39. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +296 -164
  40. data/source/bzs/db/protocol/tdap/client/groupQuery.h +77 -25
  41. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +31 -13
  42. data/source/bzs/db/protocol/tdap/client/memRecord.h +31 -21
  43. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +1 -1
  44. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -1
  45. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +69 -24
  46. data/source/bzs/db/protocol/tdap/client/nsTable.h +3 -1
  47. data/source/bzs/db/protocol/tdap/client/recordset.cpp +1 -0
  48. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +46 -27
  49. data/source/bzs/db/protocol/tdap/client/request.h +2 -1
  50. data/source/bzs/db/protocol/tdap/client/serializer.cpp +44 -9
  51. data/source/bzs/db/protocol/tdap/client/serializer.h +1 -1
  52. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +182 -76
  53. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +23 -12
  54. data/source/bzs/db/protocol/tdap/client/stringConverter.h +8 -10
  55. data/source/bzs/db/protocol/tdap/client/table.cpp +172 -93
  56. data/source/bzs/db/protocol/tdap/client/table.h +112 -37
  57. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +17 -0
  58. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +0 -1
  59. data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +0 -2
  60. data/source/bzs/db/protocol/tdap/client/trdormapi.h +1 -1
  61. data/source/bzs/db/protocol/tdap/fieldComp.h +698 -14
  62. data/source/bzs/db/protocol/tdap/myDateTime.cpp +723 -307
  63. data/source/bzs/db/protocol/tdap/myDateTime.h +294 -0
  64. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +164 -54
  65. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +6 -3
  66. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +133 -550
  67. data/source/bzs/db/protocol/tdap/mysql/request.h +6 -5
  68. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +217 -82
  69. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +1 -1
  70. data/source/bzs/db/protocol/tdap/tdapRequest.h +4 -9
  71. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +808 -17
  72. data/source/bzs/db/protocol/tdap/tdapSchema.h +656 -164
  73. data/source/bzs/db/protocol/tdap/tdapcapi.h +130 -28
  74. data/source/bzs/db/protocol/tdap/uri.h +40 -32
  75. data/source/bzs/db/transactd/connManager.cpp +1 -1
  76. data/source/bzs/db/transactd/transactd.cpp +7 -0
  77. data/source/bzs/env/compiler.h +107 -94
  78. data/source/bzs/env/crosscompile.cpp +24 -12
  79. data/source/bzs/env/crosscompile.h +75 -6
  80. data/source/bzs/env/mbcswchrLinux.cpp +2 -2
  81. data/source/bzs/env/tcharMinGW.h +4 -0
  82. data/source/bzs/example/changeSchema.cpp +22 -17
  83. data/source/bzs/example/queryData.cpp +4 -0
  84. data/source/bzs/netsvc/client/iconnection.h +3 -1
  85. data/source/bzs/netsvc/client/tcpClient.h +10 -3
  86. data/source/bzs/rtl/stringBuffers.cpp +7 -0
  87. data/source/bzs/test/tdclatl/bench_query_atl.js +6 -0
  88. data/source/bzs/test/tdclatl/bench_tdclatl.js +8 -1
  89. data/source/bzs/test/tdclatl/test_query_atl.js +22 -2
  90. data/source/bzs/test/tdclatl/test_v3.js +1017 -0
  91. data/source/bzs/test/tdclphp/transactd_Test.php +55 -21
  92. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +0 -5
  93. data/source/bzs/test/tdclphp/transactd_pool_Test.php +2 -0
  94. data/source/bzs/test/tdclphp/transactd_v3_Test.php +743 -0
  95. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +0 -5
  96. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +2 -0
  97. data/source/bzs/test/tdclrb/transactd_spec.rb +39 -16
  98. data/source/bzs/test/tdclrb/transactd_v3_spec.rb +748 -0
  99. data/source/bzs/test/transactdBench/transactdBench.cpp +55 -58
  100. data/source/bzs/test/transactdBench/transactdBench2.cpp +1 -3
  101. data/source/bzs/test/trdclengn/testField.h +3305 -0
  102. data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +1050 -0
  103. data/source/bzs/test/trdclengn/test_trdclengn.cpp +112 -190
  104. data/source/bzs/test/trdclengn/testbase.h +137 -0
  105. data/source/global/ormsrcgen/srcgen.cpp +23 -12
  106. data/source/global/ormsrcgen/template/ormDataClass_template.h +2 -0
  107. data/source/global/querystmts/querystmts.cpp +2 -3
  108. data/source/global/tdclatl/Bitset.cpp +38 -0
  109. data/source/global/tdclatl/Bitset.h +63 -0
  110. data/source/global/tdclatl/Database.cpp +59 -18
  111. data/source/global/tdclatl/Database.h +7 -4
  112. data/source/global/tdclatl/DbDef.cpp +6 -6
  113. data/source/global/tdclatl/DbDef.h +2 -1
  114. data/source/global/tdclatl/Field.cpp +112 -0
  115. data/source/global/tdclatl/Field.h +19 -5
  116. data/source/global/tdclatl/FieldDef.cpp +137 -16
  117. data/source/global/tdclatl/FieldDef.h +18 -2
  118. data/source/global/tdclatl/FieldDefs.cpp +54 -1
  119. data/source/global/tdclatl/FieldDefs.h +3 -0
  120. data/source/global/tdclatl/GroupQuery.cpp +8 -8
  121. data/source/global/tdclatl/QueryBase.cpp +65 -0
  122. data/source/global/tdclatl/QueryBase.h +10 -0
  123. data/source/global/tdclatl/Record.cpp +33 -2
  124. data/source/global/tdclatl/Record.h +3 -1
  125. data/source/global/tdclatl/RecordsetQuery.cpp +42 -0
  126. data/source/global/tdclatl/RecordsetQuery.h +8 -0
  127. data/source/global/tdclatl/Table.cpp +127 -3
  128. data/source/global/tdclatl/Table.h +10 -1
  129. data/source/global/tdclatl/TableDef.cpp +41 -8
  130. data/source/global/tdclatl/TableDef.h +7 -2
  131. data/source/global/tdclatl/activeTable.cpp +40 -71
  132. data/source/global/tdclatl/resource.h +0 -0
  133. data/source/global/tdclatl/tdclatl.idl +222 -28
  134. data/source/linux/tchar.h +100 -96
  135. data/transactd.gemspec +2 -2
  136. metadata +13 -11
  137. data/BUILD_UNIX-JA.md +0 -161
  138. data/BUILD_WIN-JA.md +0 -326
  139. data/README_ORMSRCGEN-JA.md +0 -115
  140. data/README_ORMSRCGEN.md +0 -118
  141. data/RELEASE_NOTE-JA.md +0 -356
  142. data/RELEASE_NOTE.md +0 -360
  143. data/bin/common/tdclc_32_2_4.dll +0 -0
  144. data/bin/common/tdclc_64_2_4.dll +0 -0
  145. data/source/bzs/test/trdclengn/test_blob.cpp +0 -375
@@ -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
  {