transactd 2.2.0 → 2.3.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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/BUILD_UNIX-JA +6 -6
  3. data/README +20 -18
  4. data/README-JA +19 -17
  5. data/RELEASE_NOTE +144 -0
  6. data/RELEASE_NOTE-JA +153 -0
  7. data/bin/common/tdclc_32_2_3.dll +0 -0
  8. data/bin/common/tdclc_64_2_3.dll +0 -0
  9. data/build/common/get_ruby_path.cmake +1 -1
  10. data/build/swig/ruby/ruby.swg +10 -9
  11. data/build/swig/ruby/tdclrb_wrap.cpp +1416 -561
  12. data/build/swig/tdcl.i +30 -3
  13. data/build/tdclc/tdclc.cbproj +1 -1
  14. data/build/tdclc/tdclc.rc +4 -4
  15. data/build/tdclcpp/BUILDNUMBER.txt +1 -0
  16. data/build/tdclcpp/tdclcpp.rc +4 -4
  17. data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
  18. data/build/tdclrb/BUILDNUMBER.txt +1 -0
  19. data/build/tdclrb/tdclrb.rc +4 -4
  20. data/source/bzs/db/engine/mysql/database.cpp +85 -41
  21. data/source/bzs/db/engine/mysql/database.h +35 -5
  22. data/source/bzs/db/engine/mysql/mysqlInternal.h +189 -37
  23. data/source/bzs/db/engine/mysql/mysqlThd.cpp +21 -21
  24. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +11 -0
  25. data/source/bzs/db/protocol/tdap/client/activeTable.h +1 -1
  26. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +11 -4
  27. data/source/bzs/db/protocol/tdap/client/client.h +30 -1
  28. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +2 -1
  29. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +35 -5
  30. data/source/bzs/db/protocol/tdap/client/field.cpp +100 -51
  31. data/source/bzs/db/protocol/tdap/client/field.h +7 -7
  32. data/source/bzs/db/protocol/tdap/client/filter.h +20 -6
  33. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +337 -58
  34. data/source/bzs/db/protocol/tdap/client/groupQuery.h +56 -13
  35. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +83 -5
  36. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -1
  37. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +2 -2
  38. data/source/bzs/db/protocol/tdap/client/nsTable.h +2 -1
  39. data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +20 -6
  40. data/source/bzs/db/protocol/tdap/client/recordset.cpp +7 -0
  41. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +8 -4
  42. data/source/bzs/db/protocol/tdap/client/request.h +11 -1
  43. data/source/bzs/db/protocol/tdap/client/serializer.cpp +40 -2
  44. data/source/bzs/db/protocol/tdap/client/serializer.h +4 -2
  45. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +1 -0
  46. data/source/bzs/db/protocol/tdap/client/stringConverter.h +4 -4
  47. data/source/bzs/db/protocol/tdap/client/table.cpp +124 -71
  48. data/source/bzs/db/protocol/tdap/client/table.h +8 -7
  49. data/source/bzs/db/protocol/tdap/client/trdormapi.h +33 -1
  50. data/source/bzs/db/protocol/tdap/fieldComp.h +1 -1
  51. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +3 -1
  52. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +20 -4
  53. data/source/bzs/db/protocol/tdap/mysql/request.h +14 -0
  54. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +132 -69
  55. data/source/bzs/db/protocol/tdap/tdapRequest.h +18 -4
  56. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +32 -22
  57. data/source/bzs/db/protocol/tdap/tdapSchema.h +69 -4
  58. data/source/bzs/db/protocol/tdap/tdapcapi.h +13 -5
  59. data/source/bzs/db/protocol/tdap/uri.h +4 -4
  60. data/source/bzs/db/transactd/transactd.cpp +6 -5
  61. data/source/bzs/env/crosscompile.cpp +17 -0
  62. data/source/bzs/env/crosscompile.h +4 -1
  63. data/source/bzs/env/mbcswchrLinux.cpp +3 -0
  64. data/source/bzs/example/deleteRecords.cpp +13 -0
  65. data/source/bzs/example/deleteRecords_c.cpp +8 -1
  66. data/source/bzs/example/insertRecords.cpp +14 -0
  67. data/source/bzs/example/insertRecords_c.cpp +8 -1
  68. data/source/bzs/example/ormap_c.cpp +8 -1
  69. data/source/bzs/example/queryData.cpp +92 -2
  70. data/source/bzs/example/queryData.h +3 -1
  71. data/source/bzs/example/readRecords.cpp +13 -0
  72. data/source/bzs/example/readRecords_c.cpp +8 -1
  73. data/source/bzs/example/updateRecords.cpp +13 -0
  74. data/source/bzs/example/updateRecords_c.cpp +8 -1
  75. data/source/bzs/example/update_with_transaction.cpp +13 -0
  76. data/source/bzs/example/update_with_transaction_c.cpp +8 -1
  77. data/source/bzs/example/useORMRecord.cpp +9 -3
  78. data/source/bzs/netsvc/client/iconnection.h +8 -0
  79. data/source/bzs/netsvc/client/tcpClient.cpp +61 -16
  80. data/source/bzs/netsvc/client/tcpClient.h +430 -214
  81. data/source/bzs/netsvc/server/serverPipe.cpp +2 -2
  82. data/source/bzs/test/tdclphp/transactd_Test.php +115 -19
  83. data/source/bzs/test/tdclphp/transactd_blob_Test.php +33 -5
  84. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +21 -3
  85. data/source/bzs/test/tdclphp/transactd_pool_Test.php +17 -3
  86. data/source/bzs/test/tdclrb/transactd_blob_spec.rb +26 -8
  87. data/source/bzs/test/tdclrb/transactd_kanjischema_spec.rb +13 -6
  88. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +14 -8
  89. data/source/bzs/test/tdclrb/transactd_spec.rb +117 -27
  90. data/source/bzs/test/transactdBench/scaling_bench.cpp +5 -5
  91. data/source/bzs/test/transactdBench/workerBase.h +2 -2
  92. data/source/bzs/test/trdclengn/test_trdclengn.cpp +898 -51
  93. data/source/global/tdclatl/Database.cpp +12 -0
  94. data/source/global/tdclatl/Database.h +4 -0
  95. data/source/global/tdclatl/FieldDef.cpp +19 -0
  96. data/source/global/tdclatl/FieldDef.h +4 -0
  97. data/source/global/tdclatl/FieldDefs.cpp +14 -16
  98. data/source/global/tdclatl/GroupQuery.cpp +21 -16
  99. data/source/global/tdclatl/GroupQuery.h +1 -1
  100. data/source/global/tdclatl/QueryBase.cpp +14 -0
  101. data/source/global/tdclatl/QueryBase.h +2 -0
  102. data/source/global/tdclatl/Record.cpp +41 -10
  103. data/source/global/tdclatl/Record.h +1 -1
  104. data/source/global/tdclatl/Recordset.cpp +117 -31
  105. data/source/global/tdclatl/Recordset.h +6 -5
  106. data/source/global/tdclatl/Table.cpp +24 -28
  107. data/source/global/tdclatl/Table.h +3 -4
  108. data/source/global/tdclatl/activeTable.cpp +149 -103
  109. data/source/global/tdclatl/activeTable.h +1 -1
  110. data/source/global/tdclatl/tdclatl.idl +38 -18
  111. data/transactd.gemspec +1 -1
  112. metadata +8 -4
  113. data/bin/common/tdclc_32_2_2.dll +0 -0
  114. data/bin/common/tdclc_64_2_2.dll +0 -0
