transactd 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CMakeLists.txt +37 -4
  3. data/bin/common/tdclc_32_1_2.dll +0 -0
  4. data/bin/common/tdclc_64_1_2.dll +0 -0
  5. data/build/common/transactd_cl_common.cmake +0 -1
  6. data/build/common/transactd_common.cmake +26 -6
  7. data/build/swig/php/generate.cmake.in +58 -0
  8. data/build/swig/php/generate.cmd.in +41 -0
  9. data/build/swig/php/php.swg +155 -0
  10. data/build/swig/ruby/ruby.swg +38 -0
  11. data/build/swig/tdcl.i +133 -3
  12. data/build/tdclc/CMakeLists.txt +4 -1
  13. data/build/tdclc/tdclc_32.cbproj +1 -1
  14. data/build/tdclc/tdclc_64.cbproj +1 -1
  15. data/build/tdclcpp/CMakeLists.txt +1 -1
  16. data/build/tdclcpp/tdclcpp_bcb_32.cbproj +1 -4
  17. data/build/tdclcpp/tdclcpp_bcb_64.cbproj +0 -3
  18. data/build/tdclrb/CMakeLists.txt +1 -1
  19. data/build/tdclrb/GEM_VERSION +2 -2
  20. data/source/bzs/db/engine/mysql/IReadRecords.h +1 -1
  21. data/source/bzs/db/engine/mysql/bookmark.h +3 -3
  22. data/source/bzs/db/engine/mysql/database.cpp +95 -19
  23. data/source/bzs/db/engine/mysql/database.h +6 -6
  24. data/source/bzs/db/engine/mysql/mysqlInternal.h +43 -1
  25. data/source/bzs/db/engine/mysql/mysqlThd.cpp +10 -8
  26. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +1 -1
  27. data/source/bzs/db/protocol/tdap/btrDate.h +2 -2
  28. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +15 -8
  29. data/source/bzs/db/protocol/tdap/client/dbDef.h +2 -2
  30. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +4 -0
  31. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +0 -5
  32. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +0 -4
  33. data/source/bzs/db/protocol/tdap/client/filter.cpp +0 -484
  34. data/source/bzs/db/protocol/tdap/client/filter.h +696 -84
  35. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +13 -3
  36. data/source/bzs/db/protocol/tdap/client/nsTable.h +12 -6
  37. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +2 -1
  38. data/source/bzs/db/protocol/tdap/client/stringConverter.h +1 -0
  39. data/source/bzs/db/protocol/tdap/client/table.cpp +519 -75
  40. data/source/bzs/db/protocol/tdap/client/table.h +49 -7
  41. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +145 -124
  42. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +39 -0
  43. data/source/bzs/db/protocol/tdap/client/trdormapi.h +872 -0
  44. data/source/bzs/db/protocol/tdap/myDateTime.cpp +8 -8
  45. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +7 -9
  46. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +406 -195
  47. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +64 -13
  48. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +2 -1
  49. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +35 -3
  50. data/source/bzs/db/protocol/tdap/tdapSchema.h +11 -3
  51. data/source/bzs/db/protocol/tdap/tdapcapi.h +63 -53
  52. data/source/bzs/env/crosscompile.h +8 -3
  53. data/source/bzs/example/connection_pool_c.cpp +1 -7
  54. data/source/bzs/example/useORM.cpp +585 -0
  55. data/source/bzs/rtl/exception.h +6 -0
  56. data/source/bzs/test/tdclatl/bench_tdclatl.js +12 -7
  57. data/source/bzs/test/tdclphp/transactd_Test.php +1845 -0
  58. data/source/bzs/test/tdclphp/transactd_blob_Test.php +325 -0
  59. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +183 -0
  60. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +212 -0
  61. data/source/bzs/test/tdclrb/transactd_blob_spec.rb +332 -0
  62. data/source/bzs/test/tdclrb/transactd_spec.rb +256 -1
  63. data/source/bzs/test/trdclengn/test_blob.cpp +327 -0
  64. data/source/bzs/test/trdclengn/test_trdclengn.cpp +485 -5
  65. data/source/global/tdclatl/QueryBase.cpp +231 -0
  66. data/source/global/tdclatl/QueryBase.h +96 -0
  67. data/source/global/tdclatl/Table.cpp +24 -0
  68. data/source/global/tdclatl/Table.h +2 -1
  69. data/source/global/tdclatl/resource.h +0 -0
  70. data/source/global/tdclatl/tdclatl.idl +88 -2
  71. metadata +16 -3
  72. data/bin/common/tdclc_32_1_1.dll +0 -0
  73. data/bin/common/tdclc_64_1_1.dll +0 -0
