transactd 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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)