data/build/swig/tdcl.i CHANGED
@@ -412,18 +412,17 @@ using namespace bzs::db::protocol::tdap::client;
412
412
  %ignore bzs::db::protocol::tdap::client::count::create;
413
413
  %ignore bzs::db::protocol::tdap::client::fieldNames::operator=;
414
414
  %ignore bzs::db::protocol::tdap::client::fieldNames::create;
415
+ %ignore bzs::db::protocol::tdap::client::first::create;
415
416
  %ignore bzs::db::protocol::tdap::client::groupFuncBase::operator=;
416
417
  %ignore bzs::db::protocol::tdap::client::groupFuncBase::operator();
417
418
  %ignore bzs::db::protocol::tdap::client::groupQuery::operator=;
418
419
  %ignore bzs::db::protocol::tdap::client::groupQuery::create;
420
+ %ignore bzs::db::protocol::tdap::client::last::create;
419
421
  %ignore bzs::db::protocol::tdap::client::max::create;
420
422
  %ignore bzs::db::protocol::tdap::client::min::create;
421
423
  %ignore bzs::db::protocol::tdap::client::recordsetQuery::operator=;
422
424
  %ignore bzs::db::protocol::tdap::client::recordsetQuery::create;
423
425
  %ignore bzs::db::protocol::tdap::client::recordsetQuery::internalQuery;
424
- %ignore bzs::db::protocol::tdap::client::sortField;
425
- %ignore bzs::db::protocol::tdap::client::sortFields;
426
- %ignore bzs::db::protocol::tdap::client::sortFields::operator[];
427
426
  %ignore bzs::db::protocol::tdap::client::sum::create;
428
427
  // create and release methods for fieldNames class