@@ -25,6 +25,9 @@
25
25
  #include <bzs/db/engine/mysql/fieldAccess.h>
26
26
  #include <boost/shared_ptr.hpp>
27
27
 
28
+ #ifndef MAX_KEY_SEGMENT
29
+ #define MAX_KEY_SEGMENT 8
30
+ #endif
28
31
  namespace bzs
29
32
  {
30
33
  namespace db
@@ -145,7 +148,7 @@ inline int compareInt24(const char* l, const char* r)
145
148
  }
146
149
 
147
150
  template <class T>
148
- int compare(const char* l, const char* r)
151
+ inline int compare(const char* l, const char* r)
149
152
  {
150
153
  if (*((T*)l) < *((T*)r))
151
154
  return -1;
@@ -155,7 +158,7 @@ int compare(const char* l, const char* r)
155
158
  }
156
159
 
157
160
  template <class T>
158
- int compare(T l, T r)
161
+ inline int compare(T l, T r)
159
162
  {
160
163
  if (l < r)
161
164
  return -1;
@@ -165,7 +168,7 @@ int compare(T l, T r)
165
168
  }
166
169
 
167
170
  template <class T>
168
- int compareVartype(const char* l, const char* r, bool bin, char logType)
171
+ inline int compareVartype(const char* l, const char* r, bool bin, char logType)
169
172
  {
170
173
  int llen = (*(T*)l);
171
174
  int rlen = (*(T*)r);
@@ -183,7 +186,7 @@ int compareVartype(const char* l, const char* r, bool bin, char logType)
183
186
  }
184
187
 
185
188
  template <class T>
186
- int compareWvartype(const char* l, const char* r, bool bin, char logType)
189
+ inline int compareWvartype(const char* l, const char* r, bool bin, char logType)
187
190
  {
188
191
  int llen = (*(T*)l) / sizeof(char16_t);
189
192
  int rlen = (*(T*)r) / sizeof(char16_t);
@@ -220,32 +223,17 @@ inline int compareBlobType(const char* l, const char* r, bool bin, char logType,
220
223
  return (tmp==0 && (llen < rlen))? -1:tmp;
221
224
  }
222
225
 
223
- #define MAX_ISINDEX_CACHE 8
224
226
  #define REC_MACTH 0
225
227
  #define REC_NOMACTH 1
226
228
  #define REC_NOMACTH_NOMORE 2
227
229
 
230
+ //#define COMP_USE_SWITCHCASE
231
+ #ifndef COMP_USE_SWITCHCASE
232
+ #define COMP_USE_FUNCTION_POINTER
233
+ #endif
228
234
 
229
-
230
-
231
- struct extRequest;
232
- class fieldInfoCache
233
- {
234
- char m_sizeBytes[1000];
235
- bool m_isIndex[MAX_ISINDEX_CACHE];
236
- mutable int m_index;
237
-
238
- public:
239
- inline fieldInfoCache();
240
- inline ~fieldInfoCache();
241
- inline short cache(extRequest& req, position& position, const KEY* key);
242
- inline int getPos()const;
243
- inline bool isIndex()const;
244
- inline void reset()const;
245
-
246
- };
247
-
248
-
235
+ struct logicalField;
236
+ typedef int (logicalField::*compFunc)(const char* l, const char* r, int sizeByte) const;
249
237
  struct logicalField
250
238
  {
251
239
 
@@ -260,13 +248,14 @@ public:
260
248
  unsigned short offset;
261
249
  unsigned char ptr[2]; //variable
262
250
  };
263
-
251
+
264
252
  logicalField* next() const
265
253
  {
266
- return (logType & 64)?(logicalField*)(ptr + 2):(logicalField*)(ptr + len/*std::max((unsigned short)2,len)*/);
254
+ return (logType & 64)?(logicalField*)(ptr + 2):(logicalField*)(ptr + len);
267
255
  }
268
256
 
269
- private:
257
+ public:
258
+ #ifdef COMP_USE_SWITCHCASE
270
259
  int comp(const char* record, int sizeByte) const
271
260
  {
272
261
  const char* r = (const char*) ptr;
@@ -300,6 +289,7 @@ private:
300
289
  return strncmp(l, r, len);
301
290
  case ft_logical:
302
291
  case ft_uinteger:
292
+ case ft_autoIncUnsigned:
303
293
  case ft_date:
304
294
  case ft_time:
305
295
  case ft_timestamp:
@@ -350,48 +340,146 @@ private:
350
340
  }
351
341
  return 0;
352
342
  };
