transactd 3.1.0 → 3.2.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/bin/common/tdclc_32_3_2.dll +0 -0
  3. data/bin/common/{tdclc_64_3_1.dll → tdclc_64_3_2.dll} +0 -0
  4. data/build/swig/ruby/ruby.swg +3 -0
  5. data/build/swig/ruby/tdclrb_wrap.cpp +2413 -126
  6. data/build/swig/tdcl.i +120 -9
  7. data/build/tdclc/tdclc.cbproj +4 -1
  8. data/build/tdclc/tdclc.rc +4 -4
  9. data/build/tdclcpp/tdclcpp.rc +4 -4
  10. data/build/tdclcpp/tdclcpp_bc.cbproj +8 -1
  11. data/build/tdclrb/tdclrb.rc +4 -4
  12. data/source/bzs/db/engine/mysql/database.cpp +138 -130
  13. data/source/bzs/db/engine/mysql/database.h +43 -48
  14. data/source/bzs/db/engine/mysql/dbManager.cpp +81 -96
  15. data/source/bzs/db/engine/mysql/dbManager.h +13 -22
  16. data/source/bzs/db/engine/mysql/mysqlInternal.h +157 -291
  17. data/source/bzs/db/engine/mysql/mysqlProtocol.cpp +425 -0
  18. data/source/bzs/db/engine/mysql/mysqlProtocol.h +72 -0
  19. data/source/bzs/db/engine/mysql/mysqlThd.cpp +8 -6
  20. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +7 -3
  21. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +1 -0
  22. data/source/bzs/db/protocol/tdap/client/client.h +22 -8
  23. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +225 -21
  24. data/source/bzs/db/protocol/tdap/client/connMgr.h +42 -16
  25. data/source/bzs/db/protocol/tdap/client/database.cpp +58 -15
  26. data/source/bzs/db/protocol/tdap/client/database.h +3 -3
  27. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +93 -85
  28. data/source/bzs/db/protocol/tdap/client/dbDef.h +1 -2
  29. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +9 -5
  30. data/source/bzs/db/protocol/tdap/client/filter.h +2 -2
  31. data/source/bzs/db/protocol/tdap/client/groupComp.h +2 -2
  32. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +1 -1
  33. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +71 -12
  34. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +7 -1
  35. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +35 -2
  36. data/source/bzs/db/protocol/tdap/client/nsTable.h +1 -0
  37. data/source/bzs/db/protocol/tdap/client/recordset.cpp +5 -1
  38. data/source/bzs/db/protocol/tdap/client/recordset.h +15 -0
  39. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +21 -16
  40. data/source/bzs/db/protocol/tdap/client/serializer.cpp +32 -11
  41. data/source/bzs/db/protocol/tdap/client/serializer.h +4 -1
  42. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +3 -2
  43. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +3 -0
  44. data/source/bzs/db/protocol/tdap/client/table.cpp +18 -14
  45. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +8 -3
  46. data/source/bzs/db/protocol/tdap/mysql/characterset.cpp +1 -0
  47. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +83 -43
  48. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +3 -1
  49. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +7 -7
  50. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +247 -137
  51. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +9 -9
  52. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +1 -4
  53. data/source/bzs/db/protocol/tdap/tdapSchema.h +3 -7
  54. data/source/bzs/db/protocol/tdap/tdapcapi.h +23 -3
  55. data/source/bzs/db/protocol/tdap/uri.h +40 -0
  56. data/source/bzs/db/transactd/appModule.cpp +14 -5
  57. data/source/bzs/db/transactd/appModule.h +10 -1
  58. data/source/bzs/db/transactd/connManager.cpp +93 -48
  59. data/source/bzs/db/transactd/connManager.h +10 -7
  60. data/source/bzs/db/transactd/connectionRecord.h +114 -19
  61. data/source/bzs/env/tstring.h +2 -0
  62. data/source/bzs/example/changeSchema.cpp +1 -1
  63. data/source/bzs/example/changeSchema_c.cpp +1 -1
  64. data/source/bzs/example/insertRecords.cpp +2 -1
  65. data/source/bzs/example/insertRecords_c.cpp +2 -1
  66. data/source/bzs/example/queryData.cpp +5 -2
  67. data/source/bzs/netsvc/server/IAppModule.h +6 -0
  68. data/source/bzs/test/tdclatl/test_v3.js +75 -0
  69. data/source/bzs/test/tdclphp/transactd_v3_Test.php +104 -7
  70. data/source/bzs/test/tdclrb/transactd_v3_spec.rb +84 -0
  71. data/source/bzs/test/trdclengn/testField.h +66 -6
  72. data/source/bzs/test/trdclengn/test_tdclcpp_v3.cpp +10 -1
  73. data/source/bzs/test/trdclengn/test_trdclengn.cpp +85 -0
  74. data/source/bzs/test/trdclengn/testbase.h +1 -1
  75. data/source/global/tdclatl/BinlogPos.cpp +64 -0
  76. data/source/global/tdclatl/BinlogPos.h +84 -0
  77. data/source/global/tdclatl/ConnMgr.cpp +285 -0
  78. data/source/global/tdclatl/ConnMgr.h +83 -0
  79. data/source/global/tdclatl/ConnRecord.cpp +123 -0
  80. data/source/global/tdclatl/ConnRecord.h +69 -0
  81. data/source/global/tdclatl/ConnRecords.cpp +57 -0
  82. data/source/global/tdclatl/ConnRecords.h +55 -0
  83. data/source/global/tdclatl/Database.cpp +36 -0
  84. data/source/global/tdclatl/Database.h +4 -0
  85. data/source/global/tdclatl/Table.cpp +14 -1
  86. data/source/global/tdclatl/Table.h +1 -0
  87. data/source/global/tdclatl/resource.h +0 -0
  88. data/source/global/tdclatl/tdclatl.idl +148 -4
  89. metadata +14 -4
  90. data/bin/common/tdclc_32_3_1.dll +0 -0