429
428
  %extend bzs::db::protocol::tdap::client::fieldNames {
@@ -481,10 +480,38 @@ using namespace bzs::db::protocol::tdap::client;
481
480
  ~count() {
482
481
  self->release();
483
482
  }
483
+ };
484
+ // create and release methods for first class
485
+ %extend bzs::db::protocol::tdap::client::first {
486
+ first(const fieldNames& targetNames, const _TCHAR* resultName = NULL) {
487
+ return bzs::db::protocol::tdap::client::first::create(targetNames, resultName);
488
+ }
489
+ ~first() {
490
+ self->release();
491
+ }
484
492
  };
493
+ // ignore original methods
494
+ %ignore bzs::db::protocol::tdap::client::first::first;
495
+ %ignore bzs::db::protocol::tdap::client::first::~first;
496
+
485
497
  // ignore original methods
486
498
  %ignore bzs::db::protocol::tdap::client::count::count;
487
499
  %ignore bzs::db::protocol::tdap::client::count::~count;
500
+
501
+ // create and release methods for last class
502
+ %extend bzs::db::protocol::tdap::client::last {
503
+ last(const fieldNames& targetNames, const _TCHAR* resultName = NULL) {
504
+ return bzs::db::protocol::tdap::client::last::create(targetNames, resultName);
505
+ }
506
+ ~last() {
507
+ self->release();
508
+ }
509
+ };
510
+
511
+ // ignore original methods
512
+ %ignore bzs::db::protocol::tdap::client::last::last;
513
+ %ignore bzs::db::protocol::tdap::client::last::~last;
514
+
488
515
  // create and release methods for max class