353
- bool matchThis(const char* record, int sizeByte) const
354
- {
355
-
356
- int v = comp(record, sizeByte);
357
- switch(logType & 0xF) //16 or more are disregarded.
358
- {
359
- case 1:return (v==0); //==
360
- case 2:return (v>0); //>
361
- case 3:return (v<0); //<
362
- case 4:return (v!=0); //!=
363
- case 5:return (v>=0); //>=
364
- case 6:return (v<=0); //<=
365
- }
366
- return false;
343
+ #else //COMP_USE_FUNCTION_POINTER
344
+
345
+ template <class T>
346
+ int compNumber(const char* l, const char* r, int sizeByte) const
347
+ {
348
+ return compare<T>(l , r);
367
349
  }
368
- public:
369
- int checkNomore(bool matchResult, bool typeNext, const fieldInfoCache& sb)const
370
- {
371
- if (matchResult)
372
- return REC_MACTH;
373
- else if(sb.isIndex())
350
+
351
+ int compNumber24(const char* l, const char* r, int sizeByte) const
352
+ {
353
+ return compareInt24(l , r);
354
+ }
355
+
356
+ int compNumberU24(const char* l, const char* r, int sizeByte) const
357
+ {
358
+ return compareUint24(l , r);
359
+ }
360
+
361
+ int compMem(const char* l, const char* r, int sizeByte) const
362
+ {
363
+ return memcmp(l , r, len);
364
+ }
365
+
366
+ int compString(const char* l, const char* r, int sizeByte) const
367
+ {
368
+ return strncmp(l , r, len);
369
+ }
370
+
371
+ int compiString(const char* l, const char* r, int sizeByte) const
372
+ {
373
+ return _strnicmp(l , r, len);
374
+ }
375
+
376
+ int compWString(const char* l, const char* r, int sizeByte) const
377
+ {
378
+ return wcsncmp16((char16_t*)l , (char16_t*)r, len);
379
+ }
380
+
381
+ int compiWString(const char* l, const char* r, int sizeByte) const
382
+ {
383
+ return wcsnicmp16((char16_t*)l , (char16_t*)r, len);
384
+ }
385
+
386
+ template <class T>
387
+ int compVarString(const char* l, const char* r, int sizeByte) const
388
+ {
389
+ return compareVartype<T>(l, r, type==ft_myvarbinary, logType);
390
+ }
391
+
392
+ template <class T>
393
+ int compWVarString(const char* l, const char* r, int sizeByte) const
394
+ {
395
+ return compareWvartype<T>(l, r, type==ft_mywvarbinary, logType);
396
+ }
397
+
398
+ int compBlob(const char* l, const char* r, int sizeByte) const
399
+ {
400
+ return compareBlobType(l, r, type==ft_myblob, logType, sizeByte);
401
+ }
402
+
403
+ compFunc logicalField::getCompFunc(int sizeByte)
404
+ {
405
+ switch(type)
374
406
  {
375
- char log = logType & 0xF;
376
- if (log == 1)//==
377
- return REC_NOMACTH_NOMORE;
378
- else if (typeNext && (log == 3 || log==6))
379
- return REC_NOMACTH_NOMORE;
380
- else if (!typeNext && (log == 2 || log==5))
381
- return REC_NOMACTH_NOMORE;
407
+ case ft_integer:
408
+ case ft_autoinc:
409
+ case ft_currency:
410
+ {
411
+ switch(len)
412
+ {
413
+ case 1:return &logicalField::compNumber<char>;
414
+ case 2:return &logicalField::compNumber<short>;
415
+ case 3:return &logicalField::compNumber24;
416
+ case 4:return &logicalField::compNumber<int>;
417
+ case 8:return &logicalField::compNumber<__int64>;
418
+ }
382
419
  }
383
- return REC_NOMACTH;
384
- }
385
- int match(const char* record, bool typeNext, const fieldInfoCache& sb) const
386
- {
387
- bool ret = matchThis(record, sb.getPos());
388
- if (opr == 0) //this is last
389
- return checkNomore(ret, typeNext, sb);
390
- if (!ret)
391
- return (opr == 1)?checkNomore(ret, typeNext, sb):next()->match(record, typeNext, sb);
392
- else
393
- return (opr == 1)?next()->match(record, typeNext, sb):checkNomore(ret, typeNext, sb);
420
+ case ft_mychar:
421
+ case ft_string:
422
+ if (logType & CMPLOGICAL_CASEINSENSITIVE)
423
+ return &logicalField::compiString;
424
+ return &logicalField::compMem;
425
+ case ft_zstring:
426
+ case ft_note:
427
+ if (logType & CMPLOGICAL_CASEINSENSITIVE)
428
+ return &logicalField::compiString;
429
+ return &logicalField::compString;
430
+ case ft_logical:
431
+ case ft_uinteger:
432
+ case ft_autoIncUnsigned:
433
+ case ft_date:
434
+ case ft_time:
435
+ case ft_timestamp:
436
+ case ft_mydate:
437
+ {
438
+ switch(len)
439
+ {
440
+ case 1:return &logicalField::compNumber<unsigned char>;
441
+ case 2:return &logicalField::compNumber<unsigned short>;
442
+ case 3:return &logicalField::compNumberU24;
443
+ case 4:return &logicalField::compNumber<unsigned int>;
444
+ case 8:return &logicalField::compNumber<unsigned __int64>;
445
+ }
446
+ }
447
+ case ft_mytime:
448
+ case ft_mydatetime:
449
+ case ft_mytimestamp:
450
+ return &logicalField::compMem;
451
+ case ft_float:
452
+ switch(len)
453
+ {
454
+ case 4:return &logicalField::compNumber<float>;
455
+ case 8:return &logicalField::compNumber<double>;
456
+ }
457
+ case ft_mywchar:
458
+ case ft_wstring:
459
+ case ft_wzstring:
460
+ if (logType & CMPLOGICAL_CASEINSENSITIVE)
461
+ return &logicalField::compiWString;
462
+ if ((type==ft_wstring)||(type==ft_mywchar))
463
+ return &logicalField::compMem;
464
+ return &logicalField::compWString;
465
+ case ft_lstring:
466
+ case ft_myvarchar:
467
+ case ft_myvarbinary:
468
+ if (sizeByte==1)
469
+ return &logicalField::compVarString<unsigned char>;
470
+ return &logicalField::compVarString<unsigned short>;
471
+ case ft_mywvarchar:
472
+ case ft_mywvarbinary:
473
+ if (sizeByte==1)
474
+ return &logicalField::compWVarString<unsigned char>;
475
+ return &logicalField::compWVarString<unsigned short>;
476
+ case ft_mytext:
477
+ case ft_myblob:
478
+ return &logicalField::compBlob;
479
+ }
480
+ return NULL;
394
481
  }
482
+ #endif
395
483
  extResultDef* resultDef() const
396
484
  {
397
485
  if (opr == 0)
@@ -407,12 +495,7 @@ struct extRequest
407
495
  unsigned short rejectCount;
408
496
  unsigned short logicalCount;
409
497
  logicalField field;
410
- int match(const char* record, bool typeNext, const fieldInfoCache& sb)const
411
- {
412
- if (logicalCount)
413
- return field.match(record, typeNext, sb);
414
- return REC_MACTH;
415
- }
498
+
416
499
  extResultDef* resultDef()const
417
500
  {
418
501
  if (logicalCount)
@@ -425,6 +508,185 @@ struct extRequest
425
508
  #pragma option -a
426
509
  pragma_pop
427
510
 
511
+ bool isMatch1(int v){return (v==0);}
512
+ bool isMatch2(int v){return (v>0);}
513
+ bool isMatch3(int v){return (v<0);}
514
+ bool isMatch4(int v){return (v!=0);}
515
+ bool isMatch5(int v){return (v>=0);}
516
+ bool isMatch6(int v){return (v<=0);}
517
+
518
+ class fields;
519
+ class fieldAdapter
520
+ {
521
+ logicalField* m_fd;
522
+ fieldAdapter* m_next;
523
+ bool (*m_isMatchFunc)(int);
524
+ #ifdef COMP_USE_FUNCTION_POINTER
525
+ compFunc m_compFunc;
526
+ #endif
527
+ unsigned char m_keySeg;
528
+ mutable bool m_judge;
529
+ char m_judgeType;
530
+ char m_sizeBytes;
531
+ mutable bool m_matched;
532
+ public:
533
+ friend class fields;
534
+ fieldAdapter(): m_keySeg(0xff),m_judge(false)
535
+ ,m_judgeType(0),m_sizeBytes(0),m_matched(false){}
536
+
537
+ int init(logicalField* fd, position& position, const KEY* key, bool forword)
538
+ {
539
+ m_fd = fd;
540
+ int num = position.getFieldNumByPos(fd->pos);
541
+ if (num == -1)
542
+ return STATUS_INVALID_FIELD_OFFSET;
543
+ m_sizeBytes = (char)position.fieldSizeByte(num);
544
+ #ifdef COMP_USE_FUNCTION_POINTER
545
+ m_compFunc = fd->getCompFunc(m_sizeBytes);
546
+ #endif
547
+ if (fd->opr == 2)
548
+ {
549
+ m_judgeType = 0;
550
+ return 0;
551
+ }
552
+ int segmentIndex = 0;
553
+ int segments = std::min<uint>(MAX_KEY_SEGMENT, key->user_defined_key_parts);
554
+ while (segmentIndex < segments)
555
+ {
556
+ if (key->key_part[segmentIndex].field->field_index == num)
557
+ {
558
+ eCompType comp = (eCompType)(fd->logType);
559
+ bool gt = (comp == greater)||(comp == greaterEq);
560
+ bool le = (comp == less)||(comp == lessEq);
561
+ bool valid = !(forword ? gt:le);
562
+ if (valid)
563
+ {
564
+ m_keySeg = (unsigned char)segmentIndex+1;
565
+ m_judgeType = (comp == equal) ? 2:1;
566
+ }
567
+ break;
568
+ }
569
+ ++segmentIndex;
570
+ }
571
+ return 0;
572
+ }
573
+
574
+ inline int checkNomore(bool typeNext, eCompType log)const
575
+ {
576
+ if (m_judge)
577
+ {
578
+ if ((log == equal) && m_matched)//==
579
+ return REC_NOMACTH_NOMORE;
580
+ else if (typeNext && (log == less || log==lessEq))
581
+ return REC_NOMACTH_NOMORE;
582
+ else if (!typeNext && (log == greater || log==greaterEq))
583
+ return REC_NOMACTH_NOMORE;
584
+ }
585
+ return REC_NOMACTH;
586
+ }
587
+
588
+ int match(const char* record, bool typeNext) const
589
+ {
590
+ #ifdef COMP_USE_SWITCHCASE
591
+ int v = m_fd->comp(record, m_sizeBytes);
592
+ #else //COMP_USE_FUNCTION_POINTER
593
+ const char* r = (const char*) m_fd->ptr;
594
+ if (m_fd->logType & CMPLOGICAL_FIELD)
595
+ r = record + m_fd->offset;
596
+ const char* l = record + m_fd->pos;
597
+ int v = (m_fd->*m_compFunc)(l, r , m_sizeBytes);
598
+ #endif
599
+ bool ret = m_isMatchFunc(v);
600
+ if (ret && m_judgeType)
601
+ {
602
+ m_matched = true;
603
+ // check is this logic range of max ?
604
+ // if max then set judge node to next logic
605
+ if ((m_fd->opr != 0) && m_judge && (v == 0) && m_next->m_judgeType)
606
+ m_next->m_judge = true;
607
+ }
608
+ bool end = (m_fd->opr == 0)||(!ret && (m_fd->opr == 1))||(ret && (m_fd->opr == 2));
609
+ if (!end)return m_next->match(record, typeNext);
610
+ return ret ? REC_MACTH : checkNomore(typeNext, (eCompType)(m_fd->logType & 0xF));
611
+ }
612
+
613
+ bool operator<(const fieldAdapter& r)
614
+ {
615
+ if (m_judgeType != r.m_judgeType)
616
+ return m_judgeType > r.m_judgeType;
617
+ return m_keySeg < r.m_keySeg;
618
+ }
619
+ };
620
+
621
+ class fields
622
+ {
623
+ fieldAdapter* m_fields;
624
+
625
+ public:
626
+ fields():m_fields(NULL){};
627
+
628
+ ~fields()
629
+ {
630
+ delete [] m_fields;
631
+ }
632
+
633
+ void init(extRequest& req, position& position, const KEY* key, bool forword)
634
+ {
635
+ if (req.logicalCount==0) return ;
636
+
637
+ logicalField* fd = &req.field;
638
+ delete [] m_fields;
639
+ m_fields = new fieldAdapter[req.logicalCount];
640
+ int lastIndex = req.logicalCount;
641
+ for (int i=0;i<req.logicalCount;++i)
642
+ {
643
+ fieldAdapter& fda = m_fields[i];
644
+ fda.init(fd, position, key, forword);
645
+ eCompType log = (eCompType)(fd->logType & 0xF);
646
+ switch(log)
647
+ {
648
+ case 1:fda.m_isMatchFunc = isMatch1;break;
649
+ case 2:fda.m_isMatchFunc = isMatch2;break;
650
+ case 3:fda.m_isMatchFunc = isMatch3;break;
651
+ case 4:fda.m_isMatchFunc = isMatch4;break;
652
+ case 5:fda.m_isMatchFunc = isMatch5;break;
653
+ case 6:fda.m_isMatchFunc = isMatch6;break;
654
+ }
655
+
656
+ fd = fd->next();
657
+ if (fda.m_fd->opr == 2)
658
+ lastIndex = i;
659
+ }
660
+ fieldAdapter* begin = &m_fields[0], *cur = &m_fields[0], *end = &m_fields[lastIndex];
661
+ char tmpOpr = (lastIndex != req.logicalCount) ? end->m_fd->opr: 0;
662
+ std::sort(begin, end);
663
+ bool flag = true;
664
+ while (cur != end)
665
+ {
666
+ cur->m_fd->opr = 1;//and
667
+ if (flag && cur->m_judgeType == 2)
668
+ cur->m_judge = true;
669
+ else
670
+ flag = false;
671
+ ++cur;
672
+ }
673
+
674
+ //if first logic is first segmnet then first logic can judge.
675
+ if ((begin->m_keySeg == 1) && begin->m_judgeType)
676
+ begin->m_judge = true;
677
+
678
+ if (lastIndex == req.logicalCount) --end;
679
+ end->m_fd->opr = tmpOpr;
680
+ for (int i=0;i<req.logicalCount-1;++i)
681
+ m_fields[i].m_next = &m_fields[i+1];
682
+ }
683
+
684
+ int match(const char* record, bool typeNext) const
685
+ {
686
+ return m_fields[0].match(record, typeNext);
687
+ }
688
+ };
689
+
428
690
  class resultWriter
429
691
  {
430
692
  char* m_buf;
@@ -437,8 +699,7 @@ class resultWriter
437
699
  short writeFirst( position* pos, unsigned int bookmark)
438
700
  {
439
701
  m_rowsPos = m_resultLen;
440
-
441
- memset(m_buf + m_resultLen, 0x00, sizeof(unsigned short));
702
+ *((unsigned short*)(m_buf + m_resultLen)) = 0;
442
703
  m_resultLen += sizeof(unsigned short);
443
704
  return doWrite(pos, bookmark);
444
705
  }
@@ -448,50 +709,56 @@ class resultWriter
448
709
  // write rowCount
449
710
  unsigned short* rows = (unsigned short*) (m_buf + m_rowsPos);
450
711
  ++(*rows);
712
+
451
713
  //write recLength space;
452
714
  unsigned short recLen = 0;
453
715
  unsigned short recLenPos = m_resultLen;
454
- memcpy(m_buf + m_resultLen, (const char*)&recLen, sizeof(unsigned short));
716
+ *((unsigned short*)(m_buf + m_resultLen)) = recLen;
455
717
  m_resultLen += sizeof(unsigned short);
718
+
456
719
  //write bookmark
457
- memcpy(m_buf + m_resultLen, (const char*)&bookmark, sizeof(unsigned int));
720
+ *((unsigned int*)(m_buf + m_resultLen)) = bookmark;
458
721
  m_resultLen += sizeof(unsigned int);
459
722
 
460
- if ((m_def->fieldCount == 1) && (m_def->field[0].len >= pos->recordLenCl()))
461
- { //write whole row
462
- int len = pos->recordLenCl();
463
- if (m_maxLen + RETBUF_EXT_RESERVE_SIZE >= m_resultLen + len)
464
- {
465
- int maxlen = m_maxLen + RETBUF_EXT_RESERVE_SIZE - m_resultLen;
466
- len = pos->recordPackCopy(m_buf + m_resultLen, maxlen);
467
- if (len == 0)
723
+ //if pos ==NULL , that is not found record in a TD_KEY_SEEK_MULTI operation
724
+ // and bookmark has error code also STATUS_NOT_FOUND_TI
725
+ // in the client, fieldCount > 0 buf recLen=0 then this pattern
726
+ if (pos)
727
+ {
728
+ if ((m_def->fieldCount == 1) && (m_def->field[0].len >= pos->recordLenCl()))
729
+ { //write whole row
730
+ int len = pos->recordLenCl();
731
+ if (m_maxLen + RETBUF_EXT_RESERVE_SIZE >= m_resultLen + len)
732
+ {
733
+ int maxlen = m_maxLen + RETBUF_EXT_RESERVE_SIZE - m_resultLen;
734
+ len = pos->recordPackCopy(m_buf + m_resultLen, maxlen);
735
+ if (len == 0)
736
+ return STATUS_BUFFERTOOSMALL;
737
+ m_resultLen += len;
738
+ recLen += len;
739
+ }else
468
740
  return STATUS_BUFFERTOOSMALL;
469
- m_resultLen += len;
470
- recLen += len;
471
741
  }else
472
- return STATUS_BUFFERTOOSMALL;
473
- }else
474
- {
475
- //write each fields by field num.
476
- for (int i=0;i<m_def->fieldCount;i++)
477
742
  {
478
- resultField& fd = m_def->field[i];
479
- if (m_maxLen+RETBUF_EXT_RESERVE_SIZE>= m_resultLen + fd.len)
743
+ //write each fields by field num.
744
+ for (int i=0;i<m_def->fieldCount;i++)
480
745
  {
481
- //memcpy(m_buf + m_resultLen, pos->record() + fd.pos, fd.len);
482
- memcpy(m_buf + m_resultLen, pos->fieldPtr(&fd), fd.len);
483
- m_resultLen += fd.len;
484
- recLen += fd.len;
485
- if (pos->isBlobField(&fd))
486
- pos->addBlobBuffer(fd.fieldNum);
746
+ resultField& fd = m_def->field[i];
747
+ if (m_maxLen+RETBUF_EXT_RESERVE_SIZE>= m_resultLen + fd.len)
748
+ {
749
+ memcpy(m_buf + m_resultLen, pos->fieldPtr(&fd), fd.len);
750
+ m_resultLen += fd.len;
751
+ recLen += fd.len;
752
+ if (pos->isBlobField(&fd))
753
+ pos->addBlobBuffer(fd.fieldNum);
754
+ }
755
+ else
756
+ return STATUS_BUFFERTOOSMALL;
487
757
  }
488
- else
489
- return STATUS_BUFFERTOOSMALL;
490
758
  }
491
759
  }
492
760
  //write recLength;
493
- unsigned short* tmp = (unsigned short*) (m_buf + recLenPos);
494
- *tmp = recLen;
761
+ *((unsigned short*)(m_buf + recLenPos)) = recLen;
495
762
  return 0;
496
763
  }
497
764
  public:
@@ -516,77 +783,6 @@ public:
516
783
  const char* resultBuffer(){return m_buf;}
517
784
  };
518
785
 
519
- /* ---------------------------------------------------------------
520
- * Implement fieldInfoCache
521
- * ---------------------------------------------------------------*/
522
- inline fieldInfoCache::fieldInfoCache()
523
- {
524
- memset(m_isIndex, 0, sizeof(bool) * MAX_ISINDEX_CACHE);
525
- }
526
-
527
- inline fieldInfoCache::~fieldInfoCache()
528
- {
529
-
530
- }
531
-
532
- inline short fieldInfoCache::cache(extRequest& req, position& position, const KEY* key)
533
- {
534
-
535
- m_index = 0;
536
- logicalField* fd = &req.field;
537
- char* pos = m_sizeBytes;
538
- bool isCheckKeyseg = (key != NULL);
539
- unsigned short segmentIndex = 0;
540
- for (int i=0;i<req.logicalCount;i++)
541
- {
542
-
543
- int num = position.getFieldNumByPos(fd->pos);
544
- if (num == -1)
545
- return STATUS_INVALID_FIELD_OFFSET;
546
- *pos = (char)position.fieldSizeByte(num);
547
-
548
- /* Is target field current keynum segnmnt
549
- For optimize match() return NOMATCH_NOMORE
550
- */
551
- if (isCheckKeyseg && (i < MAX_ISINDEX_CACHE))
552
- {
553
- if (segmentIndex < key->user_defined_key_parts)
554
- {
555
- m_isIndex[i] = (key->key_part[segmentIndex].field->field_index == num);
556
- if (!m_isIndex[i] && (++segmentIndex < key->user_defined_key_parts))
557
- m_isIndex[i] = (key->key_part[segmentIndex].field->field_index == num);
558
- }
559
- isCheckKeyseg = m_isIndex[i];
560
- if (fd->opr == 2) isCheckKeyseg = false;
561
- }
562
-
563
- ++pos;
564
- fd = fd->next();
565
- }
566
- return 0;
567
- }
568
-
569
- /* get value and inc index.
570
- */
571
- inline int fieldInfoCache::getPos()const
572
- {
573
- return m_sizeBytes[m_index++];
574
- }
575
-
576
- /* It certainly calls after getPos() */
577
- inline bool fieldInfoCache::isIndex()const
578
- {
579
- return m_isIndex[m_index-1];
580
- }
581
-
582
- /* reset for next record */
583
- inline void fieldInfoCache::reset()const
584
- {
585
- m_index = 0;
586
-
587
- }
588
-
589
- /* ---------------------------------------------------------------*/
590
786
 
591
787
  class ReadRecordsHandler : public engine::mysql::IReadRecordsHandler
592
788
  {
@@ -594,20 +790,23 @@ class ReadRecordsHandler : public engine::mysql::IReadRecordsHandler
594
790
  extRequest* m_req;
595
791
  extResultDef* m_resultDef;
596
792
  position m_position;
597
- fieldInfoCache m_fieldInfoCache;
598
- public:
793
+ fields m_fields;
599
794
 
600
- short begin(engine::mysql::table* tb, extRequest* req, char* buf,size_t offset, unsigned short maxlen)
795
+ public:
796
+ short begin(engine::mysql::table* tb, extRequest* req, bool fieldCache
797
+ , char* buf,size_t offset, unsigned short maxlen, bool forword)
601
798
  {
602
799
  short ret = 0;
603
800
  m_position.setTable(tb);
604
801
  m_req = req;
605
- const KEY* key = NULL;
606
- if (tb->keyNum() >= 0)
607
- key = &tb->keyDef(tb->keyNum());
608
- m_fieldInfoCache.cache(*m_req, m_position, key);
609
-
610
802
  m_resultDef = m_req->resultDef();
803
+ if (fieldCache)
804
+ {
805
+ const KEY* key = NULL;
806
+ if (tb->keyNum() >= 0)
807
+ key = &tb->keyDef(tb->keyNum());
808
+ m_fields.init(*m_req, m_position, key, forword);
809
+ }
611
810
  if (m_resultDef->fieldCount > 1)
612
811
  ret = convResultPosToFieldNum();
613
812
 
@@ -647,25 +846,37 @@ public:
647
846
 
648
847
  int match(bool typeNext)const
649
848
  {
650
- m_fieldInfoCache.reset();
651
- return m_req->match(m_position.record(), typeNext, m_fieldInfoCache);
849
+ if (m_req->logicalCount)
850
+ return m_fields.match(m_position.record(), typeNext);
851
+ return REC_MACTH;
652
852
  }
653
853
 
654
- short write(const unsigned char* bmPtr, unsigned int bmlen)
854
+ short write(const unsigned char* bmPtr, unsigned int bmlen, short stat=0)
655
855
  {
656
856
  unsigned int bookmark = 0;
657
- switch(bmlen)
857
+ //if bmPtr ==NULL , that is not found record in a TD_KEY_SEEK_MULTI operation
858
+ // and set error code to bookmark also STATUS_NOT_FOUND_TI
859
+ if (bmPtr == NULL)
860
+ {
861
+ bookmark = stat;
862
+ return m_writer->write(NULL, bookmark);
863
+ }
864
+ else
658
865
  {
659
- case 4:
660
- bookmark = *((unsigned int*)bmPtr);break;
661
- case 2:
662
- bookmark = *((unsigned short*)bmPtr);break;
663
- case 3:
664
- bookmark = *((unsigned int*)bmPtr) & 0x0FFFFFF;break;
665
- case 1:
666
- bookmark = *((unsigned short*)bmPtr) & 0x0FF;break;
866
+ switch(bmlen)
867
+ {
868
+ case 4:
869
+ bookmark = *((unsigned int*)bmPtr);break;
870
+ case 2:
871
+ bookmark = *((unsigned short*)bmPtr);break;
872
+ case 3:
873
+ bookmark = *((unsigned int*)bmPtr) & 0x0FFFFFF;break;
874
+ case 1:
875
+ bookmark = *((unsigned short*)bmPtr) & 0x0FF;break;
876
+ }
877
+ return m_writer->write(&m_position, bookmark);
667
878
  }
668
- return m_writer->write(&m_position, bookmark);
879
+
669
880
  }
670
881
  unsigned short rejectCount(){return m_req->rejectCount;};
671
882
  unsigned short maxRows(){return m_resultDef->maxRows;};