@@ -23,6 +23,7 @@
23
23
  #include "percentageKey.h"
24
24
  #include "mydebuglog.h"
25
25
  #include "mysqlThd.h"
26
+ #include "mysqlProtocol.h"
26
27
  #include "bookmark.h"
27
28
  #include <bzs/rtl/stl_uty.h>
28
29
  #include <boost/shared_array.hpp>
@@ -118,7 +119,7 @@ void tableCacheCounter::release(const std::string& dbname,
118
119
  bool lockTable(THD* thd, TABLE* tb)
119
120
  {
120
121
  bool append = (thd->lock != 0);
121
- #ifdef MARIADDB_10_1
122
+ #ifdef MARIADB_10_1
122
123
  thd->variables.option_bits |= OPTION_TABLE_LOCK;
123
124
  #endif
124
125
  MYSQL_LOCK* lock = mysql_lock_tables(thd, &tb, 1, 0);
@@ -195,6 +196,10 @@ database::database(const char* name, short cid)
195
196
  m_usingExclusive(false), m_trnType(0), m_cid(cid)
196
197
  {
197
198
  cp_security_ctx(m_thd)->skip_grants();
199
+
200
+ //backup current sctx
201
+ m_backup_sctx = cp_security_ctx(m_thd);
202
+ setDbName(m_thd, m_dbname.c_str());
198
203
  }
199
204
 
200
205
  #ifdef _MSC_VER
@@ -229,7 +234,7 @@ unsigned char* database::getUserSha1Passwd(const char* host, const char* user,
229
234
  try
230
235
  {
231
236
  use();
232
- tb2 = openTable("user", TD_OPEN_READONLY, "");
237
+ tb2 = openTable("user", TD_OPEN_READONLY, "", "");
233
238
  if (tb2)
234
239
  {
235
240
  tb = useTable(tb2->id(), SQLCOM_SELECT, NULL);
@@ -269,32 +274,51 @@ unsigned char* database::getUserSha1Passwd(const char* host, const char* user,
269
274
  return retPtr;
270
275
  }
271
276
 
272
- bool setGrant(THD* thd, const char* host, const char* user, const char* db)
277
+ int database::findSecurityCtxs(const std::string& dbname)
273
278
  {
274
- return (acl_getroot(cp_security_ctx(thd), cp_strdup(user, MYF(0)),
275
- cp_strdup(host, MYF(0)), cp_strdup(host, MYF(0)), (char*)db)) == false;
279
+ for (size_t i=0;i < m_securityCtxs.size(); ++i)
280
+ if (m_securityCtxs[i].db == dbname) return (int)i;
281
+ return -1;
276
282
  }
277
283
 
278
- bool copyGrant(THD* thd, THD* thdSrc, const char* db)
284
+ void database::addDbName(const std::string& dbname)
279
285
  {
280
- Security_context* sctx = cp_security_ctx(thdSrc);
281
- if (sctx->cp_master_accsess() == (ulong)~NO_ACCESS)
282
- {
283
- cp_security_ctx(thd)->skip_grants();
284
- return true;
285
- }
286
- return setGrant(thd, sctx->cp_priv_host(), sctx->cp_priv_user(), db);
286
+ m_securityCtxs.push_back(sec_db(dbname));
287
+ sec_db* secx = &m_securityCtxs[m_securityCtxs.size() -1];
288
+
289
+ // Change security_ctx
290
+ secx->security_ctx.restore_security_context(m_thd, &secx->security_ctx);
291
+
292
+ //Get Grant
293
+ bool ret = ::setGrant(m_thd, m_backup_sctx->cp_priv_host(), m_backup_sctx->cp_priv_user(), dbname.c_str());
294
+ if (ret)
295
+ check_access(m_thd, SELECT_ACL, dbname.c_str(), &secx->privilege, NULL, false, true);
296
+
297
+ //Restore current ctx
298
+ restoreSctx();
287
299
  }
300
+
288
301
  // true ok false fail
289
- bool database::setGrant(const char* host, const char* user)
302
+ bool database::setGrant(const char* host, const char* user, const char* dbname)
290
303
  {
291
- bool ret = mysql::setGrant(m_thd, host, user, m_dbname.c_str());
304
+ bool ret = ::setGrant(m_thd, host, user, dbname);
292
305
  if (ret)
293
- check_access(m_thd, SELECT_ACL, m_dbname.c_str(), &m_privilege, NULL, false, true);
294
-
306
+ {
307
+ check_access(m_thd, SELECT_ACL, dbname, &m_privilege, NULL, false, true);
308
+ }
295
309
  return ret;
296
310
  }
297
311
 
312
+ void database::restoreSctx()
313
+ {
314
+ m_backup_sctx->restore_security_context(m_thd, m_backup_sctx);
315
+ }
316
+
317
+ void database::changeSctx(int index)
318
+ {
319
+ m_backup_sctx->restore_security_context(m_thd, &m_securityCtxs[index].security_ctx);
320
+ }
321
+
298
322
  // for mysql database only
299
323
  short database::aclReload()
300
324
  {
@@ -305,20 +329,16 @@ short database::aclReload()
305
329
  short ret = STATUS_SUCCESS;
306
330
 
307
331
  THD* thdCur = _current_thd();
308
- THD* thd = NULL;
309
332
  try
310
333
  {
311
- thd = createThdForThread();
312
- attachThd(thd);
313
- thd->clear_error();
314
- acl_reload(thd);
334
+ boost::shared_ptr<THD> thd(createThdForThread(), deleteThdForThread);
335
+ attachThd(thd.get());
336
+ acl_reload(thd.get());
315
337
  }
316
338
  catch (...)
317
339
  {
318
340
  ret = 1;
319
341
  }
320
- if (thd)
321
- deleteThdForThread(thd);
322
342
  attachThd(thdCur);
323
343
  return ret;
324
344
  }
@@ -359,7 +379,6 @@ void database::prebuildExclusieLockMode(table* tb)
359
379
  else
360
380
  tb->m_table->reginfo.lock_type = TL_READ_NO_INSERT;
361
381
  m_thd->in_lock_tables = 1;
362
-
363
382
  }
364
383
 
365
384
  void database::prebuildLocktype(table* tb, enum_sql_command& cmd, rowLockMode* lck)
@@ -435,24 +454,6 @@ void database::changeIntentionLock(table* tb, thr_lock_type lock_type)
435
454
  }
436
455
  }
437
456
 
438
- inline void database::checkACL(enum_sql_command cmd)
439
- {
440
- switch(cmd)
441
- {
442
- case SQLCOM_UPDATE:
443
- if (!(m_privilege & UPDATE_ACL)) THROW_BZS_ERROR_WITH_CODE(STATUS_ACCESS_DENIED);
444
- break;
445
- case SQLCOM_INSERT:
446
- if (!(m_privilege & INSERT_ACL)) THROW_BZS_ERROR_WITH_CODE(STATUS_ACCESS_DENIED);
447
- break;
448
- case SQLCOM_DELETE:
449
- if (!(m_privilege & DELETE_ACL)) THROW_BZS_ERROR_WITH_CODE(STATUS_ACCESS_DENIED);
450
- break;
451
- default:
452
- break;
453
- }
454
- }
455
-
456
457
  /*
457
458
  How to set the lock value to InnoDB prebuilt->select_lock_type variable.
458
459
 
@@ -511,7 +512,8 @@ table* database::useTable(int index, enum_sql_command cmd, rowLockMode* lck)
511
512
  return tb;
512
513
  }
513
514
 
514
- checkACL(cmd);
515
+ tb->checkACL(cmd);
516
+ //checkACL(cmd);
515
517
  prebuildLocktype(tb, cmd, lck);
516
518
  prebuildIsoratinMode();
517
519
 
@@ -700,62 +702,7 @@ void database::useAllTables()
700
702
  }
701
703
  }
702
704
 
703
- // See USE_BINLOG_GTID and USE_BINLOG_VAR in mysqlInternal.h
704
- #ifdef NOTUSE_BINLOG_VAR
705
- // Windows MySQL can not use mysql_bin_log variable
706
- inline short getBinlogPos(THD* currentThd, binlogPos* bpos)
707
- {
708
- short result = 0;
709
- THD* thd = createThdForThread();
710
- attachThd(thd);
711
- copyGrant(thd, currentThd, NULL);
712
- masterStatus p(thd, bpos);
713
- cp_query_command(thd, "show master status");
714
- if (thd->is_error())
715
- result = thd->cp_get_sql_error();
716
- deleteThdForThread(thd);
717
- attachThd(currentThd);
718
- return result;
719
- }
720
- #endif
721
-
722
- #ifdef USE_BINLOG_GTID
723
- inline short getBinlogPos(THD* currentThd, binlogPos* bpos)
724
- {
725
- if (mysql_bin_log.is_open())
726
- {
727
- rpl_gtid gtid;
728
- bpos->type = REPL_POSTYPE_MARIA_GTID;
729
- if (mysql_bin_log.lookup_domain_in_binlog_state(currentThd->variables.gtid_domain_id, &gtid))
730
- {
731
- sprintf_s(bpos->gtid, GTID_SIZE, "%u-%u-%llu", gtid.domain_id, gtid.server_id, gtid.seq_no);
732
- size_t dir_len = dirname_length(mysql_bin_log.get_log_fname());
733
- strncpy(bpos->filename, mysql_bin_log.get_log_fname() + dir_len, BINLOGNAME_SIZE);
734
- bpos->pos = my_b_tell(mysql_bin_log.get_log_file());
735
- bpos->filename[BINLOGNAME_SIZE-1] = 0x00;
736
- }
737
- }
738
- return 0;
739
- }
740
- #endif
741
-
742
- #ifdef USE_BINLOG_VAR
743
- // Linux MySQL can access to the mysql_bin_log variable
744
- inline short getBinlogPos(THD* , binlogPos* bpos)
745
- {
746
- if (mysql_bin_log.is_open())
747
- {
748
- size_t dir_len = dirname_length(mysql_bin_log.get_log_fname());
749
- strncpy(bpos->filename, mysql_bin_log.get_log_fname() + dir_len, BINLOGNAME_SIZE);
750
- bpos->pos = my_b_tell(mysql_bin_log.get_log_file());
751
- bpos->filename[BINLOGNAME_SIZE-1] = 0x00;
752
- bpos->type = REPL_POSTYPE_POS;
753
- }
754
- return 0;
755
- }
756
- #endif //USE_BINLOG_VAR
757
-
758
- bool database::beginSnapshot(enum_tx_isolation iso, binlogPos* bpos)
705
+ bool database::beginSnapshot(enum_tx_isolation iso, binlogPos* bpos, THD* tmpThd)
759
706
  {
760
707
  if (m_inTransaction)
761
708
  THROW_BZS_ERROR_WITH_CODEMSG(STATUS_ALREADY_INTRANSACTION, "Transaction is already beginning.");
@@ -775,11 +722,12 @@ bool database::beginSnapshot(enum_tx_isolation iso, binlogPos* bpos)
775
722
  if (bpos)
776
723
  {
777
724
  safe_commit_lock commit(m_thd);
778
- if (!commit.lock()) return false;
779
- #ifndef NOTUSE_BINLOG_VAR
780
- safe_mysql_mutex_lock lck(mysql_bin_log.get_log_lock());
781
- #endif
782
- m_stat = getBinlogPos(m_thd, bpos);
725
+ if (!commit.lock())
726
+ {
727
+ m_stat = STATUS_LOCK_ERROR;
728
+ return false;
729
+ }
730
+ m_stat = getBinlogPos(m_thd, bpos, tmpThd);
783
731
  if (m_stat) return false;
784
732
  useAllTables(); // execute scope in safe_commit_lock
785
733
  }else
@@ -800,18 +748,28 @@ bool database::endSnapshot()
800
748
  return (m_inSnapshot == 0);
801
749
  }
802
750
 
751
+ /*bool database::existsTable(const char* tablename)
752
+ {
753
+ char path[FN_REFLEN + 1];
754
+ enum legacy_db_type not_used;
755
+ build_table_filename(path, sizeof(path) - 1, name().c_str(), tablename, "", 0);
756
+ frm_type_enum ftype = dd_frm_type(thd(), (char*)path, &not_used);
757
+ return FRMTYPE_TABLE == ftype;
758
+ }*/
759
+
803
760
  /** Metadata lock, a table name is case-sensitive
804
761
  * However, in actual opening, it is not distinguished at Windows.
805
762
  */
806
763
  TABLE* database::doOpenTable(const std::string& name, short mode,
807
- const char* ownerName)
764
+ const char* ownerName, string& dbname)
808
765
  {
809
- TABLE_LIST tables;
810
766
  m_thd->variables.lock_wait_timeout = OPEN_TABLE_TIMEOUT_SEC;
811
- tables.init_one_table(m_dbname.c_str(), m_dbname.size(), name.c_str(),
812
- name.size(), name.c_str(), TL_READ);
813
- if(!(m_privilege & SELECT_ACL) &&
814
- (check_grant(m_thd, SELECT_ACL, &tables, FALSE, 1, true)))
767
+ TABLE_LIST tables;
768
+ tables.init_one_table(dbname.c_str(), dbname.size(), name.c_str(),
769
+ name.size(), name.c_str(), TL_READ);
770
+ long want_access = SELECT_ACL;//IS_MODE_READONLY(mode) ? SELECT_ACL : SELECT_ACL|INSERT_ACL|UPDATE_ACL|DELETE_ACL;
771
+ if(!(m_privilege & want_access) &&
772
+ (check_grant(m_thd, want_access, &tables, FALSE, 1, true)))
815
773
  {
816
774
  m_stat = STATUS_ACCESS_DENIED;
817
775
  return NULL;
@@ -863,7 +821,7 @@ TABLE* database::doOpenTable(const std::string& name, short mode,
863
821
  }
864
822
 
865
823
  table* database::openTable(const std::string& name, short mode,
866
- const char* ownerName)
824
+ const char* ownerName, std::string dbname)
867
825
  {
868
826
  if (m_thd->variables.sql_log_bin && m_inTransaction)
869
827
  {
@@ -872,8 +830,27 @@ table* database::openTable(const std::string& name, short mode,
872
830
  }
873
831
  bool mysql_null = IS_MODE_MYSQL_NULL(mode);
874
832
  if (mysql_null)
875
- mode -= TD_OPEN_MASK_MYSQL_NULL;
876
- TABLE* t = doOpenTable(name, mode, ownerName);
833
+ mode -= TD_OPEN_MASK_MYSQL_NULL;
834
+
835
+ int index = -1;
836
+ if (dbname == "")
837
+ {
838
+ dbname = m_dbname;
839
+ restoreSctx();
840
+ }
841
+ else if (dbname == m_dbname)
842
+ restoreSctx();
843
+ else
844
+ {
845
+ index = findSecurityCtxs(dbname);
846
+ if (index == -1)
847
+ addDbName(dbname);
848
+ index = (int)m_securityCtxs.size() - 1;
849
+ assert(index >= 0);
850
+ changeSctx(index);
851
+ }
852
+
853
+ TABLE* t = doOpenTable(name, mode, ownerName, dbname);
877
854
  if (t)
878
855
  {
879
856
  boost::shared_ptr<table> tb(
@@ -881,14 +858,18 @@ table* database::openTable(const std::string& name, short mode,
881
858
  {
882
859
  boost::mutex::scoped_lock lck(tableRef.mutex());
883
860
  m_tables.push_back(tb);
884
- tableRef.addref(m_dbname, name); // addef first then table open.
861
+ tableRef.addref(dbname, name); // addef first then table open.
885
862
  }
863
+ tb->m_dbname = dbname;
864
+ tb->m_privilege = (index == -1) ? this->m_privilege : m_securityCtxs[index].privilege;
886
865
  m_stat = STATUS_SUCCESS;
887
866
  if (tb->isExclusveMode())
888
867
  ++m_usingExclusive;
889
868
 
869
+ if (index != -1) restoreSctx();
890
870
  return tb.get();
891
871
  }
872
+ if (index != -1) restoreSctx();
892
873
  return NULL;
893
874
  }
894
875
 
@@ -989,7 +970,8 @@ void database::reopen(bool forceReadonly)
989
970
  if (forceReadonly)
990
971
  m_tables[i]->m_mode = TD_OPEN_READONLY;
991
972
  TABLE* table = doOpenTable(m_tables[i]->m_name.c_str(),
992
- m_tables[i]->m_mode, NULL);
973
+ m_tables[i]->m_mode, NULL,
974
+ m_tables[i]->m_dbname);
993
975
  if (table)
994
976
  m_tables[i]->resetInternalTable(table);
995
977
  else
@@ -1041,7 +1023,7 @@ table::table(TABLE* myTable, database& db, const std::string& name, short mode,
1041
1023
  m_keybuf(new unsigned char[MAX_KEYLEN]),
1042
1024
  m_stat(0),
1043
1025
  m_keyconv(m_table->key_info, m_table->s->keys), m_blobBuffer(NULL),
1044
- m_readCount(0), m_updCount(0), m_delCount(0), m_insCount(0),
1026
+ m_readCount(0), m_updCount(0), m_delCount(0), m_insCount(0), m_privilege(0xFFFF),
1045
1027
  m_keyNum(-1), m_nonNcc(false), m_validCursor(true), m_cursor(false),
1046
1028
  m_locked(false), m_changed(false), m_nounlock(false), m_bulkInserting(false),
1047
1029
  m_delayAutoCommit(false),m_forceConsistentRead(false), m_mysqlNull(mysqlnull),
@@ -1154,6 +1136,24 @@ void table::resetInternalTable(TABLE* table)
1154
1136
  }
1155
1137
  }
1156
1138
 
1139
+ void table::checkACL(enum_sql_command cmd)
1140
+ {
1141
+ switch(cmd)
1142
+ {
1143
+ case SQLCOM_UPDATE:
1144
+ if (!(m_privilege & UPDATE_ACL)) THROW_BZS_ERROR_WITH_CODE(STATUS_ACCESS_DENIED);
1145
+ break;
1146
+ case SQLCOM_INSERT:
1147
+ if (!(m_privilege & INSERT_ACL)) THROW_BZS_ERROR_WITH_CODE(STATUS_ACCESS_DENIED);
1148
+ break;
1149
+ case SQLCOM_DELETE:
1150
+ if (!(m_privilege & DELETE_ACL)) THROW_BZS_ERROR_WITH_CODE(STATUS_ACCESS_DENIED);
1151
+ break;
1152
+ default:
1153
+ break;
1154
+ }
1155
+ }
1156
+
1157
1157
  bool table::setNonKey(bool scan)
1158
1158
  {
1159
1159
  if (m_keyNum != -2)
@@ -1170,22 +1170,22 @@ bool table::setNonKey(bool scan)
1170
1170
 
1171
1171
  bool table::setKeyNum(char num, bool sorted)
1172
1172
  {
1173
+ if (num < 0)
1174
+ {
1175
+ m_stat = STATUS_INVALID_KEYNUM;
1176
+ return false;
1177
+ }
1173
1178
  if ((m_keyNum != num) ||
1174
1179
  ((m_keyNum >= 0) && (m_table->file->inited == handler::NONE)))
1175
1180
  {
1176
1181
  m_table->file->ha_index_or_rnd_end();
1177
-
1178
- if (keynumCheck(num))
1179
- {
1180
- m_keyNum = num;
1181
- m_table->file->ha_index_init(m_keyNum, sorted);
1182
- return true;
1183
- }
1184
- else
1182
+ if (!keynumCheck(num))
1185
1183
  {
1186
1184
  m_stat = STATUS_INVALID_KEYNUM;
1187
1185
  return false;
1188
1186
  }
1187
+ m_keyNum = num;
1188
+ m_table->file->ha_index_init(m_keyNum, sorted);
1189
1189
  }
1190
1190
  return true;
1191
1191
  }
@@ -1603,11 +1603,11 @@ uint table::recordPackCopy(char* buf, uint maxsize)
1603
1603
  return 0;
1604
1604
  memcpy(p, fd->ptr, len);
1605
1605
  p += len;
1606
- if (isBlobType(fd->type()))
1607
- {
1608
- ++blobs;
1609
- addBlobBuffer(fd->field_index);
1610
- }
1606
+ }
1607
+ if (isBlobType(fd->type()))
1608
+ {
1609
+ ++blobs;
1610
+ addBlobBuffer(fd->field_index);
1611
1611
  }
1612
1612
  }
1613
1613
  setBlobFieldCount(blobs);
@@ -2714,6 +2714,14 @@ unsigned int table::writeSchemaImage(unsigned char* p, size_t size)
2714
2714
  return len + sizeof(unsigned short);
2715
2715
  }
2716
2716
 
2717
+ void table::getCreateSql(String* s)
2718
+ {
2719
+ TABLE_LIST tables;
2720
+ tables.init_one_table(m_dbname.c_str(), m_dbname.size(), m_name.c_str(),
2721
+ m_name.size(), m_name.c_str(), TL_READ);
2722
+ tables.table = m_table;
2723
+ cp_store_create_info(m_db.thd(), &tables, s, NULL, (int)FALSE);
2724
+ }
2717
2725
 
2718
2726
  #ifdef USE_HANDLERSOCKET
2719
2727
 
@@ -31,11 +31,13 @@
31
31
 
32
32
  class THD;
33
33
  struct TABLE;
34
+ struct binlogPos;
34
35
 
35
36
  #ifndef MAX_KEYLEN
36
37
  #define MAX_KEYLEN 1023
37
38
  #endif
38
39
 
40
+
39
41
  namespace bzs
40
42
  {
41
43
  namespace db
@@ -45,6 +47,8 @@ namespace engine
45
47
  namespace mysql
46
48
  {
47
49
 
50
+ class table;
51
+
48
52
  /*
49
53
  Please comment out the following,
50
54
  when you emulate btrv variable length record of btrv with a server.
@@ -69,12 +73,11 @@ namespace mysql
69
73
  #define MODE_EXCLUSIVE -4
70
74
  #define MODE_READ_EXCLUSIVE -6
71
75
 
72
- #define OPEN_TABLE_TIMEOUT_SEC 2
73
76
  /** bookmark size
74
77
  * btreive API is MAX 4 byte
75
78
  */
76
79
  #define REF_SIZE_MAX 112
77
- class table;
80
+
78
81
 
79
82
 
80
83
  /** Control mysql table cahche
@@ -103,6 +106,15 @@ struct rowLockMode
103
106
  bool read : 1;
104
107
  };
105
108
 
109
+ struct sec_db
110
+ {
111
+ std::string db;
112
+ Security_context security_ctx;
113
+ ulong privilege;
114
+ sec_db(const std::string& dbname) :
115
+ db(dbname), privilege(0xFFFF){}
116
+ };
117
+
106
118
  class database : private boost::noncopyable
107
119
  {
108
120
  friend class table;
@@ -122,24 +134,29 @@ private:
122
134
  short m_trnType;
123
135
  short m_cid;
124
136
  enum_tx_isolation m_iso;
137
+ std::vector<sec_db> m_securityCtxs;
138
+ Security_context* m_backup_sctx;
125
139
 
126
140
  TABLE* doOpenTable(const std::string& name, short mode,
127
- const char* ownerName);
141
+ const char* ownerName, std::string& dbname);
128
142
  void unUseTable(table* tb);
129
143
  size_t getNomalOpenTables(tableList& tables);
130
144
  void prebuildIsoratinMode();
131
145
  void prebuildExclusieLockMode(table* tb);
132
146
  void prebuildLocktype(table* tb, enum_sql_command& cmd, rowLockMode* lck) ;
133
147
  void changeIntentionLock(table* tb, thr_lock_type lock_type);
134
- void checkACL(enum_sql_command cmd);
135
148
  void releaseTable(size_t index);
136
149
  void useAllTables();
150
+ int findSecurityCtxs(const std::string& dbname);
151
+ void addDbName(const std::string& dbname);
152
+ void restoreSctx();
153
+ void changeSctx(int index);
137
154
  public:
138
-
139
-
140
155
  database(const char* name, short cid);
156
+
141
157
  ~database();
142
- bool setGrant(const char* host, const char* user);
158
+
159
+ bool setGrant(const char* host, const char* user, const char* dbname);
143
160
 
144
161
  unsigned char* getUserSha1Passwd(const char* host, const char* user,
145
162
  unsigned char* buf);
@@ -166,10 +183,10 @@ public:
166
183
  return m_tables;
167
184
  }
168
185
 
169
- bool beginSnapshot(enum_tx_isolation iso, struct binlogPos* bpos);
186
+ bool beginSnapshot(enum_tx_isolation iso, binlogPos* bpos, THD* tmpThd);
170
187
  bool endSnapshot();
171
188
  table* openTable(const std::string& name, short mode,
172
- const char* ownerName);
189
+ const char* ownerName, std::string dbname);
173
190
  table* useTable(int index, enum_sql_command cmd, rowLockMode* lck);
174
191
  bool beginTrn(short type, enum_tx_isolation iso);
175
192
  bool commitTrn();
@@ -195,8 +212,14 @@ public:
195
212
  return ((m_inSnapshot + m_inTransaction) == 0);
196
213
  }
197
214
 
215
+ inline bool checkAcl(ulong wantAccess) const
216
+ {
217
+ return (m_privilege & wantAccess) != 0;
218
+ }
219
+
198
220
  short aclReload();
199
221
  inline void setCurTime(){m_thd->set_current_time();}
222
+ inline bool usingExclusveMode() const {return m_usingExclusive != 0;}
200
223
 
201
224
  static tableCacheCounter tableRef;
202
225
 
@@ -247,8 +270,8 @@ public:
247
270
  {
248
271
  if (num < m_keyCount)
249
272
  {
250
- if (strstr(m_key[num].name, "key"))
251
- return m_key[num].name[3] - '0';
273
+ if (strstr(m_key[(int)num].name, "key"))
274
+ return m_key[(int)num].name[3] - '0';
252
275
  }
253
276
  return -1;
254
277
  }
@@ -261,7 +284,7 @@ class table : private boost::noncopyable
261
284
  TABLE* m_table;
262
285
 
263
286
  std::string m_name;
264
-
287
+ std::string m_dbname;
265
288
  short m_mode;
266
289
  unsigned short m_nisNullFields;
267
290
  int m_id;
@@ -285,6 +308,7 @@ class table : private boost::noncopyable
285
308
  unsigned int m_updCount;
286
309
  unsigned int m_delCount;
287
310
  unsigned int m_insCount;
311
+ ulong m_privilege;
288
312
  char m_keyNum;
289
313
  unsigned char m_nullBytesCl;
290
314
  struct
@@ -378,6 +402,10 @@ public:
378
402
 
379
403
  ~table();
380
404
 
405
+ inline void checkACL(enum_sql_command cmd);
406
+
407
+ inline ulong* privilegePtr() {return &m_privilege;}
408
+
381
409
  inline void setBlobBuffer(IblobBuffer* blobBuffer)
382
410
  {
383
411
  m_blobBuffer = blobBuffer;
@@ -573,36 +601,11 @@ public:
573
601
  }
574
602
  unsigned short fieldDataLen(int fieldNum) const;
575
603
 
576
- inline unsigned short fieldLen(int fieldNum) const
577
- {
578
- return m_table->field[fieldNum]->pack_length();
579
- }
580
-
581
604
  inline unsigned short filedVarLenBytes(int fieldNum) const
582
605
  {
583
606
  return var_bytes_if(m_table->field[fieldNum]);
584
607
  }
585
-
586
- inline char* fieldPos(int fieldNum) const
587
- {
588
- return (char*)m_table->field[fieldNum]->ptr;
589
- }
590
-
591
- inline enum enum_field_types fieldType(int fieldNum) const
592
- {
593
- return m_table->field[fieldNum]->type();
594
- }
595
-
596
- inline enum enum_field_types fieldRealType(int fieldNum) const
597
- {
598
- return m_table->field[fieldNum]->real_type();
599
- }
600
-
601
- inline unsigned int fieldFlags(int fieldNum) const
602
- {
603
- return m_table->field[fieldNum]->flags;
604
- }
605
-
608
+
606
609
  inline bool isLegacyTimeFormat(int fieldNum) const
607
610
  {
608
611
  return m_table->field[fieldNum]->key_type() != HA_KEYTYPE_BINARY;
@@ -614,16 +617,6 @@ public:
614
617
 
615
618
  inline unsigned int nisFields() const { return m_nisNullFields; }
616
619
 
617
- inline const char* fieldName(int fieldNum) const
618
- {
619
- return m_table->s->field[fieldNum]->field_name;
620
- }
621
-
622
- inline const CHARSET_INFO& fieldCharset(int fieldNum) const
623
- {
624
- return *m_table->s->field[fieldNum]->charset();
625
- }
626
-
627
620
  /* number of key. */
628
621
  inline unsigned short keys() const { return m_table->s->keys; }
629
622
 
@@ -790,6 +783,8 @@ public:
790
783
  inline unsigned int insCount() const { return m_insCount; }
791
784
 
792
785
  inline void setTimestampAlways(bool v) { m_timestampAlways = v;}
786
+
787
+ void getCreateSql(String* s);
793
788
  };
794
789
 
795
790
  class fieldBitmap