489
516
  %extend bzs::db::protocol::tdap::client::max {
490
517
  max(const fieldNames& targetNames, const _TCHAR* resultName = NULL) {
@@ -62,7 +62,7 @@
62
62
  <VerInfo_Locale>1041</VerInfo_Locale>
63
63
  <BRCC_CompilerToUse>rc</BRCC_CompilerToUse>
64
64
  <BRCC_IncludePath>$(BDSINCLUDE)\windows\sdk;$(BRCC_IncludePath)</BRCC_IncludePath>
65
- <DllSuffix>_2_2</DllSuffix>
65
+ <DllSuffix>_2_3</DllSuffix>
66
66
  <DynamicRTL>false</DynamicRTL>
67
67
  <BPILibOutputDir>..\..\lib</BPILibOutputDir>
68
68
  <BCC_PCHUsage>None</BCC_PCHUsage>
data/build/tdclc/tdclc.rc CHANGED
@@ -29,8 +29,8 @@
29
29
  //
30
30
 
31
31
  VS_VERSION_INFO VERSIONINFO
32
- FILEVERSION 2,2,0,10
33
- PRODUCTVERSION 2,2,0,10
32
+ FILEVERSION 2,3,0,11
33
+ PRODUCTVERSION 2,3,0,11
34
34
  FILEFLAGSMASK 0x3fL
35
35
  #ifdef _DEBUG
36
36
  FILEFLAGS 0x1L
@@ -47,9 +47,9 @@ BEGIN
47
47
  BEGIN
48
48
  VALUE "CompanyName", "BizStation Corp."
49
49
  VALUE "FileDescription", "Transactd C client"
50
- VALUE "FileVersion", "2.2.0.10"
50
+ VALUE "FileVersion", "2.3.0.11"
51
51
  VALUE "LegalCopyright", "Copyright(C) 2014 BizStation Corp"
52
- VALUE "ProductVersion", "2.2.0.10"
52
+ VALUE "ProductVersion", "2.3.0.11"
53
53
  VALUE "ProductName", "Transactd Client (GPL V2)"
54
54
  END
55
55
  END
@@ -0,0 +1 @@
1
+ 10
@@ -29,8 +29,8 @@
29
29
  //
30
30
 
31
31
  VS_VERSION_INFO VERSIONINFO
32
- FILEVERSION 2,2,0,10
33
- PRODUCTVERSION 2,2,0,10
32
+ FILEVERSION 2,3,0,11
33
+ PRODUCTVERSION 2,3,0,11
34
34
  FILEFLAGSMASK 0x3fL
35
35
  #ifdef _DEBUG
36
36
  FILEFLAGS 0x1L
@@ -47,9 +47,9 @@ BEGIN
47
47
  BEGIN
48
48
  VALUE "CompanyName", "BizStation Corp."
49
49
  VALUE "FileDescription", "Transactd C++ client"
50
- VALUE "FileVersion", "2.2.0.10"
50
+ VALUE "FileVersion", "2.3.0.11"
51
51
  VALUE "LegalCopyright", "Copyright(C) 2014 BizStation Corp"
52
- VALUE "ProductVersion", "2.2.0.10"
52
+ VALUE "ProductVersion", "2.3.0.11"
53
53
  VALUE "ProductName", "Transactd Client (GPL V2)"
54
54
  END
55
55
  END
@@ -152,7 +152,7 @@
152
152
  <BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
153
153
  <BCC_ExtendedErrorInfo>true</BCC_ExtendedErrorInfo>
154
154
  <TD_VER_MAJOR>2</TD_VER_MAJOR>
155
- <TD_VER_MINOR>2</TD_VER_MINOR>
155
+ <TD_VER_MINOR>3</TD_VER_MINOR>
156
156
  <DllSuffix>$(TD_VER_MAJOR)_$(TD_VER_MINOR)</DllSuffix>
157
157
  <TD_CPU>32</TD_CPU>
158
158
  </PropertyGroup>
@@ -0,0 +1 @@
1
+ 10
@@ -29,8 +29,8 @@
29
29
  //
30
30
 
31
31
  VS_VERSION_INFO VERSIONINFO
32
- FILEVERSION 2,2,0,10
33
- PRODUCTVERSION 2,2,0,10
32
+ FILEVERSION 2,3,0,11
33
+ PRODUCTVERSION 2,3,0,11
34
34
  FILEFLAGSMASK 0x3fL
35
35
  #ifdef _DEBUG
36
36
  FILEFLAGS 0x1L
@@ -47,9 +47,9 @@ BEGIN
47
47
  BEGIN
48
48
  VALUE "CompanyName", "BizStation Corp."
49
49
  VALUE "FileDescription", "Transactd Ruby client"
50
- VALUE "FileVersion", "2.2.0.10"
50
+ VALUE "FileVersion", "2.3.0.11"
51
51
  VALUE "LegalCopyright", "Copyright(C) 2014 BizStation Corp"
52
- VALUE "ProductVersion", "2.2.0.10"
52
+ VALUE "ProductVersion", "2.3.0.11"
53
53
  VALUE "ProductName", "Transactd Client (GPL V2)"
54
54
  END
55
55
  END
@@ -53,6 +53,7 @@ using namespace std;
53
53
  #error "MODE_READ_EXCLUSIVE != TD_OPEN_READONLY_EXCLUSIVE"
54
54
  #endif
55
55
 
56
+
56
57
  unsigned int hash(const char* s, size_t len)
57
58
  {
58
59
  unsigned int h = 0;
@@ -189,7 +190,7 @@ database::database(const char* name, short cid)
189
190
  m_inTransaction(0), m_inSnapshot(0), m_stat(0), m_usingExclusive(false),
190
191
  m_inAutoTransaction(NULL), m_trnType(0), m_cid(cid), m_privilege(0xFFFF)
191
192
  {
192
- m_thd->security_ctx->skip_grants();
193
+ cp_security_ctx(m_thd)->skip_grants();
193
194
  }
194
195
 
195
196
  #ifdef _MSC_VER
@@ -199,7 +200,7 @@ database::database(const char* name, short cid)
199
200
  database::~database()
200
201
  {
201
202
  use();
202
- unUseTables(false);
203
+ unUseTables(true/*rollback*/);
203
204
  closeForReopen();
204
205
  m_tables.clear(); // It clears ahead of the destructor of m_trn.
205
206
  deleteThdForThread(m_thd);
@@ -260,8 +261,8 @@ unsigned char* database::getUserSha1Passwd(const char* host, const char* user,
260
261
  // true ok false fail
261
262
  bool database::setGrant(const char* host, const char* user)
262
263
  {
263
- bool ret = (acl_getroot(m_thd->security_ctx, my_strdup(user, MYF(0)),
264
- my_strdup(host, MYF(0)), my_strdup(host, MYF(0)), (char*)m_dbname.c_str())) == false;
264
+ bool ret = (acl_getroot(cp_security_ctx(m_thd), cp_strdup(user, MYF(0)),
265
+ cp_strdup(host, MYF(0)), cp_strdup(host, MYF(0)), (char*)m_dbname.c_str())) == false;
265
266
  if (ret)
266
267
  check_access(m_thd, SELECT_ACL, m_dbname.c_str(), &m_privilege, NULL, false, true);
267
268
 
@@ -304,7 +305,7 @@ void database::use() const
304
305
 
305
306
  void database::prebuildIsoratinMode()
306
307
  {
307
- cp_thd_set_read_only(m_thd);
308
+ cp_thd_set_read_only(m_thd, m_inSnapshot != 0);
308
309
  if (m_inTransaction)
309
310
  {
310
311
  m_thd->tx_isolation = m_iso;
@@ -364,7 +365,7 @@ void database::prebuildLocktype(table* tb, enum_sql_command& cmd, rowLockMode* l
364
365
  m_thd->lex->sql_command = cmd;
365
366
 
366
367
  if ((lock_type >= TL_WRITE) &&
367
- (tb->isReadOnly() || cp_thd_get_read_only(m_thd)))
368
+ (tb->isReadOnly() || cp_thd_get_global_read_only(m_thd)))
368
369
  THROW_BZS_ERROR_WITH_CODEMSG(STATUS_ACCESS_DENIED, "Access denined.");
369
370
 
370
371
  if ((lock_type >= TL_WRITE) &&
@@ -383,11 +384,28 @@ void database::changeIntentionLock(table* tb, thr_lock_type lock_type)
383
384
  tb->m_table->file->ha_external_lock(m_thd, F_UNLCK);
384
385
  if (lock_type == TL_READ)
385
386
  tb->m_table->file->init_table_handle_for_HANDLER();//prebuilt->select_lock_type = LOCK_NONE;
386
-
387
+ m_thd->in_lock_tables = 1;
387
388
  tb->m_table->file->ha_external_lock(m_thd,
388
389
  (lock_type == TL_WRITE) ? F_WRLCK : F_RDLCK);
390
+
391
+ if (m_iso == ISO_READ_COMMITTED)
392
+ {
393
+ if (lock_type == TL_READ)
394
+ {
395
+ THR_LOCK_DATA* to[2] = {NULL};
396
+ tb->m_table->file->store_lock(m_thd, to, lock_type);
397
+ }
398
+ }
399
+ // For call build_tmplate()
400
+ tb->m_table->file->ha_index_or_rnd_end();
401
+ if (tb->keyNum() >= 0)
402
+ tb->m_table->file->ha_index_init(tb->keyNum(), true);
403
+ else
404
+ tb->m_table->file->ha_rnd_init(true);
405
+
389
406
  m_thd->variables.option_bits &= ~(OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
390
407
  tb->m_validCursor = false;
408
+ m_thd->in_lock_tables = 0;
391
409
  }
392
410
  }
393
411
 
@@ -446,7 +464,7 @@ table* database::useTable(int index, enum_sql_command cmd, rowLockMode* lck)
446
464
 
447
465
  // Change to shared lock is user tranasction only.
448
466
  if (lck && lck->read && lck->lock && !m_inTransaction)
449
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_LOCKTYPE,
467
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_LOCKTYPE,
450
468
  "Invalid lock type.");
451
469
 
452
470
  // in-transaction or in-snapshort or exclusive or inAutoTransaction(lock delay)
@@ -456,7 +474,7 @@ table* database::useTable(int index, enum_sql_command cmd, rowLockMode* lck)
456
474
  if (tb->m_table == NULL)
457
475
  THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED,
458
476
  "Invalid table id.");
459
- if (m_inTransaction && (m_iso >= ISO_REPEATABLE_READ))
477
+ if (m_inTransaction && (m_iso >= ISO_READ_COMMITTED))
460
478
  changeIntentionLock(tb, (lck && lck->lock && lck->read) ? TL_READ : TL_WRITE);
461
479
 
462
480
  if (tb->isExclusveMode())
@@ -570,16 +588,13 @@ void database::unUseTables(bool rollback)
570
588
  }else
571
589
  ret = unlockTables(needUnlock, m_thd, rollback, NULL);
572
590
 
573
- if (ret)
591
+ for (int i = 0; i < (int)m_tables.size(); i++)
574
592
  {
575
- for (int i = 0; i < (int)m_tables.size(); i++)
576
- {
577
- if (m_tables[i])
578
- m_tables[i]->resetTransctionInfo(m_thd);
579
- }
580
- DEBUG_WRITELOG("UNLOCK TABLES \n")
593
+ if (m_tables[i])
594
+ m_tables[i]->resetTransctionInfo(m_thd);
581
595
  }
582
- else
596
+
597
+ if (!ret)
583
598
  {
584
599
  if (m_thd->is_error())
585
600
  {
@@ -590,6 +605,10 @@ void database::unUseTables(bool rollback)
590
605
  m_stat = m_thd->cp_get_sql_error();
591
606
  THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "Transaction commit error.");
592
607
  }
608
+ }else
609
+ {
610
+ ;
611
+ DEBUG_WRITELOG("UNLOCK TABLES \n")
593
612
  }
594
613
  }
595
614
 
@@ -612,6 +631,14 @@ bool database::beginTrn(short type, enum_tx_isolation iso)
612
631
  ret = true;
613
632
  }
614
633
  ++m_inTransaction;
634
+ if (m_thd->variables.sql_log_bin && (m_inTransaction==1))
635
+ {
636
+ for (int i = 0; i < (int)m_tables.size(); ++i)
637
+ {
638
+ if (m_tables[i])
639
+ useTable(i, SQLCOM_SELECT, NULL);
640
+ }
641
+ }
615
642
  return ret;
616
643
  }
617
644
 
@@ -674,24 +701,27 @@ TABLE* database::doOpenTable(const std::string& name, short mode,
674
701
  TABLE_LIST tables;
675
702
  m_thd->variables.lock_wait_timeout = OPEN_TABLE_TIMEOUT_SEC;
676
703
  tables.init_one_table(m_dbname.c_str(), m_dbname.size(), name.c_str(),
677
- name.size(), name.c_str(), TL_READ);
704
+ name.size(), name.c_str(), TL_READ);
678
705
  if(!(m_privilege & SELECT_ACL) &&
679
706
  (check_grant(m_thd, SELECT_ACL, &tables, FALSE, 1, true)))
680
707
  {
681
708
  m_stat = STATUS_ACCESS_DENIED;
682
709
  return NULL;
683
710
  }
684
- tables.mdl_request.set_type(MDL_SHARED_READ);
711
+ cp_set_mdl_request_types(tables, mode);
685
712
 
686
- Open_table_context ot_act(m_thd, MYSQL_OPEN_GET_NEW_TABLE);
713
+ Open_table_context ot_act(m_thd, OPEN_TABLE_FLAG_TYPE);
687
714
  m_thd->cp_set_overwrite_status(true);
688
- if (cp_open_table(m_thd, &tables, &ot_act))
715
+ if (cp_open_table(m_thd, &tables, &ot_act))
689
716
  {
690
717
  m_stat = STATUS_TABLE_NOTOPEN;
691
718
  if (ER_LOCK_WAIT_TIMEOUT == m_thd->cp_get_sql_error())
692
719
  m_stat = STATUS_CANNOT_LOCK_TABLE;
720
+ else
721
+ cp_open_error_release(m_thd, tables);
693
722
  return NULL;
694
723
  }
724
+ cp_set_transaction_duration_for_all_locks(m_thd);
695
725
 
696
726
  // Check owner name
697
727
  if (ownerName && ownerName[0])
@@ -724,6 +754,11 @@ TABLE* database::doOpenTable(const std::string& name, short mode,
724
754
  table* database::openTable(const std::string& name, short mode,
725
755
  const char* ownerName)
726
756
  {
757
+ if (m_thd->variables.sql_log_bin && m_inTransaction)
758
+ {
759
+ m_stat = STATUS_ALREADY_INTRANSACTION;
760
+ return NULL;
761
+ }
727
762
  TABLE* t = doOpenTable(name, mode, ownerName);
728
763
  if (t)
729
764
  {
@@ -811,13 +846,11 @@ void database::closeForReopen()
811
846
  if (m_tables[i] && (m_tables[i]->m_table != NULL))
812
847
  m_tables[i]->resetInternalTable(NULL);
813
848
  }
814
-
815
849
  trans_commit_stmt(m_thd);
816
850
  if (m_thd->mdl_context.has_locks())
817
851
  close_thread_tables(m_thd);
818
852
  m_thd->mdl_context.release_transactional_locks();
819
853
  m_usingExclusive = 0;
820
- // It is certainly after close_thread_tables.
821
854
  }
822
855
 
823
856
  void database::reopen()
@@ -879,6 +912,7 @@ table::table(TABLE* myTable, database& db, const std::string& name, short mode,
879
912
  m_keybuf(new unsigned char[MAX_KEYLEN]),
880
913
  m_nonNccKeybuf(new unsigned char[MAX_KEYLEN]), m_stat(0),
881
914
  m_keyconv(m_table->key_info, m_table->s->keys), m_blobBuffer(NULL),
915
+ m_readCount(0), m_updCount(0), m_delCount(0), m_insCount(0),
882
916
  m_keyNum(-1), m_nonNcc(false), m_validCursor(true), m_cursor(false),
883
917
  m_locked(false), m_changed(false), m_nounlock(false), m_bulkInserting(false),
884
918
  m_delayAutoCommit(false),m_forceConsistentRead(false)
@@ -953,6 +987,7 @@ void table::resetTransctionInfo(THD* thd)
953
987
  m_locked = false;
954
988
  m_validCursor = false;
955
989
  m_nounlock = false;
990
+ m_readCount = m_updCount = m_delCount = m_insCount = 0;
956
991
  }
957
992
 
958
993
  void table::resetInternalTable(TABLE* table)
@@ -1399,11 +1434,6 @@ ushort table::fieldPackCopy(unsigned char* dest, short fieldNum)
1399
1434
  return (ushort)len;
1400
1435
  }
1401
1436
 
1402
- inline bool table::keynumCheck(char num)
1403
- {
1404
- return ((num >= 0) && (num < (short)m_table->s->keys));
1405
- }
1406
-
1407
1437
  inline void table::tryConsistentRead(bool noConsistent)
1408
1438
  {
1409
1439
  /* Don't read old version that next operation is write, or inTransaqction. */
@@ -1903,7 +1933,6 @@ void table::readRecords(IReadRecordsHandler* hdr, bool includeCurrent, int type,
1903
1933
  // private
1904
1934
  void table::seekPos(const uchar* rawPos)
1905
1935
  {
1906
-
1907
1936
  seekKey(HA_READ_KEY_OR_NEXT, keymap());
1908
1937
  if (m_keyNum == (int)m_table->s->primary_key)
1909
1938
  return;
@@ -1926,9 +1955,7 @@ void table::movePos(const uchar* pos, char keyNum, bool sureRawValue)
1926
1955
  setNonKey();
1927
1956
  unlockRow(m_delayAutoCommit);
1928
1957
  m_stat = m_table->file->ha_rnd_pos(m_table->record[0], (uchar*)rawPos);
1929
- m_cursor = (m_stat == 0) ? true :
1930
- ((m_stat == HA_ERR_LOCK_WAIT_TIMEOUT) ||
1931
- (m_stat == HA_ERR_LOCK_DEADLOCK)) ? m_cursor : false;
1958
+ setCursorStaus();
1932
1959
  if ((keyNum == -1) || (keyNum == -64) || (keyNum == -2))
1933
1960
  return;
1934
1961
  if (m_stat == 0)
@@ -1971,19 +1998,25 @@ uint table::posPtrLen() const
1971
1998
 
1972
1999
  ha_rows table::recordCount(bool estimate)
1973
2000
  {
1974
- if ((m_table->file->ha_table_flags() &
1975
- (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0)
1976
- return m_table->file->records();
2001
+ ha_rows rows = 0;
2002
+ m_stat = 0;
2003
+ if ((m_table->file->ha_table_flags() &
2004
+ (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0)
2005
+ {
2006
+ m_stat = cp_record_count(m_table->file, &rows);
2007
+ return rows;
2008
+ }
1977
2009
  if (estimate)
1978
2010
  { /* Since the answer of innodb is random, 1 returns also 0.
1979
2011
  Since it is important, in the case of 1
1980
2012
  , whether there is nothing or it is scan and investigate.
1981
2013
  info() is update statistics variables */
1982
2014
  m_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1983
- ha_rows rows = m_table->file->records();
1984
- if (rows > 1)
2015
+ m_stat = cp_record_count(m_table->file, &rows);
2016
+ if (m_stat || rows > 1)
1985
2017
  return rows;
1986
2018
  }
2019
+
1987
2020
  uint n = 0;
1988
2021
  fieldBitmap fb(m_table);
1989
2022
  char keynum = m_keyNum;
@@ -1997,7 +2030,8 @@ ha_rows table::recordCount(bool estimate)
1997
2030
  while (m_stat == 0)
1998
2031
  {
1999
2032
  m_table->file->unlock_row();
2000
- n++;
2033
+ ++n;
2034
+ ++m_readCount;
2001
2035
  m_stat = m_table->file->ha_index_next(m_table->record[0]);
2002
2036
  }
2003
2037
  fb.setKeyRead(false);
@@ -2017,6 +2051,7 @@ ha_rows table::recordCount(bool estimate)
2017
2051
  {
2018
2052
  m_table->file->unlock_row();
2019
2053
  ++n;
2054
+ ++m_readCount;
2020
2055
  m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
2021
2056
  }
2022
2057
  }
@@ -2143,6 +2178,7 @@ __int64 table::insert(bool ncc)
2143
2178
 
2144
2179
  if (m_stat == 0)
2145
2180
  {
2181
+ ++m_insCount;
2146
2182
  if (!ncc) // innodb default is ncc=-1.
2147
2183
  m_nonNcc = true;
2148
2184
  else if (!m_bulkInserting)
@@ -2253,7 +2289,11 @@ void table::update(bool ncc)
2253
2289
  }
2254
2290
  }
2255
2291
  /* Do not change to m_changed = false */
2256
- if (m_stat == 0) m_changed = true;
2292
+ if (m_stat == 0)
2293
+ {
2294
+ ++m_updCount;
2295
+ m_changed = true;
2296
+ }
2257
2297
  m_nounlock = setCursorStaus();
2258
2298
  }
2259
2299
  }
@@ -2269,7 +2309,11 @@ void table::del()
2269
2309
  {
2270
2310
  m_stat = m_table->file->ha_delete_row(m_table->record[0]);
2271
2311
  /* Do not change to m_changed = false */
2272
- if (m_stat == 0) m_changed = true;
2312
+ if (m_stat == 0)
2313
+ {
2314
+ ++m_delCount;
2315
+ m_changed = true;
2316
+ }
2273
2317
  }
2274
2318
 
2275
2319
  //No cursor changed
@@ -2357,7 +2401,7 @@ const char* table::valStr(int fieldNum, int& size)
2357
2401
  return "";
2358
2402
  else
2359
2403
  fd->val_str(&m_str, &m_str);
2360
- size = m_str.length();
2404
+ size = (int)m_str.length();
2361
2405
  return m_str.c_ptr();
2362
2406
  }
2363
2407
 
@@ -233,7 +233,7 @@ public:
233
233
  for (int i = 0; i < m_keyCount; i++)
234
234
  if (strstr(m_key[i].name, "key") && m_key[i].name[3] == num + '0')
235
235
  return m_convNum = i;
236
- return m_convNum = num; // If not found, a value as it is is returned.
236
+ return m_convNum = num; // If not found, a value as it is returned.
237
237
  }
238
238
  };
239
239
 
@@ -264,6 +264,10 @@ class table : private boost::noncopyable
264
264
  keynumConvert m_keyconv;
265
265
  IblobBuffer* m_blobBuffer;
266
266
  std::vector<Field*> m_nonKeySegNullFields;
267
+ int m_readCount;
268
+ int m_updCount;
269
+ int m_delCount;
270
+ int m_insCount;
267
271
  char m_keyNum;
268
272
  struct
269
273
  {
@@ -288,7 +292,6 @@ class table : private boost::noncopyable
288
292
  int type, bool noBookmark);
289
293
 
290
294
  bool keyCheckForPercent();
291
- inline bool keynumCheck(char num);
292
295
  void preBuildPercent(uchar* first, uchar* last);
293
296
  void seekPos(const uchar* pos);
294
297
  int setKeyNullFlags();
@@ -311,10 +314,17 @@ class table : private boost::noncopyable
311
314
 
312
315
  inline bool setCursorStaus()
313
316
  {
314
- m_validCursor = (m_stat == 0);
315
- m_cursor = (m_stat == 0) ? true :
316
- ((m_stat == HA_ERR_LOCK_WAIT_TIMEOUT) ||
317
+ if (m_stat == 0)
318
+ {
319
+ ++m_readCount;
320
+ m_validCursor = true;
321
+ m_cursor = true;
322
+ }else
323
+ {
324
+ m_validCursor = false;
325
+ m_cursor = ((m_stat == HA_ERR_LOCK_WAIT_TIMEOUT) ||
317
326
  (m_stat == HA_ERR_LOCK_DEADLOCK)) ? m_cursor : false;
327
+ }
318
328
  return m_validCursor;
319
329
  }
320
330
 
@@ -358,6 +368,8 @@ public:
358
368
 
359
369
  inline short mode() const { return m_mode; }
360
370
 
371
+ inline bool cursor() const {return m_cursor;}
372
+
361
373
  inline bool isReadOnly() const
362
374
  {
363
375
  return (m_mode == MODE_READ_ONLY)
@@ -444,6 +456,11 @@ public:
444
456
  return m_keyconv.keyNumByMakeOrder(num);
445
457
  }
446
458
 
459
+ inline bool keynumCheck(char num)
460
+ {
461
+ return ((num >= 0) && (num < (short)m_table->s->keys));
462
+ }
463
+
447
464
  bool setKeyNum(char num, bool sorted = true);
448
465
 
449
466
  inline void setKeyNum(const char* name, bool sorted = true)
@@ -621,6 +638,11 @@ public:
621
638
  /** bookmark length */
622
639
  uint posPtrLen() const;
623
640
 
641
+ inline uint posPtrLenRaw() const
642
+ {
643
+ return m_table->file->ref_length;
644
+ }
645
+
624
646
  /** bookmark */
625
647
  const uchar* position(bool raw = false);
626
648
  const char* keyName(char keyNum);
@@ -684,12 +706,20 @@ public:
684
706
  m_delayAutoCommit = false;
685
707
  }
686
708
 
709
+ inline bool isDelayAutoCommit() const
710
+ {
711
+ return m_delayAutoCommit;
712
+ }
713
+
687
714
  inline short unlock()
688
715
  {
689
716
  if (m_db.inSnapshot() || m_db.inTransaction())
690
717
  {
691
718
  if (m_validCursor)
719
+ {
692
720
  m_table->file->unlock_row();
721
+ m_nounlock = true;
722
+ }
693
723
  else
694
724
  return 1;
695
725
  }else if (m_db.m_inAutoTransaction == this)