From 4f553314edfc04e2551fed2dc94d72f060b722e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Oct 2004 19:37:25 +0300 Subject: [PATCH 01/44] VIEW support for CHECK TABLE command (WL#1984) mysql-test/r/view.result: test of CHECK TABLE for VIEW mysql-test/t/view.test: test of CHECK TABLE for VIEW sql/handler.h: new check message sql/sql_table.cc: view support for admin table sql/sql_view.cc: check of view MD5 added sql/sql_view.h: check of view MD5 added --- mysql-test/r/view.result | 15 +++++++++ mysql-test/t/view.test | 10 ++++++ sql/handler.h | 1 + sql/sql_table.cc | 66 ++++++++++++++++++++++++++++++++-------- sql/sql_view.cc | 29 +++++++++++++++++- sql/sql_view.h | 2 ++ 6 files changed, 110 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 3f12a582868..fd7abf571c2 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1626,3 +1626,18 @@ Field 3,'Field 4| |Field 6| | 'Field 7'| drop view v1; drop table t1; +create table t1 (a int); +create view v1 as select * from t1; +check table t1,v1; +Table Op Msg_type Msg_text +test.t1 check status OK +test.v1 check status OK +check table v1,t1; +Table Op Msg_type Msg_text +test.v1 check status OK +test.t1 check status OK +drop table t1; +check table v1; +Table Op Msg_type Msg_text +test.v1 check error View 'test.v1' references invalid table(s) or column(s) +drop view v1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 8e38b5616f8..4a0dabe2509 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1554,3 +1554,13 @@ select concat('|',a,'|'), concat('|',b,'|') from v1; drop view v1; drop table t1; +# +# CHECK TABLE with VIEW +# +create table t1 (a int); +create view v1 as select * from t1; +check table t1,v1; +check table v1,t1; +drop table t1; +check table v1; +drop view v1; diff --git a/sql/handler.h b/sql/handler.h index 9a08b8ed78c..8005828c0d8 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -44,6 +44,7 @@ #define HA_ADMIN_INVALID -5 #define HA_ADMIN_REJECT -6 #define HA_ADMIN_TRY_ALTER -7 +#define HA_ADMIN_WRONG_CHECKSUM -8 /* Bits in table_flags() to show what database can do */ #define HA_READ_RND_SAME (1 << 0) /* can switch index during the scan diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d84611ae496..6951ffa6531 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1731,12 +1731,15 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, int (*prepare_func)(THD *, TABLE_LIST *, HA_CHECK_OPT *), int (handler::*operator_func) - (THD *, HA_CHECK_OPT *)) + (THD *, HA_CHECK_OPT *), + int (view_operator_func) + (THD *, TABLE_LIST*)) { - TABLE_LIST *table; + TABLE_LIST *table, *next_global_table; List field_list; Item *item; Protocol *protocol= thd->protocol; + int result_code; DBUG_ENTER("mysql_admin_table"); field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2)); @@ -1760,7 +1763,18 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, strxmov(table_name,db ? db : "",".",table->real_name,NullS); thd->open_options|= extra_open_options; - table->table = open_ltable(thd, table, lock_type); + table->lock_type= lock_type; + /* open only one table from local list of command */ + next_global_table= table->next_global; + table->next_global= 0; + open_and_lock_tables(thd, table); + table->next_global= next_global_table; + /* if view are unsupported */ + if (table->view && !view_operator_func) + { + result_code= HA_ADMIN_NOT_IMPLEMENTED; + goto send_result; + } thd->open_options&= ~extra_open_options; if (prepare_func) @@ -1772,8 +1786,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, } } + /* + for this command used only temporary table method (without + filling tables), so if opening succeed, table will be opened + */ if (!table->table) { + char buf[ERRMSGSIZE+25]; const char *err_msg; protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); @@ -1781,12 +1800,26 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store("error",5, system_charset_info); if (!(err_msg=thd->net.last_error)) err_msg=ER(ER_CHECK_NO_SUCH_TABLE); + /* if it was a view will check md5 sum */ + if (table->view && + view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM) + { + strxmov(buf, "View checksum failed and ", err_msg, NullS); + err_msg= (const char *)buf; + } protocol->store(err_msg, system_charset_info); thd->clear_error(); if (protocol->write()) goto err; continue; } + + if (table->view) + { + result_code= (*view_operator_func)(thd, table); + goto send_result; + } + table->table->pos_in_table_list= table; if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) { @@ -1825,7 +1858,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, open_for_modify=0; } - int result_code = (table->table->file->*operator_func)(thd, check_opt); + result_code = (table->table->file->*operator_func)(thd, check_opt); + +send_result: + thd->clear_error(); // these errors shouldn't get client protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); @@ -1901,6 +1937,12 @@ send_result_message: table->next_global= save_next_global; goto send_result_message; } + case HA_ADMIN_WRONG_CHECKSUM: + { + protocol->store("note", 4, system_charset_info); + protocol->store("Checksum error", 14, system_charset_info); + break; + } default: // Probably HA_ADMIN_INTERNAL_ERROR protocol->store("error", 5, system_charset_info); @@ -1941,7 +1983,7 @@ bool mysql_backup_table(THD* thd, TABLE_LIST* table_list) DBUG_ENTER("mysql_backup_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, "backup", TL_READ, 0, 0, 0, - &handler::backup)); + &handler::backup, 0)); } @@ -1951,7 +1993,7 @@ bool mysql_restore_table(THD* thd, TABLE_LIST* table_list) DBUG_RETURN(mysql_admin_table(thd, table_list, 0, "restore", TL_WRITE, 1, 0, &prepare_for_restore, - &handler::restore)); + &handler::restore, 0)); } @@ -1961,7 +2003,7 @@ bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, &prepare_for_repair, - &handler::repair)); + &handler::repair, 0)); } @@ -1970,7 +2012,7 @@ bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_optimize_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "optimize", TL_WRITE, 1,0,0, - &handler::optimize)); + &handler::optimize, 0)); } @@ -2006,7 +2048,7 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, check_opt.key_cache= key_cache; DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt, "assign_to_keycache", TL_READ_NO_INSERT, 0, - 0, 0, &handler::assign_to_keycache)); + 0, 0, &handler::assign_to_keycache, 0)); } @@ -2067,7 +2109,7 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) DBUG_ENTER("mysql_preload_keys"); DBUG_RETURN(mysql_admin_table(thd, tables, 0, "preload_keys", TL_READ, 0, 0, 0, - &handler::preload_keys)); + &handler::preload_keys, 0)); } @@ -2232,7 +2274,7 @@ bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_analyze_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "analyze", lock_type, 1,0,0, - &handler::analyze)); + &handler::analyze, 0)); } @@ -2248,7 +2290,7 @@ bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "check", lock_type, 0, HA_OPEN_FOR_REPAIR, 0, - &handler::check)); + &handler::check, &view_checksum)); } /* table_list should contain just one table */ diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 7894287aee4..361771cd04e 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -21,6 +21,8 @@ #include "parse_file.h" #include "sp.h" +#define MD5_BUFF_LENGTH 33 + static int mysql_register_view(THD *thd, TABLE_LIST *view, enum_view_create_mode mode); @@ -381,7 +383,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, { char buff[4096]; String str(buff,(uint32) sizeof(buff), system_charset_info); - char md5[33]; + char md5[MD5_BUFF_LENGTH]; bool can_be_merged; char dir_buff[FN_REFLEN], file_buff[FN_REFLEN]; LEX_STRING dir, file; @@ -1036,3 +1038,28 @@ void insert_view_fields(List *list, TABLE_LIST *view) } DBUG_VOID_RETURN; } + +/* + checking view md5 check suum + + SINOPSYS + view_checksum() + thd threar handler + view view for check + + RETUIRN + HA_ADMIN_OK OK + HA_ADMIN_NOT_IMPLEMENTED it is not VIEW + HA_ADMIN_WRONG_CHECKSUM check sum is wrong +*/ + +int view_checksum(THD *thd, TABLE_LIST *view) +{ + char md5[MD5_BUFF_LENGTH]; + if (!view->view || view->md5.length != 32) + return HA_ADMIN_NOT_IMPLEMENTED; + view->calc_md5(md5); + return (strncmp(md5, view->md5.str, 32) ? + HA_ADMIN_WRONG_CHECKSUM : + HA_ADMIN_OK); +} diff --git a/sql/sql_view.h b/sql/sql_view.h index 4cb2514f5b9..3248c8819f5 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -29,6 +29,8 @@ void insert_view_fields(List *list, TABLE_LIST *view); frm_type_enum mysql_frm_type(char *path); +int view_checksum(THD *thd, TABLE_LIST *view); + extern TYPELIB updatable_views_with_limit_typelib; #define VIEW_ANY_ACL (SELECT_ACL | UPDATE_ACL | INSERT_ACL | DELETE_ACL) From 7a7ee30cb5a26f8e0f2edb560be36e6219e6a4a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 13 Nov 2004 17:34:34 +0100 Subject: [PATCH 02/44] ndb: fix bug-4644 Err Out of fragment operations sql/ha_ndbcluster.cc: compile fix in DBUG code ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp: fix count of metadata pages ndb/include/kernel/signaldata/TupFrag.hpp: bug-4644 fix ndb/src/kernel/blocks/ERROR_codes.txt: bug-4644 fix ndb/src/kernel/blocks/dblqh/Dblqh.hpp: bug-4644 fix ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: bug-4644 fix ndb/src/kernel/blocks/dbtup/Dbtup.hpp: bug-4644 fix ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp: bug-4644 fix ndb/src/kernel/blocks/dbtux/Dbtux.hpp: bug-4644 fix ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp: bug-4644 fix ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp: bug-4644 fix ndb/test/ndbapi/testDict.cpp: bug-4644 fix --- ndb/include/kernel/signaldata/TupFrag.hpp | 6 +- ndb/src/kernel/blocks/ERROR_codes.txt | 10 +- ndb/src/kernel/blocks/dblqh/Dblqh.hpp | 2 +- ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 105 ++++++++++++++++++++- ndb/src/kernel/blocks/dbtup/Dbtup.hpp | 2 + ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp | 54 +++++++++-- ndb/src/kernel/blocks/dbtux/Dbtux.hpp | 2 + ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp | 13 +++ ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp | 9 +- ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp | 88 ++++++++++++++--- ndb/test/ndbapi/testDict.cpp | 67 +++++++++++++ sql/ha_ndbcluster.cc | 11 +-- 12 files changed, 328 insertions(+), 41 deletions(-) diff --git a/ndb/include/kernel/signaldata/TupFrag.hpp b/ndb/include/kernel/signaldata/TupFrag.hpp index c1e861c5dff..c132b19c50a 100644 --- a/ndb/include/kernel/signaldata/TupFrag.hpp +++ b/ndb/include/kernel/signaldata/TupFrag.hpp @@ -132,9 +132,10 @@ class TupAddAttrConf { friend class Dblqh; friend class Dbtup; public: - STATIC_CONST( SignalLength = 1 ); + STATIC_CONST( SignalLength = 2 ); private: Uint32 userPtr; + Uint32 lastAttr; // bool: got last attr and closed frag op }; class TupAddAttrRef { @@ -171,9 +172,10 @@ class TuxAddAttrConf { friend class Dblqh; friend class Dbtux; public: - STATIC_CONST( SignalLength = 1 ); + STATIC_CONST( SignalLength = 2 ); private: Uint32 userPtr; + Uint32 lastAttr; // bool: got last attr and closed frag op }; class TuxAddAttrRef { diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 70f11c33cd7..7ff03684cff 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -2,7 +2,7 @@ Next QMGR 1 Next NDBCNTR 1000 Next NDBFS 2000 Next DBACC 3001 -Next DBTUP 4007 +Next DBTUP 4013 Next DBLQH 5042 Next DBDICT 6006 Next DBDIH 7174 @@ -10,7 +10,7 @@ Next DBTC 8035 Next CMVMI 9000 Next BACKUP 10022 Next DBUTIL 11002 -Next DBTUX 12001 +Next DBTUX 12007 Next SUMA 13001 TESTING NODE FAILURE, ARBITRATION @@ -393,6 +393,12 @@ Failed Create Table: -------------------- 7173: Create table failed due to not sufficient number of fragment or replica records. +4007 12001: Fail create 1st fragment +4008 12002: Fail create 2nd fragment +4009 12003: Fail create 1st attribute in 1st fragment +4010 12004: Fail create last attribute in 1st fragment +4011 12005: Fail create 1st attribute in 2nd fragment +4012 12006: Fail create last attribute in 2nd fragment Drop Table/Index: ----------------- diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index d6987f3e478..739c3c741fb 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -2474,7 +2474,7 @@ private: void sendExecFragRefLab(Signal* signal); void fragrefLab(Signal* signal, BlockReference retRef, Uint32 retPtr, Uint32 errorCode); - void accFragRefLab(Signal* signal); + void abortAddFragOps(Signal* signal); void rwConcludedLab(Signal* signal); void sendsttorryLab(Signal* signal); void initialiseRecordsLab(Signal* signal, Uint32 data, Uint32, Uint32); diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index af1131e5e55..5622706a96c 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -912,6 +912,10 @@ void Dblqh::execREAD_CONFIG_REQ(Signal* signal) /* *********************************************************> */ /* LQHFRAGREQ: Create new fragments for a table. Sender DICT */ /* *********************************************************> */ + +// this unbelievable mess could be replaced by one signal to LQH +// and execute direct to local DICT to get everything at once + void Dblqh::execLQHFRAGREQ(Signal* signal) { jamEntry(); @@ -1049,6 +1053,11 @@ void Dblqh::execLQHFRAGREQ(Signal* signal) addfragptr.p->lh3DistrBits = tlhstar; addfragptr.p->tableType = tableType; addfragptr.p->primaryTableId = primaryTableId; + // + addfragptr.p->tup1Connectptr = RNIL; + addfragptr.p->tup2Connectptr = RNIL; + addfragptr.p->tux1Connectptr = RNIL; + addfragptr.p->tux2Connectptr = RNIL; if (DictTabInfo::isTable(tableType) || DictTabInfo::isHashIndex(tableType)) { @@ -1329,15 +1338,21 @@ void Dblqh::execTUP_ADD_ATTCONF(Signal* signal) { jamEntry(); addfragptr.i = signal->theData[0]; + // implies that operation was released on the other side + const bool lastAttr = signal->theData[1]; ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord); switch (addfragptr.p->addfragStatus) { case AddFragRecord::TUP_ATTR_WAIT1: jam(); + if (lastAttr) + addfragptr.p->tup1Connectptr = RNIL; addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT2; sendAddAttrReq(signal); break; case AddFragRecord::TUP_ATTR_WAIT2: jam(); + if (lastAttr) + addfragptr.p->tup2Connectptr = RNIL; if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) { addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT1; sendAddAttrReq(signal); @@ -1347,11 +1362,15 @@ void Dblqh::execTUP_ADD_ATTCONF(Signal* signal) break; case AddFragRecord::TUX_ATTR_WAIT1: jam(); + if (lastAttr) + addfragptr.p->tux1Connectptr = RNIL; addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT2; sendAddAttrReq(signal); break; case AddFragRecord::TUX_ATTR_WAIT2: jam(); + if (lastAttr) + addfragptr.p->tux2Connectptr = RNIL; goto done_with_attr; break; done_with_attr: @@ -1455,6 +1474,7 @@ Dblqh::sendAddAttrReq(Signal* signal) jam(); TupAddAttrConf* tupconf = (TupAddAttrConf*)signal->getDataPtrSend(); tupconf->userPtr = addfragptr.i; + tupconf->lastAttr = false; sendSignal(reference(), GSN_TUP_ADD_ATTCONF, signal, TupAddAttrConf::SignalLength, JBB); return; @@ -1485,6 +1505,7 @@ Dblqh::sendAddAttrReq(Signal* signal) jam(); TuxAddAttrConf* tuxconf = (TuxAddAttrConf*)signal->getDataPtrSend(); tuxconf->userPtr = addfragptr.i; + tuxconf->lastAttr = false; sendSignal(reference(), GSN_TUX_ADD_ATTRCONF, signal, TuxAddAttrConf::SignalLength, JBB); return; @@ -1549,6 +1570,40 @@ void Dblqh::fragrefLab(Signal* signal, return; }//Dblqh::fragrefLab() +/* + * Abort on-going ops. + */ +void Dblqh::abortAddFragOps(Signal* signal) +{ + fragptr.i = addfragptr.p->fragmentPtr; + ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord); + signal->theData[0] = (Uint32)-1; + if (addfragptr.p->tup1Connectptr != RNIL) { + jam(); + signal->theData[1] = addfragptr.p->tup1Connectptr; + sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB); + addfragptr.p->tup1Connectptr = RNIL; + } + if (addfragptr.p->tup2Connectptr != RNIL) { + jam(); + signal->theData[1] = addfragptr.p->tup2Connectptr; + sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB); + addfragptr.p->tup2Connectptr = RNIL; + } + if (addfragptr.p->tux1Connectptr != RNIL) { + jam(); + signal->theData[1] = addfragptr.p->tux1Connectptr; + sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB); + addfragptr.p->tux1Connectptr = RNIL; + } + if (addfragptr.p->tux2Connectptr != RNIL) { + jam(); + signal->theData[1] = addfragptr.p->tux2Connectptr; + sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB); + addfragptr.p->tux2Connectptr = RNIL; + } +} + /* ************>> */ /* ACCFRAGREF > */ /* ************>> */ @@ -1582,6 +1637,27 @@ void Dblqh::execTUPFRAGREF(Signal* signal) fragptr.i = addfragptr.p->fragmentPtr; ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord); addfragptr.p->addfragErrorCode = terrorCode; + + // no operation to release, just add some jams + switch (addfragptr.p->addfragStatus) { + case AddFragRecord::WAIT_TWO_TUP: + jam(); + break; + case AddFragRecord::WAIT_ONE_TUP: + jam(); + break; + case AddFragRecord::WAIT_TWO_TUX: + jam(); + break; + case AddFragRecord::WAIT_ONE_TUX: + jam(); + break; + default: + ndbrequire(false); + break; + } + abortAddFragOps(signal); + const Uint32 ref = addfragptr.p->dictBlockref; const Uint32 senderData = addfragptr.p->dictConnectptr; const Uint32 errorCode = addfragptr.p->addfragErrorCode; @@ -1605,11 +1681,38 @@ void Dblqh::execTUXFRAGREF(Signal* signal) void Dblqh::execTUP_ADD_ATTRREF(Signal* signal) { jamEntry(); - addfragptr.i = signal->theData[0]; ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord); terrorCode = signal->theData[1]; addfragptr.p->addfragErrorCode = terrorCode; + + // operation was released on the other side + switch (addfragptr.p->addfragStatus) { + case AddFragRecord::TUP_ATTR_WAIT1: + jam(); + ndbrequire(addfragptr.p->tup1Connectptr != RNIL); + addfragptr.p->tup1Connectptr = RNIL; + break; + case AddFragRecord::TUP_ATTR_WAIT2: + jam(); + ndbrequire(addfragptr.p->tup2Connectptr != RNIL); + addfragptr.p->tup2Connectptr = RNIL; + break; + case AddFragRecord::TUX_ATTR_WAIT1: + jam(); + ndbrequire(addfragptr.p->tux1Connectptr != RNIL); + addfragptr.p->tux1Connectptr = RNIL; + break; + case AddFragRecord::TUX_ATTR_WAIT2: + jam(); + ndbrequire(addfragptr.p->tux2Connectptr != RNIL); + addfragptr.p->tux2Connectptr = RNIL; + break; + default: + ndbrequire(false); + break; + } + abortAddFragOps(signal); const Uint32 Ref = addfragptr.p->dictBlockref; const Uint32 senderData = addfragptr.p->dictConnectptr; diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 55ad1d0910a..b48546576f9 100644 --- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -504,6 +504,7 @@ struct Fragoperrec { Uint32 noOfNewAttrCount; Uint32 charsetIndex; BlockReference lqhBlockrefFrag; + bool inUse; }; typedef Ptr FragoperrecPtr; @@ -1936,6 +1937,7 @@ private: void setUpKeyArray(Tablerec* const regTabPtr); bool addfragtotab(Tablerec* const regTabPtr, Uint32 fragId, Uint32 fragIndex); void deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId); + void abortAddFragOp(Signal* signal); void releaseTabDescr(Tablerec* const regTabPtr); void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* const regTabPtr); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp index efea312b865..914dba00674 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp @@ -39,11 +39,18 @@ /* ---------------------------------------------------------------- */ void Dbtup::execTUPFRAGREQ(Signal* signal) { + ljamEntry(); + + if (signal->theData[0] == (Uint32)-1) { + ljam(); + abortAddFragOp(signal); + return; + } + FragoperrecPtr fragOperPtr; FragrecordPtr regFragPtr; TablerecPtr regTabPtr; - ljamEntry(); Uint32 userptr = signal->theData[0]; Uint32 userblockref = signal->theData[1]; Uint32 reqinfo = signal->theData[2]; @@ -132,6 +139,15 @@ void Dbtup::execTUPFRAGREQ(Signal* signal) return; }//if + if (ERROR_INSERTED(4007) && regTabPtr.p->fragid[0] == fragId || + ERROR_INSERTED(4008) && regTabPtr.p->fragid[1] == fragId) { + ljam(); + terrorCode = 1; + fragrefuse4Lab(signal, fragOperPtr, regFragPtr, regTabPtr.p, fragId); + CLEAR_ERROR_INSERT_VALUE; + return; + } + if (regTabPtr.p->tableStatus == NOT_DEFINED) { ljam(); //------------------------------------------------------------------------------------- @@ -243,6 +259,7 @@ void Dbtup::seizeFragoperrec(FragoperrecPtr& fragOperPtr) ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec); cfirstfreeFragopr = fragOperPtr.p->nextFragoprec; fragOperPtr.p->nextFragoprec = RNIL; + fragOperPtr.p->inUse = true; }//Dbtup::seizeFragoperrec() /* **************************************************************** */ @@ -273,6 +290,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ndbrequire(fragOperPtr.p->attributeCount > 0); fragOperPtr.p->attributeCount--; + const bool lastAttr = (fragOperPtr.p->attributeCount == 0); if ((regTabPtr.p->tableStatus == DEFINING) && (fragOperPtr.p->definingFragment)) { @@ -346,20 +364,30 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId); return; }//if - if ((fragOperPtr.p->attributeCount == 0) && - (fragOperPtr.p->freeNullBit != 0)) { + if (lastAttr && (fragOperPtr.p->freeNullBit != 0)) { ljam(); terrorCode = ZINCONSISTENT_NULL_ATTRIBUTE_COUNT; addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId); return; }//if }//if + if (ERROR_INSERTED(4009) && regTabPtr.p->fragid[0] == fragId && attrId == 0 || + ERROR_INSERTED(4010) && regTabPtr.p->fragid[0] == fragId && lastAttr || + ERROR_INSERTED(4011) && regTabPtr.p->fragid[1] == fragId && attrId == 0 || + ERROR_INSERTED(4012) && regTabPtr.p->fragid[1] == fragId && lastAttr) { + ljam(); + terrorCode = 1; + addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId); + CLEAR_ERROR_INSERT_VALUE; + return; + } /* **************************************************************** */ /* ************** TUP_ADD_ATTCONF ****************** */ /* **************************************************************** */ signal->theData[0] = fragOperPtr.p->lqhPtrFrag; - sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF, signal, 1, JBB); - if (fragOperPtr.p->attributeCount > 0) { + signal->theData[1] = lastAttr; + sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF, signal, 2, JBB); + if (! lastAttr) { ljam(); return; /* EXIT AND WAIT FOR MORE */ }//if @@ -491,11 +519,11 @@ void Dbtup::fragrefuseLab(Signal* signal, FragoperrecPtr fragOperPtr) void Dbtup::releaseFragoperrec(FragoperrecPtr fragOperPtr) { + fragOperPtr.p->inUse = false; fragOperPtr.p->nextFragoprec = cfirstfreeFragopr; cfirstfreeFragopr = fragOperPtr.i; }//Dbtup::releaseFragoperrec() - void Dbtup::deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId) { for (Uint32 i = 0; i < (2 * MAX_FRAG_PER_NODE); i++) { @@ -510,6 +538,20 @@ void Dbtup::deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId) ndbrequire(false); }//Dbtup::deleteFragTab() +/* + * LQH aborts on-going create table operation. The table is later + * dropped by DICT. + */ +void Dbtup::abortAddFragOp(Signal* signal) +{ + FragoperrecPtr fragOperPtr; + + fragOperPtr.i = signal->theData[1]; + ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec); + ndbrequire(fragOperPtr.p->inUse); + releaseFragoperrec(fragOperPtr); +} + void Dbtup::execDROP_TAB_REQ(Signal* signal) { diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index 8896324f793..8f49b7fa6d6 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -575,6 +575,7 @@ private: void execDROP_TAB_REQ(Signal* signal); bool allocDescEnt(IndexPtr indexPtr); void freeDescEnt(IndexPtr indexPtr); + void abortAddFragOp(Signal* signal); void dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 senderData); /* @@ -684,6 +685,7 @@ private: friend class NdbOut& operator<<(NdbOut&, const ScanOp&); friend class NdbOut& operator<<(NdbOut&, const Index&); friend class NdbOut& operator<<(NdbOut&, const Frag&); + friend class NdbOut& operator<<(NdbOut&, const FragOp&); friend class NdbOut& operator<<(NdbOut&, const NodeHandle&); FILE* debugFile; NdbOut debugOut; diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp index c5c22264460..1e1b0d1d5b6 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp @@ -403,6 +403,19 @@ operator<<(NdbOut& out, const Dbtux::Frag& frag) return out; } +NdbOut& +operator<<(NdbOut& out, const Dbtux::FragOp& fragOp) +{ + out << "[FragOp " << hex << &fragOp; + out << " [userPtr " << dec << fragOp.m_userPtr << "]"; + out << " [indexId " << dec << fragOp.m_indexId << "]"; + out << " [fragId " << dec << fragOp.m_fragId << "]"; + out << " [fragNo " << dec << fragOp.m_fragNo << "]"; + out << " numAttrsRecvd " << dec << fragOp.m_numAttrsRecvd << "]"; + out << "]"; + return out; +} + NdbOut& operator<<(NdbOut& out, const Dbtux::NodeHandle& node) { diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index ded02696a89..18aa914de05 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -24,12 +24,7 @@ Dbtux::Dbtux(const Configuration& conf) : #ifdef VM_TRACE debugFile(0), debugOut(*new NullOutputStream()), - // until ndb_mgm supports dump -#ifdef DBTUX_DEBUG_TREE - debugFlags(DebugTree), -#else debugFlags(0), -#endif #endif c_internalStartPhase(0), c_typeOfStart(NodeState::ST_ILLEGAL_TYPE), @@ -86,7 +81,7 @@ Dbtux::execCONTINUEB(Signal* signal) jamEntry(); const Uint32* data = signal->getDataPtr(); switch (data[0]) { - case TuxContinueB::DropIndex: + case TuxContinueB::DropIndex: // currently unused { IndexPtr indexPtr; c_indexPool.getPtr(indexPtr, data[1]); @@ -174,7 +169,7 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal) ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_ATTRIBUTE, &nAttribute)); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp)); - const Uint32 nDescPage = (nIndex + nAttribute + DescPageSize - 1) / DescPageSize; + const Uint32 nDescPage = (nIndex * DescHeadSize + nAttribute * DescAttrSize + DescPageSize - 1) / DescPageSize; const Uint32 nScanBoundWords = nScanOp * ScanBoundSegmentSize * 4; c_indexPool.setSize(nIndex); diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp index 1577c5045e0..b7526593a08 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp @@ -29,6 +29,11 @@ void Dbtux::execTUXFRAGREQ(Signal* signal) { jamEntry(); + if (signal->theData[0] == (Uint32)-1) { + jam(); + abortAddFragOp(signal); + return; + } const TuxFragReq reqCopy = *(const TuxFragReq*)signal->getDataPtr(); const TuxFragReq* const req = &reqCopy; IndexPtr indexPtr; @@ -61,6 +66,11 @@ Dbtux::execTUXFRAGREQ(Signal* signal) fragOpPtr.p->m_fragId = req->fragId; fragOpPtr.p->m_fragNo = indexPtr.p->m_numFrags; fragOpPtr.p->m_numAttrsRecvd = 0; +#ifdef VM_TRACE + if (debugFlags & DebugMeta) { + debugOut << "Seize frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl; + } +#endif // check if index has place for more fragments ndbrequire(indexPtr.p->m_numFrags < MaxIndexFragments); // seize new fragment record @@ -129,6 +139,14 @@ Dbtux::execTUXFRAGREQ(Signal* signal) debugOut << "Add frag " << fragPtr.i << " " << *fragPtr.p << endl; } #endif + // error inserts + if (ERROR_INSERTED(12001) && fragOpPtr.p->m_fragNo == 0 || + ERROR_INSERTED(12002) && fragOpPtr.p->m_fragNo == 1) { + jam(); + errorCode = (TuxFragRef::ErrorCode)1; + CLEAR_ERROR_INSERT_VALUE; + break; + } // success TuxFragConf* const conf = (TuxFragConf*)signal->getDataPtrSend(); conf->userPtr = req->userPtr; @@ -145,10 +163,18 @@ Dbtux::execTUXFRAGREQ(Signal* signal) ref->errorCode = errorCode; sendSignal(req->userRef, GSN_TUXFRAGREF, signal, TuxFragRef::SignalLength, JBB); - if (fragOpPtr.i != RNIL) + if (fragOpPtr.i != RNIL) { +#ifdef VM_TRACE + if (debugFlags & DebugMeta) { + debugOut << "Release on frag error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl; + } +#endif c_fragOpPool.release(fragOpPtr); - if (indexPtr.i != RNIL) - dropIndex(signal, indexPtr, 0, 0); + } + if (indexPtr.i != RNIL) { + jam(); + // let DICT drop the unfinished index + } } void @@ -203,7 +229,16 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) } } #endif - if (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd) { + const bool lastAttr = (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd); + if (ERROR_INSERTED(12003) && fragOpPtr.p->m_fragNo == 0 && attrId == 0 || + ERROR_INSERTED(12004) && fragOpPtr.p->m_fragNo == 0 && lastAttr || + ERROR_INSERTED(12005) && fragOpPtr.p->m_fragNo == 1 && attrId == 0 || + ERROR_INSERTED(12006) && fragOpPtr.p->m_fragNo == 1 && lastAttr) { + errorCode = (TuxAddAttrRef::ErrorCode)1; + CLEAR_ERROR_INSERT_VALUE; + break; + } + if (lastAttr) { jam(); // initialize tree header TreeHead& tree = fragPtr.p->m_tree; @@ -246,11 +281,17 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) } #endif // fragment is defined +#ifdef VM_TRACE + if (debugFlags & DebugMeta) { + debugOut << "Release frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl; + } +#endif c_fragOpPool.release(fragOpPtr); } // success TuxAddAttrConf* conf = (TuxAddAttrConf*)signal->getDataPtrSend(); conf->userPtr = fragOpPtr.p->m_userPtr; + conf->lastAttr = lastAttr; sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRCONF, signal, TuxAddAttrConf::SignalLength, JBB); return; @@ -261,8 +302,32 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) ref->errorCode = errorCode; sendSignal(fragOpPtr.p->m_userRef, GSN_TUX_ADD_ATTRREF, signal, TuxAddAttrRef::SignalLength, JBB); +#ifdef VM_TRACE + if (debugFlags & DebugMeta) { + debugOut << "Release on attr error frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl; + } +#endif c_fragOpPool.release(fragOpPtr); - dropIndex(signal, indexPtr, 0, 0); + // let DICT drop the unfinished index +} + +/* + * LQH aborts on-going create index operation. + */ +void +Dbtux::abortAddFragOp(Signal* signal) +{ + FragOpPtr fragOpPtr; + IndexPtr indexPtr; + c_fragOpPool.getPtr(fragOpPtr, signal->theData[1]); + c_indexPool.getPtr(indexPtr, fragOpPtr.p->m_indexId); +#ifdef VM_TRACE + if (debugFlags & DebugMeta) { + debugOut << "Release on abort frag op " << fragOpPtr.i << " " << *fragOpPtr.p << endl; + } +#endif + c_fragOpPool.release(fragOpPtr); + // let DICT drop the unfinished index } /* @@ -341,20 +406,13 @@ Dbtux::dropIndex(Signal* signal, IndexPtr indexPtr, Uint32 senderRef, Uint32 sen { jam(); indexPtr.p->m_state = Index::Dropping; - // drop one fragment at a time - if (indexPtr.p->m_numFrags > 0) { + // drop fragments + while (indexPtr.p->m_numFrags > 0) { jam(); - unsigned i = --indexPtr.p->m_numFrags; + Uint32 i = --indexPtr.p->m_numFrags; FragPtr fragPtr; c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]); c_fragPool.release(fragPtr); - // the real time break is not used for anything currently - signal->theData[0] = TuxContinueB::DropIndex; - signal->theData[1] = indexPtr.i; - signal->theData[2] = senderRef; - signal->theData[3] = senderData; - sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB); - return; } // drop attributes if (indexPtr.p->m_descPage != RNIL) { diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index 9552e321f00..b832cb7039b 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1479,6 +1479,69 @@ runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){ + static int tuplst[] = { 4007, 4008, 4009, 4010, 4011, 4012 }; + static int tuxlst[] = { 12001, 12002, 12003, 12004, 12005, 12006 }; + static unsigned tupcnt = sizeof(tuplst)/sizeof(tuplst[0]); + static unsigned tuxcnt = sizeof(tuxlst)/sizeof(tuxlst[0]); + + NdbRestarter restarter; + int nodeId = restarter.getMasterNodeId(); + Ndb* pNdb = GETNDB(step); + NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); + NdbDictionary::Table tab(*ctx->getTab()); + tab.setFragmentType(NdbDictionary::Object::FragAllLarge); + + // ordered index on first few columns + NdbDictionary::Index idx("X"); + idx.setTable(tab.getName()); + idx.setType(NdbDictionary::Index::OrderedIndex); + idx.setLogging(false); + for (int i_hate_broken_compilers = 0; + i_hate_broken_compilers < 3 && + i_hate_broken_compilers < tab.getNoOfColumns(); + i_hate_broken_compilers++) { + idx.addColumn(*tab.getColumn(i_hate_broken_compilers)); + } + + const int loops = ctx->getNumLoops(); + int result = NDBT_OK; + (void)pDic->dropTable(tab.getName()); + + for (int l = 0; l < loops; l++) { + for (unsigned i = 0; i < tupcnt; i++) { + unsigned j = (l == 0 ? i : myRandom48(tupcnt)); + int errval = tuplst[j]; + g_info << "insert error node=" << nodeId << " value=" << errval << endl; + CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0, + "failed to set error insert"); + CHECK2(pDic->createTable(tab) != 0, + "failed to fail after error insert " << errval); + CHECK2(pDic->createTable(tab) == 0, + pDic->getNdbError()); + CHECK2(pDic->dropTable(tab.getName()) == 0, + pDic->getNdbError()); + } + for (unsigned i = 0; i < tuxcnt; i++) { + unsigned j = (l == 0 ? i : myRandom48(tuxcnt)); + int errval = tuxlst[j]; + g_info << "insert error node=" << nodeId << " value=" << errval << endl; + CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0, + "failed to set error insert"); + CHECK2(pDic->createTable(tab) == 0, + pDic->getNdbError()); + CHECK2(pDic->createIndex(idx) != 0, + "failed to fail after error insert " << errval); + CHECK2(pDic->createIndex(idx) == 0, + pDic->getNdbError()); + CHECK2(pDic->dropTable(tab.getName()) == 0, + pDic->getNdbError()); + } + } +end: + return result; +} + NDBT_TESTSUITE(testDict); TESTCASE("CreateAndDrop", "Try to create and drop the table loop number of times\n"){ @@ -1574,6 +1637,10 @@ TESTCASE("DictionaryPerf", ""){ INITIALIZER(runTestDictionaryPerf); } +TESTCASE("FailAddFragment", + "Fail add fragment or attribute in TUP or TUX\n"){ + INITIALIZER(runFailAddFragment); +} NDBT_TESTSUITE_END(testDict); int main(int argc, const char** argv){ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index d9545d5cbb8..6c4870817e3 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2144,22 +2144,19 @@ void ha_ndbcluster::print_results() } case NdbDictionary::Column::Decimal: { char *value= field->ptr; - fprintf(DBUG_FILE, "Decimal\t'%-*s'", field->pack_length(), value); break; } case NdbDictionary::Column::Char:{ - char buf[field->pack_length()+1]; - char *value= (char *) field->ptr; - snprintf(buf, field->pack_length(), "%s", value); - fprintf(DBUG_FILE, "Char\t'%s'", buf); + const char *value= (char *) field->ptr; + fprintf(DBUG_FILE, "Char\t'%.*s'", field->pack_length(), value); break; } case NdbDictionary::Column::Varchar: case NdbDictionary::Column::Binary: case NdbDictionary::Column::Varbinary: { - char *value= (char *) field->ptr; - fprintf(DBUG_FILE, "'%s'", value); + const char *value= (char *) field->ptr; + fprintf(DBUG_FILE, "Var\t'%.*s'", field->pack_length(), value); break; } case NdbDictionary::Column::Datetime: { From 03d6e2453b3a421a6ab97ec1abd84cc22c9fa158 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 13 Nov 2004 17:49:20 +0100 Subject: [PATCH 03/44] ndb: minor ndb/test/ndbapi/testDict.cpp: compile fix --- ndb/test/ndbapi/testDict.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index b832cb7039b..712ab2e4d25 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1509,8 +1509,8 @@ int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){ (void)pDic->dropTable(tab.getName()); for (int l = 0; l < loops; l++) { - for (unsigned i = 0; i < tupcnt; i++) { - unsigned j = (l == 0 ? i : myRandom48(tupcnt)); + for (unsigned i1 = 0; i1 < tupcnt; i1++) { + unsigned j = (l == 0 ? i1 : myRandom48(tupcnt)); int errval = tuplst[j]; g_info << "insert error node=" << nodeId << " value=" << errval << endl; CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0, @@ -1522,8 +1522,8 @@ int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){ CHECK2(pDic->dropTable(tab.getName()) == 0, pDic->getNdbError()); } - for (unsigned i = 0; i < tuxcnt; i++) { - unsigned j = (l == 0 ? i : myRandom48(tuxcnt)); + for (unsigned i2 = 0; i2 < tuxcnt; i2++) { + unsigned j = (l == 0 ? i2 : myRandom48(tuxcnt)); int errval = tuxlst[j]; g_info << "insert error node=" << nodeId << " value=" << errval << endl; CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0, From 5d9f7edd6dfb0d6759a5374ac61c0153db48b1f7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 15 Nov 2004 15:44:29 +0300 Subject: [PATCH 04/44] Fix for bug #6266 "Invalid DATETIME value is not handled properly". In server we assume that datetime values stored in MYSQL_TIME struct are normalized (and year is not greater than 9999), so we should perform range checks in all places then we convert something to MYSQL_TIME. include/my_time.h: Added one more argument to set_zero_time() function to make it more convinient. Added comment clarifying why MAX_DATE_STRING_REP_LENGTH value is 30. include/mysql_time.h: Documented MySQL's internal assumptions for members of MYSQL_TIME structure. libmysql/libmysql.c: It does not make sense to set MYSQL_TIME::time_type twice in case of errors. mysql-test/r/type_datetime.result: Added test for bug #6266 "Invalid DATETIME value not handled properly". mysql-test/t/type_datetime.test: Added test for bug #6266 "Invalid DATETIME value not handled properly". sql-common/my_time.c: str_to_datetime(): Added missing check for too big year values. set_zero_time(): added time_type argument, since MYSQL_TIMESTAMP_NONE is not the value that we want in most cases. sql/field.cc: Field_datetime::store_time(): clarified why we don't perform any range checks here. sql/item.cc: Item_param::set_time(): Added comment describing this method and range checking for TIME values. sql/sql_prepare.cc: Removed comments about range checking for TIME values in prepared statements, which are no longer true. set_zero_time() has one more argument now. tests/client_test.c: Added test for bug #6266 "Invalid DATETIME value not handled properly" --- include/my_time.h | 5 +- include/mysql_time.h | 12 +++ libmysql/libmysql.c | 13 +-- mysql-test/r/type_datetime.result | 11 ++- mysql-test/t/type_datetime.test | 7 +- sql-common/my_time.c | 7 +- sql/field.cc | 4 + sql/item.cc | 26 ++++++ sql/sql_prepare.cc | 23 +---- tests/client_test.c | 135 ++++++++++++++++++++++++++++++ 10 files changed, 209 insertions(+), 34 deletions(-) diff --git a/include/my_time.h b/include/my_time.h index dab17904b2d..94701e159c4 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -58,14 +58,15 @@ void init_time(void); my_time_t my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap); -void set_zero_time(MYSQL_TIME *tm); +void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type); /* Required buffer length for my_time_to_str, my_date_to_str, my_datetime_to_str and TIME_to_string functions. Note, that the caller is still responsible to check that given TIME structure has values in valid ranges, otherwise size of the buffer could - be not enough. + be not enough. We also rely on the fact that even wrong values + sent using binary protocol fit in this buffer. */ #define MAX_DATE_STRING_REP_LENGTH 30 diff --git a/include/mysql_time.h b/include/mysql_time.h index ec67d60dea5..5f4fc12c005 100644 --- a/include/mysql_time.h +++ b/include/mysql_time.h @@ -33,6 +33,18 @@ enum enum_mysql_timestamp_type }; +/* + Structure which is used to represent datetime values inside MySQL. + + We assume that values in this structure are normalized, i.e. year <= 9999, + month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions + in server such as my_system_gmt_sec() or make_time() family of functions + rely on this (actually now usage of make_*() family relies on a bit weaker + restriction). Also functions that produce MYSQL_TIME as result ensure this. + There is one exception to this rule though if this structure holds time + value (time_type == MYSQL_TIMESTAMP_TIME) days and hour member can hold + bigger values. +*/ typedef struct st_mysql_time { unsigned int year, month, day, hour, minute, second; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 88f46ce19e7..bfbfd9670ca 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3256,11 +3256,12 @@ static void read_binary_time(MYSQL_TIME *tm, uchar **pos) tm->hour+= tm->day*24; tm->day= 0; } + tm->time_type= MYSQL_TIMESTAMP_TIME; + *pos+= length; } else - set_zero_time(tm); - tm->time_type= MYSQL_TIMESTAMP_TIME; + set_zero_time(tm, MYSQL_TIMESTAMP_TIME); } static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos) @@ -3285,12 +3286,12 @@ static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos) else tm->hour= tm->minute= tm->second= 0; tm->second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0; + tm->time_type= MYSQL_TIMESTAMP_DATETIME; *pos+= length; } else - set_zero_time(tm); - tm->time_type= MYSQL_TIMESTAMP_DATETIME; + set_zero_time(tm, MYSQL_TIMESTAMP_DATETIME); } static void read_binary_date(MYSQL_TIME *tm, uchar **pos) @@ -3307,12 +3308,12 @@ static void read_binary_date(MYSQL_TIME *tm, uchar **pos) tm->hour= tm->minute= tm->second= 0; tm->second_part= 0; tm->neg= 0; + tm->time_type= MYSQL_TIMESTAMP_DATE; *pos+= length; } else - set_zero_time(tm); - tm->time_type= MYSQL_TIMESTAMP_DATE; + set_zero_time(tm, MYSQL_TIMESTAMP_DATE); } diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 524bc9c50d4..127a54e087b 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -97,13 +97,15 @@ select * from t1 where a is null or b is null; a b drop table t1; create table t1 (t datetime); -insert into t1 values (20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460); +insert into t1 values (20030102030460),(20030102036301),(20030102240401), +(20030132030401),(20031302030401),(100001202030401); Warnings: Warning 1265 Data truncated for column 't' at row 1 Warning 1265 Data truncated for column 't' at row 2 Warning 1265 Data truncated for column 't' at row 3 Warning 1265 Data truncated for column 't' at row 4 Warning 1265 Data truncated for column 't' at row 5 +Warning 1265 Data truncated for column 't' at row 6 select * from t1; t 0000-00-00 00:00:00 @@ -111,14 +113,18 @@ t 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 +0000-00-00 00:00:00 delete from t1; -insert into t1 values ("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460"); +insert into t1 values +("2003-01-02 03:04:60"),("2003-01-02 03:63:01"),("2003-01-02 24:04:01"), +("2003-01-32 03:04:01"),("2003-13-02 03:04:01"), ("10000-12-02 03:04:00"); Warnings: Warning 1264 Data truncated; out of range for column 't' at row 1 Warning 1264 Data truncated; out of range for column 't' at row 2 Warning 1264 Data truncated; out of range for column 't' at row 3 Warning 1264 Data truncated; out of range for column 't' at row 4 Warning 1264 Data truncated; out of range for column 't' at row 5 +Warning 1264 Data truncated; out of range for column 't' at row 6 select * from t1; t 0000-00-00 00:00:00 @@ -126,6 +132,7 @@ t 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 +0000-00-00 00:00:00 delete from t1; insert into t1 values ("0000-00-00 00:00:00 some trailer"),("2003-01-01 00:00:00 some trailer"); Warnings: diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 47866058524..04e4a73554a 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -77,10 +77,13 @@ drop table t1; # warnings (for both strings and numbers) # create table t1 (t datetime); -insert into t1 values (20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460); +insert into t1 values (20030102030460),(20030102036301),(20030102240401), + (20030132030401),(20031302030401),(100001202030401); select * from t1; delete from t1; -insert into t1 values ("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460"); +insert into t1 values + ("2003-01-02 03:04:60"),("2003-01-02 03:63:01"),("2003-01-02 24:04:01"), + ("2003-01-32 03:04:01"),("2003-13-02 03:04:01"), ("10000-12-02 03:04:00"); select * from t1; delete from t1; insert into t1 values ("0000-00-00 00:00:00 some trailer"),("2003-01-01 00:00:00 some trailer"); diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 6c020466e1e..6b305944154 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -343,7 +343,8 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, (l_time->month || l_time->day)) l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); - if (number_of_fields < 3 || l_time->month > 12 || + if (number_of_fields < 3 || + l_time->year > 9999 || l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || l_time->minute > 59 || l_time->second > 59 || (!(flags & TIME_FUZZY_DATE) && (l_time->month == 0 || l_time->day == 0))) @@ -720,10 +721,10 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap) /* Set MYSQL_TIME structure to 0000-00-00 00:00:00.000000 */ -void set_zero_time(MYSQL_TIME *tm) +void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type) { bzero((void*) tm, sizeof(*tm)); - tm->time_type= MYSQL_TIMESTAMP_NONE; + tm->time_type= time_type; } diff --git a/sql/field.cc b/sql/field.cc index 24bd0c48c92..7d1627ef521 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4086,6 +4086,10 @@ int Field_datetime::store(longlong nr) void Field_datetime::store_time(TIME *ltime,timestamp_type type) { longlong tmp; + /* + We don't perform range checking here since values stored in TIME + structure always fit into DATETIME range. + */ if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME) tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+ (ltime->hour*10000L+ltime->minute*100+ltime->second)); diff --git a/sql/item.cc b/sql/item.cc index 7dc7e9e542c..382b85f9dc1 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -837,6 +837,21 @@ void Item_param::set_double(double d) } +/* + Set parameter value from TIME value. + + SYNOPSIS + set_time() + tm - datetime value to set (time_type is ignored) + type - type of datetime value + max_length_arg - max length of datetime value as string + + NOTE + If we value to be stored is not normalized, zero value will be stored + instead and proper warning will be produced. This function relies on + the fact that even wrong value sent over binary protocol fits into + MAX_DATE_STRING_REP_LENGTH buffer. +*/ void Item_param::set_time(TIME *tm, timestamp_type type, uint32 max_length_arg) { DBUG_ENTER("Item_param::set_time"); @@ -844,6 +859,17 @@ void Item_param::set_time(TIME *tm, timestamp_type type, uint32 max_length_arg) value.time= *tm; value.time.time_type= type; + if (value.time.year > 9999 || value.time.month > 12 || + value.time.day > 31 || + type != MYSQL_TIMESTAMP_TIME && value.time.hour > 23 || + value.time.minute > 59 || value.time.second > 59) + { + char buff[MAX_DATE_STRING_REP_LENGTH]; + uint length= my_TIME_to_str(&value.time, buff); + make_truncated_value_warning(current_thd, buff, length, type); + set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR); + } + state= TIME_VALUE; maybe_null= 0; max_length= max_length_arg; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 4ae69e40342..089853456e4 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -349,12 +349,6 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len) tm.neg= (bool) to[0]; day= (uint) sint4korr(to+1); - /* - Note, that though ranges of hour, minute and second are not checked - here we rely on them being < 256: otherwise - we'll get buffer overflow in make_{date,time} functions, - which are called when time value is converted to string. - */ tm.hour= (uint) to[5] + day * 24; tm.minute= (uint) to[6]; tm.second= (uint) to[7]; @@ -369,7 +363,7 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len) tm.day= tm.year= tm.month= 0; } else - set_zero_time(&tm); + set_zero_time(&tm, MYSQL_TIMESTAMP_TIME); param->set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; @@ -388,11 +382,6 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len) tm.year= (uint) sint2korr(to); tm.month= (uint) to[2]; tm.day= (uint) to[3]; - /* - Note, that though ranges of hour, minute and second are not checked - here we rely on them being < 256: otherwise - we'll get buffer overflow in make_{date,time} functions. - */ if (length > 4) { tm.hour= (uint) to[4]; @@ -405,7 +394,7 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len) tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0; } else - set_zero_time(&tm); + set_zero_time(&tm, MYSQL_TIMESTAMP_DATETIME); param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; @@ -419,11 +408,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) if (length >= 4) { uchar *to= *pos; - /* - Note, that though ranges of hour, minute and second are not checked - here we rely on them being < 256: otherwise - we'll get buffer overflow in make_{date,time} functions. - */ + tm.year= (uint) sint2korr(to); tm.month= (uint) to[2]; tm.day= (uint) to[3]; @@ -433,7 +418,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) tm.neg= 0; } else - set_zero_time(&tm); + set_zero_time(&tm, MYSQL_TIMESTAMP_DATE); param->set_time(&tm, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; diff --git a/tests/client_test.c b/tests/client_test.c index 227f7e29ef2..bf0b69f9354 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -11088,6 +11088,139 @@ static void test_bug6096() } +/* + Test of basic checks that are performed in server for components + of MYSQL_TIME parameters. + */ +static void test_datetime_ranges() +{ + const char *stmt_text; + int rc, i; + MYSQL_STMT *stmt; + MYSQL_BIND bind[6]; + MYSQL_TIME tm[6]; + + myheader("test_datetime_ranges"); + + stmt_text= "drop table if exists t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "create table t1 (year datetime, month datetime, day datetime, " + "hour datetime, min datetime, sec datetime)"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt= mysql_simple_prepare(mysql, + "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)"); + check_stmt(stmt); + verify_param_count(stmt, 6); + + bzero(bind, sizeof(bind)); + for (i= 0; i < 6; i++) + { + bind[i].buffer_type= MYSQL_TYPE_DATETIME; + bind[i].buffer= &tm[i]; + } + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt, rc); + + tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10; + tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30; + tm[0].second_part= 0; tm[0].neg= 0; + + tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0]; + tm[0].year= 10000; tm[1].month= 13; tm[2].day= 32; + tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60; + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + DIE_UNLESS(mysql_warning_count(mysql) != 6); + + verify_col_data("t1", "year", "0000-00-00 00:00:00"); + verify_col_data("t1", "month", "0000-00-00 00:00:00"); + verify_col_data("t1", "day", "0000-00-00 00:00:00"); + verify_col_data("t1", "hour", "0000-00-00 00:00:00"); + verify_col_data("t1", "min", "0000-00-00 00:00:00"); + verify_col_data("t1", "sec", "0000-00-00 00:00:00"); + + mysql_stmt_close(stmt); + + stmt_text= "delete from t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) " + "VALUES (?, ?, ?)"); + check_stmt(stmt); + verify_param_count(stmt, 3); + + /* + We reuse contents of bind and tm arrays left from previous part of test. + */ + for (i= 0; i < 3; i++) + bind[i].buffer_type= MYSQL_TYPE_DATE; + + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + DIE_UNLESS(mysql_warning_count(mysql) != 3); + + verify_col_data("t1", "year", "0000-00-00 00:00:00"); + verify_col_data("t1", "month", "0000-00-00 00:00:00"); + verify_col_data("t1", "day", "0000-00-00 00:00:00"); + + mysql_stmt_close(stmt); + + stmt_text= "drop table t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt= mysql_simple_prepare(mysql, + "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)"); + check_stmt(stmt); + verify_param_count(stmt, 5); + + /* + Again we reuse what we can from previous part of test. + */ + for (i= 0; i < 5; i++) + bind[i].buffer_type= MYSQL_TYPE_TIME; + + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt, rc); + + tm[0].year= 0; tm[0].month= 0; tm[0].day= 10; + tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30; + tm[0].second_part= 0; tm[0].neg= 0; + + tm[4]= tm[3]= tm[2]= tm[1]= tm[0]; + tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60; + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + DIE_UNLESS(mysql_warning_count(mysql) != 2); + + verify_col_data("t1", "day_ovfl", "838:59:59"); + verify_col_data("t1", "day", "828:30:30"); + verify_col_data("t1", "hour", "270:30:30"); + verify_col_data("t1", "min", "00:00:00"); + verify_col_data("t1", "sec", "00:00:00"); + + mysql_stmt_close(stmt); + + stmt_text= "drop table t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -11404,6 +11537,8 @@ int main(int argc, char **argv) test_bug6046(); /* NATURAL JOIN transformation works in PS */ test_bug6081(); /* test of mysql_create_db()/mysql_rm_db() */ test_bug6096(); /* max_length for numeric columns */ + test_datetime_ranges(); /* Test if basic checks are performed for + components of MYSQL_TIME parameters */ /* XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. From e1509cf78105e95f7e335f33bd3349ea77a099ac Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 15 Nov 2004 16:11:13 +0300 Subject: [PATCH 05/44] Proposed fix for bug #6439 "from_unixtime() function returns wrong datetime values for too big argument". Added range checking for from_unixtime() argument, cleaned up code a bit. mysql-test/r/func_time.result: Test for bug #6439 "from_unixtime() function returns wrong datetime values for too big argument". mysql-test/t/func_time.test: Test for bug #6439 "from_unixtime() function returns wrong datetime values for too big argument". sql/item_timefunc.cc: Item_func_from_unixtime: Added error range checking for function argument + small code clean up. --- mysql-test/r/func_time.result | 6 ++++ mysql-test/t/func_time.test | 7 +++++ sql/item_timefunc.cc | 57 ++++++++++++++--------------------- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 877ca0e2d51..32034bf289d 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -470,3 +470,9 @@ unix_timestamp(@a) select unix_timestamp('1969-12-01 19:00:01'); unix_timestamp('1969-12-01 19:00:01') 0 +select from_unixtime(0); +from_unixtime(0) +NULL +select from_unixtime(2145916800); +from_unixtime(2145916800) +NULL diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index fffda12c14e..da18269cf6a 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -225,3 +225,10 @@ drop table t1,t2,t3; select @a:=FROM_UNIXTIME(1); select unix_timestamp(@a); select unix_timestamp('1969-12-01 19:00:01'); + +# +# Test for bug #6439 "unix_timestamp() function returns wrong datetime +# values for too big argument". It should return error instead. +# +select from_unixtime(0); +select from_unixtime(2145916800); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index ed950a33166..d188310be24 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -919,21 +919,14 @@ String *Item_func_date_format::val_str(String *str) String *Item_func_from_unixtime::val_str(String *str) { - struct tm tm_tmp,*start; - time_t tmp=(time_t) args[0]->val_int(); - if ((null_value=args[0]->null_value)) + TIME ltime; + if (get_date(<ime, 0)) return 0; - localtime_r(&tmp,&tm_tmp); - start=&tm_tmp; if (str->alloc(20)) return str; /* purecov: inspected */ sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d", - (int) start->tm_year+1900, - (int) start->tm_mon+1, - (int) start->tm_mday, - (int) start->tm_hour, - (int) start->tm_min, - (int) start->tm_sec); + (int) ltime.year, (int) ltime.month, (int) ltime.day, + (int) ltime.hour, (int) ltime.minute, (int) ltime.second); str->length(19); return str; } @@ -941,37 +934,33 @@ String *Item_func_from_unixtime::val_str(String *str) longlong Item_func_from_unixtime::val_int() { - time_t tmp=(time_t) (ulong) args[0]->val_int(); - if ((null_value=args[0]->null_value)) + TIME ltime; + if (get_date(<ime, 0)) return 0; - struct tm tm_tmp,*start; - localtime_r(&tmp,&tm_tmp); - start= &tm_tmp; - return ((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+ - (((uint) start->tm_mon+1)*100+ - (uint) start->tm_mday))*LL(1000000)+ - (longlong) ((ulong) ((uint) start->tm_hour)*10000L+ - (ulong) (((uint) start->tm_min)*100L+ - (uint) start->tm_sec))); + return ((longlong)(ltime.year*10000L+ltime.month*100+ltime.day)*LL(1000000)+ + (longlong)(ltime.hour*10000L+ltime.minute*100+ltime.second)); } bool Item_func_from_unixtime::get_date(TIME *ltime, bool fuzzy_date __attribute__((unused))) { - time_t tmp=(time_t) (ulong) args[0]->val_int(); - if ((null_value=args[0]->null_value)) + struct tm tm_tmp; + time_t tmp; + longlong arg= args[0]->val_int(); + if ((null_value= (args[0]->null_value || + arg < TIMESTAMP_MIN_VALUE || + arg > TIMESTAMP_MAX_VALUE))) return 1; - struct tm tm_tmp,*start; + tmp= arg; localtime_r(&tmp,&tm_tmp); - start= &tm_tmp; - ltime->year= start->tm_year+1900; - ltime->month= start->tm_mon+1; - ltime->day= start->tm_mday; - ltime->hour= start->tm_hour; - ltime->minute=start->tm_min; - ltime->second=start->tm_sec; - ltime->second_part=0; - ltime->neg=0; + ltime->year= tm_tmp.tm_year+1900; + ltime->month= tm_tmp.tm_mon+1; + ltime->day= tm_tmp.tm_mday; + ltime->hour= tm_tmp.tm_hour; + ltime->minute= tm_tmp.tm_min; + ltime->second= tm_tmp.tm_sec; + ltime->second_part= 0; + ltime->neg= 0; return 0; } From 692311f53c08b99b3d9353e8f50927df445a0dc5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 17 Nov 2004 08:10:26 +0000 Subject: [PATCH 06/44] enabled having system tables in ndb --- sql/sql_acl.cc | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 98af43e17a7..d6f52fed1d2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1384,8 +1384,10 @@ static bool update_user_table(THD *thd, const char *host, const char *user, table->field[0]->store(host,(uint) strlen(host), &my_charset_latin1); table->field[1]->store(user,(uint) strlen(user), &my_charset_latin1); + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, - (byte*) table->field[0]->ptr,0, + (byte*) table->field[0]->ptr, + table->key_info[0].key_length, HA_READ_KEY_EXACT)) { my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */ @@ -1463,9 +1465,11 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); table->field[1]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0], 0, - (byte*) table->field[0]->ptr,0, - HA_READ_KEY_EXACT)) + (byte*) table->field[0]->ptr, + table->key_info[0].key_length, + HA_READ_KEY_EXACT)) { if (!create_user) { @@ -1568,6 +1572,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, We should NEVER delete from the user table, as a uses can still use mysqld even if he doesn't have any privileges in the user table! */ + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (cmp_record(table,record[1]) && (error=table->file->update_row(table->record[1],table->record[0]))) { // This should never happen @@ -1645,8 +1650,11 @@ static int replace_db_table(TABLE *table, const char *db, table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - if (table->file->index_read_idx(table->record[0],0,(byte*) table->field[0]->ptr,0, - HA_READ_KEY_EXACT)) + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); + if (table->file->index_read_idx(table->record[0],0, + (byte*) table->field[0]->ptr, + table->key_info[0].key_length, + HA_READ_KEY_EXACT)) { if (what == 'N') { // no row, no revoke @@ -1679,6 +1687,7 @@ static int replace_db_table(TABLE *table, const char *db, /* update old existing row */ if (rights) { + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if ((error=table->file->update_row(table->record[1],table->record[0]))) goto table_error; /* purecov: deadcode */ } @@ -1953,8 +1962,10 @@ static int replace_column_table(GRANT_TABLE *g_t, table->field[4]->store(xx->column.ptr(),xx->column.length(), &my_charset_latin1); + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr, - 0, HA_READ_KEY_EXACT)) + table->key_info[0].key_length, + HA_READ_KEY_EXACT)) { if (revoke_grant) { @@ -2022,8 +2033,10 @@ static int replace_column_table(GRANT_TABLE *g_t, if (revoke_grant) { + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read(table->record[0], (byte*) table->field[0]->ptr, - key_length, HA_READ_KEY_EXACT)) + table->key_info[0].key_length, + HA_READ_KEY_EXACT)) goto end; /* Scan through all rows with the same host,db,user and table */ @@ -2112,9 +2125,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); store_record(table,record[1]); // store at pos 1 - + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, - (byte*) table->field[0]->ptr,0, + (byte*) table->field[0]->ptr, + table->key_info[0].key_length, HA_READ_KEY_EXACT)) { /* @@ -3571,9 +3585,12 @@ int mysql_drop_user(THD *thd, List &list) tables[0].table->field[1]->store(user_name->user.str,(uint) user_name->user.length, system_charset_info); + tables[0].table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (!tables[0].table->file->index_read_idx(tables[0].table->record[0],0, (byte*) tables[0].table-> - field[0]->ptr,0, + field[0]->ptr, + tables[0].table-> + key_info[0].key_length, HA_READ_KEY_EXACT)) { int error; From c617037b2308181bc82d6c36b8b9b718d54af17d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 17 Nov 2004 08:15:53 +0000 Subject: [PATCH 07/44] Enabled usage of new system variables for ndb - ndb_use_exact_count - ndb_autoincrement_prefetch_sz - ndb_use_transactions - ndb_force_send moved "inlined" functions to .cc file since they are virtual anyways enabled printout od ndb errors in warnings even if mapping existst to mysql error code sql/ha_ndbcluster.h: Enabled usage of new system variables for ndb - ndb_use_exact_count - ndb_autoincrement_prefetch_sz - ndb_use_transactions - ndb_force_send moved "inlined" functions to .cc file since they are virtual anyways sql/mysqld.cc: Enabled usage of new system variables for ndb - ndb_use_exact_count - ndb_autoincrement_prefetch_sz - ndb_use_transactions - ndb_force_send sql/set_var.cc: Enabled usage of new system variables for ndb - ndb_use_exact_count - ndb_autoincrement_prefetch_sz - ndb_use_transactions - ndb_force_send sql/sql_class.h: Enabled usage of new system variables for ndb - ndb_use_exact_count - ndb_autoincrement_prefetch_sz - ndb_use_transactions - ndb_force_send --- sql/ha_ndbcluster.cc | 194 +++++++++++++++++++++++++++++++------------ sql/ha_ndbcluster.h | 46 ++++------ sql/mysqld.cc | 34 +++++++- sql/set_var.cc | 32 ++++++- sql/sql_class.h | 6 ++ 5 files changed, 223 insertions(+), 89 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index bc1c887bfab..8ef24ad5af1 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -39,9 +39,6 @@ static const int parallelism= 240; // createable against NDB from this handler static const int max_transactions= 256; -// Default value for prefetch of autoincrement values -static const ha_rows autoincrement_prefetch= 32; - // connectstring to cluster if given by mysqld const char *ndbcluster_connectstring= 0; @@ -103,58 +100,52 @@ struct err_code_mapping { int ndb_err; int my_err; + int show_warning; }; static const err_code_mapping err_map[]= { - { 626, HA_ERR_KEY_NOT_FOUND }, - { 630, HA_ERR_FOUND_DUPP_KEY }, - { 893, HA_ERR_FOUND_DUPP_UNIQUE }, - { 721, HA_ERR_TABLE_EXIST }, - { 4244, HA_ERR_TABLE_EXIST }, + { 626, HA_ERR_KEY_NOT_FOUND, 0 }, + { 630, HA_ERR_FOUND_DUPP_KEY, 0 }, + { 893, HA_ERR_FOUND_DUPP_UNIQUE, 0 }, + { 721, HA_ERR_TABLE_EXIST, 1 }, + { 4244, HA_ERR_TABLE_EXIST, 1 }, - { 709, HA_ERR_NO_SUCH_TABLE }, - { 284, HA_ERR_NO_SUCH_TABLE }, + { 709, HA_ERR_NO_SUCH_TABLE, 1 }, + { 284, HA_ERR_NO_SUCH_TABLE, 1 }, - { 266, HA_ERR_LOCK_WAIT_TIMEOUT }, - { 274, HA_ERR_LOCK_WAIT_TIMEOUT }, - { 296, HA_ERR_LOCK_WAIT_TIMEOUT }, - { 297, HA_ERR_LOCK_WAIT_TIMEOUT }, - { 237, HA_ERR_LOCK_WAIT_TIMEOUT }, + { 266, HA_ERR_LOCK_WAIT_TIMEOUT, 1 }, + { 274, HA_ERR_LOCK_WAIT_TIMEOUT, 1 }, + { 296, HA_ERR_LOCK_WAIT_TIMEOUT, 1 }, + { 297, HA_ERR_LOCK_WAIT_TIMEOUT, 1 }, + { 237, HA_ERR_LOCK_WAIT_TIMEOUT, 1 }, - { 623, HA_ERR_RECORD_FILE_FULL }, - { 624, HA_ERR_RECORD_FILE_FULL }, - { 625, HA_ERR_RECORD_FILE_FULL }, - { 826, HA_ERR_RECORD_FILE_FULL }, - { 827, HA_ERR_RECORD_FILE_FULL }, - { 832, HA_ERR_RECORD_FILE_FULL }, + { 623, HA_ERR_RECORD_FILE_FULL, 1 }, + { 624, HA_ERR_RECORD_FILE_FULL, 1 }, + { 625, HA_ERR_RECORD_FILE_FULL, 1 }, + { 826, HA_ERR_RECORD_FILE_FULL, 1 }, + { 827, HA_ERR_RECORD_FILE_FULL, 1 }, + { 832, HA_ERR_RECORD_FILE_FULL, 1 }, - { 0, 1 }, + { 0, 1, 0 }, - { -1, -1 } + { -1, -1, 1 } }; static int ndb_to_mysql_error(const NdbError *err) { uint i; - for (i=0 ; err_map[i].ndb_err != err->code ; i++) + for (i=0; err_map[i].ndb_err != err->code && err_map[i].my_err != -1; i++); + if (err_map[i].show_warning) { - if (err_map[i].my_err == -1){ - // Push the NDB error message as warning - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_GET_ERRMSG, ER(ER_GET_ERRMSG), - err->code, err->message, "NDB"); - return err->code; - } + // Push the NDB error message as warning + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_GET_ERRMSG, ER(ER_GET_ERRMSG), + err->code, err->message, "NDB"); } - // Push the NDB error message as warning - // this since e.g. HA_ERR_RECORD_FILE_FULL maps to - // several error codes in NDB, and the uses needs - // to know which one it is - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_GET_ERRMSG, ER(ER_GET_ERRMSG), - err->code, err->message, "NDB"); + if (err_map[i].my_err == -1) + return err->code; return err_map[i].my_err; } @@ -168,7 +159,7 @@ int execute_no_commit(ha_ndbcluster *h, NdbConnection *trans) if (m_batch_execute) return 0; #endif - return trans->execute(NoCommit,AbortOnError,1); + return trans->execute(NoCommit,AbortOnError,h->m_force_send); } inline @@ -179,7 +170,18 @@ int execute_commit(ha_ndbcluster *h, NdbConnection *trans) if (m_batch_execute) return 0; #endif - return trans->execute(Commit,AbortOnError,1); + return trans->execute(Commit,AbortOnError,h->m_force_send); +} + +inline +int execute_commit(THD *thd, NdbConnection *trans) +{ + int m_batch_execute= 0; +#ifdef NOT_USED + if (m_batch_execute) + return 0; +#endif + return trans->execute(Commit,AbortOnError,thd->variables.ndb_force_send); } inline @@ -190,7 +192,7 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbConnection *trans) if (m_batch_execute) return 0; #endif - return trans->execute(NoCommit,IgnoreError,1); + return trans->execute(NoCommit,IgnoreError,h->m_force_send); } /* @@ -233,6 +235,8 @@ void ha_ndbcluster::set_rec_per_key() void ha_ndbcluster::records_update() { + if (m_ha_not_exact_count) + return; DBUG_ENTER("ha_ndbcluster::records_update"); struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info; DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d", @@ -256,6 +260,8 @@ void ha_ndbcluster::records_update() void ha_ndbcluster::no_uncommitted_rows_execute_failure() { + if (m_ha_not_exact_count) + return; DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_execute_failure"); THD *thd= current_thd; ((Thd_ndb*)(thd->transaction.thd_ndb))->error= 1; @@ -264,6 +270,8 @@ void ha_ndbcluster::no_uncommitted_rows_execute_failure() void ha_ndbcluster::no_uncommitted_rows_init(THD *thd) { + if (m_ha_not_exact_count) + return; DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_init"); struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info; Thd_ndb *thd_ndb= (Thd_ndb *)thd->transaction.thd_ndb; @@ -281,6 +289,8 @@ void ha_ndbcluster::no_uncommitted_rows_init(THD *thd) void ha_ndbcluster::no_uncommitted_rows_update(int c) { + if (m_ha_not_exact_count) + return; DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_update"); struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info; @@ -293,6 +303,8 @@ void ha_ndbcluster::no_uncommitted_rows_update(int c) void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd) { + if (m_ha_not_exact_count) + return; DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_reset"); ((Thd_ndb*)(thd->transaction.thd_ndb))->count++; ((Thd_ndb*)(thd->transaction.thd_ndb))->error= 0; @@ -1229,7 +1241,8 @@ inline int ha_ndbcluster::next_result(byte *buf) DBUG_PRINT("info", ("ops_pending: %d", m_ops_pending)); if (m_ops_pending) { - if (current_thd->transaction.on) + // if (current_thd->transaction.on) + if (m_transaction_on) { if (execute_no_commit(this,trans) != 0) DBUG_RETURN(ndb_err(trans)); @@ -1715,7 +1728,8 @@ int ha_ndbcluster::write_row(byte *record) (int)m_rows_inserted, (int)m_bulk_insert_rows)); m_bulk_insert_not_flushed= FALSE; - if (thd->transaction.on) + // if (thd->transaction.on) + if (m_transaction_on) { if (execute_no_commit(this,trans) != 0) { @@ -1888,7 +1902,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) for (i= 0; i < table->fields; i++) { Field *field= table->field[i]; - if ((thd->query_id == field->query_id) && + if (((thd->query_id == field->query_id) || m_retrieve_all_fields) && (!(field->flags & PRI_KEY_FLAG)) && set_ndb_value(op, field, i)) ERR_RETURN(op->getNdbError()); @@ -2547,14 +2561,17 @@ void ha_ndbcluster::info(uint flag) DBUG_PRINT("info", ("HA_STATUS_VARIABLE")); if (m_table_info) { - records_update(); + if (m_ha_not_exact_count) + records= 100; + else + records_update(); } else { - Uint64 rows; - if(ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0) == 0){ - records= rows; - } + Uint64 rows= 100; + if (current_thd->variables.ndb_use_exact_count) + ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0); + records= rows; } } if (flag & HA_STATUS_CONST) @@ -2943,6 +2960,15 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) pointer to point to the NDB transaction. */ + // store thread specific data first to set the right context + m_force_send= thd->variables.ndb_force_send; + m_ha_not_exact_count= !thd->variables.ndb_use_exact_count; + m_autoincrement_prefetch= thd->variables.ndb_autoincrement_prefetch_sz; + if (!thd->transaction.on) + m_transaction_on= FALSE; + else + m_transaction_on= thd->variables.ndb_use_transactions; + m_active_trans= thd->transaction.all.ndb_tid ? (NdbConnection*)thd->transaction.all.ndb_tid: (NdbConnection*)thd->transaction.stmt.ndb_tid; @@ -3063,7 +3089,7 @@ int ndbcluster_commit(THD *thd, void *ndb_transaction) "stmt" : "all")); DBUG_ASSERT(ndb && trans); - if (execute_commit(0,trans) != 0) + if (execute_commit(thd,trans) != 0) { const NdbError err= trans->getNdbError(); const NdbOperation *error_op= trans->getNdbErrorOperation(); @@ -3617,11 +3643,11 @@ longlong ha_ndbcluster::get_auto_increment() DBUG_ENTER("get_auto_increment"); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); int cache_size= - (m_rows_to_insert - m_rows_inserted < autoincrement_prefetch) ? + (m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ? m_rows_to_insert - m_rows_inserted - : (m_rows_to_insert > autoincrement_prefetch) ? + : (m_rows_to_insert > m_autoincrement_prefetch) ? m_rows_to_insert - : autoincrement_prefetch; + : m_autoincrement_prefetch; Uint64 auto_value= (m_skip_auto_increment) ? m_ndb->readAutoIncrementValue((const NDBTAB *) m_table) @@ -3659,7 +3685,11 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_blobs_pending(0), m_blobs_buffer(0), m_blobs_buffer_size(0), - m_dupkey((uint) -1) + m_dupkey((uint) -1), + m_ha_not_exact_count(FALSE), + m_force_send(TRUE), + m_autoincrement_prefetch(32), + m_transaction_on(TRUE) { int i; @@ -4309,6 +4339,62 @@ ha_ndbcluster::records_in_range(uint inx, key_range *min_key, DBUG_RETURN(10); /* Good guess when you don't know anything */ } +ulong ha_ndbcluster::table_flags(void) const +{ + if (m_ha_not_exact_count) + return m_table_flags | HA_NOT_EXACT_COUNT; + else + return m_table_flags; +} +const char * ha_ndbcluster::table_type() const +{ + return("ndbcluster"); +} +uint ha_ndbcluster::max_supported_record_length() const +{ + return NDB_MAX_TUPLE_SIZE; +} +uint ha_ndbcluster::max_supported_keys() const +{ + return MAX_KEY; +} +uint ha_ndbcluster::max_supported_key_parts() const +{ + return NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY; +} +uint ha_ndbcluster::max_supported_key_length() const +{ + return NDB_MAX_KEY_SIZE; +} +bool ha_ndbcluster::low_byte_first() const +{ +#ifdef WORDS_BIGENDIAN + return FALSE; +#else + return TRUE; +#endif +} +bool ha_ndbcluster::has_transactions() +{ + return TRUE; +} +const char* ha_ndbcluster::index_type(uint key_number) +{ + switch (get_index_type(key_number)) { + case ORDERED_INDEX: + case UNIQUE_ORDERED_INDEX: + case PRIMARY_KEY_ORDERED_INDEX: + return "BTREE"; + case UNIQUE_INDEX: + case PRIMARY_KEY_INDEX: + default: + return "HASH"; + } +} +uint8 ha_ndbcluster::table_cache_type() +{ + return HA_CACHE_TBL_NOCACHE; +} /* Handling the shared NDB_SHARE structure that is needed to diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 2121228a869..6c51d1f0af7 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -118,15 +118,14 @@ class ha_ndbcluster: public handler int reset(); int external_lock(THD *thd, int lock_type); int start_stmt(THD *thd); - const char * table_type() const { return("ndbcluster");} + const char * table_type() const; const char ** bas_ext() const; - ulong table_flags(void) const { return m_table_flags; } + ulong table_flags(void) const; ulong index_flags(uint idx, uint part, bool all_parts) const; - uint max_supported_record_length() const { return NDB_MAX_TUPLE_SIZE; }; - uint max_supported_keys() const { return MAX_KEY; } - uint max_supported_key_parts() const - { return NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY; }; - uint max_supported_key_length() const { return NDB_MAX_KEY_SIZE;}; + uint max_supported_record_length() const; + uint max_supported_keys() const; + uint max_supported_key_parts() const; + uint max_supported_key_length() const; int rename_table(const char *from, const char *to); int delete_table(const char *name); @@ -135,28 +134,9 @@ class ha_ndbcluster: public handler THR_LOCK_DATA **to, enum thr_lock_type lock_type); - bool low_byte_first() const - { -#ifdef WORDS_BIGENDIAN - return FALSE; -#else - return TRUE; -#endif - } - bool has_transactions() { return TRUE; } - - const char* index_type(uint key_number) { - switch (get_index_type(key_number)) { - case ORDERED_INDEX: - case UNIQUE_ORDERED_INDEX: - case PRIMARY_KEY_ORDERED_INDEX: - return "BTREE"; - case UNIQUE_INDEX: - case PRIMARY_KEY_INDEX: - default: - return "HASH"; - } - } + bool low_byte_first() const; + bool has_transactions(); + const char* index_type(uint key_number); double scan_time(); ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); @@ -165,7 +145,7 @@ class ha_ndbcluster: public handler static Thd_ndb* seize_thd_ndb(); static void release_thd_ndb(Thd_ndb* thd_ndb); - uint8 table_cache_type() { return HA_CACHE_TBL_NOCACHE; } + uint8 table_cache_type(); private: int alter_table_name(const char *from, const char *to); @@ -256,6 +236,10 @@ class ha_ndbcluster: public handler char *m_blobs_buffer; uint32 m_blobs_buffer_size; uint m_dupkey; + bool m_ha_not_exact_count; + bool m_force_send; + ha_rows m_autoincrement_prefetch; + bool m_transaction_on; void set_rec_per_key(); void records_update(); @@ -265,6 +249,8 @@ class ha_ndbcluster: public handler void no_uncommitted_rows_reset(THD *); friend int execute_no_commit(ha_ndbcluster*, NdbConnection*); + friend int execute_commit(ha_ndbcluster*, NdbConnection*); + friend int execute_no_commit_ie(ha_ndbcluster*, NdbConnection*); }; bool ndbcluster_init(void); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1da5359bae0..5ee52326276 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3947,7 +3947,11 @@ enum options_mysqld OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB, OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG, - OPT_INNODB, OPT_ISAM, OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_SKIP_SAFEMALLOC, + OPT_INNODB, OPT_ISAM, + OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT, + OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, + OPT_NDB_USE_TRANSACTIONS, + OPT_SKIP_SAFEMALLOC, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, @@ -4386,9 +4390,31 @@ Disable with --skip-ndbcluster (will save memory).", (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, #ifdef HAVE_NDBCLUSTER_DB - {"ndb-connectstring", OPT_NDB_CONNECTSTRING, "Connect string for ndbcluster.", - (gptr*) &ndbcluster_connectstring, (gptr*) &ndbcluster_connectstring, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"ndb-connectstring", OPT_NDB_CONNECTSTRING, + "Connect string for ndbcluster.", + (gptr*) &ndbcluster_connectstring, (gptr*) &ndbcluster_connectstring, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"ndb_autoincrement_prefetch_sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, + "Specify number of autoincrement values that are prefetched", + (gptr*) &global_system_variables.ndb_autoincrement_prefetch_sz, + (gptr*) &global_system_variables.ndb_autoincrement_prefetch_sz, + 0, GET_INT, REQUIRED_ARG, 32, 1, 256, 0, 0, 0}, + {"ndb_force_send", OPT_NDB_FORCE_SEND, + "Force send of buffers to ndb immediately without waiting for other threads", + (gptr*) &global_system_variables.ndb_force_send, + (gptr*) &global_system_variables.ndb_force_send, + 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"ndb_use_exact_count", OPT_NDB_USE_EXACT_COUNT, + "Use exact records count during query planning and for " + "fast select count(*)", + (gptr*) &global_system_variables.ndb_use_exact_count, + (gptr*) &global_system_variables.ndb_use_exact_count, + 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS, + "Use transactions in ndb", + (gptr*) &global_system_variables.ndb_use_transactions, + (gptr*) &global_system_variables.ndb_use_transactions, + 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, #endif {"new", 'n', "Use very new possible 'unsafe' functions.", (gptr*) &global_system_variables.new_mode, diff --git a/sql/set_var.cc b/sql/set_var.cc index a97506ad07c..f1973b53e49 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -359,6 +359,23 @@ sys_var_thd_bool sys_innodb_table_locks("innodb_table_locks", sys_var_long_ptr sys_innodb_autoextend_increment("innodb_autoextend_increment", &srv_auto_extend_increment); #endif +#ifdef HAVE_NDBCLUSTER_DB +// ndb thread specific variable settings +sys_var_thd_ulong +sys_ndb_autoincrement_prefetch_sz("ndb_autoincrement_prefetch_sz", + &SV::ndb_autoincrement_prefetch_sz); +sys_var_thd_bool +sys_ndb_force_send("ndb_force_send", + &SV::ndb_force_send); +sys_var_thd_bool +sys_ndb_use_exact_count("ndb_use_exact_count", + &SV::ndb_use_exact_count); +sys_var_thd_bool +sys_ndb_use_transactions("ndb_use_transactions", + &SV::ndb_use_transactions); +// ndb server global variable settings +// none +#endif /* Time/date/datetime formats */ @@ -612,7 +629,13 @@ sys_var *sys_variables[]= &sys_innodb_table_locks, &sys_innodb_max_purge_lag, &sys_innodb_autoextend_increment, -#endif +#endif +#ifdef HAVE_NDBCLUSTER_DB + &sys_ndb_autoincrement_prefetch_sz, + &sys_ndb_force_send, + &sys_ndb_use_exact_count, + &sys_ndb_use_transactions, +#endif &sys_unique_checks, &sys_warning_count }; @@ -772,6 +795,13 @@ struct show_var_st init_vars[]= { {sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS}, #ifdef __NT__ {"named_pipe", (char*) &opt_enable_named_pipe, SHOW_MY_BOOL}, +#endif +#ifdef HAVE_NDBCLUSTER_DB + {sys_ndb_autoincrement_prefetch_sz.name, + (char*) &sys_ndb_autoincrement_prefetch_sz, SHOW_SYS}, + {sys_ndb_force_send.name, (char*) &sys_ndb_force_send, SHOW_SYS}, + {sys_ndb_use_exact_count.name,(char*) &sys_ndb_use_exact_count, SHOW_SYS}, + {sys_ndb_use_transactions.name,(char*) &sys_ndb_use_transactions, SHOW_SYS}, #endif {sys_net_buffer_length.name,(char*) &sys_net_buffer_length, SHOW_SYS}, {sys_net_read_timeout.name, (char*) &sys_net_read_timeout, SHOW_SYS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 312d9de9794..d0d9afc7746 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -399,6 +399,12 @@ struct system_variables #ifdef HAVE_INNOBASE_DB my_bool innodb_table_locks; #endif /* HAVE_INNOBASE_DB */ +#ifdef HAVE_NDBCLUSTER_DB + ulong ndb_autoincrement_prefetch_sz; + my_bool ndb_force_send; + my_bool ndb_use_exact_count; + my_bool ndb_use_transactions; +#endif /* HAVE_NDBCLUSTER_DB */ my_bool old_passwords; /* Only charset part of these variables is sensible */ From 2267ea3e029cb2b450a4ca6a67f0ae036ff709f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 08:42:26 +0000 Subject: [PATCH 08/44] ifdef'd unused table reorg code --- ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 12 ++++++++++-- ndb/src/kernel/blocks/dbdict/Dbdict.hpp | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 882557daae1..2b9072ab042 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -239,7 +239,11 @@ Dbdict::packTableIntoPagesImpl(SimpleProperties::Writer & w, w.add(DictTabInfo::TableName, tablePtr.p->tableName); w.add(DictTabInfo::TableId, tablePtr.i); +#ifdef HAVE_TABLE_REORG w.add(DictTabInfo::SecondTableId, tablePtr.p->secondTable); +#else + w.add(DictTabInfo::SecondTableId, (Uint32)0); +#endif w.add(DictTabInfo::TableVersion, tablePtr.p->tableVersion); w.add(DictTabInfo::NoOfKeyAttr, tablePtr.p->noOfPrimkey); w.add(DictTabInfo::NoOfAttributes, tablePtr.p->noOfAttributes); @@ -1436,6 +1440,7 @@ Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId) jam(); return RNIL; }//if +#ifdef HAVE_TABLE_REORG bool secondFound = false; for (tablePtr.i = firstTablePtr.i + 1; tablePtr.i < tabSize ; tablePtr.i++) { jam(); @@ -1455,6 +1460,7 @@ Uint32 Dbdict::getFreeTableRecord(Uint32 primaryTableId) firstTablePtr.p->tabState = TableRecord::NOT_DEFINED; return RNIL; }//if +#endif return firstTablePtr.i; }//Dbdict::getFreeTableRecord() @@ -4623,7 +4629,7 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, jam(); tablePtr.p->tabState = TableRecord::DEFINING; }//if - +#ifdef HAVE_TABLE_REORG /* ---------------------------------------------------------------- */ // Get id of second table id and check that table doesn't already exist // and set up links between first and second table. @@ -4637,7 +4643,7 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, secondTablePtr.p->tabState = TableRecord::REORG_TABLE_PREPARED; secondTablePtr.p->secondTable = tablePtr.i; tablePtr.p->secondTable = secondTablePtr.i; - +#endif /* ---------------------------------------------------------------- */ // Set table version /* ---------------------------------------------------------------- */ @@ -5535,10 +5541,12 @@ void Dbdict::releaseTableObject(Uint32 tableId, bool removeFromHash) nextAttrRecord = attrPtr.p->nextAttrInTable; c_attributeRecordPool.release(attrPtr); }//if +#ifdef HAVE_TABLE_REORG Uint32 secondTableId = tablePtr.p->secondTable; initialiseTableRecord(tablePtr); c_tableRecordPool.getPtr(tablePtr, secondTableId); initialiseTableRecord(tablePtr); +#endif return; }//releaseTableObject() diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index 19c03a86e22..af80bcf5f94 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -151,10 +151,10 @@ public: /* Temporary record used during add/drop table */ Uint32 myConnect; - +#ifdef HAVE_TABLE_REORG /* Second table used by this table (for table reorg) */ Uint32 secondTable; - +#endif /* Next record in Pool */ Uint32 nextPool; From 9615e9becf2af5d3f5184115e390d1a10c0ce261 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 11:48:21 +0100 Subject: [PATCH 09/44] ndb: charset fix from Bar (strxfrm_multiply can be 0) ndb/src/common/util/NdbSqlUtil.cpp: charset fix from Bar (strxfrm_multiply can be 0) ndb/src/ndbapi/NdbIndexOperation.cpp: charset fix from Bar (strxfrm_multiply can be 0) ndb/src/ndbapi/NdbOperationSearch.cpp: charset fix from Bar (strxfrm_multiply can be 0) ndb/src/ndbapi/NdbScanOperation.cpp: charset fix from Bar (strxfrm_multiply can be 0) --- ndb/src/common/util/NdbSqlUtil.cpp | 6 +++--- ndb/src/ndbapi/NdbIndexOperation.cpp | 2 +- ndb/src/ndbapi/NdbOperationSearch.cpp | 2 +- ndb/src/ndbapi/NdbScanOperation.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp index 6e4e5919e43..5b2381df50a 100644 --- a/ndb/src/common/util/NdbSqlUtil.cpp +++ b/ndb/src/common/util/NdbSqlUtil.cpp @@ -582,7 +582,7 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info) cs->cset != 0 && cs->coll != 0 && cs->coll->strnxfrm != 0 && - cs->strxfrm_multiply == 1; // current limitation + cs->strxfrm_multiply <= 1; // current limitation } break; case Type::Varchar: @@ -618,7 +618,7 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) cs->coll != 0 && cs->coll->strnxfrm != 0 && cs->coll->strnncollsp != 0 && - cs->strxfrm_multiply == 1; // current limitation + cs->strxfrm_multiply <= 1; // current limitation } break; case Type::Varchar: @@ -633,7 +633,7 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) cs->coll != 0 && cs->coll->strnxfrm != 0 && cs->coll->strnncollsp != 0 && - cs->strxfrm_multiply == 1; // current limitation + cs->strxfrm_multiply <= 1; // current limitation } break; default: diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index 3f174a61b64..23af646c4c7 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -272,7 +272,7 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo, CHARSET_INFO* cs = tAttrInfo->m_cs; if (cs != 0) { // current limitation: strxfrm does not increase length - assert(cs->strxfrm_multiply == 1); + assert(cs->strxfrm_multiply <= 1); unsigned n = (*cs->coll->strnxfrm)(cs, (uchar*)xfrmData, sizeof(xfrmData), diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp index 69b4e803acd..28a70abcb9b 100644 --- a/ndb/src/ndbapi/NdbOperationSearch.cpp +++ b/ndb/src/ndbapi/NdbOperationSearch.cpp @@ -142,7 +142,7 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, CHARSET_INFO* cs = tAttrInfo->m_cs; if (cs != 0) { // current limitation: strxfrm does not increase length - assert(cs->strxfrm_multiply == 1); + assert(cs->strxfrm_multiply <= 1); unsigned n = (*cs->coll->strnxfrm)(cs, (uchar*)xfrmData, sizeof(xfrmData), diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 373fec1a2b0..4b10ebb10cd 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -1091,7 +1091,7 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, Uint32 xfrmData[2000]; if (cs != NULL && aValue != NULL) { // current limitation: strxfrm does not increase length - assert(cs->strxfrm_multiply == 1); + assert(cs->strxfrm_multiply <= 1); unsigned n = (*cs->coll->strnxfrm)(cs, (uchar*)xfrmData, sizeof(xfrmData), From be5b6f4d4b29e2393b73f7c9f6a8d17ad7a95422 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 12:11:56 +0100 Subject: [PATCH 10/44] Fix for bug#4312 ndb table, wrong behaviour on insert .. on duplicate key .. --- mysql-test/r/ndb_charset.result | 4 +- mysql-test/r/ndb_index_unique.result | 8 ++-- mysql-test/r/ndb_insert.result | 45 +++++++++++++------ mysql-test/t/ndb_charset.test | 4 +- mysql-test/t/ndb_index_unique.test | 8 ++-- mysql-test/t/ndb_insert.test | 36 ++++++++++----- sql/ha_ndbcluster.cc | 66 ++++++++++++++++++++++------ sql/ha_ndbcluster.h | 4 +- sql/sql_insert.cc | 7 ++- 9 files changed, 130 insertions(+), 52 deletions(-) diff --git a/mysql-test/r/ndb_charset.result b/mysql-test/r/ndb_charset.result index 93429a1fcb0..501bec99ea3 100644 --- a/mysql-test/r/ndb_charset.result +++ b/mysql-test/r/ndb_charset.result @@ -78,9 +78,9 @@ unique key(a) ) engine=ndb; insert into t1 values(1, 'aAa'); insert into t1 values(2, 'aaa'); -ERROR 23000: Can't write, because of unique constraint, to table 't1' +ERROR 23000: Duplicate entry '2' for key 1 insert into t1 values(3, 'AAA'); -ERROR 23000: Can't write, because of unique constraint, to table 't1' +ERROR 23000: Duplicate entry '3' for key 1 select * from t1 order by p; p a 1 aAa diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result index f1407dfe78d..af9b84022ed 100644 --- a/mysql-test/r/ndb_index_unique.result +++ b/mysql-test/r/ndb_index_unique.result @@ -22,7 +22,7 @@ select * from t1 where b = 4 order by a; a b c 3 4 6 insert into t1 values(8, 2, 3); -ERROR 23000: Can't write, because of unique constraint, to table 't1' +ERROR 23000: Duplicate entry '8' for key 1 select * from t1 order by a; a b c 1 2 3 @@ -65,7 +65,7 @@ select * from t2 where b = 4 order by a; a b c 3 4 6 insert into t2 values(8, 2, 3); -ERROR 23000: Can't write, because of unique constraint, to table 't2' +ERROR 23000: Duplicate entry '8' for key 1 select * from t2 order by a; a b c 1 2 3 @@ -123,7 +123,7 @@ pk a 3 NULL 4 4 insert into t1 values (5,0); -ERROR 23000: Can't write, because of unique constraint, to table 't1' +ERROR 23000: Duplicate entry '5' for key 1 select * from t1 order by pk; pk a -1 NULL @@ -156,7 +156,7 @@ pk a b c 0 NULL 18 NULL 1 3 19 abc insert into t2 values(2,3,19,'abc'); -ERROR 23000: Can't write, because of unique constraint, to table 't2' +ERROR 23000: Duplicate entry '2' for key 1 select * from t2 order by pk; pk a b c -1 1 17 NULL diff --git a/mysql-test/r/ndb_insert.result b/mysql-test/r/ndb_insert.result index 16c76f39680..7503010a66b 100644 --- a/mysql-test/r/ndb_insert.result +++ b/mysql-test/r/ndb_insert.result @@ -535,27 +535,46 @@ count(*) 2000 insert into t1 select * from t1 where b < 10 order by pk1; ERROR 23000: Duplicate entry '9' for key 1 +DELETE FROM t1 WHERE pk1=2; begin; -INSERT IGNORE INTO t1 VALUES(1,2,3); -ERROR HY000: Table storage engine for 't1' doesn't have this option -commit; -select * from t1 where pk1=1; +INSERT IGNORE INTO t1 VALUES(1,2,3),(2,3,4); +select * from t1 where pk1 < 3 order by pk1; pk1 b c +0 0 0 1 1 1 -INSERT IGNORE INTO t1 VALUES(1,2,3); -ERROR HY000: Table storage engine for 't1' doesn't have this option -select * from t1 where pk1=1; +2 3 4 +rollback; +INSERT IGNORE INTO t1 VALUES(1,2,3),(2,3,4); +select * from t1 where pk1 < 3 order by pk1; pk1 b c +0 0 0 1 1 1 -REPLACE INTO t1 values(1, 2, 3); +2 3 4 +REPLACE INTO t1 values(1, 78, 3); select * from t1 where pk1=1; pk1 b c -1 2 3 -INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79; -ERROR HY000: Table storage engine for 't1' doesn't have this option -select * from t1 where pk1=1; +1 78 3 +INSERT INTO t1 VALUES(1,1,1),(3,4,5) ON DUPLICATE KEY UPDATE b=79; +select * from t1 where pk1 < 4 order by pk1; pk1 b c -1 2 3 +0 0 0 +1 79 3 +2 3 4 +3 79 3 +INSERT INTO t1 VALUES(1,1,1),(3,4,5) ON DUPLICATE KEY UPDATE b=pk1+c; +select * from t1 where pk1 < 4 order by pk1; +pk1 b c +0 0 0 +1 4 3 +2 3 4 +3 6 3 +DELETE FROM t1 WHERE pk1 = 2 OR pk1 = 4 OR pk1 = 6; +INSERT INTO t1 VALUES(1,1,1),(2,2,17),(3,4,5) ON DUPLICATE KEY UPDATE pk1=b; +select * from t1 where pk1 = b and b != c order by pk1; +pk1 b c +2 2 17 +4 4 3 +6 6 3 DROP TABLE t1; CREATE TABLE t1(a INT) ENGINE=ndb; INSERT IGNORE INTO t1 VALUES (1); diff --git a/mysql-test/t/ndb_charset.test b/mysql-test/t/ndb_charset.test index b9f28ed0faf..f1ec0485e12 100644 --- a/mysql-test/t/ndb_charset.test +++ b/mysql-test/t/ndb_charset.test @@ -86,9 +86,9 @@ create table t1 ( # ok insert into t1 values(1, 'aAa'); # fail ---error 1169 +--error 1062 insert into t1 values(2, 'aaa'); ---error 1169 +--error 1062 insert into t1 values(3, 'AAA'); # 1 select * from t1 order by p; diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test index 4a0c689bafb..bdb23949763 100644 --- a/mysql-test/t/ndb_index_unique.test +++ b/mysql-test/t/ndb_index_unique.test @@ -21,7 +21,7 @@ select * from t1 where b = 4 order by b; insert into t1 values(7,8,3); select * from t1 where b = 4 order by a; --- error 1169 +-- error 1062 insert into t1 values(8, 2, 3); select * from t1 order by a; delete from t1 where a = 1; @@ -49,7 +49,7 @@ select * from t2 where c = 6; insert into t2 values(7,8,3); select * from t2 where b = 4 order by a; --- error 1169 +-- error 1062 insert into t2 values(8, 2, 3); select * from t2 order by a; delete from t2 where a = 1; @@ -92,7 +92,7 @@ insert into t1 values (-1,NULL), (0,0), (1,NULL),(2,2),(3,NULL),(4,4); select * from t1 order by pk; ---error 1169 +--error 1062 insert into t1 values (5,0); select * from t1 order by pk; delete from t1 where a = 0; @@ -111,7 +111,7 @@ insert into t2 values (-1,1,17,NULL),(0,NULL,18,NULL),(1,3,19,'abc'); select * from t2 order by pk; ---error 1169 +--error 1062 insert into t2 values(2,3,19,'abc'); select * from t2 order by pk; delete from t2 where c IS NOT NULL; diff --git a/mysql-test/t/ndb_insert.test b/mysql-test/t/ndb_insert.test index c3da4641014..611df3d84e9 100644 --- a/mysql-test/t/ndb_insert.test +++ b/mysql-test/t/ndb_insert.test @@ -564,23 +564,37 @@ select count(*) from t1; --error 1062 insert into t1 select * from t1 where b < 10 order by pk1; +DELETE FROM t1 WHERE pk1=2; begin; ---error 1031 -INSERT IGNORE INTO t1 VALUES(1,2,3); -commit; +INSERT IGNORE INTO t1 VALUES(1,2,3),(2,3,4); +select * from t1 where pk1 < 3 order by pk1; +rollback; + +INSERT IGNORE INTO t1 VALUES(1,2,3),(2,3,4); +select * from t1 where pk1 < 3 order by pk1; + +REPLACE INTO t1 values(1, 78, 3); select * from t1 where pk1=1; ---error 1031 -INSERT IGNORE INTO t1 VALUES(1,2,3); -select * from t1 where pk1=1; +INSERT INTO t1 VALUES(1,1,1),(3,4,5) ON DUPLICATE KEY UPDATE b=79; +select * from t1 where pk1 < 4 order by pk1; -REPLACE INTO t1 values(1, 2, 3); -select * from t1 where pk1=1; +INSERT INTO t1 VALUES(1,1,1),(3,4,5) ON DUPLICATE KEY UPDATE b=pk1+c; +select * from t1 where pk1 < 4 order by pk1; ---error 1031 -INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79; -select * from t1 where pk1=1; +DELETE FROM t1 WHERE pk1 = 2 OR pk1 = 4 OR pk1 = 6; +INSERT INTO t1 VALUES(1,1,1),(2,2,17),(3,4,5) ON DUPLICATE KEY UPDATE pk1=b; +select * from t1 where pk1 = b and b != c order by pk1; + +# The following test case currently does not work +#DELETE FROM t1; +#CREATE UNIQUE INDEX bi ON t1(b); +#INSERT INTO t1 VALUES +#(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5), +#(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10); +#INSERT INTO t1 VALUES(0,1,0),(21,21,21) ON DUPLICATE KEY UPDATE pk1=b+10,c=b+10; +#select * from t1 order by pk1; DROP TABLE t1; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index cdbf2eb3d6a..84d1b2468d5 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -109,7 +109,7 @@ static const err_code_mapping err_map[]= { { 626, HA_ERR_KEY_NOT_FOUND }, { 630, HA_ERR_FOUND_DUPP_KEY }, - { 893, HA_ERR_FOUND_DUPP_UNIQUE }, + { 893, HA_ERR_FOUND_DUPP_KEY }, // Unique constraint { 721, HA_ERR_TABLE_EXIST }, { 4244, HA_ERR_TABLE_EXIST }, @@ -144,7 +144,7 @@ static int ndb_to_mysql_error(const NdbError *err) // Push the NDB error message as warning push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), - err->code, err->message, "NDB"); + err->code, err->message, "NDB"); return err->code; } } @@ -1018,7 +1018,8 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) { Field *field= table->field[i]; if ((thd->query_id == field->query_id) || - m_retrieve_all_fields) + m_retrieve_all_fields || + (field->flags & PRI_KEY_FLAG) && m_retrieve_primary_key) { if (get_ndb_value(op, field, i, buf)) ERR_RETURN(trans->getNdbError()); @@ -1029,7 +1030,6 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) m_value[i].ptr= NULL; } } - if (execute_no_commit_ie(this,trans) != 0) { table->status= STATUS_NOT_FOUND; @@ -1093,6 +1093,34 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) DBUG_RETURN(0); } +/* + Peek to check if a particular row already exists +*/ + +int ha_ndbcluster::peek_row() +{ + NdbConnection *trans= m_active_trans; + NdbOperation *op; + THD *thd= current_thd; + DBUG_ENTER("peek_row"); + + NdbOperation::LockMode lm= + (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type); + if (!(op= trans->getNdbOperation((const NDBTAB *) m_table)) || + op->readTuple(lm) != 0) + ERR_RETURN(trans->getNdbError()); + + int res; + if ((res= set_primary_key(op))) + ERR_RETURN(trans->getNdbError()); + + if (execute_no_commit_ie(this,trans) != 0) + { + table->status= STATUS_NOT_FOUND; + DBUG_RETURN(ndb_err(trans)); + } + DBUG_RETURN(0); +} /* Read one record from NDB using unique secondary index @@ -1138,7 +1166,7 @@ int ha_ndbcluster::unique_index_read(const byte *key, { Field *field= table->field[i]; if ((thd->query_id == field->query_id) || - (field->flags & PRI_KEY_FLAG)) + (field->flags & PRI_KEY_FLAG)) // && m_retrieve_primary_key ?? { if (get_ndb_value(op, field, i, buf)) ERR_RETURN(op->getNdbError()); @@ -1566,7 +1594,7 @@ int ha_ndbcluster::filtered_scan(const byte *key, uint key_len, Field* field= key_part->field; uint ndb_fieldnr= key_part->fieldnr-1; DBUG_PRINT("key_part", ("fieldnr: %d", ndb_fieldnr)); - // const NDBCOL *col= tab->getColumn(ndb_fieldnr); + //const NDBCOL *col= ((const NDBTAB *) m_table)->getColumn(ndb_fieldnr); uint32 field_len= field->pack_length(); DBUG_DUMP("key", (char*)key, field_len); @@ -1635,9 +1663,17 @@ int ha_ndbcluster::write_row(byte *record) int res; DBUG_ENTER("write_row"); - if(m_ignore_dup_key_not_supported) + if(m_ignore_dup_key && table->primary_key != MAX_KEY) { - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + int peek_res= peek_row(); + + if (!peek_res) + { + m_dupkey= table->primary_key; + DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY); + } + if (peek_res != HA_ERR_KEY_NOT_FOUND) + DBUG_RETURN(peek_res); } statistic_increment(ha_write_count,&LOCK_status); @@ -1791,7 +1827,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) NdbOperation *op; uint i; DBUG_ENTER("update_row"); - + statistic_increment(ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); @@ -2653,15 +2689,15 @@ int ha_ndbcluster::extra(enum ha_extra_function operation) m_use_write= TRUE; } else { - if (table->keys) - m_ignore_dup_key_not_supported= TRUE; + DBUG_PRINT("info", ("Ignoring duplicate key")); + m_ignore_dup_key= TRUE; } break; case HA_EXTRA_NO_IGNORE_DUP_KEY: DBUG_PRINT("info", ("HA_EXTRA_NO_IGNORE_DUP_KEY")); DBUG_PRINT("info", ("Turning OFF use of write instead of insert")); m_use_write= FALSE; - m_ignore_dup_key_not_supported= FALSE; + m_ignore_dup_key= FALSE; break; case HA_EXTRA_RETRIEVE_ALL_COLS: /* Retrieve all columns, not just those where field->query_id is the same as @@ -2680,6 +2716,7 @@ int ha_ndbcluster::extra(enum ha_extra_function operation) break; case HA_EXTRA_RETRIEVE_PRIMARY_KEY: DBUG_PRINT("info", ("HA_EXTRA_RETRIEVE_PRIMARY_KEY")); + m_retrieve_primary_key= TRUE; break; case HA_EXTRA_CHANGE_KEY_TO_UNIQUE: DBUG_PRINT("info", ("HA_EXTRA_CHANGE_KEY_TO_UNIQUE")); @@ -2942,6 +2979,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) DBUG_ASSERT(m_active_trans); // Start of transaction m_retrieve_all_fields= FALSE; + m_retrieve_primary_key= FALSE; m_ops_pending= 0; { NDBDICT *dict= m_ndb->getDictionary(); @@ -3034,6 +3072,7 @@ int ha_ndbcluster::start_stmt(THD *thd) // Start of statement m_retrieve_all_fields= FALSE; + m_retrieve_primary_key= FALSE; m_ops_pending= 0; DBUG_RETURN(error); @@ -3640,9 +3679,10 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): HA_NO_PREFIX_CHAR_KEYS), m_share(0), m_use_write(FALSE), - m_ignore_dup_key_not_supported(FALSE), + m_ignore_dup_key(FALSE), m_primary_key_update(FALSE), m_retrieve_all_fields(FALSE), + m_retrieve_primary_key(FALSE), m_rows_to_insert(1), m_rows_inserted(0), m_bulk_insert_rows(1024), diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 2121228a869..c6c233c013c 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -183,6 +183,7 @@ class ha_ndbcluster: public handler int pk_read(const byte *key, uint key_len, byte *buf); int complemented_pk_read(const byte *old_data, byte *new_data); + int peek_row(); int unique_index_read(const byte *key, uint key_len, byte *buf); int ordered_index_scan(const key_range *start_key, @@ -242,9 +243,10 @@ class ha_ndbcluster: public handler typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue; NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE]; bool m_use_write; - bool m_ignore_dup_key_not_supported; + bool m_ignore_dup_key; bool m_primary_key_update; bool m_retrieve_all_fields; + bool m_retrieve_primary_key; ha_rows m_rows_to_insert; ha_rows m_rows_inserted; ha_rows m_bulk_insert_rows; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 822ce622b1b..d590d3b5093 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -453,8 +453,8 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, setup_tables(insert_table_list) || setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) || (duplic == DUP_UPDATE && - (setup_fields(thd, 0, insert_table_list, update_fields, 0, 0, 0) || - setup_fields(thd, 0, insert_table_list, update_values, 0, 0, 0)))) + (setup_fields(thd, 0, insert_table_list, update_fields, 1, 0, 0) || + setup_fields(thd, 0, insert_table_list, update_values, 1, 0, 0)))) DBUG_RETURN(-1); if (find_real_table_in_list(table_list->next, table_list->db, table_list->real_name)) @@ -462,6 +462,9 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); DBUG_RETURN(-1); } + if (duplic == DUP_UPDATE || duplic == DUP_REPLACE) + table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); + DBUG_RETURN(0); } From 8453693a0552528808d4bb985be991de01f40ccb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 16:15:48 +0400 Subject: [PATCH 11/44] Check that the third UNION part with COLLATE clause resolves collation conflict for the first and the second parts pair. --- mysql-test/r/union.result | 10 ++++++++++ mysql-test/t/union.test | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 7820cd1d6ff..49a2907f571 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1110,4 +1110,14 @@ t1 CREATE TABLE `t1` ( `a` char(1) character set latin1 collate latin1_german1_ci default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +create table t1 as +(select a from t2) union +(select b from t2) union +(select 'c' collate latin1_german1_ci from t2); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) character set latin1 collate latin1_german1_ci default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; drop table t2; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 36027e8c4cb..468a88b83db 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -652,5 +652,11 @@ create table t1 as (select b collate latin1_german1_ci from t2); show create table t1; drop table t1; +create table t1 as +(select a from t2) union +(select b from t2) union +(select 'c' collate latin1_german1_ci from t2); +show create table t1; +drop table t1; drop table t2; From 1faf1d2349c2ccc29cc17e66bd24906cfcd3dd57 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 16:52:45 +0200 Subject: [PATCH 12/44] correct name of function in synopsis BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + mysys/mf_keycaches.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 1f1918027e2..1c1a3efc542 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -199,6 +199,7 @@ tim@siva.hindu.god tim@threads.polyesthetic.msg tim@white.box tim@work.mysql.com +timour@mysql.com tom@basil-firewall.home.com tomas@mc05.(none) tomas@poseidon.(none) diff --git a/mysys/mf_keycaches.c b/mysys/mf_keycaches.c index 20465f3d23b..8bf203e249f 100644 --- a/mysys/mf_keycaches.c +++ b/mysys/mf_keycaches.c @@ -309,7 +309,7 @@ void multi_keycache_free(void) Get a key cache to be used for a specific table. SYNOPSIS - multi_key_cache_get() + multi_key_cache_search() key key to find (usually table path) uint length Length of key. From 9039cff65dac4ebed5a67d9f2245fec7774d9cc2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 17:01:33 +0200 Subject: [PATCH 13/44] row0ins.c: row_ins_scan_sec_index_for_duplicate(), row_ins_duplicate_error_in_clust(): remove unused variables "ptr" innobase/row/row0ins.c: row_ins_scan_sec_index_for_duplicate(), row_ins_duplicate_error_in_clust(): remove unused variables "ptr" --- innobase/row/row0ins.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index c45818ddd26..6d1482b6720 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -1509,7 +1509,6 @@ row_ins_scan_sec_index_for_duplicate( ibool moved; mtr_t mtr; trx_t* trx; - const char* ptr; n_unique = dict_index_get_n_unique(index); @@ -1630,7 +1629,6 @@ row_ins_duplicate_error_in_clust( page_t* page; ulint n_unique; trx_t* trx = thr_get_trx(thr); - const char* ptr; UT_NOT_USED(mtr); From 50ef2cc1a5592d08cc91cb9a2b98f060d4707db4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 16:44:50 +0100 Subject: [PATCH 14/44] ndb: new arbitrator behaviour for >=3-way: < 1/2 nodes can survive ndb/include/kernel/signaldata/ArbitSignalData.hpp: new arbitrator behaviour for >=3-way: < 1/2 nodes can survive ndb/src/common/debugger/EventLogger.cpp: new arbitrator behaviour for >=3-way: < 1/2 nodes can survive ndb/src/kernel/blocks/qmgr/QmgrMain.cpp: new arbitrator behaviour for >=3-way: < 1/2 nodes can survive --- .../kernel/signaldata/ArbitSignalData.hpp | 15 +++++----- ndb/src/common/debugger/EventLogger.cpp | 5 ++++ ndb/src/kernel/blocks/qmgr/QmgrMain.cpp | 29 +++++++++++++------ 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/ndb/include/kernel/signaldata/ArbitSignalData.hpp b/ndb/include/kernel/signaldata/ArbitSignalData.hpp index f255b8dcbbe..34b73644a13 100644 --- a/ndb/include/kernel/signaldata/ArbitSignalData.hpp +++ b/ndb/include/kernel/signaldata/ArbitSignalData.hpp @@ -94,13 +94,14 @@ public: // arbitration result LoseNodes = 41, // lose on ndb node count - WinGroups = 42, // we win, no need for arbitration - LoseGroups = 43, // we lose, missing node group - Partitioning = 44, // possible network partitioning - WinChoose = 45, // positive reply - LoseChoose = 46, // negative reply - LoseNorun = 47, // arbitrator required but not running - LoseNocfg = 48, // arbitrator required but none configured + WinNodes = 42, // win on ndb node count + WinGroups = 43, // we win, no need for arbitration + LoseGroups = 44, // we lose, missing node group + Partitioning = 45, // possible network partitioning + WinChoose = 46, // positive reply + LoseChoose = 47, // negative reply + LoseNorun = 48, // arbitrator required but not running + LoseNocfg = 49, // arbitrator required but none configured // general error codes ErrTicket = 91, // invalid arbitrator-ticket diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp index 8a09be9a0a7..59be0affcb4 100644 --- a/ndb/src/common/debugger/EventLogger.cpp +++ b/ndb/src/common/debugger/EventLogger.cpp @@ -421,6 +421,11 @@ EventLogger::getText(char * m_text, size_t m_text_len, "%sArbitration check lost - less than 1/2 nodes left", theNodeId); break; + case ArbitCode::WinNodes: + BaseString::snprintf(m_text, m_text_len, + "%sArbitration check won - all node groups and more than 1/2 nodes left", + theNodeId); + break; case ArbitCode::WinGroups: BaseString::snprintf(m_text, m_text_len, "%sArbitration check won - node group majority", diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index a433d72744e..da8596076ec 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -2946,6 +2946,12 @@ void Qmgr::sendPrepFailReq(Signal* signal, Uint16 aNode) * the "handle" routines. */ +/** + * Should < 1/2 nodes die unconditionally. Affects only >= 3-way + * replication. + */ +static const bool g_ndb_arbit_one_half_rule = false; + /** * Config signals are logically part of CM_INIT. */ @@ -3157,7 +3163,8 @@ Qmgr::handleArbitCheck(Signal* signal) ndbrequire(cpresident == getOwnNodeId()); NodeBitmask ndbMask; computeArbitNdbMask(ndbMask); - if (2 * ndbMask.count() < cnoOfNodes) { + if (g_ndb_arbit_one_half_rule && + 2 * ndbMask.count() < cnoOfNodes) { jam(); arbitRec.code = ArbitCode::LoseNodes; } else { @@ -3181,6 +3188,11 @@ Qmgr::handleArbitCheck(Signal* signal) case CheckNodeGroups::Partitioning: jam(); arbitRec.code = ArbitCode::Partitioning; + if (g_ndb_arbit_one_half_rule && + 2 * ndbMask.count() > cnoOfNodes) { + jam(); + arbitRec.code = ArbitCode::WinNodes; + } break; default: ndbrequire(false); @@ -3190,8 +3202,12 @@ Qmgr::handleArbitCheck(Signal* signal) switch (arbitRec.code) { case ArbitCode::LoseNodes: jam(); + case ArbitCode::LoseGroups: + jam(); goto crashme; - case ArbitCode::WinGroups: + case ArbitCode::WinNodes: + jam(); + case ArbitCode::WinGroups: jam(); if (arbitRec.state == ARBIT_RUN) { jam(); @@ -3200,9 +3216,6 @@ Qmgr::handleArbitCheck(Signal* signal) arbitRec.state = ARBIT_INIT; arbitRec.newstate = true; break; - case ArbitCode::LoseGroups: - jam(); - goto crashme; case ArbitCode::Partitioning: if (arbitRec.state == ARBIT_RUN) { jam(); @@ -3762,8 +3775,7 @@ Qmgr::execARBIT_CHOOSEREF(Signal* signal) } /** - * Handle CRASH state. We must crash immediately. But it - * would be nice to wait until event reports have been sent. + * Handle CRASH state. We must crash immediately. * XXX tell other nodes in our party to crash too. */ void @@ -3773,12 +3785,11 @@ Qmgr::stateArbitCrash(Signal* signal) if (arbitRec.newstate) { jam(); CRASH_INSERTION((Uint32)910 + arbitRec.state); - arbitRec.setTimestamp(); arbitRec.code = 0; arbitRec.newstate = false; } -#if 0 +#ifdef ndb_arbit_crash_wait_for_event_report_to_get_out if (! (arbitRec.getTimediff() > getArbitTimeout())) return; #endif From 75431a2e1678004b63d9119ac88df2dddd59b2e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 20:28:36 +0000 Subject: [PATCH 15/44] fix for mysqladmin link problem .c -> .cc fix source dist problem for ndb fix type check problem for mysqladmin client/Makefile.am: fix for mysqladmin link problem .c -> .cc client/mysqladmin.cc: fix for mysqladmin link problem .c -> .cc configure.in: fix for mysqladmin link problem .c -> .cc ndb/include/Makefile.am: fix source dist problem for ndb ndb/src/mgmclient/CommandInterpreter.cpp: fix type check problem ndb/src/mgmclient/ndb_mgmclient.hpp: fix type check problem ndb/src/mgmclient/ndb_mgmclient.h: fix type check problem --- client/Makefile.am | 1 + client/{mysqladmin.c => mysqladmin.cc} | 3 --- configure.in | 1 - ndb/include/Makefile.am | 1 + ndb/src/mgmclient/CommandInterpreter.cpp | 4 ++-- ndb/src/mgmclient/ndb_mgmclient.h | 2 +- ndb/src/mgmclient/ndb_mgmclient.hpp | 2 +- 7 files changed, 6 insertions(+), 8 deletions(-) rename client/{mysqladmin.c => mysqladmin.cc} (99%) diff --git a/client/Makefile.am b/client/Makefile.am index 1c552036f9b..5034dd5bf51 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -27,6 +27,7 @@ bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ client_priv.h +mysqladmin_SOURCES = mysqladmin.cc mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/client/mysqladmin.c b/client/mysqladmin.cc similarity index 99% rename from client/mysqladmin.c rename to client/mysqladmin.cc index a32dfa14d28..a9fc3f31d03 100644 --- a/client/mysqladmin.c +++ b/client/mysqladmin.cc @@ -1287,9 +1287,6 @@ static my_bool wait_pidfile(char *pidfile, time_t last_modified, } DBUG_RETURN(error); } -#ifdef HAVE_NDBCLUSTER_DB -/* lib linked in contains c++ code */ #ifdef __GNUC__ FIX_GCC_LINKING_PROBLEM #endif -#endif diff --git a/configure.in b/configure.in index f360ee46453..1fcba6b8f5f 100644 --- a/configure.in +++ b/configure.in @@ -399,7 +399,6 @@ then then if $CXX -v 2>&1 | grep 'version 3' > /dev/null 2>&1 then - CFLAGS="$CFLAGS -DDEFINE_CXA_PURE_VIRTUAL" CXXFLAGS="$CXXFLAGS -DUSE_MYSYS_NEW -DDEFINE_CXA_PURE_VIRTUAL" fi fi diff --git a/ndb/include/Makefile.am b/ndb/include/Makefile.am index 7b3f80b5560..ca2e8152352 100644 --- a/ndb/include/Makefile.am +++ b/ndb/include/Makefile.am @@ -28,6 +28,7 @@ ndbapi/NdbIndexScanOperation.hpp \ ndbapi/ndberror.h mgmapiinclude_HEADERS = \ +mgmapi/LocalConfig.hpp \ mgmapi/mgmapi.h \ mgmapi/mgmapi_debug.h diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index d940f6e165a..a36263395ec 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -193,7 +193,7 @@ extern "C" { { return (Ndb_mgmclient_handle) new Ndb_mgmclient(connect_string); } - int ndb_mgmclient_execute(Ndb_mgmclient_handle h, int argc, const char** argv) + int ndb_mgmclient_execute(Ndb_mgmclient_handle h, int argc, char** argv) { return ((Ndb_mgmclient*)h)->execute(argc, argv, 1); } @@ -226,7 +226,7 @@ extern "C" { #include #include -int Ndb_mgmclient::execute(int argc, const char** argv, int _try_reconnect) +int Ndb_mgmclient::execute(int argc, char** argv, int _try_reconnect) { if (argc <= 0) return 0; diff --git a/ndb/src/mgmclient/ndb_mgmclient.h b/ndb/src/mgmclient/ndb_mgmclient.h index 265e6bc67ec..b62a33999a3 100644 --- a/ndb/src/mgmclient/ndb_mgmclient.h +++ b/ndb/src/mgmclient/ndb_mgmclient.h @@ -23,7 +23,7 @@ extern "C" { typedef void* Ndb_mgmclient_handle; Ndb_mgmclient_handle ndb_mgmclient_handle_create(const char *connect_string); -int ndb_mgmclient_execute(Ndb_mgmclient_handle, int argc, const char** argv); +int ndb_mgmclient_execute(Ndb_mgmclient_handle, int argc, char** argv); int ndb_mgmclient_handle_destroy(Ndb_mgmclient_handle); #ifdef __cplusplus diff --git a/ndb/src/mgmclient/ndb_mgmclient.hpp b/ndb/src/mgmclient/ndb_mgmclient.hpp index 933d1bab5ce..f6bcebc3896 100644 --- a/ndb/src/mgmclient/ndb_mgmclient.hpp +++ b/ndb/src/mgmclient/ndb_mgmclient.hpp @@ -24,7 +24,7 @@ public: Ndb_mgmclient(const char*); ~Ndb_mgmclient(); int execute(const char *_line, int _try_reconnect=-1); - int execute(int argc, const char** argv, int _try_reconnect=-1); + int execute(int argc, char** argv, int _try_reconnect=-1); int disconnect(); private: CommandInterpreter *m_cmd; From 6aab88c9169960da307d39eb7b9977f215c63508 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 22:28:37 +0200 Subject: [PATCH 16/44] fil0fil.h, fil0fil.c: Fix bug introduced in 4.1.1: InnoDB no longer respected the data file max size given in :autoextend:max: innobase/fil/fil0fil.c: Fix bug introduced in 4.1.1: InnoDB no longer respected the data file max size given in :autoextend:max: innobase/include/fil0fil.h: Fix bug introduced in 4.1.1: InnoDB no longer respected the data file max size given in :autoextend:max: --- innobase/fil/fil0fil.c | 19 ++++++++++++++++--- innobase/include/fil0fil.h | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 7d57468f632..de528355182 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -106,7 +106,7 @@ struct fil_node_struct { device or a raw disk partition */ ulint size; /* size of the file in database pages, 0 if not known yet; the possible last incomplete - megabyte is ignored if space == 0 */ + megabyte may be ignored if space == 0 */ ulint n_pending; /* count of pending i/o's on this file; closing of the file is not allowed if @@ -160,7 +160,9 @@ struct fil_space_struct { UT_LIST_BASE_NODE_T(fil_node_t) chain; /* base node for the file chain */ ulint size; /* space size in pages; 0 if a single-table - tablespace whose size we do not know yet */ + tablespace whose size we do not know yet; + last incomplete megabytes in data files may be + ignored if space == 0 */ ulint n_reserved_extents; /* number of reserved free extents for ongoing operations like B-tree page split */ @@ -3255,7 +3257,7 @@ fil_extend_space_to_desired_size( ulint* actual_size, /* out: size of the space after extension; if we ran out of disk space this may be lower than the desired size */ - ulint space_id, /* in: space id, must be != 0 */ + ulint space_id, /* in: space id */ ulint size_after_extend)/* in: desired size in pages after the extension; if the current space size is bigger than this already, the function does nothing */ @@ -3352,6 +3354,17 @@ fil_extend_space_to_desired_size( fil_node_complete_io(node, system, OS_FILE_WRITE); *actual_size = space->size; + + if (space_id == 0) { + ulint pages_per_mb = (1024 * 1024) / UNIV_PAGE_SIZE; + + /* Keep the last data file size info up to date, rounded to + full megabytes */ + + srv_data_file_sizes[srv_n_data_files - 1] = + (node->size / pages_per_mb) * pages_per_mb; + } + /* printf("Extended %s to %lu, actual size %lu pages\n", space->name, size_after_extend, *actual_size); */ diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h index 5a5db77073a..43327aab9d2 100644 --- a/innobase/include/fil0fil.h +++ b/innobase/include/fil0fil.h @@ -478,7 +478,7 @@ fil_extend_space_to_desired_size( ulint* actual_size, /* out: size of the space after extension; if we ran out of disk space this may be lower than the desired size */ - ulint space_id, /* in: space id, must be != 0 */ + ulint space_id, /* in: space id */ ulint size_after_extend);/* in: desired size in pages after the extension; if the current space size is bigger than this already, the function does nothing */ From a8ba534cee918abd55df54be7136385b57155044 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 23:35:45 +0300 Subject: [PATCH 17/44] Some comments regarding Bug#6275 ""client_test" fail in 4.1.7 make test" --- tests/client_test.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tests/client_test.c b/tests/client_test.c index 2f28da6d00d..0ada98d44b0 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -635,12 +635,15 @@ static void verify_prepare_field(MYSQL_RES *result, unsigned long length, const char *def) { MYSQL_FIELD *field; + CHARSET_INFO *cs; if (!(field= mysql_fetch_field_direct(result, no))) { fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***"); exit(1); } + cs= get_charset(field->charsetnr, 0); + DIE_UNLESS(cs); if (!opt_silent) { fprintf(stdout, "\n field[%d]:", no); @@ -654,7 +657,7 @@ static void verify_prepare_field(MYSQL_RES *result, field->org_table, org_table); fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); fprintf(stdout, "\n length :`%ld`\t(expected: `%ld`)", - field->length, length); + field->length, length * cs->mbmaxlen); fprintf(stdout, "\n maxlength:`%ld`", field->max_length); fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr); fprintf(stdout, "\n default :`%s`\t(expected: `%s`)", @@ -663,11 +666,24 @@ static void verify_prepare_field(MYSQL_RES *result, } DIE_UNLESS(strcmp(field->name, name) == 0); DIE_UNLESS(strcmp(field->org_name, org_name) == 0); - DIE_UNLESS(field->type == type); + /* + XXX: silent column specification change works based on number of + bytes a column occupies. So CHAR -> VARCHAR upgrade is possible even + for CHAR(2) column if its character set is multibyte. + VARCHAR -> CHAR downgrade won't work for VARCHAR(3) as one would + expect. + */ + if (cs->mbmaxlen == 1) + DIE_UNLESS(field->type == type); DIE_UNLESS(strcmp(field->table, table) == 0); DIE_UNLESS(strcmp(field->org_table, org_table) == 0); DIE_UNLESS(strcmp(field->db, db) == 0); - DIE_UNLESS(field->length == length); + /* + Character set should be taken into account for multibyte encodings, such + as utf8. Field length is calculated as number of characters * maximum + number of bytes a character can occupy. + */ + DIE_UNLESS(field->length == length * cs->mbmaxlen); if (def) DIE_UNLESS(strcmp(field->def, def) == 0); } From ebe7fe1481da8429d6f273a63c9297cdf2969df4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 21:15:18 +0000 Subject: [PATCH 18/44] bug#6677 bug#6684 --- ndb/src/mgmclient/CommandInterpreter.cpp | 7 +++++- ndb/tools/restore/main.cpp | 27 +++++++++++++++++------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index a36263395ec..bdeb885ed8b 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -1386,7 +1386,7 @@ void CommandInterpreter::executeDumpState(int processId, const char* parameters, bool all) { - if(parameters == 0 || strlen(parameters) == 0){ + if(emptyString(parameters)){ ndbout << "Expected argument" << endl; return; } @@ -1806,6 +1806,10 @@ CommandInterpreter::executeEventReporting(int processId, const char* parameters, bool all) { + if (emptyString(parameters)) { + ndbout << "Expected argument" << endl; + return; + } connect(); BaseString tmp(parameters); @@ -1906,6 +1910,7 @@ void CommandInterpreter::executeAbortBackup(char* parameters) { connect(); + strtok(parameters, " "); struct ndb_mgm_reply reply; char* id = strtok(NULL, "\0"); diff --git a/ndb/tools/restore/main.cpp b/ndb/tools/restore/main.cpp index 482212911cb..064fbad43a3 100644 --- a/ndb/tools/restore/main.cpp +++ b/ndb/tools/restore/main.cpp @@ -74,7 +74,7 @@ static struct my_option my_long_options[] = "No of parallel transactions during restore of data." "(parallelism can be 1 to 1024)", (gptr*) &ga_nParallelism, (gptr*) &ga_nParallelism, 0, - GET_INT, REQUIRED_ARG, 128, 0, 0, 0, 0, 0 }, + GET_INT, REQUIRED_ARG, 128, 1, 1024, 0, 1, 0 }, { "print", 256, "Print data and log to stdout", (gptr*) &_print, (gptr*) &_print, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, @@ -120,6 +120,18 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'V': print_version(); exit(0); + case 'n': + if (ga_nodeId == 0) + { + printf("Error in --nodeid|-n setting, see --help\n"); + exit(1); + } + case 'b': + if (ga_backupId == 0) + { + printf("Error in --backupid|-b setting, see --help\n"); + exit(1); + } case '?': usage(); exit(0); @@ -131,11 +143,8 @@ readArguments(int *pargc, char*** pargv) { const char *load_default_groups[]= { "ndb_tools","ndb_restore",0 }; load_defaults("my",load_default_groups,pargc,pargv); - if (handle_options(pargc, pargv, my_long_options, get_one_option) || - ga_nodeId == 0 || - ga_backupId == 0 || - ga_nParallelism < 1 || - ga_nParallelism >1024) { + if (handle_options(pargc, pargv, my_long_options, get_one_option)) + { exit(1); } @@ -343,7 +352,8 @@ main(int argc, char** argv) if (res < 0) { - err << "Restore: An error occured while restoring data. Exiting... res=" << res << endl; + err << "Restore: An error occured while restoring data. Exiting... " + << "res=" << res << endl; return -1; } @@ -369,7 +379,8 @@ main(int argc, char** argv) } if (res < 0) { - err << "Restore: An restoring the data log. Exiting... res=" << res << endl; + err << "Restore: An restoring the data log. Exiting... res=" + << res << endl; return -1; } logIter.validateFooter(); //not implemented From 13710e869fb66e6dc9f21a974b43a3c0dd821535 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 21:42:25 +0000 Subject: [PATCH 19/44] change file name to avoid conflict corrected mistake in previous patch ndb/tools/Makefile.am: change file name to avoid conflict ndb/tools/restore/restore_main.cpp: corrected mistake in previous patch --- ndb/tools/Makefile.am | 2 +- ndb/tools/restore/{main.cpp => restore_main.cpp} | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) rename ndb/tools/restore/{main.cpp => restore_main.cpp} (98%) diff --git a/ndb/tools/Makefile.am b/ndb/tools/Makefile.am index 9c086d665c1..7a61a9b1be5 100644 --- a/ndb/tools/Makefile.am +++ b/ndb/tools/Makefile.am @@ -26,7 +26,7 @@ ndb_select_all_SOURCES = select_all.cpp \ ../test/src/NDBT_ResultRow.cpp \ $(tools_common_sources) ndb_select_count_SOURCES = select_count.cpp $(tools_common_sources) -ndb_restore_SOURCES = restore/main.cpp \ +ndb_restore_SOURCES = restore/restore_main.cpp \ restore/consumer.cpp \ restore/consumer_restore.cpp \ restore/consumer_printer.cpp \ diff --git a/ndb/tools/restore/main.cpp b/ndb/tools/restore/restore_main.cpp similarity index 98% rename from ndb/tools/restore/main.cpp rename to ndb/tools/restore/restore_main.cpp index 064fbad43a3..c43791c6723 100644 --- a/ndb/tools/restore/main.cpp +++ b/ndb/tools/restore/restore_main.cpp @@ -123,15 +123,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'n': if (ga_nodeId == 0) { - printf("Error in --nodeid|-n setting, see --help\n"); + printf("Error in --nodeid,-n setting, see --help\n"); exit(1); } + break; case 'b': if (ga_backupId == 0) { - printf("Error in --backupid|-b setting, see --help\n"); + printf("Error in --backupid,-b setting, see --help\n"); exit(1); } + break; case '?': usage(); exit(0); From f336c62a4480d4175942a6ed23fa5fe09f411b15 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 22:59:17 +0100 Subject: [PATCH 20/44] When mysqlbinlog prints LOAD DATA INFILE, let it print the thread id. Some customer would have benefited much from this in his recovery. All this change does is adding one commented (#) line before the LOAD DATA command, so it is quite innocuous. --- sql/log_event.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index f707eabebd5..007bb6e7b85 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1612,7 +1612,7 @@ void Create_file_log_event::print(FILE* file, bool short_form, if (enable_local) { - Load_log_event::print(file, 1, last_db, !check_fname_outside_temp_buf()); + Load_log_event::print(file, short_form, last_db, !check_fname_outside_temp_buf()); /* That one is for "file_id: etc" below: in mysqlbinlog we want the #, in SHOW BINLOG EVENTS we don't. From 3ef38a3732a832f91d1ab5db62659a36a081646e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Nov 2004 22:45:48 +0000 Subject: [PATCH 21/44] moved ndb_use_transactions out of opts and to be set default true in THD::init --- sql/mysqld.cc | 6 ------ sql/sql_class.cc | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5ee52326276..5033c42ac69 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3950,7 +3950,6 @@ enum options_mysqld OPT_INNODB, OPT_ISAM, OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT, OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, - OPT_NDB_USE_TRANSACTIONS, OPT_SKIP_SAFEMALLOC, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, @@ -4410,11 +4409,6 @@ Disable with --skip-ndbcluster (will save memory).", (gptr*) &global_system_variables.ndb_use_exact_count, (gptr*) &global_system_variables.ndb_use_exact_count, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, - {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS, - "Use transactions in ndb", - (gptr*) &global_system_variables.ndb_use_transactions, - (gptr*) &global_system_variables.ndb_use_transactions, - 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, #endif {"new", 'n', "Use very new possible 'unsafe' functions.", (gptr*) &global_system_variables.new_mode, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index eda60b5cfdb..bab81d785c3 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -280,6 +280,9 @@ void THD::init(void) variables.date_format); variables.datetime_format= date_time_format_copy((THD*) 0, variables.datetime_format); +#ifdef HAVE_NDBCLUSTER_DB + variables.ndb_use_transactions= 1; +#endif pthread_mutex_unlock(&LOCK_global_system_variables); server_status= SERVER_STATUS_AUTOCOMMIT; options= thd_startup_options; From fb36bc2a43b910ed5a46dba72153e2cc795b51b2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 00:57:26 +0100 Subject: [PATCH 22/44] log_event.cc: post-conflict-merge fix (duplicate comment) sql/log_event.cc: post-conflict-merge fix (duplicate comment) --- sql/log_event.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 31b02a5a29a..2fdc89504d7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,4 +1,3 @@ -/* Copyright (C) 2000-2004 MySQL AB /* Copyright (C) 2000-2004 MySQL AB This program is free software; you can redistribute it and/or modify From bd51cf30d27dab3cb240c6f0f45e2c40080618c6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 09:17:36 +0000 Subject: [PATCH 23/44] ndb_grant.result, ndb_grant.test: new file --- mysql-test/r/ndb_grant.result | 416 ++++++++++++++++++++++++++++++++++ mysql-test/t/ndb_grant.test | 374 ++++++++++++++++++++++++++++++ 2 files changed, 790 insertions(+) create mode 100644 mysql-test/r/ndb_grant.result create mode 100644 mysql-test/t/ndb_grant.test diff --git a/mysql-test/r/ndb_grant.result b/mysql-test/r/ndb_grant.result new file mode 100644 index 00000000000..6583065a0c4 --- /dev/null +++ b/mysql-test/r/ndb_grant.result @@ -0,0 +1,416 @@ +drop table if exists t1; +SET NAMES binary; +use mysql; +alter table columns_priv engine=ndb; +alter table db engine=ndb; +alter table func engine=ndb; +alter table help_category engine=ndb; +alter table help_keyword engine=ndb; +alter table help_relation engine=ndb; +alter table help_topic engine=ndb; +alter table host engine=ndb; +alter table tables_priv engine=ndb; +alter table time_zone engine=ndb; +alter table time_zone_leap_second engine=ndb; +alter table time_zone_name engine=ndb; +alter table time_zone_transition engine=ndb; +alter table time_zone_transition_type engine=ndb; +alter table user engine=ndb; +use test; +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +flush privileges; +begin; +grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA"; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' +GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +begin; +grant delete on mysqltest.* to mysqltest_1@localhost; +commit; +select * from mysql.user where user="mysqltest_1"; +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' +GRANT SELECT, DELETE ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +begin; +revoke delete on mysqltest.* from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' +GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +begin; +grant select on mysqltest.* to mysqltest_1@localhost require NONE; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +begin; +grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB"; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA' +GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +begin; +revoke all privileges on mysqltest.* from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA' +delete from mysql.user where user='mysqltest_1'; +flush privileges; +begin; +grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT CREATE TEMPORARY TABLES, LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +flush privileges; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT CREATE TEMPORARY TABLES, LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +begin; +revoke CREATE TEMPORARY TABLES on mysqltest.* from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT LOCK TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +begin; +grant ALL PRIVILEGES on mysqltest.* to mysqltest_1@localhost with GRANT OPTION; +commit; +flush privileges; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +begin; +revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +begin; +revoke all privileges on mysqltest.* from mysqltest_1@localhost; +commit; +delete from mysql.user where user='mysqltest_1'; +flush privileges; +begin; +grant usage on test.* to mysqltest_1@localhost with grant option; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT USAGE ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +GRANT USAGE ON `test`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1'; +delete from mysql.columns_priv where user='mysqltest_1'; +flush privileges; +show grants for mysqltest_1@localhost; +ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host 'localhost' +create table t1 (a int); +begin; +GRANT select,update,insert on t1 to mysqltest_1@localhost; +GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT, SELECT (a), INSERT, INSERT (a), UPDATE, UPDATE (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost' +select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; +table_priv column_priv +Select,Insert,Update Select,Insert,Update,References +begin; +REVOKE select (a), update on t1 from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT, INSERT, INSERT (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost' +begin; +REVOKE select,update,insert,insert (a) on t1 from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost' +begin; +GRANT select,references on t1 to mysqltest_1@localhost; +commit; +select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; +table_priv column_priv +Select,References References +begin; +grant all on test.* to mysqltest_3@localhost with grant option; +revoke all on test.* from mysqltest_3@localhost; +commit; +show grants for mysqltest_3@localhost; +Grants for mysqltest_3@localhost +GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost' +GRANT USAGE ON `test`.* TO 'mysqltest_3'@'localhost' WITH GRANT OPTION +begin; +revoke grant option on test.* from mysqltest_3@localhost; +commit; +show grants for mysqltest_3@localhost; +Grants for mysqltest_3@localhost +GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost' +begin; +grant all on test.t1 to mysqltest_2@localhost with grant option; +revoke all on test.t1 from mysqltest_2@localhost; +commit; +show grants for mysqltest_2@localhost; +Grants for mysqltest_2@localhost +GRANT USAGE ON *.* TO 'mysqltest_2'@'localhost' +GRANT USAGE ON `test`.`t1` TO 'mysqltest_2'@'localhost' WITH GRANT OPTION +begin; +revoke grant option on test.t1 from mysqltest_2@localhost; +commit; +show grants for mysqltest_2@localhost; +Grants for mysqltest_2@localhost +GRANT USAGE ON *.* TO 'mysqltest_2'@'localhost' +delete from mysql.user where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3"; +delete from mysql.db where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3"; +delete from mysql.tables_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3"; +delete from mysql.columns_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3"; +flush privileges; +drop table t1; +begin; +GRANT FILE on mysqltest.* to mysqltest_1@localhost; +ERROR HY000: Incorrect usage of DB GRANT and GLOBAL PRIVILEGES +commit; +select 1; +1 +1 +create database mysqltest1; +begin; +grant usage on mysqltest1.* to test6123 identified by 'magic123'; +commit; +select host,db,user,select_priv,insert_priv from mysql.db where db="mysqltest1"; +host db user select_priv insert_priv +delete from mysql.user where user='test6123'; +drop database mysqltest1; +create table t1 (a int); +begin; +grant ALL PRIVILEGES on *.* to drop_user2@localhost with GRANT OPTION; +commit; +show grants for drop_user2@localhost; +Grants for drop_user2@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user2'@'localhost' WITH GRANT OPTION +begin; +revoke all privileges, grant option from drop_user2@localhost; +commit; +drop user drop_user2@localhost; +begin; +grant ALL PRIVILEGES on *.* to drop_user@localhost with GRANT OPTION; +grant ALL PRIVILEGES on test.* to drop_user@localhost with GRANT OPTION; +grant select(a) on test.t1 to drop_user@localhost; +commit; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT ALL PRIVILEGES ON `test`.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT SELECT (a) ON `test`.`t1` TO 'drop_user'@'localhost' +set sql_mode=ansi_quotes; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT ALL PRIVILEGES ON "test".* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT SELECT (a) ON "test"."t1" TO 'drop_user'@'localhost' +set sql_mode=default; +set sql_quote_show_create=0; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT ALL PRIVILEGES ON test.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT SELECT (a) ON test.t1 TO 'drop_user'@'localhost' +set sql_mode="ansi_quotes"; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT ALL PRIVILEGES ON test.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT SELECT (a) ON test.t1 TO 'drop_user'@'localhost' +set sql_quote_show_create=1; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT ALL PRIVILEGES ON "test".* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT SELECT (a) ON "test"."t1" TO 'drop_user'@'localhost' +set sql_mode=""; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT ALL PRIVILEGES ON `test`.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT SELECT (a) ON `test`.`t1` TO 'drop_user'@'localhost' +revoke all privileges, grant option from drop_user@localhost; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT USAGE ON *.* TO 'drop_user'@'localhost' +drop user drop_user@localhost; +begin; +revoke all privileges, grant option from drop_user@localhost; +ERROR HY000: Can't revoke all privileges, grant for one or more of the requested users +commit; +begin; +grant select(a) on test.t1 to drop_user1@localhost; +commit; +flush privileges; +begin; +grant select on test.t1 to drop_user2@localhost; +grant select on test.* to drop_user3@localhost; +grant select on *.* to drop_user4@localhost; +commit; +drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, +drop_user4@localhost; +ERROR HY000: Can't drop one or more of the requested users +begin; +revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost, +drop_user3@localhost, drop_user4@localhost; +commit; +drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, +drop_user4@localhost; +drop table t1; +begin; +grant usage on *.* to mysqltest_1@localhost identified by "password"; +grant select, update, insert on test.* to mysqltest@localhost; +commit; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' +drop user mysqltest_1@localhost; +SET NAMES koi8r; +CREATE DATABASE бд; +USE бд; +CREATE TABLE таб (кол int); +begin; +GRANT SELECT ON бд.* TO юзер@localhost; +commit; +SHOW GRANTS FOR юзер@localhost; +Grants for юзер@localhost +GRANT USAGE ON *.* TO 'юзер'@'localhost' +GRANT SELECT ON `бд`.* TO 'юзер'@'localhost' +begin; +REVOKE SELECT ON бд.* FROM юзер@localhost; +commit; +begin; +GRANT SELECT ON бд.таб TO юзер@localhost; +commit; +SHOW GRANTS FOR юзер@localhost; +Grants for юзер@localhost +GRANT USAGE ON *.* TO 'юзер'@'localhost' +GRANT SELECT ON `бд`.`таб` TO 'юзер'@'localhost' +begin; +REVOKE SELECT ON бд.таб FROM юзер@localhost; +commit; +begin; +GRANT SELECT (кол) ON бд.таб TO юзер@localhost; +commit; +SHOW GRANTS FOR юзер@localhost; +Grants for юзер@localhost +GRANT USAGE ON *.* TO 'юзер'@'localhost' +GRANT SELECT (кол) ON `бд`.`таб` TO 'юзер'@'localhost' +begin; +REVOKE SELECT (кол) ON бд.таб FROM юзер@localhost; +commit; +DROP DATABASE бд; +SET NAMES latin1; +USE test; +CREATE TABLE t1 (a int ); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; +CREATE TABLE t4 LIKE t1; +CREATE TABLE t5 LIKE t1; +CREATE TABLE t6 LIKE t1; +CREATE TABLE t7 LIKE t1; +CREATE TABLE t8 LIKE t1; +CREATE TABLE t9 LIKE t1; +CREATE TABLE t10 LIKE t1; +CREATE DATABASE testdb1; +CREATE DATABASE testdb2; +CREATE DATABASE testdb3; +CREATE DATABASE testdb4; +CREATE DATABASE testdb5; +CREATE DATABASE testdb6; +CREATE DATABASE testdb7; +CREATE DATABASE testdb8; +CREATE DATABASE testdb9; +CREATE DATABASE testdb10; +begin; +GRANT ALL ON testdb1.* TO testuser@localhost; +GRANT ALL ON testdb2.* TO testuser@localhost; +GRANT ALL ON testdb3.* TO testuser@localhost; +GRANT ALL ON testdb4.* TO testuser@localhost; +GRANT ALL ON testdb5.* TO testuser@localhost; +GRANT ALL ON testdb6.* TO testuser@localhost; +GRANT ALL ON testdb7.* TO testuser@localhost; +GRANT ALL ON testdb8.* TO testuser@localhost; +GRANT ALL ON testdb9.* TO testuser@localhost; +GRANT ALL ON testdb10.* TO testuser@localhost; +GRANT SELECT ON test.t1 TO testuser@localhost; +GRANT SELECT ON test.t2 TO testuser@localhost; +GRANT SELECT ON test.t3 TO testuser@localhost; +GRANT SELECT ON test.t4 TO testuser@localhost; +GRANT SELECT ON test.t5 TO testuser@localhost; +GRANT SELECT ON test.t6 TO testuser@localhost; +GRANT SELECT ON test.t7 TO testuser@localhost; +GRANT SELECT ON test.t8 TO testuser@localhost; +GRANT SELECT ON test.t9 TO testuser@localhost; +GRANT SELECT ON test.t10 TO testuser@localhost; +GRANT SELECT (a) ON test.t1 TO testuser@localhost; +GRANT SELECT (a) ON test.t2 TO testuser@localhost; +GRANT SELECT (a) ON test.t3 TO testuser@localhost; +GRANT SELECT (a) ON test.t4 TO testuser@localhost; +GRANT SELECT (a) ON test.t5 TO testuser@localhost; +GRANT SELECT (a) ON test.t6 TO testuser@localhost; +GRANT SELECT (a) ON test.t7 TO testuser@localhost; +GRANT SELECT (a) ON test.t8 TO testuser@localhost; +GRANT SELECT (a) ON test.t9 TO testuser@localhost; +GRANT SELECT (a) ON test.t10 TO testuser@localhost; +commit; +begin; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM testuser@localhost; +commit; +SHOW GRANTS FOR testuser@localhost; +Grants for testuser@localhost +GRANT USAGE ON *.* TO 'testuser'@'localhost' +DROP USER testuser@localhost; +DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; +DROP DATABASE testdb1; +DROP DATABASE testdb2; +DROP DATABASE testdb3; +DROP DATABASE testdb4; +DROP DATABASE testdb5; +DROP DATABASE testdb6; +DROP DATABASE testdb7; +DROP DATABASE testdb8; +DROP DATABASE testdb9; +DROP DATABASE testdb10; +use mysql; +alter table columns_priv engine=myisam; +alter table db engine=myisam; +alter table func engine=myisam; +alter table help_category engine=myisam; +alter table help_keyword engine=myisam; +alter table help_relation engine=myisam; +alter table help_topic engine=myisam; +alter table host engine=myisam; +alter table tables_priv engine=myisam; +alter table time_zone engine=myisam; +alter table time_zone_leap_second engine=myisam; +alter table time_zone_name engine=myisam; +alter table time_zone_transition engine=myisam; +alter table time_zone_transition_type engine=myisam; +alter table user engine=myisam; +use test; +flush privileges; diff --git a/mysql-test/t/ndb_grant.test b/mysql-test/t/ndb_grant.test new file mode 100644 index 00000000000..d3899d9972f --- /dev/null +++ b/mysql-test/t/ndb_grant.test @@ -0,0 +1,374 @@ +-- source include/have_ndb.inc +# Test of GRANT commands + +# Cleanup +--disable_warnings +drop table if exists t1; +--enable_warnings + +SET NAMES binary; + +# +# Alter mysql system tables to ndb +# make sure you alter all back in the end +# +use mysql; +alter table columns_priv engine=ndb; +alter table db engine=ndb; +alter table func engine=ndb; +alter table help_category engine=ndb; +alter table help_keyword engine=ndb; +alter table help_relation engine=ndb; +alter table help_topic engine=ndb; +alter table host engine=ndb; +alter table tables_priv engine=ndb; +alter table time_zone engine=ndb; +alter table time_zone_leap_second engine=ndb; +alter table time_zone_name engine=ndb; +alter table time_zone_transition engine=ndb; +alter table time_zone_transition_type engine=ndb; +alter table user engine=ndb; +use test; + +# +# Test that SSL options works properly +# +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +flush privileges; +begin; +grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA"; +commit; +show grants for mysqltest_1@localhost; +begin; +grant delete on mysqltest.* to mysqltest_1@localhost; +commit; +select * from mysql.user where user="mysqltest_1"; +show grants for mysqltest_1@localhost; +begin; +revoke delete on mysqltest.* from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +begin; +grant select on mysqltest.* to mysqltest_1@localhost require NONE; +commit; +show grants for mysqltest_1@localhost; +begin; +grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB"; +commit; +show grants for mysqltest_1@localhost; +begin; +revoke all privileges on mysqltest.* from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +delete from mysql.user where user='mysqltest_1'; +flush privileges; + +# +# Test that the new db privileges are stored/retrieved correctly +# + +begin; +grant CREATE TEMPORARY TABLES, LOCK TABLES on mysqltest.* to mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +flush privileges; +show grants for mysqltest_1@localhost; +begin; +revoke CREATE TEMPORARY TABLES on mysqltest.* from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +begin; +grant ALL PRIVILEGES on mysqltest.* to mysqltest_1@localhost with GRANT OPTION; +commit; +flush privileges; +show grants for mysqltest_1@localhost; +begin; +revoke LOCK TABLES, ALTER on mysqltest.* from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +begin; +revoke all privileges on mysqltest.* from mysqltest_1@localhost; +commit; +delete from mysql.user where user='mysqltest_1'; +flush privileges; +begin; +grant usage on test.* to mysqltest_1@localhost with grant option; +commit; +show grants for mysqltest_1@localhost; +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1'; +delete from mysql.columns_priv where user='mysqltest_1'; +flush privileges; +--error 1141 +show grants for mysqltest_1@localhost; + +# +# Test what happens when you have same table and colum level grants +# + +create table t1 (a int); +begin; +GRANT select,update,insert on t1 to mysqltest_1@localhost; +GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; +begin; +REVOKE select (a), update on t1 from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +begin; +REVOKE select,update,insert,insert (a) on t1 from mysqltest_1@localhost; +commit; +show grants for mysqltest_1@localhost; +begin; +GRANT select,references on t1 to mysqltest_1@localhost; +commit; +select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; +begin; +grant all on test.* to mysqltest_3@localhost with grant option; +revoke all on test.* from mysqltest_3@localhost; +commit; +show grants for mysqltest_3@localhost; +begin; +revoke grant option on test.* from mysqltest_3@localhost; +commit; +show grants for mysqltest_3@localhost; +begin; +grant all on test.t1 to mysqltest_2@localhost with grant option; +revoke all on test.t1 from mysqltest_2@localhost; +commit; +show grants for mysqltest_2@localhost; +begin; +revoke grant option on test.t1 from mysqltest_2@localhost; +commit; +show grants for mysqltest_2@localhost; +delete from mysql.user where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3"; +delete from mysql.db where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3"; +delete from mysql.tables_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3"; +delete from mysql.columns_priv where user='mysqltest_1' or user="mysqltest_2" or user="mysqltest_3"; +flush privileges; +drop table t1; + +# +# Test some error conditions +# +begin; +--error 1221 +GRANT FILE on mysqltest.* to mysqltest_1@localhost; +commit; +select 1; -- To test that the previous command didn't cause problems + +# +# Bug#6123: GRANT USAGE inserts useless Db row +# +create database mysqltest1; +begin; +grant usage on mysqltest1.* to test6123 identified by 'magic123'; +commit; +select host,db,user,select_priv,insert_priv from mysql.db where db="mysqltest1"; +delete from mysql.user where user='test6123'; +drop database mysqltest1; + +# +# Test for 'drop user', 'revoke privileges, grant' +# + +create table t1 (a int); +begin; +grant ALL PRIVILEGES on *.* to drop_user2@localhost with GRANT OPTION; +commit; +show grants for drop_user2@localhost; +begin; +revoke all privileges, grant option from drop_user2@localhost; +commit; +drop user drop_user2@localhost; + +begin; +grant ALL PRIVILEGES on *.* to drop_user@localhost with GRANT OPTION; +grant ALL PRIVILEGES on test.* to drop_user@localhost with GRANT OPTION; +grant select(a) on test.t1 to drop_user@localhost; +commit; +show grants for drop_user@localhost; + +# +# Bug3086 +# +set sql_mode=ansi_quotes; +show grants for drop_user@localhost; +set sql_mode=default; + +set sql_quote_show_create=0; +show grants for drop_user@localhost; +set sql_mode="ansi_quotes"; +show grants for drop_user@localhost; +set sql_quote_show_create=1; +show grants for drop_user@localhost; +set sql_mode=""; +show grants for drop_user@localhost; + +revoke all privileges, grant option from drop_user@localhost; +show grants for drop_user@localhost; +drop user drop_user@localhost; +begin; +--error 1269 +revoke all privileges, grant option from drop_user@localhost; +commit; + +begin; +grant select(a) on test.t1 to drop_user1@localhost; +commit; +flush privileges; +begin; +grant select on test.t1 to drop_user2@localhost; +grant select on test.* to drop_user3@localhost; +grant select on *.* to drop_user4@localhost; +commit; +--error 1268 +drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, +drop_user4@localhost; +begin; +revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost, +drop_user3@localhost, drop_user4@localhost; +commit; +drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, +drop_user4@localhost; +drop table t1; +begin; +grant usage on *.* to mysqltest_1@localhost identified by "password"; +grant select, update, insert on test.* to mysqltest@localhost; +commit; +show grants for mysqltest_1@localhost; +drop user mysqltest_1@localhost; + +# +# Bug #3403 Wrong encodin in SHOW GRANTS output +# +SET NAMES koi8r; +CREATE DATABASE бд; +USE бд; +CREATE TABLE таб (кол int); + +begin; +GRANT SELECT ON бд.* TO юзер@localhost; +commit; +SHOW GRANTS FOR юзер@localhost; +begin; +REVOKE SELECT ON бд.* FROM юзер@localhost; +commit; + +begin; +GRANT SELECT ON бд.таб TO юзер@localhost; +commit; +SHOW GRANTS FOR юзер@localhost; +begin; +REVOKE SELECT ON бд.таб FROM юзер@localhost; +commit; + +begin; +GRANT SELECT (кол) ON бд.таб TO юзер@localhost; +commit; +SHOW GRANTS FOR юзер@localhost; +begin; +REVOKE SELECT (кол) ON бд.таб FROM юзер@localhost; +commit; + +DROP DATABASE бд; +SET NAMES latin1; + +# +# Bug #5831: REVOKE ALL PRIVILEGES, GRANT OPTION does not revoke everything +# +USE test; +CREATE TABLE t1 (a int ); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; +CREATE TABLE t4 LIKE t1; +CREATE TABLE t5 LIKE t1; +CREATE TABLE t6 LIKE t1; +CREATE TABLE t7 LIKE t1; +CREATE TABLE t8 LIKE t1; +CREATE TABLE t9 LIKE t1; +CREATE TABLE t10 LIKE t1; +CREATE DATABASE testdb1; +CREATE DATABASE testdb2; +CREATE DATABASE testdb3; +CREATE DATABASE testdb4; +CREATE DATABASE testdb5; +CREATE DATABASE testdb6; +CREATE DATABASE testdb7; +CREATE DATABASE testdb8; +CREATE DATABASE testdb9; +CREATE DATABASE testdb10; +begin; +GRANT ALL ON testdb1.* TO testuser@localhost; +GRANT ALL ON testdb2.* TO testuser@localhost; +GRANT ALL ON testdb3.* TO testuser@localhost; +GRANT ALL ON testdb4.* TO testuser@localhost; +GRANT ALL ON testdb5.* TO testuser@localhost; +GRANT ALL ON testdb6.* TO testuser@localhost; +GRANT ALL ON testdb7.* TO testuser@localhost; +GRANT ALL ON testdb8.* TO testuser@localhost; +GRANT ALL ON testdb9.* TO testuser@localhost; +GRANT ALL ON testdb10.* TO testuser@localhost; +GRANT SELECT ON test.t1 TO testuser@localhost; +GRANT SELECT ON test.t2 TO testuser@localhost; +GRANT SELECT ON test.t3 TO testuser@localhost; +GRANT SELECT ON test.t4 TO testuser@localhost; +GRANT SELECT ON test.t5 TO testuser@localhost; +GRANT SELECT ON test.t6 TO testuser@localhost; +GRANT SELECT ON test.t7 TO testuser@localhost; +GRANT SELECT ON test.t8 TO testuser@localhost; +GRANT SELECT ON test.t9 TO testuser@localhost; +GRANT SELECT ON test.t10 TO testuser@localhost; +GRANT SELECT (a) ON test.t1 TO testuser@localhost; +GRANT SELECT (a) ON test.t2 TO testuser@localhost; +GRANT SELECT (a) ON test.t3 TO testuser@localhost; +GRANT SELECT (a) ON test.t4 TO testuser@localhost; +GRANT SELECT (a) ON test.t5 TO testuser@localhost; +GRANT SELECT (a) ON test.t6 TO testuser@localhost; +GRANT SELECT (a) ON test.t7 TO testuser@localhost; +GRANT SELECT (a) ON test.t8 TO testuser@localhost; +GRANT SELECT (a) ON test.t9 TO testuser@localhost; +GRANT SELECT (a) ON test.t10 TO testuser@localhost; +commit; +begin; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM testuser@localhost; +commit; +SHOW GRANTS FOR testuser@localhost; +DROP USER testuser@localhost; +DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; +DROP DATABASE testdb1; +DROP DATABASE testdb2; +DROP DATABASE testdb3; +DROP DATABASE testdb4; +DROP DATABASE testdb5; +DROP DATABASE testdb6; +DROP DATABASE testdb7; +DROP DATABASE testdb8; +DROP DATABASE testdb9; +DROP DATABASE testdb10; + +# +# Alter mysql system tables back to myisam +# +use mysql; +alter table columns_priv engine=myisam; +alter table db engine=myisam; +alter table func engine=myisam; +alter table help_category engine=myisam; +alter table help_keyword engine=myisam; +alter table help_relation engine=myisam; +alter table help_topic engine=myisam; +alter table host engine=myisam; +alter table tables_priv engine=myisam; +alter table time_zone engine=myisam; +alter table time_zone_leap_second engine=myisam; +alter table time_zone_name engine=myisam; +alter table time_zone_transition engine=myisam; +alter table time_zone_transition_type engine=myisam; +alter table user engine=myisam; +use test; +flush privileges; From d6407c760e753fb53bfaa1ad5b3174d424edffd9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 09:27:16 +0000 Subject: [PATCH 24/44] ha_ndbcluster.cc: merge error sql/ha_ndbcluster.cc: merge error --- sql/ha_ndbcluster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index fd8660b29d2..bec4dfd9401 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -107,7 +107,7 @@ static const err_code_mapping err_map[]= { { 626, HA_ERR_KEY_NOT_FOUND, 0 }, { 630, HA_ERR_FOUND_DUPP_KEY, 0 }, - { 893, HA_ERR_FOUND_DUPP_UNIQUE, 0 }, + { 893, HA_ERR_FOUND_DUPP_KEY, 0 }, { 721, HA_ERR_TABLE_EXIST, 1 }, { 4244, HA_ERR_TABLE_EXIST, 1 }, From b140e465f442f13483102582fa40deecfbc5fcec Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 09:35:12 +0000 Subject: [PATCH 25/44] added to ignore list BitKeeper/etc/ignore: added ../ndb/tools/ndb_restore --- .bzrignore | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.bzrignore b/.bzrignore index e794d7d51cc..f98e9f7e6b6 100644 --- a/.bzrignore +++ b/.bzrignore @@ -924,3 +924,18 @@ Docs/Images/mydsn.txt Docs/Images/myflowchart.txt mysql-test/mysql_test_run_new ndb/tools/ndb_test_platform +help +ndbcluster-1186 +ndbcluster-1186/SCCS +ndbcluster-1186/config.ini +ndbcluster-1186/ndb_1.pid +ndbcluster-1186/ndb_1_out.log +ndbcluster-1186/ndb_1_signal.log +ndbcluster-1186/ndb_2.pid +ndbcluster-1186/ndb_2_out.log +ndbcluster-1186/ndb_2_signal.log +ndbcluster-1186/ndb_3.pid +ndbcluster-1186/ndb_3_cluster.log +ndbcluster-1186/ndb_3_out.log +ndbcluster-1186/ndbcluster.pid +../ndb/tools/ndb_restore From ac9891722a5bfe26ab268ec6e33d91befc80f016 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 09:38:41 +0000 Subject: [PATCH 26/44] ignore fix --- .bzrignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzrignore b/.bzrignore index f98e9f7e6b6..670d46db613 100644 --- a/.bzrignore +++ b/.bzrignore @@ -938,4 +938,4 @@ ndbcluster-1186/ndb_3.pid ndbcluster-1186/ndb_3_cluster.log ndbcluster-1186/ndb_3_out.log ndbcluster-1186/ndbcluster.pid -../ndb/tools/ndb_restore +ndb/tools/ndb_restore From e136b462502804bb7345e5a65ee253228ff4d4ca Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 14:25:25 +0400 Subject: [PATCH 27/44] Incorrect response with partial utf8 index strings/ctype-mb.c: Incorrect response with partial utf8 index: Fill the max string with max_sort_char up to res_length bytes. strings/ctype-uca.c: Incorrect response with partial utf8 index. Typo fixes for UTF8 collations. --- mysql-test/include/ctype_common.inc | 56 +++++++++++++++++++++ mysql-test/r/ctype_uca.result | 57 ++++++++++++++++++++++ mysql-test/t/ctype_uca.test | 4 ++ strings/ctype-mb.c | 75 +++++++++++++++++------------ strings/ctype-uca.c | 32 ++++++------ 5 files changed, 178 insertions(+), 46 deletions(-) create mode 100644 mysql-test/include/ctype_common.inc diff --git a/mysql-test/include/ctype_common.inc b/mysql-test/include/ctype_common.inc new file mode 100644 index 00000000000..77937bdb854 --- /dev/null +++ b/mysql-test/include/ctype_common.inc @@ -0,0 +1,56 @@ +# +# Common tests for all character sets and collations. +# Include this file from a test with @test_characrer_set +# and @test_collation set to desired values. +# +# Please don't use SHOW CREATE TABLE in this file, +# we want it to be HANDLER independent. You can +# use SHOW FULL COLUMNS instead. +# +# Please surround all CREATE TABLE with --disable_warnings +# and --enable_warnings to be able to set storage_engine +# without having to check if the hanlder exists. + +SET @safe_character_set_server= @@character_set_server; +SET @safe_collation_server= @@collation_server; +SET character_set_server= @test_character_set; +SET collation_server= @test_collation; +CREATE DATABASE d1; +USE d1; + +# +# Bug 1883: LIKE did not work in some cases with a key. +# +--disable_warnings +CREATE TABLE t1 (c CHAR(10), KEY(c)); +--enable_warnings +# check the column was created with the expected charset/collation +SHOW FULL COLUMNS FROM t1; +INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); +SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%'; +DROP TABLE t1; + +# +# Bug 6643 incorrect response with partial utf8 index +# +--disable_warnings +CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2))); +--enable_warnings +# check the column was created with the expected charset/collation +SHOW FULL COLUMNS FROM t1; +INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab'); +SELECT c1 as want3results from t1 where c1 like 'l%'; +SELECT c1 as want3results from t1 where c1 like 'lo%'; +SELECT c1 as want1result from t1 where c1 like 'loc%'; +SELECT c1 as want1result from t1 where c1 like 'loca%'; +SELECT c1 as want1result from t1 where c1 like 'locat%'; +SELECT c1 as want1result from t1 where c1 like 'locati%'; +SELECT c1 as want1result from t1 where c1 like 'locatio%'; +SELECT c1 as want1result from t1 where c1 like 'location%'; +DROP TABLE t1; + +DROP DATABASE d1; +# Restore settings +USE test; +SET character_set_server= @safe_character_set_server; +SET collation_server= @safe_collation_server; diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result index 90681795513..7620b18eea6 100644 --- a/mysql-test/r/ctype_uca.result +++ b/mysql-test/r/ctype_uca.result @@ -2315,3 +2315,60 @@ HEX(CONVERT(col1 USING ucs2)) 064A06A9062F064A06AF0631 064A06A9064A DROP TABLE t1; +SET @test_character_set= 'utf8'; +SET @test_collation= 'utf8_swedish_ci'; +SET @safe_character_set_server= @@character_set_server; +SET @safe_collation_server= @@collation_server; +SET character_set_server= @test_character_set; +SET collation_server= @test_collation; +CREATE DATABASE d1; +USE d1; +CREATE TABLE t1 (c CHAR(10), KEY(c)); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c char(10) utf8_swedish_ci YES MUL NULL select,insert,update,references +INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); +SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%'; +want3results +aaa +aaaa +aaaaa +DROP TABLE t1; +CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2))); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c1 varchar(15) utf8_swedish_ci YES MUL NULL select,insert,update,references +INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab'); +SELECT c1 as want3results from t1 where c1 like 'l%'; +want3results +location +loberge +lotre +SELECT c1 as want3results from t1 where c1 like 'lo%'; +want3results +location +loberge +lotre +SELECT c1 as want1result from t1 where c1 like 'loc%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'loca%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locat%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locati%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locatio%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'location%'; +want1result +location +DROP TABLE t1; +DROP DATABASE d1; +USE test; +SET character_set_server= @safe_character_set_server; +SET collation_server= @safe_collation_server; diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test index 708a31d637e..e640e6b53dc 100644 --- a/mysql-test/t/ctype_uca.test +++ b/mysql-test/t/ctype_uca.test @@ -435,3 +435,7 @@ INSERT INTO t1 VALUES (CONVERT(_ucs2 0x06280648062F0646062F USING utf8)); INSERT INTO t1 VALUES (CONVERT(_ucs2 0x06450647064506270646 USING utf8)); SELECT HEX(CONVERT(col1 USING ucs2)) FROM t1 ORDER BY col1 COLLATE utf8_persian_ci, col1 COLLATE utf8_bin; DROP TABLE t1; + +SET @test_character_set= 'utf8'; +SET @test_collation= 'utf8_swedish_ci'; +-- source include/ctype_common.inc diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 7d81766c4cb..3cdf7f460cd 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -443,6 +443,37 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)), } } + +/* + Write max key: create a buffer with multibyte + representation of the max_sort_char character, + and copy it into max_str in a loop. +*/ +static void pad_max_char(CHARSET_INFO *cs, char *str, char *end) +{ + char buf[10]; + char buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf, + (uchar*) buf + sizeof(buf)); + DBUG_ASSERT(buflen > 0); + do + { + if ((str + buflen) < end) + { + /* Enough space for the characer */ + memcpy(str, buf, buflen); + str+= buflen; + } + else + { + /* + There is no space for whole multibyte + character, then add trailing spaces. + */ + *str++= ' '; + } + } while (str < end); +} + /* ** Calculate min_str and max_str that ranges a LIKE string. ** Arguments: @@ -467,10 +498,15 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, char *min_str,char *max_str, uint *min_length,uint *max_length) { - const char *end=ptr+ptr_length; - char *min_org=min_str; - char *min_end=min_str+res_length; - char *max_end=max_str+res_length; + const char *end; + char *min_org= min_str; + char *min_end= min_str + res_length; + char *max_end= max_str + res_length; + uint charlen= my_charpos(cs, ptr, ptr+ptr_length, res_length/cs->mbmaxlen); + + if (charlen < ptr_length) + ptr_length= charlen; + end= ptr + ptr_length; for (; ptr != end && min_str != min_end ; ptr++) { @@ -482,16 +518,14 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, } if (*ptr == w_one || *ptr == w_many) /* '_' and '%' in SQL */ { - char buf[10]; - uint buflen; - uint charlen= my_charpos(cs, min_org, min_str, res_length/cs->mbmaxlen); + charlen= my_charpos(cs, min_org, min_str, res_length/cs->mbmaxlen); if (charlen < (uint) (min_str - min_org)) min_str= min_org + charlen; /* Write min key */ *min_length= (uint) (min_str - min_org); - *max_length=res_length; + *max_length= res_length; do { *min_str++= (char) cs->min_sort_char; @@ -502,27 +536,7 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, representation of the max_sort_char character, and copy it into max_str in a loop. */ - buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf, - (uchar*) buf + sizeof(buf)); - DBUG_ASSERT(buflen > 0); - do - { - if ((max_str + buflen) <= max_end) - { - /* Enough space for max characer */ - memcpy(max_str, buf, buflen); - max_str+= buflen; - } - else - { - /* - There is no space for whole multibyte - character, then add trailing spaces. - */ - - *max_str++= ' '; - } - } while (max_str != max_end); + pad_max_char(cs, max_str, max_end); return 0; } *min_str++= *max_str++ = *ptr; @@ -530,7 +544,8 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, *min_length= *max_length = (uint) (min_str - min_org); while (min_str != min_end) - *min_str++ = *max_str++ = ' '; /* Because if key compression */ + *min_str++= ' '; /* Because if key compression */ + pad_max_char(cs, max_str, max_end); return 0; } diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 91af7af0c54..8df5b3277c1 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -8567,7 +8567,7 @@ CHARSET_INFO my_charset_utf8_icelandic_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8594,7 +8594,7 @@ CHARSET_INFO my_charset_utf8_latvian_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8621,7 +8621,7 @@ CHARSET_INFO my_charset_utf8_romanian_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8648,7 +8648,7 @@ CHARSET_INFO my_charset_utf8_slovenian_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8675,7 +8675,7 @@ CHARSET_INFO my_charset_utf8_polish_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8702,7 +8702,7 @@ CHARSET_INFO my_charset_utf8_estonian_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8729,7 +8729,7 @@ CHARSET_INFO my_charset_utf8_spanish_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8756,7 +8756,7 @@ CHARSET_INFO my_charset_utf8_swedish_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8783,7 +8783,7 @@ CHARSET_INFO my_charset_utf8_turkish_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8810,7 +8810,7 @@ CHARSET_INFO my_charset_utf8_czech_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8838,7 +8838,7 @@ CHARSET_INFO my_charset_utf8_danish_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8865,7 +8865,7 @@ CHARSET_INFO my_charset_utf8_lithuanian_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8892,7 +8892,7 @@ CHARSET_INFO my_charset_utf8_slovak_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8919,7 +8919,7 @@ CHARSET_INFO my_charset_utf8_spanish2_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8946,7 +8946,7 @@ CHARSET_INFO my_charset_utf8_roman_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, @@ -8973,7 +8973,7 @@ CHARSET_INFO my_charset_utf8_persian_uca_ci= NULL, /* ident_map */ 8, /* strxfrm_multiply */ 1, /* mbminlen */ - 2, /* mbmaxlen */ + 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ &my_charset_utf8_handler, From 9e9715963a549ee83d907bc5497acd21995c4543 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 14:33:55 +0400 Subject: [PATCH 28/44] Reuse ctype_common.inc instead of retyping the same queries. --- mysql-test/r/ctype_big5.result | 56 +++++++++++++++++++++++++++++++--- mysql-test/t/ctype_big5.test | 12 ++------ 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result index 44fad0cd96a..789b6e586ad 100644 --- a/mysql-test/r/ctype_big5.result +++ b/mysql-test/r/ctype_big5.result @@ -1,10 +1,58 @@ drop table if exists t1; -SET NAMES big5; -CREATE TABLE t1 (c CHAR(10) CHARACTER SET big5, KEY(c)); +SET @test_character_set= 'big5'; +SET @test_collation= 'big5_chinese_ci'; +SET @safe_character_set_server= @@character_set_server; +SET @safe_collation_server= @@collation_server; +SET character_set_server= @test_character_set; +SET collation_server= @test_collation; +CREATE DATABASE d1; +USE d1; +CREATE TABLE t1 (c CHAR(10), KEY(c)); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c char(10) big5_chinese_ci YES MUL NULL select,insert,update,references INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); -SELECT * FROM t1 WHERE c LIKE 'aaa%'; -c +SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%'; +want3results aaa aaaa aaaaa DROP TABLE t1; +CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2))); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c1 varchar(15) big5_chinese_ci YES MUL NULL select,insert,update,references +INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab'); +SELECT c1 as want3results from t1 where c1 like 'l%'; +want3results +location +loberge +lotre +SELECT c1 as want3results from t1 where c1 like 'lo%'; +want3results +location +loberge +lotre +SELECT c1 as want1result from t1 where c1 like 'loc%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'loca%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locat%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locati%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locatio%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'location%'; +want1result +location +DROP TABLE t1; +DROP DATABASE d1; +USE test; +SET character_set_server= @safe_character_set_server; +SET collation_server= @safe_collation_server; diff --git a/mysql-test/t/ctype_big5.test b/mysql-test/t/ctype_big5.test index 9bf1808636e..b1d71a6af15 100644 --- a/mysql-test/t/ctype_big5.test +++ b/mysql-test/t/ctype_big5.test @@ -7,12 +7,6 @@ drop table if exists t1; --enable_warnings -SET NAMES big5; - -# -# Bug 1883: LIKE did not work in some cases with a key. -# -CREATE TABLE t1 (c CHAR(10) CHARACTER SET big5, KEY(c)); -INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); -SELECT * FROM t1 WHERE c LIKE 'aaa%'; -DROP TABLE t1; +SET @test_character_set= 'big5'; +SET @test_collation= 'big5_chinese_ci'; +-- source include/ctype_common.inc From 83f39beea215aaf08d9a38be757189ec4f035c2d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 11:19:27 +0000 Subject: [PATCH 29/44] fixed error messages for some error codes --- ndb/src/ndbapi/ndberror.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index 1a0d8132d71..e08b80f2433 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -53,6 +53,9 @@ typedef struct ErrorBundle { #define NI ndberror_cl_function_not_implemented #define UE ndberror_cl_unknown_error_code +static const char REDO_BUFFER_MSG[]= +"REDO log buffers overloaded, consult online manual (increase RedoBuffer, and|or decrease TimeBetweenLocalCheckpoints, and|or increase NoOfFragmentLogFiles)"; + static const char* empty_string = ""; static @@ -137,9 +140,8 @@ ErrorBundle ErrorCodes[] = { { 805, TR, "Out of attrinfo records in tuple manager" }, { 830, TR, "Out of add fragment operation records" }, { 873, TR, "Out of attrinfo records for scan in tuple manager" }, - { 1217, TR, "1217" }, - { 1219, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" }, - { 1220, TR, "1220" }, + { 1217, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" }, + { 1220, TR, REDO_BUFFER_MSG }, { 1222, TR, "Out of transaction markers in LQH" }, { 4021, TR, "Out of Send Buffer space in NDB API" }, { 4022, TR, "Out of Send Buffer space in NDB API" }, @@ -165,14 +167,13 @@ ErrorBundle ErrorCodes[] = { { 297, TO, "Time-out in NDB, probably caused by deadlock" }, /* Scan trans timeout, temporary!! */ { 237, TO, "Transaction had timed out when trying to commit it" }, - /** * OverloadError */ - { 410, OL, "Out of log file space temporarily" }, + { 410, OL, REDO_BUFFER_MSG }, { 677, OL, "Index UNDO buffers overloaded (increase UndoIndexBuffer)" }, { 891, OL, "Data UNDO buffers overloaded (increase UndoDataBuffer)" }, - { 1221, OL, "REDO log buffers overloaded (increase RedoBuffer)" }, + { 1221, OL, REDO_BUFFER_MSG }, { 4006, OL, "Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)" }, From f85b20aa7843d29d169bf4d0bca8288cbb9c113a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 13:52:21 +0000 Subject: [PATCH 30/44] set sizes array sizes correctly in ndb blocks configuration --- ndb/src/kernel/vm/Configuration.cpp | 36 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index b3a436275f7..c2f47adff29 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -590,6 +590,23 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ */ ConfigValuesFactory cfg(ownConfig); + Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes + + noOfUniqueHashIndexes; + if (noOfMetaTables > MAX_TABLES) + noOfMetaTables= MAX_TABLES; + + { + /** + * Dict Size Alt values + */ + cfg.put(CFG_DICT_ATTRIBUTE, + noOfAttributes); + + cfg.put(CFG_DICT_TABLE, + noOfMetaTables); + } + + if (noOfLocalScanRecords == 0) { noOfLocalScanRecords = (noOfDBNodes * noOfScanRecords) + 1; } @@ -599,7 +616,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ Uint32 noOfTCScanRecords = noOfScanRecords; { - Uint32 noOfAccTables= noOfTables + noOfUniqueHashIndexes; + Uint32 noOfAccTables= noOfMetaTables/*noOfTables+noOfUniqueHashIndexes*/; /** * Acc Size Alt values */ @@ -641,19 +658,6 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords); } - Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes + - noOfUniqueHashIndexes; - { - /** - * Dict Size Alt values - */ - cfg.put(CFG_DICT_ATTRIBUTE, - noOfAttributes); - - cfg.put(CFG_DICT_TABLE, - noOfMetaTables); - } - { /** * Dih Size Alt values @@ -758,9 +762,9 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ * Tux Size Alt values */ cfg.put(CFG_TUX_INDEX, - noOfOrderedIndexes); + noOfMetaTables /*noOfOrderedIndexes*/); - cfg.put(CFG_TUX_FRAGMENT, + cfg.put(CFG_TUX_FRAGMENT, 2 * NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas); cfg.put(CFG_TUX_ATTRIBUTE, From 77c163c3e3bdfb884e96f89bfb90e277ecfc816e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 15:35:35 +0000 Subject: [PATCH 31/44] correct some linking problem --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 81917372206..58e24dcbc5e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1687,7 +1687,7 @@ AC_DEFUN([MYSQL_CHECK_NDBCLUSTER], [ ndbcluster_includes="-I../ndb/include -I../ndb/include/ndbapi" ndbcluster_libs="\$(top_builddir)/ndb/src/.libs/libndbclient.a" ndbcluster_system_libs="" - ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la" + ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la \$(top_builddir)/mysys/libmysys.a" MYSQL_CHECK_NDB_OPTIONS ;; * ) From aa6785d7a8a8c70ff9335bb4c875d3ae9db9db6a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 19:35:36 +0400 Subject: [PATCH 32/44] Bug #6658 MAX(column) returns incorrect coercibility Also, Item_sum_hybrid->charset was removed as redundant, and switched to use collation.collation instead. mysql-test/r/func_group.result: Bug #6658 MAX(column) returns incorrect coercibility mysql-test/r/func_str.result: Bug #6658 MAX(column) returns incorrect coercibility mysql-test/t/func_group.test: Bug #6658 MAX(column) returns incorrect coercibility sql/item_func.cc: Bug #6658 MAX(column) returns incorrect coercibility sql/item_sum.cc: Bug #6658 MAX(column) returns incorrect coercibility sql/item_sum.h: Bug #6658 MAX(column) returns incorrect coercibility --- mysql-test/r/func_group.result | 16 +++++++++++++++- mysql-test/r/func_str.result | 14 ++++++++++++++ mysql-test/t/func_group.test | 11 +++++++++++ sql/item_func.cc | 1 + sql/item_sum.cc | 9 +++------ sql/item_sum.h | 9 ++++----- 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index c25f89d4df3..4bb79a1cb41 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -637,8 +637,22 @@ create table t1 (a char(10)); insert into t1 values ('a'),('b'),('c'); select coercibility(max(a)) from t1; coercibility(max(a)) -3 +2 drop table t1; +create table t1 (a char character set latin2); +insert into t1 values ('a'),('b'); +select charset(max(a)), coercibility(max(a)), +charset(min(a)), coercibility(min(a)) from t1; +charset(max(a)) coercibility(max(a)) charset(min(a)) coercibility(min(a)) +latin2 2 latin2 2 +create table t2 select max(a),min(a) from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `max(a)` char(1) character set latin2 default NULL, + `min(a)` char(1) character set latin2 default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t2,t1; create table t1 (a int); insert into t1 values (1); select max(a) as b from t1 having b=1; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 8d49d55be39..083f85ee6fa 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -614,6 +614,20 @@ t1 CREATE TABLE `t1` ( `encode('abcd','ab')` binary(4) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +create table t1 (a char character set latin2); +insert into t1 values ('a'),('b'); +select charset(max(a)), coercibility(max(a)), +charset(min(a)), coercibility(min(a)) from t1; +charset(max(a)) coercibility(max(a)) charset(min(a)) coercibility(min(a)) +latin2 2 latin2 2 +create table t2 select max(a),min(a) from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `max(a)` char(1) character set latin2 default NULL, + `min(a)` char(1) character set latin2 default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t2,t1; select SUBSTR('abcdefg',3,2); SUBSTR('abcdefg',3,2) cd diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 8d8779e9d1b..79d6112e6de 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -383,6 +383,17 @@ insert into t1 values ('a'),('b'),('c'); select coercibility(max(a)) from t1; drop table t1; +# +# Bug #6658 MAX(column) returns incorrect coercibility +# +create table t1 (a char character set latin2); +insert into t1 values ('a'),('b'); +select charset(max(a)), coercibility(max(a)), + charset(min(a)), coercibility(min(a)) from t1; +create table t2 select max(a),min(a) from t1; +show create table t2; +drop table t2,t1; + # # aggregate functions on static tables # diff --git a/sql/item_func.cc b/sql/item_func.cc index c07e9f23ea2..3fb5bcd01c6 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -350,6 +350,7 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array, { uint el= fields.elements; Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name); + new_item->collation.set(item->collation); fields.push_front(item); ref_pointer_array[el]= item; thd->change_item_tree(arg, new_item); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 3b3a6083725..c43a7d87f8f 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -218,16 +218,13 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) hybrid_type= item->result_type(); if (hybrid_type == INT_RESULT) { - cmp_charset= &my_charset_bin; max_length=20; } else if (hybrid_type == REAL_RESULT) { - cmp_charset= &my_charset_bin; max_length=float_length(decimals); }else { - cmp_charset= item->collation.collation; max_length=item->max_length; } decimals=item->decimals; @@ -557,7 +554,7 @@ bool Item_sum_min::add() { String *result=args[0]->val_str(&tmp_value); if (!args[0]->null_value && - (null_value || sortcmp(&value,result,cmp_charset) > 0)) + (null_value || sortcmp(&value,result,collation.collation) > 0)) { value.copy(*result); null_value=0; @@ -610,7 +607,7 @@ bool Item_sum_max::add() { String *result=args[0]->val_str(&tmp_value); if (!args[0]->null_value && - (null_value || sortcmp(&value,result,cmp_charset) < 0)) + (null_value || sortcmp(&value,result,collation.collation) < 0)) { value.copy(*result); null_value=0; @@ -921,7 +918,7 @@ Item_sum_hybrid::min_max_update_str_field() result_field->val_str(&tmp_value); if (result_field->is_null() || - (cmp_sign * sortcmp(res_str,&tmp_value,cmp_charset)) < 0) + (cmp_sign * sortcmp(res_str,&tmp_value,collation.collation)) < 0) result_field->store(res_str->ptr(),res_str->length(),res_str->charset()); result_field->set_notnull(); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 5aa0d37190b..f9c48304795 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -402,20 +402,19 @@ class Item_sum_hybrid :public Item_sum enum_field_types hybrid_field_type; int cmp_sign; table_map used_table_cache; - CHARSET_INFO *cmp_charset; public: Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par), sum(0.0), sum_int(0), hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG), - cmp_sign(sign), used_table_cache(~(table_map) 0), - cmp_charset(&my_charset_bin) - {} + cmp_sign(sign), used_table_cache(~(table_map) 0) + { collation.set(&my_charset_bin); } Item_sum_hybrid(THD *thd, Item_sum_hybrid *item): Item_sum(thd, item), value(item->value), sum(item->sum), sum_int(item->sum_int), hybrid_type(item->hybrid_type), hybrid_field_type(item->hybrid_field_type),cmp_sign(item->cmp_sign), - used_table_cache(item->used_table_cache), cmp_charset(item->cmp_charset) {} + used_table_cache(item->used_table_cache) + { collation.set(item->collation); } bool fix_fields(THD *, TABLE_LIST *, Item **); table_map used_tables() const { return used_table_cache; } bool const_item() const { return !used_table_cache; } From 716b401817b05e2bfebf11471e8a61740bff8a3e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 18:35:36 +0300 Subject: [PATCH 33/44] Added --disable-log-bin option to the mysqlbinlog (WL1787) BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + client/mysqlbinlog.cc | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 1c1a3efc542..8fcec769a0c 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -163,6 +163,7 @@ pem@mysql.com peter@linux.local peter@mysql.com peterg@mysql.com +petr@mysql.com pgulutzan@linux.local ram@deer.(none) ram@gw.mysql.r18.ru diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 8015871428e..de53831c43d 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -44,7 +44,7 @@ static const char *load_default_groups[]= { "mysqlbinlog","client",0 }; void sql_print_error(const char *format, ...); -static bool one_database=0, to_last_remote_log= 0; +static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static const char* database= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0; static ulonglong offset = 0; @@ -438,6 +438,13 @@ static struct my_option my_long_options[] = {"database", 'd', "List entries for just this database (local log only).", (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"disable-log-bin", 'D', "Disable binary log. This is useful, if you " + "enabled --to-last-log and are sending the output to the same MySQL server. " + "This way you could avoid an endless loop. You would also like to use it " + "when restoring after a crash to avoid duplication of the statements you " + "already have. NOTE: you will need a SUPER privilege to use this option.", + (gptr*) &disable_log_bin, (gptr*) &disable_log_bin, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, {"force-read", 'f', "Force reading unknown binlog events.", (gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -1068,6 +1075,11 @@ int main(int argc, char** argv) fprintf(result_file, "/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n"); + + if (disable_log_bin) + fprintf(result_file, + "/*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/;\n"); + for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ; (--argc >= 0) && !stop_passed ; ) { @@ -1082,6 +1094,9 @@ int main(int argc, char** argv) start_position= BIN_LOG_HEADER_SIZE; } + if (disable_log_bin) + fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n"); + if (tmpdir.list) free_tmpdir(&tmpdir); if (result_file != stdout) From 42fb5937829c9da540087f1a4e0dd05b99bde5b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 19:35:37 +0400 Subject: [PATCH 34/44] func_str.result: This test was moved into func_group. mysql-test/r/func_str.result: This test was moved into func_group. --- mysql-test/r/func_str.result | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 083f85ee6fa..8d49d55be39 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -614,20 +614,6 @@ t1 CREATE TABLE `t1` ( `encode('abcd','ab')` binary(4) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; -create table t1 (a char character set latin2); -insert into t1 values ('a'),('b'); -select charset(max(a)), coercibility(max(a)), -charset(min(a)), coercibility(min(a)) from t1; -charset(max(a)) coercibility(max(a)) charset(min(a)) coercibility(min(a)) -latin2 2 latin2 2 -create table t2 select max(a),min(a) from t1; -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `max(a)` char(1) character set latin2 default NULL, - `min(a)` char(1) character set latin2 default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 -drop table t2,t1; select SUBSTR('abcdefg',3,2); SUBSTR('abcdefg',3,2) cd From 02201d127a7d19e11025e037c495c1b6eaf8670a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 19:46:16 +0300 Subject: [PATCH 35/44] work around for compiler bug (5.0.2 build fails on octane2) server-tools/instance-manager/thread_repository.cc: Moved info declaration out of the loops to work around a compiler bug. --- server-tools/instance-manager/thread_repository.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server-tools/instance-manager/thread_repository.cc b/server-tools/instance-manager/thread_repository.cc index 0a46f61c831..d0b302d29fb 100644 --- a/server-tools/instance-manager/thread_repository.cc +++ b/server-tools/instance-manager/thread_repository.cc @@ -148,10 +148,11 @@ void Thread_repository::deliver_shutdown() { struct timespec shutdown_time; set_timespec(shutdown_time, 1); + Thread_info *info; pthread_mutex_lock(&LOCK_thread_repository); shutdown_in_progress= true; - for (Thread_info *info= head.next; info != &head; info= info->next) + for (info= head.next; info != &head; info= info->next) { pthread_kill(info->thread_id, THREAD_KICK_OFF_SIGNAL); /* @@ -173,7 +174,7 @@ void Thread_repository::deliver_shutdown() so this time everybody should be informed (presumably each worker can get CPU during shutdown_time.) */ - for (Thread_info *info= head.next; info != &head; info= info->next) + for (info= head.next; info != &head; info= info->next) { pthread_kill(info->thread_id, THREAD_KICK_OFF_SIGNAL); if (info->current_cond) From d831ff2648b54efb1f0ab012a6326410141250e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 16:58:02 +0000 Subject: [PATCH 36/44] corrected some erroneous size calculations in tup fixed erroneous error message - set auto increment was done even if create table failed so real error message got lost behind "table not found" and simplified code a bit ndb/src/kernel/vm/Configuration.cpp: corrected some erroneous size calculations ndb/src/ndbapi/NdbDictionaryImpl.cpp: fixed erroneous error message - set auto increment was done even if create table failed so real error message got lost behind "table not found" and simplified code a bit --- ndb/src/kernel/vm/Configuration.cpp | 4 +-- ndb/src/ndbapi/NdbDictionaryImpl.cpp | 42 +++++++++++++++------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index c2f47adff29..aac035fe1b7 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -750,8 +750,8 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ noOfMetaTables); cfg.put(CFG_TUP_TABLE_DESC, - 4 * NO_OF_FRAG_PER_NODE * noOfAttributes* noOfReplicas + - 12 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas ); + 2 * 6 * NO_OF_FRAG_PER_NODE * noOfAttributes * noOfReplicas + + 2 * 10 * NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas ); cfg.put(CFG_TUP_STORED_PROC, noOfLocalScanRecords); diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 304d1b904d4..345f2caac89 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -1571,7 +1571,13 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, NdbApiSignal tSignal(m_reference); tSignal.theReceiversBlockNumber = DBDICT; - if (alter) { + + LinearSectionPtr ptr[3]; + ptr[0].p = (Uint32*)m_buffer.get_data(); + ptr[0].sz = m_buffer.length() / 4; + int ret; + if (alter) + { AlterTableReq * const req = CAST_PTR(AlterTableReq, tSignal.getDataPtrSend()); @@ -1582,8 +1588,10 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, req->tableVersion = impl.m_version;; tSignal.theVerId_signalNumber = GSN_ALTER_TABLE_REQ; tSignal.theLength = AlterTableReq::SignalLength; + ret= alterTable(&tSignal, ptr); } - else { + else + { CreateTableReq * const req = CAST_PTR(CreateTableReq, tSignal.getDataPtrSend()); @@ -1591,25 +1599,21 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, req->senderData = 0; tSignal.theVerId_signalNumber = GSN_CREATE_TABLE_REQ; tSignal.theLength = CreateTableReq::SignalLength; - } - - LinearSectionPtr ptr[3]; - ptr[0].p = (Uint32*)m_buffer.get_data(); - ptr[0].sz = m_buffer.length() / 4; + ret= createTable(&tSignal, ptr); - int ret = (alter) ? - alterTable(&tSignal, ptr) - : createTable(&tSignal, ptr); + if (ret) + return ret; - if (!alter && haveAutoIncrement) { - if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(), - autoIncrementValue)) { - if (ndb.theError.code == 0) { - m_error.code = 4336; - ndb.theError = m_error; - } else - m_error= ndb.theError; - ret = -1; // errorcode set in initialize_autoincrement + if (haveAutoIncrement) { + if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(), + autoIncrementValue)) { + if (ndb.theError.code == 0) { + m_error.code = 4336; + ndb.theError = m_error; + } else + m_error= ndb.theError; + ret = -1; // errorcode set in initialize_autoincrement + } } } return ret; From 2d5f9f57cef5546d56d2838c5a2e29bb389b0ff3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 17:18:46 +0000 Subject: [PATCH 37/44] acinclude.m4: reverting my last fix acinclude.m4: reverting my last fix --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 58e24dcbc5e..81917372206 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1687,7 +1687,7 @@ AC_DEFUN([MYSQL_CHECK_NDBCLUSTER], [ ndbcluster_includes="-I../ndb/include -I../ndb/include/ndbapi" ndbcluster_libs="\$(top_builddir)/ndb/src/.libs/libndbclient.a" ndbcluster_system_libs="" - ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la \$(top_builddir)/mysys/libmysys.a" + ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la" MYSQL_CHECK_NDB_OPTIONS ;; * ) From 724697f54cc97d2bf726840ae957cdd9c8761e2b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 17:21:27 +0000 Subject: [PATCH 38/44] Makefile.am, mysqladmin.cc: reverting linking ndbclisnt to mysqladmin.cc client/mysqladmin.cc: reverting linking ndbclisnt to mysqladmin.cc client/Makefile.am: reverting linking ndbclisnt to mysqladmin.cc --- client/Makefile.am | 3 +-- client/mysqladmin.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/client/Makefile.am b/client/Makefile.am index 5034dd5bf51..514ed7fdf51 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -20,8 +20,7 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/regex \ $(openssl_includes) LIBS = @CLIENT_LIBS@ -DEPLIB= @ndb_mgmclient_libs@ \ - ../libmysql/libmysqlclient.la +DEPLIB= ../libmysql/libmysqlclient.la LDADD = @CLIENT_EXTRA_LDFLAGS@ $(DEPLIB) bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ mysqldump mysqlimport mysqltest mysqlbinlog mysqlmanagerc mysqlmanager-pwgen diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index a9fc3f31d03..eec0dcb90fe 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -24,7 +24,7 @@ #include #include -#ifdef HAVE_NDBCLUSTER_DB +#ifdef LATER_HAVE_NDBCLUSTER_DB #include "../ndb/src/mgmclient/ndb_mgmclient.h" #endif @@ -45,7 +45,7 @@ static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations, opt_count_iterations= 0; static ulong opt_connect_timeout, opt_shutdown_timeout; static my_string unix_port=0; -#ifdef HAVE_NDBCLUSTER_DB +#ifdef LATER_HAVE_NDBCLUSTER_DB static my_bool opt_ndbcluster=0; static char *opt_ndb_connectstring=0; #endif @@ -101,7 +101,7 @@ enum commands { ADMIN_PING, ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS, ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE, ADMIN_STOP_SLAVE, ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD -#ifdef HAVE_NDBCLUSTER_DB +#ifdef LATER_HAVE_NDBCLUSTER_DB ,ADMIN_NDB_MGM #endif }; @@ -114,7 +114,7 @@ static const char *command_names[]= { "ping", "extended-status", "flush-status", "flush-privileges", "start-slave", "stop-slave", "flush-threads","old-password", -#ifdef HAVE_NDBCLUSTER_DB +#ifdef LATER_HAVE_NDBCLUSTER_DB "ndb-mgm", #endif NullS @@ -197,7 +197,7 @@ static struct my_option my_long_options[] = {"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (gptr*) &opt_shutdown_timeout, (gptr*) &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG, SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0}, -#ifdef HAVE_NDBCLUSTER_DB +#ifdef LATER_HAVE_NDBCLUSTER_DB {"ndbcluster", OPT_NDBCLUSTER, "" "", (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -903,7 +903,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } mysql->reconnect=1; /* Automatic reconnect is default */ break; -#ifdef HAVE_NDBCLUSTER_DB +#ifdef LATER_HAVE_NDBCLUSTER_DB case ADMIN_NDB_MGM: { if (argc < 2) From 99d2d10097da69f33637ec43fce22b1a70c6ad85 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2004 14:53:40 -0600 Subject: [PATCH 39/44] mysql.cc: Tweak some help text. client/mysql.cc: Tweak some help text. --- client/mysql.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 358b13e652b..8e9dd84c8f0 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1609,7 +1609,7 @@ static void print_help_item(MYSQL_ROW *cur, int num_name, int num_cat, char *las char ccat= (*cur)[num_cat][0]; if (*last_char != ccat) { - put_info(ccat == 'Y' ? "categories :" : "topics :", INFO_INFO); + put_info(ccat == 'Y' ? "categories:" : "topics:", INFO_INFO); *last_char= ccat; } tee_fprintf(PAGER, " %s\n", (*cur)[num_name]); @@ -1676,8 +1676,8 @@ static int com_server_help(String *buffer __attribute__((unused)), if (num_fields == 2) { - put_info("Many help items for your request exist", INFO_INFO); - put_info("To make a more specific request, please type 'help ',\nwhere item is one of next", INFO_INFO); + put_info("Many help items for your request exist.", INFO_INFO); + put_info("To make a more specific request, please type 'help ',\nwhere item is one of the following", INFO_INFO); num_name= 0; num_cat= 1; last_char= '_'; From 15092975f506dfadeb379805f78e50e2939a2911 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 20 Nov 2004 01:17:18 +0300 Subject: [PATCH 40/44] changed field names, fields order according to WL description fixed bug: "create view v7 as select * from information_schema.tables;" failed mysql-test/r/information_schema.result: changed field names, fields order according to WL description mysql-test/t/information_schema.test: changed field names, fields order according to WL description sql/sql_show.cc: changed field names, fields order according to WL description sql/sql_view.cc: fixed bug: "create view v7 as select * from information_schema.tables;" failed tests/client_test.c: changed field names, fields order according to WL description --- mysql-test/r/information_schema.result | 96 ++++++---- mysql-test/t/information_schema.test | 12 +- sql/sql_show.cc | 249 +++++++++++++++---------- sql/sql_view.cc | 2 +- tests/client_test.c | 4 +- 5 files changed, 226 insertions(+), 137 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index f3dcdf66399..9ebf33be5bd 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1,16 +1,16 @@ grant all privileges on test.* to mysqltest_1@localhost; select * from information_schema.SCHEMATA where schema_name > 'm'; -CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME -NULL mysql latin1 -NULL test latin1 +CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME SQL_PATH +NULL mysql latin1 NULL +NULL test latin1 NULL select schema_name from information_schema.schemata; schema_name mysql test show databases *; -CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME -NULL mysql latin1 -NULL test latin1 +CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME SQL_PATH +NULL mysql latin1 NULL +NULL test latin1 NULL show databases like 't%'; Database (t%) test @@ -19,10 +19,10 @@ Database mysql test show databases * where schema_name like 't%'; -CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME -NULL test latin1 +CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME SQL_PATH +NULL test latin1 NULL show databases * where schema_name = 't%'; -CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME +CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME SQL_PATH create database testtets; create table testtets.t1(a int, b VARCHAR(30), KEY string_data (b)); create table test.t2(a int); @@ -119,24 +119,24 @@ Field Type Collation Null Key Default Extra Privileges Comment c char(64) utf8_general_ci select,insert,update,references select * from information_schema.COLUMNS where table_name="t1" and column_name= "a"; -TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME TYPE COLLATION_NAME IS_NULLABLE KEY COLUMN_DEFAULT EXTRA PRIVILEGES COMMENT -NULL testtets t1 a 1 int 0 11 4 0 NULL int(11) NULL YES NULL select,insert,update,references +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT +NULL testtets t1 a 1 NULL YES int 11 11 11 0 NULL NULL int(11) select,insert,update,references show columns * where table_name = "t1"; -TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME TYPE COLLATION_NAME IS_NULLABLE KEY COLUMN_DEFAULT EXTRA PRIVILEGES COMMENT -NULL testtets t1 a 1 int 0 11 4 0 NULL int(11) NULL YES NULL select,insert,update,references -NULL testtets t1 b 2 varchar 30 30 30 31 latin1 varchar(30) latin1_swedish_ci YES MUL NULL select,insert,update,references +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT +NULL testtets t1 a 1 NULL YES int 11 11 11 0 NULL NULL int(11) select,insert,update,references +NULL testtets t1 b 2 NULL YES varchar 30 30 NULL NULL latin1 latin1_swedish_ci varchar(30) MUL select,insert,update,references drop view v1; drop tables testtets.t4, testtets.t1, t2, t3; drop database testtets; select * from information_schema.CHARACTER_SETS where CHARACTER_SET_NAME like 'latin1%'; -CHARACTER_SET_NAME Description DEFAULT_COLLATE_NAME Maxlen +CHARACTER_SET_NAME DESCRIPTION DEFAULT_COLLATE_NAME MAXLEN latin1 ISO 8859-1 West European latin1_swedish_ci 1 SHOW CHARACTER SET LIKE 'latin1%'; Charset Description Default collation Maxlen latin1 ISO 8859-1 West European latin1_swedish_ci 1 SHOW CHARACTER SET * LIKE 'latin1%'; -CHARACTER_SET_NAME Description DEFAULT_COLLATE_NAME Maxlen +CHARACTER_SET_NAME DESCRIPTION DEFAULT_COLLATE_NAME MAXLEN latin1 ISO 8859-1 West European latin1_swedish_ci 1 SHOW CHARACTER SET WHERE CHARACTER_SET_NAME like 'latin1%'; Charset Description Default collation Maxlen @@ -145,11 +145,11 @@ SHOW CHARACTER SET CHARACTER_SET_NAME WHERE CHARACTER_SET_NAME like 'latin1%'; CHARACTER_SET_NAME latin1 SHOW CHARACTER SET * WHERE CHARACTER_SET_NAME like 'latin1%'; -CHARACTER_SET_NAME Description DEFAULT_COLLATE_NAME Maxlen +CHARACTER_SET_NAME DESCRIPTION DEFAULT_COLLATE_NAME MAXLEN latin1 ISO 8859-1 West European latin1_swedish_ci 1 select * from information_schema.COLLATIONS where COLLATION_NAME like 'latin1%'; -COLLATION_NAME Charset Id Default Compiled Sortlen +COLLATION_NAME CHARSET ID DEFAULT COMPILED SORTLEN latin1_german1_ci latin1 5 0 latin1_swedish_ci latin1 8 Yes Yes 1 latin1_danish_ci latin1 15 0 @@ -169,7 +169,7 @@ latin1_general_ci latin1 48 0 latin1_general_cs latin1 49 0 latin1_spanish_ci latin1 94 0 SHOW COLLATION * LIKE 'latin1%'; -COLLATION_NAME Charset Id Default Compiled Sortlen +COLLATION_NAME CHARSET ID DEFAULT COMPILED SORTLEN latin1_german1_ci latin1 5 0 latin1_swedish_ci latin1 8 Yes Yes 1 latin1_danish_ci latin1 15 0 @@ -199,7 +199,7 @@ latin1_general_ci latin1_general_cs latin1_spanish_ci SHOW COLLATION * WHERE COLLATION_NAME like 'latin1%'; -COLLATION_NAME Charset Id Default Compiled Sortlen +COLLATION_NAME CHARSET ID DEFAULT COMPILED SORTLEN latin1_german1_ci latin1 5 0 latin1_swedish_ci latin1 8 Yes Yes 1 latin1_danish_ci latin1 15 0 @@ -358,11 +358,11 @@ NULL test key_1 test t1 UNIQUE NULL NULL test key_2 test t1 UNIQUE NULL select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; -CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME -NULL test PRIMARY test t1 a 1 NULL NULL NULL -NULL test constraint_1 test t1 a 1 NULL NULL NULL -NULL test key_1 test t1 a 1 NULL NULL NULL -NULL test key_2 test t1 a 1 NULL NULL NULL +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +NULL test PRIMARY NULL test t1 a 1 NULL NULL NULL +NULL test constraint_1 NULL test t1 a 1 NULL NULL NULL +NULL test key_1 NULL test t1 a 1 NULL NULL NULL +NULL test key_2 NULL test t1 a 1 NULL NULL NULL drop table t1; CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), @@ -377,11 +377,11 @@ NULL test t2_ibfk_1 test t2 FOREIGN KEY ON DELETE CASCADE NULL test t2_ibfk_2 test t2 FOREIGN KEY ON UPDATE CASCADE select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; -CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME -NULL test PRIMARY test t1 id 1 NULL NULL NULL -NULL test PRIMARY test t2 id 1 NULL NULL NULL -NULL test t2_ibfk_1 test t2 t1_id 1 test t1 id -NULL test t2_ibfk_2 test t2 t1_id 1 test t1 id +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +NULL test PRIMARY NULL test t1 id 1 NULL NULL NULL +NULL test PRIMARY NULL test t2 id 1 NULL NULL NULL +NULL test t2_ibfk_1 NULL test t2 t1_id 1 NULL id +NULL test t2_ibfk_2 NULL test t2 t1_id 1 NULL id select table_name from information_schema.TABLES where table_schema like "test%"; table_name t1 @@ -439,6 +439,9 @@ v call px5()// v 9 +select sql_mode from information_schema.ROUTINES; +sql_mode + create table t1 (a int not null auto_increment,b int, primary key (a)); insert into t1 values (1,1),(NULL,3),(NULL,4); select AUTO_INCREMENT from information_schema.tables where table_name = 't1'; @@ -457,32 +460,51 @@ SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS; Table Create Table CHARACTER_SETS CREATE TEMPORARY TABLE `CHARACTER_SETS` ( `CHARACTER_SET_NAME` char(30) NOT NULL default '', - `Description` char(60) NOT NULL default '', + `DESCRIPTION` char(60) NOT NULL default '', `DEFAULT_COLLATE_NAME` char(60) NOT NULL default '', - `Maxlen` bigint(3) NOT NULL default '0' + `MAXLEN` bigint(3) NOT NULL default '0' ) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=2282 set names latin2; SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS; Table Create Table CHARACTER_SETS CREATE TEMPORARY TABLE `CHARACTER_SETS` ( `CHARACTER_SET_NAME` char(30) NOT NULL default '', - `Description` char(60) NOT NULL default '', + `DESCRIPTION` char(60) NOT NULL default '', `DEFAULT_COLLATE_NAME` char(60) NOT NULL default '', - `Maxlen` bigint(3) NOT NULL default '0' + `MAXLEN` bigint(3) NOT NULL default '0' ) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=2282 set names latin1; create table t1 select * from information_schema.CHARACTER_SETS where CHARACTER_SET_NAME like "latin1"; select * from t1; -CHARACTER_SET_NAME Description DEFAULT_COLLATE_NAME Maxlen +CHARACTER_SET_NAME DESCRIPTION DEFAULT_COLLATE_NAME MAXLEN latin1 ISO 8859-1 West European latin1_swedish_ci 1 alter table t1 default character set utf8; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `CHARACTER_SET_NAME` char(30) NOT NULL default '', - `Description` char(60) NOT NULL default '', + `DESCRIPTION` char(60) NOT NULL default '', `DEFAULT_COLLATE_NAME` char(60) NOT NULL default '', - `Maxlen` bigint(3) NOT NULL default '0' + `MAXLEN` bigint(3) NOT NULL default '0' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 drop table t1; +create view v1 as select * from information_schema.TABLES; +drop view v1; +create table t1(a NUMERIC(5,3), b NUMERIC(5,1), c float(5,2), +d NUMERIC(6,4), e float, f DECIMAL(6,3), g int(11), h DOUBLE(10,3), +i DOUBLE); +select COLUMN_NAME,COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH, +CHARACTER_OCTET_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE +from information_schema.columns where table_name= 't1'; +COLUMN_NAME COLUMN_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE +a decimal(5,3) 7 7 5 3 +b decimal(5,1) 7 7 5 1 +c float(5,2) 5 5 5 2 +d decimal(6,4) 8 8 6 4 +e float 12 12 12 NULL +f decimal(6,3) 8 8 6 3 +g int(11) 11 11 11 0 +h double(10,3) 10 10 10 3 +i double 22 22 22 NULL +drop table t1; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 5132717707e..ce8dc0290e9 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -217,6 +217,7 @@ end;// call px5()// call px5()// delimiter ;// +select sql_mode from information_schema.ROUTINES; create table t1 (a int not null auto_increment,b int, primary key (a)); insert into t1 values (1,1),(NULL,3),(NULL,4); @@ -240,5 +241,14 @@ where CHARACTER_SET_NAME like "latin1"; select * from t1; alter table t1 default character set utf8; show create table t1; -drop table t1; +drop table t1; +create view v1 as select * from information_schema.TABLES; +drop view v1; +create table t1(a NUMERIC(5,3), b NUMERIC(5,1), c float(5,2), + d NUMERIC(6,4), e float, f DECIMAL(6,3), g int(11), h DOUBLE(10,3), + i DOUBLE); +select COLUMN_NAME,COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH, + CHARACTER_OCTET_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE +from information_schema.columns where table_name= 't1'; +drop table t1; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 720d09b454f..1642a2eaa17 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2297,17 +2297,16 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, cs); table->field[4]->store((longlong) count); field->sql_type(type); - table->field[11]->store(type.ptr(), type.length(), cs); + table->field[14]->store(type.ptr(), type.length(), cs); tmp_buff= strchr(type.ptr(),'('); - table->field[5]->store(type.ptr(), + table->field[7]->store(type.ptr(), (tmp_buff ? tmp_buff - type.ptr() : type.length()), cs); - if (show_table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_UN_FIELD) { - table->field[15]->store("CURRENT_TIMESTAMP", 17, cs); - table->field[15]->set_notnull(); + table->field[5]->store("CURRENT_TIMESTAMP", 17, cs); + table->field[5]->set_notnull(); } else if (field->unireg_check != Field::NEXT_NUMBER && !field->is_null() && @@ -2318,46 +2317,77 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, field->val_str(&type); uint dummy_errors; def.copy(type.ptr(), type.length(), type.charset(), cs, &dummy_errors); - table->field[15]->store(def.ptr(), def.length(), def.charset()); - table->field[15]->set_notnull(); + table->field[5]->store(def.ptr(), def.length(), def.charset()); + table->field[5]->set_notnull(); } else if (field->unireg_check == Field::NEXT_NUMBER || field->maybe_null()) - table->field[15]->set_null(); // Null as default + table->field[5]->set_null(); // Null as default else { - table->field[15]->store("",0, cs); - table->field[15]->set_notnull(); + table->field[5]->store("",0, cs); + table->field[5]->set_notnull(); } - pos=(byte*) ((flags & NOT_NULL_FLAG) && field->type() != FIELD_TYPE_TIMESTAMP ? "" : "YES"); - table->field[13]->store((const char*) pos, - strlen((const char*) pos), cs); + table->field[6]->store((const char*) pos, + strlen((const char*) pos), cs); if (field->has_charset()) - { - table->field[6]->store((longlong) field->field_length/ + table->field[8]->store((longlong) field->field_length/ field->charset()->mbmaxlen); + else + table->field[8]->store((longlong) field->field_length); + table->field[9]->store((longlong) field->field_length); + + { + uint dec =field->decimals(); + switch (field->type()) { + case FIELD_TYPE_DECIMAL: + { + uint int_part=field->field_length - (dec ? dec + 1 : 0); + table->field[10]->store((longlong) (int_part + dec - 1)); + table->field[10]->set_notnull(); + table->field[11]->store((longlong) field->decimals()); + table->field[11]->set_notnull(); + } + break; + case FIELD_TYPE_TINY: + case FIELD_TYPE_SHORT: + case FIELD_TYPE_LONG: + case FIELD_TYPE_LONGLONG: + case FIELD_TYPE_INT24: + case FIELD_TYPE_FLOAT: + case FIELD_TYPE_DOUBLE: + { + table->field[10]->store((longlong) field->field_length); + table->field[10]->set_notnull(); + if (dec != NOT_FIXED_DEC) + { + table->field[11]->store((longlong) dec); + table->field[11]->set_notnull(); + } + } + break; + default: + break; + } } - table->field[7]->store((longlong) field->field_length); - table->field[8]->store((longlong) field->pack_length()); - table->field[9]->store((longlong) field->decimals()); if (field->has_charset()) { pos=(byte*) field->charset()->csname; - table->field[10]->store((const char*) pos, - strlen((const char*) pos), cs); - table->field[10]->set_notnull(); - pos=(byte*) field->charset()->name; table->field[12]->store((const char*) pos, strlen((const char*) pos), cs); table->field[12]->set_notnull(); + pos=(byte*) field->charset()->name; + table->field[13]->store((const char*) pos, + strlen((const char*) pos), cs); + table->field[13]->set_notnull(); } pos=(byte*) ((field->flags & PRI_KEY_FLAG) ? "PRI" : (field->flags & UNIQUE_KEY_FLAG) ? "UNI" : (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":""); - table->field[14]->store((const char*) pos, + table->field[15]->store((const char*) pos, strlen((const char*) pos), cs); char *end=tmp; if (field->unireg_check == Field::NEXT_NUMBER) @@ -2511,45 +2541,46 @@ void store_schema_proc(THD *thd, TABLE *table, { table->field[3]->store(tmp_string.ptr(), tmp_string.length(), cs); tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[3], &tmp_string); + table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); get_field(thd->mem_root, proc_table->field[0], &tmp_string); table->field[2]->store(tmp_string.ptr(), tmp_string.length(), cs); tmp_string.length(0); get_field(thd->mem_root, proc_table->field[2], &tmp_string); table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs); tmp_string.length(0); - get_field(thd->mem_root, proc_table->field[3], &tmp_string); - table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs); - tmp_string.length(0); - get_field(thd->mem_root, proc_table->field[5], &tmp_string); - table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs); - tmp_string.length(0); - get_field(thd->mem_root, proc_table->field[6], &tmp_string); - table->field[10]->store(tmp_string.ptr(), tmp_string.length(), cs); - tmp_string.length(0); - get_field(thd->mem_root, proc_table->field[7], &tmp_string); - table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs); - tmp_string.length(0); get_field(thd->mem_root, proc_table->field[9], &tmp_string); - table->field[6]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[6]->store("SQL", 3, cs); tmp_string.length(0); get_field(thd->mem_root, proc_table->field[10], &tmp_string); - table->field[8]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[8]->store("SQL", 3, cs); tmp_string.length(0); - get_field(thd->mem_root, proc_table->field[11], &tmp_string); - table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs); + get_field(thd->mem_root, proc_table->field[6], &tmp_string); + table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[5], &tmp_string); + table->field[12]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[7], &tmp_string); + table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs); bzero((char *)&time, sizeof(time)); ((Field_timestamp *) proc_table->field[12])->get_time(&time); - table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); bzero((char *)&time, sizeof(time)); ((Field_timestamp *) proc_table->field[13])->get_time(&time); - table->field[13]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + tmp_string.length(0); get_field(thd->mem_root, proc_table->field[14], &tmp_string); - table->field[16]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); tmp_string.length(0); get_field(thd->mem_root, proc_table->field[15], &tmp_string); - table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); - table->field[7]->store("SQL", 3, cs); - table->field[9]->store("SQL", 3, cs); + table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[11], &tmp_string); + table->field[19]->store(tmp_string.ptr(), tmp_string.length(), cs); table->file->write_row(table->record[0]); } } @@ -2785,11 +2816,11 @@ static int get_schema_key_column_usage_record(THD *thd, restore_record(table, default_values); table->field[1]->store(base_name, strlen(base_name), cs); table->field[2]->store(key_info->name, strlen(key_info->name), cs); - table->field[3]->store(base_name, strlen(base_name), cs); - table->field[4]->store(file_name, strlen(file_name), cs); - table->field[5]->store(key_part->field->field_name, + table->field[4]->store(base_name, strlen(base_name), cs); + table->field[5]->store(file_name, strlen(file_name), cs); + table->field[6]->store(key_part->field->field_name, strlen(key_part->field->field_name), cs); - table->field[6]->store((longlong) f_idx); + table->field[7]->store((longlong) f_idx); table->file->write_row(table->record[0]); } } @@ -2812,18 +2843,18 @@ static int get_schema_key_column_usage_record(THD *thd, table->field[1]->store(base_name, strlen(base_name), cs); table->field[2]->store(f_key_info->forein_id->str, f_key_info->forein_id->length, cs); - table->field[3]->store(base_name, strlen(base_name), cs); - table->field[4]->store(file_name, strlen(file_name), cs); - table->field[5]->store(f_info->str, f_info->length, cs); - table->field[6]->store((longlong) f_idx); - table->field[7]->store(f_key_info->referenced_db->str, + table->field[4]->store(base_name, strlen(base_name), cs); + table->field[5]->store(file_name, strlen(file_name), cs); + table->field[6]->store(f_info->str, f_info->length, cs); + table->field[7]->store((longlong) f_idx); + table->field[8]->store(f_key_info->referenced_db->str, f_key_info->referenced_db->length, cs); - table->field[7]->set_notnull(); - table->field[8]->store(f_key_info->referenced_table->str, - f_key_info->referenced_table->length, cs); - table->field[8]->set_notnull(); - table->field[9]->store(r_info->str, r_info->length, cs); table->field[9]->set_notnull(); + table->field[10]->store(f_key_info->referenced_table->str, + f_key_info->referenced_table->length, cs); + table->field[9]->set_notnull(); + table->field[10]->store(r_info->str, r_info->length, cs); + table->field[10]->set_notnull(); table->file->write_row(table->record[0]); } } @@ -3035,24 +3066,46 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) { - ST_FIELD_INFO *field_info= &schema_table->fields_info[3]; - int count= 2; - for ( ; field_info->field_name; field_info++) + int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1}; + int *field_num= fields_arr; + ST_FIELD_INFO *field_info; + for (; *field_num >= 0; field_num++) { - count++; - if (field_info->old_name) + field_info= &schema_table->fields_info[*field_num]; + if (!thd->lex->verbose && (*field_num == 13 || + *field_num == 17 || + *field_num == 18)) + continue; + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (field) { - if (!thd->lex->verbose && (count == 12 ||count == 17 || count == 18)) - continue; - Item_field *field= new Item_field(NullS, NullS, field_info->field_name); - if (field) - { - field->set_name(field_info->old_name, - strlen(field_info->old_name), - system_charset_info); - if (add_item_to_list(thd, field)) - return 1; - } + field->set_name(field_info->old_name, + strlen(field_info->old_name), + system_charset_info); + if (add_item_to_list(thd, field)) + return 1; + } + } + return 0; +} + + +int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, -1}; + int *field_num= fields_arr; + ST_FIELD_INFO *field_info; + for (; *field_num >= 0; field_num++) + { + field_info= &schema_table->fields_info[*field_num]; + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (field) + { + field->set_name(field_info->old_name, + strlen(field_info->old_name), + system_charset_info); + if (add_item_to_list(thd, field)) + return 1; } } return 0; @@ -3197,6 +3250,7 @@ ST_FIELD_INFO schema_fields_info[]= {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, {"SCHEMA_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"}, {"DEFAULT_CHARACTER_SET_NAME", 60, MYSQL_TYPE_STRING, 0, 0, 0}, + {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; @@ -3210,7 +3264,7 @@ ST_FIELD_INFO tables_fields_info[]= {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine"}, {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version"}, {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"}, - {"ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows"}, + {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows"}, {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length"}, {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length"}, {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length"}, @@ -3223,7 +3277,7 @@ ST_FIELD_INFO tables_fields_info[]= {"COLLATION", 60, MYSQL_TYPE_STRING, 0, 1, "Collation"}, {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum"}, {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options"}, - {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"}, + {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; @@ -3235,20 +3289,20 @@ ST_FIELD_INFO columns_fields_info[]= {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Field"}, {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0}, + {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Default"}, + {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"}, {"DATA_TYPE", 40, MYSQL_TYPE_STRING, 0, 0, 0}, {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0}, {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0}, - {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 0, 0}, - {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 0, 0}, + {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0}, + {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0}, {"CHARACTER_SET_NAME", 40, MYSQL_TYPE_STRING, 0, 1, 0}, - {"TYPE", 40, MYSQL_TYPE_STRING, 0, 0, "Type"}, {"COLLATION_NAME", 40, MYSQL_TYPE_STRING, 0, 1, "Collation"}, - {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"}, - {"KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key"}, - {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Default"}, + {"COLUMN_TYPE", 40, MYSQL_TYPE_STRING, 0, 0, "Type"}, + {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key"}, {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, "Extra"}, {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges"}, - {"COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment"}, + {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment"}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; @@ -3256,9 +3310,9 @@ ST_FIELD_INFO columns_fields_info[]= ST_FIELD_INFO charsets_fields_info[]= { {"CHARACTER_SET_NAME", 30, MYSQL_TYPE_STRING, 0, 0, "Charset"}, - {"Description", 60, MYSQL_TYPE_STRING, 0, 0, "Description"}, + {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description"}, {"DEFAULT_COLLATE_NAME", 60, MYSQL_TYPE_STRING, 0, 0, "Default collation"}, - {"Maxlen", 3 ,MYSQL_TYPE_LONG, 0, 0, "Maxlen"}, + {"MAXLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Maxlen"}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; @@ -3266,11 +3320,11 @@ ST_FIELD_INFO charsets_fields_info[]= ST_FIELD_INFO collation_fields_info[]= { {"COLLATION_NAME", 30, MYSQL_TYPE_STRING, 0, 0, "Collation"}, - {"Charset", 30, MYSQL_TYPE_STRING, 0, 0, "Charset"}, - {"Id", 11, MYSQL_TYPE_LONG, 0, 0, "Id"}, - {"Default", 30 ,MYSQL_TYPE_STRING, 0, 0, "Default"}, - {"Compiled", 30 ,MYSQL_TYPE_STRING, 0, 0, "Compiled"}, - {"Sortlen", 3 ,MYSQL_TYPE_LONG, 0, 0, "Sortlen"}, + {"CHARSET", 30, MYSQL_TYPE_STRING, 0, 0, "Charset"}, + {"ID", 11, MYSQL_TYPE_LONG, 0, 0, "Id"}, + {"DEFAULT", 30 ,MYSQL_TYPE_STRING, 0, 0, "Default"}, + {"COMPILED", 30 ,MYSQL_TYPE_STRING, 0, 0, "Compiled"}, + {"SORTLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Sortlen"}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; @@ -3290,19 +3344,21 @@ ST_FIELD_INFO proc_fields_info[]= {"ROUTINE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"}, {"ROUTINE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"}, {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"}, - {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"}, {"DTD_IDENTIFIER", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"ROUTINE_BODY", 3, MYSQL_TYPE_STRING, 0, 0, 0}, {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0}, + {"EXTERNAL_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, + {"EXTERNAL_LANGUAGE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, {"PARAMETER_STYLE", 3, MYSQL_TYPE_STRING, 0, 0, 0}, {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0}, {"SQL_DATA_ACCESS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"SQL_PATH", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0}, - {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Modified"}, - {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Created"}, {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type"}, + {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Created"}, + {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Modified"}, {"SQL_MODE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"ROUTINE_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment"}, + {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; @@ -3404,6 +3460,7 @@ ST_FIELD_INFO key_column_usage_fields_info[]= {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, @@ -3444,7 +3501,7 @@ ST_SCHEMA_TABLE schema_tables[]= {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info, create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1}, {"ROUTINES", proc_fields_info, create_schema_table, - fill_schema_proc, make_old_format, 0, -1, -1}, + fill_schema_proc, make_proc_old_format, 0, -1, -1}, {"STATISTICS", stat_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_stat_record, 1, 2}, {"VIEWS", view_fields_info, create_schema_table, @@ -3460,7 +3517,7 @@ ST_SCHEMA_TABLE schema_tables[]= {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table, get_all_tables, 0, get_schema_constarints_record, 3, 4}, {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, - get_all_tables, 0, get_schema_key_column_usage_record, 3, 4}, + get_all_tables, 0, get_schema_key_column_usage_record, 4, 5}, {"TABLE_NAMES", table_names_fields_info, create_schema_table, get_all_tables, make_table_names_old_format, 0, 1, 2}, {0, 0, 0, 0, 0, 0, 0, 0} diff --git a/sql/sql_view.cc b/sql/sql_view.cc index aa7fda4e3d0..56f85667bb1 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -283,7 +283,7 @@ bool mysql_create_view(THD *thd, /* Do we have more privileges on view field then underlying table field? */ - if ((~fld->have_privileges & priv)) + if (!fld->field->table->tmp_table && (~fld->have_privileges & priv)) { /* VIEW column has more privileges */ my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), diff --git a/tests/client_test.c b/tests/client_test.c index 7d264d682da..12462cd35b9 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -7263,13 +7263,13 @@ static void test_explain_bug() verify_prepare_field(result, 0, "Field", "COLUMN_NAME", MYSQL_TYPE_STRING, 0, 0, "", 192, 0); - verify_prepare_field(result, 1, "Type", "TYPE", + verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_STRING, 0, 0, "", 120, 0); verify_prepare_field(result, 2, "Null", "IS_NULLABLE", MYSQL_TYPE_STRING, 0, 0, "", 9, 0); - verify_prepare_field(result, 3, "Key", "KEY", + verify_prepare_field(result, 3, "Key", "COLUMN_KEY", MYSQL_TYPE_STRING, 0, 0, "", 9, 0); verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT", From 5e53947da80be2ce8e398244643b5929dbb0bd93 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 20 Nov 2004 20:19:08 +0100 Subject: [PATCH 41/44] post-merge fix --- sql/item.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item.cc b/sql/item.cc index a16520a8a8d..944d377282d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1036,7 +1036,7 @@ void Item_param::set_time(TIME *tm, timestamp_type type, uint32 max_length_arg) { char buff[MAX_DATE_STRING_REP_LENGTH]; uint length= my_TIME_to_str(&value.time, buff); - make_truncated_value_warning(current_thd, buff, length, type); + make_truncated_value_warning(current_thd, buff, length, type, 0); set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR); } From 00e79db8ac3ab23776bd22d7f26c8e00c0a48e55 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 21 Nov 2004 16:35:42 +0200 Subject: [PATCH 42/44] postreview changes include/mysqld_error.h: checksum error message sql/share/czech/errmsg.txt: checksum error message sql/share/danish/errmsg.txt: checksum error message sql/share/dutch/errmsg.txt: checksum error message sql/share/english/errmsg.txt: checksum error message sql/share/estonian/errmsg.txt: checksum error message sql/share/french/errmsg.txt: checksum error message sql/share/german/errmsg.txt: checksum error message sql/share/greek/errmsg.txt: checksum error message sql/share/hungarian/errmsg.txt: checksum error message sql/share/italian/errmsg.txt: checksum error message sql/share/japanese/errmsg.txt: checksum error message sql/share/korean/errmsg.txt: checksum error message sql/share/norwegian-ny/errmsg.txt: checksum error message sql/share/norwegian/errmsg.txt: checksum error message sql/share/polish/errmsg.txt: checksum error message sql/share/portuguese/errmsg.txt: checksum error message sql/share/romanian/errmsg.txt: checksum error message sql/share/russian/errmsg.txt: checksum error message sql/share/serbian/errmsg.txt: checksum error message sql/share/slovak/errmsg.txt: checksum error message sql/share/spanish/errmsg.txt: checksum error message sql/share/swedish/errmsg.txt: checksum error message sql/share/ukrainian/errmsg.txt: checksum error message sql/sql_table.cc: fixed layout fixed comment allow cocalization of error --- include/mysqld_error.h | 3 ++- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 3 ++- sql/sql_table.cc | 22 +++++++++++++--------- 25 files changed, 39 insertions(+), 11 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 4ef23f446c9..a581453f576 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -408,4 +408,5 @@ #define ER_WRONG_MAGIC 1389 #define ER_PS_MANY_PARAM 1390 #define ER_KEY_PART_0 1391 -#define ER_ERROR_MESSAGES 392 +#define ER_VIEW_CHECKSUM 1392 +#define ER_ERROR_MESSAGES 393 diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index c6ee78ffbb2..0382e2f95d6 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -420,3 +420,4 @@ character-set=latin2 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 37b523526ce..8b38a3a072e 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -411,3 +411,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 7cf441e899d..995d29ef39e 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -420,3 +420,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 990e3819053..4218b2f5b47 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -408,3 +408,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index ff2f2a922ce..9ef85e60382 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -413,3 +413,4 @@ character-set=latin7 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index b9062214ecc..248c1c8cf9b 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -408,3 +408,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 757274bf1d5..b41c0a3bee9 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -421,3 +421,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 883bd0887c9..7887ffa9dd6 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -408,3 +408,4 @@ character-set=greek "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index e93970e7eb8..51576bd3bdf 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -413,3 +413,4 @@ character-set=latin2 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 1745c31f114..771f0c7ff95 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -408,3 +408,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 969bacc8d8f..04cd9f7fb49 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -412,3 +412,4 @@ character-set=ujis "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index cdb67ba004c..2063dc3b275 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -408,3 +408,4 @@ character-set=euckr "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 35b5a3d464b..cb00db472e9 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -410,3 +410,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index bb34b3d653c..53e28d71899 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -410,3 +410,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index e4dfb9442dd..b318c6415b2 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -413,3 +413,4 @@ character-set=latin2 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 4f3c73b900b..489a8395b66 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -410,3 +410,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index b96ddc1fe88..b24ba200a8a 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -413,3 +413,4 @@ character-set=latin2 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 2da6cbdfc1a..9d5c708ffcd 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -413,3 +413,4 @@ character-set=koi8r "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"Проверка контрольной суммы текста VIEW провалилась" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 461a4942131..5a66ab271c6 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -401,3 +401,4 @@ character-set=cp1250 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 862ca741640..373ce767f2d 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -416,3 +416,4 @@ character-set=latin2 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 64e6da34d2b..3ba13373c05 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -412,3 +412,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index bb7cd72f3df..9a5bbb6d0fc 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -408,3 +408,4 @@ character-set=latin1 "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"View text checksum failed" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index a7b139bc2c3..891798fb3a1 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -391,7 +391,7 @@ character-set=koi8u "Incorrect %-.32s value: '%-.128s' for column '%.64s' at row %ld", "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION для VIEW '%-.64s.%-.64s' що не може бути оновленним" -"перев╕рка CHECK OPTION для VIEW '%-.64s.%-.64s' не пройшла" +"Перев╕рка CHECK OPTION для VIEW '%-.64s.%-.64s' не пройшла" "Access denied; you are not the procedure/function definer of '%s'" "Failed purging old relay logs: %s" "Password hash should be a %d-digit hexadecimal number" @@ -414,3 +414,4 @@ character-set=koi8u "Wrong magic in %-.64s" "Prepared statement contains too many placeholders" "Key part '%-.64s' length cannot be 0" +"Перев╕рка контрольно╖ суми тексту VIEW не пройшла" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a12a08d1170..5020b4820a0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1747,10 +1747,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, uint extra_open_options, int (*prepare_func)(THD *, TABLE_LIST *, HA_CHECK_OPT *), - int (handler::*operator_func) - (THD *, HA_CHECK_OPT *), - int (view_operator_func) - (THD *, TABLE_LIST*)) + int (handler::*operator_func)(THD *, + HA_CHECK_OPT *), + int (view_operator_func)(THD *, TABLE_LIST*)) { TABLE_LIST *table, *next_global_table; List field_list; @@ -1808,12 +1807,16 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, } /* - for this command used only temporary table method (without - filling tables), so if opening succeed, table will be opened + CHECK TABLE command is only command where VIEW allowed here and this + command use only temporary teble method for VIEWs resolving => there + can't be VIEW tree substitition of join view => if opening table + succeed then table->table will have real TABLE pointer as value (in + case of join view substitution table->table can be 0, but here it is + impossible) */ if (!table->table) { - char buf[ERRMSGSIZE+25]; + char buf[ERRMSGSIZE+ERRMSGSIZE+2]; const char *err_msg; protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); @@ -1825,7 +1828,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (table->view && view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM) { - strxmov(buf, "View checksum failed and ", err_msg, NullS); + strxmov(buf, err_msg, "; ", ER(ER_VIEW_CHECKSUM), NullS); err_msg= (const char *)buf; } protocol->store(err_msg, system_charset_info); @@ -1961,7 +1964,8 @@ send_result_message: case HA_ADMIN_WRONG_CHECKSUM: { protocol->store("note", 4, system_charset_info); - protocol->store("Checksum error", 14, system_charset_info); + protocol->store(ER(ER_VIEW_CHECKSUM), strlen(ER(ER_VIEW_CHECKSUM)), + system_charset_info); break; } From 60b283515ef455f1eb3cd714d8fb041bbecfffb7 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 21 Nov 2004 15:37:52 +0100 Subject: [PATCH 43/44] make the test results repeatable --- mysql-test/r/myisam.result | 1 + mysql-test/t/myisam.test | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 31b14f9b822..d155a14bb60 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -529,6 +529,7 @@ show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 1 a 1 a A NULL NULL NULL YES BTREE disabled create table t2 (a int); +set @@rand_seed1=31415926,@@rand_seed2=2718281828; insert t1 select * from t2; show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index f9081e8769b..c8ed7910b76 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -498,11 +498,12 @@ alter table t1 disable keys; show keys from t1; create table t2 (a int); let $i=1000; +set @@rand_seed1=31415926,@@rand_seed2=2718281828; --disable_query_log while ($i) { dec $i; - eval insert t2 values (rand()*100000); + insert t2 values (rand()*100000); } --enable_query_log insert t1 select * from t2; From 5b08a68f0513648c21eb570de6625095f53ff0b4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 21 Nov 2004 16:42:54 +0200 Subject: [PATCH 44/44] test made independend of server builtin features --- mysql-test/r/rpl_auto_increment.result | 3 +-- mysql-test/t/rpl_auto_increment.test | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/rpl_auto_increment.result b/mysql-test/r/rpl_auto_increment.result index ec3bf4019e0..9eca51ad2d9 100644 --- a/mysql-test/r/rpl_auto_increment.result +++ b/mysql-test/r/rpl_auto_increment.result @@ -37,11 +37,10 @@ a b 32 6 drop table t1; set @@session.auto_increment_increment=100, @@session.auto_increment_offset=10; -show variables like "%auto%"; +show variables like "%auto_inc%"; Variable_name Value auto_increment_increment 100 auto_increment_offset 10 -innodb_autoextend_increment 8 create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; insert into t1 values (NULL),(5),(NULL); insert into t1 values (250),(NULL); diff --git a/mysql-test/t/rpl_auto_increment.test b/mysql-test/t/rpl_auto_increment.test index cfe1d44b11a..71032404307 100644 --- a/mysql-test/t/rpl_auto_increment.test +++ b/mysql-test/t/rpl_auto_increment.test @@ -26,7 +26,7 @@ connection master; drop table t1; set @@session.auto_increment_increment=100, @@session.auto_increment_offset=10; -show variables like "%auto%"; +show variables like "%auto_inc%"; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; # Insert with 2 insert statements to get better testing of logging