From 1a3cb50c24f8af7124823ddd8d85e97632182cb2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Apr 2006 11:49:20 +0500 Subject: [PATCH 01/15] Bug#18170: XML: ExtractValue(): XPath expression can't use QNames (colon in names) Problem source: Qualified names (aka QName) didn't work as tag names and attribute names, because the parser lacked a real rule to scan QName, so it understood only non-qualified names without prefixes. Solution: New rule was added to check both "ident" and "ident:ident" sequences. mysql-test/r/xml.result: Adding test case mysql-test/t/xml.test: Adding test case sql/item_xmlfunc.cc: Adding real QName parser rule and using it in NodeTest rule. --- mysql-test/r/xml.result | 9 +++++++++ mysql-test/t/xml.test | 8 ++++++++ sql/item_xmlfunc.cc | 26 +++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index 7e44673dd78..fdc06a0a2e6 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -641,3 +641,12 @@ CALL p2(); EXTRACTVALUE(p,'/Ñ/r') A DROP PROCEDURE p2; +select extractValue('','count(ns:element)'); +extractValue('','count(ns:element)') +1 +select extractValue('a','/ns:element'); +extractValue('a','/ns:element') +a +select extractValue('a','/ns:element/@xmlns:ns'); +extractValue('a','/ns:element/@xmlns:ns') +myns diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test index 8ed623883b6..d3e2da46413 100644 --- a/mysql-test/t/xml.test +++ b/mysql-test/t/xml.test @@ -321,3 +321,11 @@ END// DELIMITER ;// CALL p2(); DROP PROCEDURE p2; + +# +# Bug#18170: XML: ExtractValue(): +# XPath expression can't use QNames (colon in names) +# +select extractValue('','count(ns:element)'); +select extractValue('a','/ns:element'); +select extractValue('a','/ns:element/@xmlns:ns'); diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 71900c26c2d..2e70b896af7 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2266,6 +2266,30 @@ static int my_xpath_parse_Number(MY_XPATH *xpath) } +/* + QName grammar can be found in a separate document + http://www.w3.org/TR/REC-xml-names/#NT-QName + + [6] QName ::= (Prefix ':')? LocalPart + [7] Prefix ::= NCName + [8] LocalPart ::= NCName +*/ +static int +my_xpath_parse_QName(MY_XPATH *xpath) +{ + const char *beg; + if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT)) + return 0; + beg= xpath->prevtok.beg; + if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_COLON)) + return 1; /* Non qualified name */ + if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT)) + return 0; + xpath->prevtok.beg= beg; + return 1; +} + + /* Scan Variable reference @@ -2299,7 +2323,7 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath) static int my_xpath_parse_NodeTest_QName(MY_XPATH *xpath) { - if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT)) + if (!my_xpath_parse_QName(xpath)) return 0; DBUG_ASSERT(xpath->context); uint len= xpath->prevtok.end - xpath->prevtok.beg; From dfbf652165def750409cc1e8519e1aacd7a17f8b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 24 Apr 2006 18:57:00 +0400 Subject: [PATCH 02/15] Fix for bug#11081 "Using a CONVERT_TZ function in a stored function or trigger fails". In cases when CONVERT_TZ() function was used in trigger or stored function (or in stored procedure which was called from trigger or stored function) error about non existing '.' table was reported. Statements that use CONVERT_TZ() function should have time zone related tables in their table list. tz_init_table_list() function which is used to produce part of table list containing those tables didn't set TABLE_LIST::db_length/table_name_length members properly. As result time zone tables needed for CONVERT_TZ() function were incorrectly handled by prelocking algorithm and "Table '.' doesn't exist' error was emitted. This fix changes tz_init_table_list() in such way that it properly inits TABLE_LIST::table_name_length/db_length members and thus produces table list which can be handled by prelocking algorithm correctly. mysql-test/r/timezone2.result: Added test for bug #11081 "Using a CONVERT_TZ function in a stored function or trigger fails". mysql-test/t/timezone2.test: Added test for bug #11081 "Using a CONVERT_TZ function in a stored function or trigger fails". sql/tztime.cc: Now tz_init_table_list() inits table_name_length and db_length members in TABLE_LIST objects, so table lists produced with its help can be handled by prelocking algorithm properly. Also two clean-ups are included: - Now we use MY_TZ_TABLES_COUNT instead of magical number 4 in places where it is appropriate. - TZ_NAMES_ENTRY structure was converted to Tz_names_entry class in order to emphasize its non-POD nature. sql/tztime.h: Added MY_TZ_TABLES_COUNT constant to be used as number of time zone related tables which are needed for dynamical loading of time zone descriptions. --- mysql-test/r/timezone2.result | 15 +++++++ mysql-test/t/timezone2.test | 20 +++++++++ sql/tztime.cc | 82 ++++++++++++++++++++++------------- sql/tztime.h | 13 +++++- 4 files changed, 98 insertions(+), 32 deletions(-) diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result index df51a6aac9b..a1ae2f63212 100644 --- a/mysql-test/r/timezone2.result +++ b/mysql-test/r/timezone2.result @@ -1,4 +1,5 @@ drop table if exists t1, t2; +drop function if exists f1; create table t1 (ts timestamp); set time_zone='+00:00'; select unix_timestamp(utc_timestamp())-unix_timestamp(current_timestamp()); @@ -268,3 +269,17 @@ select * from t1; convert_tz(NULL, NULL, NULL) NULL drop table t1; +create table t1 (ldt datetime, udt datetime); +create function f1(i datetime) returns datetime +return convert_tz(i, 'UTC', 'Europe/Moscow'); +create trigger t1_bi before insert on t1 for each row +set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC'); +insert into t1 (ldt) values ('2006-04-19 16:30:00'); +select * from t1; +ldt udt +2006-04-19 16:30:00 2006-04-19 12:30:00 +select ldt, f1(udt) as ldt2 from t1; +ldt ldt2 +2006-04-19 16:30:00 2006-04-19 16:30:00 +drop table t1; +drop function f1; diff --git a/mysql-test/t/timezone2.test b/mysql-test/t/timezone2.test index 069c19341e4..bfc909d6995 100644 --- a/mysql-test/t/timezone2.test +++ b/mysql-test/t/timezone2.test @@ -3,6 +3,7 @@ # Preparing playground --disable_warnings drop table if exists t1, t2; +drop function if exists f1; --enable_warnings @@ -222,3 +223,22 @@ select * from t1; drop table t1; # End of 4.1 tests + +# +# Test for bug #11081 "Using a CONVERT_TZ function in a stored function +# or trigger fails". +# +create table t1 (ldt datetime, udt datetime); +create function f1(i datetime) returns datetime + return convert_tz(i, 'UTC', 'Europe/Moscow'); +create trigger t1_bi before insert on t1 for each row + set new.udt:= convert_tz(new.ldt, 'Europe/Moscow', 'UTC'); +# This should work without errors +insert into t1 (ldt) values ('2006-04-19 16:30:00'); +select * from t1; +# This should work without errors as well +select ldt, f1(udt) as ldt2 from t1; +drop table t1; +drop function f1; + +# End of 5.0 tests diff --git a/sql/tztime.cc b/sql/tztime.cc index b86c9a44561..079abfc9299 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1370,11 +1370,30 @@ static LS_INFO *tz_lsis= 0; static bool time_zone_tables_exist= 1; -typedef struct st_tz_names_entry: public Sql_alloc +/* + Names of tables (with their lengths) that are needed + for dynamical loading of time zone descriptions. +*/ + +static const LEX_STRING tz_tables_names[MY_TZ_TABLES_COUNT]= { + {(char *) STRING_WITH_LEN("time_zone_name")}, + {(char *) STRING_WITH_LEN("time_zone")}, + {(char *) STRING_WITH_LEN("time_zone_transition_type")}, + {(char *) STRING_WITH_LEN("time_zone_transition")} +}; + +/* Name of database to which those tables belong. */ + +static const LEX_STRING tz_tables_db_name= {(char *) STRING_WITH_LEN("mysql")}; + + +class Tz_names_entry: public Sql_alloc +{ +public: String name; Time_zone *tz; -} TZ_NAMES_ENTRY; +}; /* @@ -1382,7 +1401,7 @@ typedef struct st_tz_names_entry: public Sql_alloc they should obey C calling conventions. */ -extern "C" byte* my_tz_names_get_key(TZ_NAMES_ENTRY *entry, uint *length, +extern "C" byte* my_tz_names_get_key(Tz_names_entry *entry, uint *length, my_bool not_used __attribute__((unused))) { *length= entry->name.length(); @@ -1403,7 +1422,8 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, SYNOPSIS tz_init_table_list() - tz_tabs - pointer to preallocated array of 4 TABLE_LIST objects + tz_tabs - pointer to preallocated array of MY_TZ_TABLES_COUNT + TABLE_LIST objects global_next_ptr - pointer to variable which points to global_next member of last element of global table list (or list root then list is empty) (in/out). @@ -1418,27 +1438,27 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, static void tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr) { - bzero(tz_tabs, sizeof(TABLE_LIST) * 4); - tz_tabs[0].alias= tz_tabs[0].table_name= (char*)"time_zone_name"; - tz_tabs[1].alias= tz_tabs[1].table_name= (char*)"time_zone"; - tz_tabs[2].alias= tz_tabs[2].table_name= (char*)"time_zone_transition_type"; - tz_tabs[3].alias= tz_tabs[3].table_name= (char*)"time_zone_transition"; - tz_tabs[0].next_global= tz_tabs[0].next_local= tz_tabs+1; - tz_tabs[1].next_global= tz_tabs[1].next_local= tz_tabs+2; - tz_tabs[2].next_global= tz_tabs[2].next_local= tz_tabs+3; - tz_tabs[0].lock_type= tz_tabs[1].lock_type= tz_tabs[2].lock_type= - tz_tabs[3].lock_type= TL_READ; - tz_tabs[0].db= tz_tabs[1].db= tz_tabs[2].db= tz_tabs[3].db= (char *)"mysql"; + bzero(tz_tabs, sizeof(TABLE_LIST) * MY_TZ_TABLES_COUNT); + + for (int i= 0; i < MY_TZ_TABLES_COUNT; i++) + { + tz_tabs[i].alias= tz_tabs[i].table_name= tz_tables_names[i].str; + tz_tabs[i].table_name_length= tz_tables_names[i].length; + tz_tabs[i].db= tz_tables_db_name.str; + tz_tabs[i].db_length= tz_tables_db_name.length; + tz_tabs[i].lock_type= TL_READ; + + if (i != MY_TZ_TABLES_COUNT - 1) + tz_tabs[i].next_global= tz_tabs[i].next_local= &tz_tabs[i+1]; + if (i != 0) + tz_tabs[i].prev_global= &tz_tabs[i-1].next_global; + } /* Link into global list */ tz_tabs[0].prev_global= *global_next_ptr; - tz_tabs[1].prev_global= &tz_tabs[0].next_global; - tz_tabs[2].prev_global= &tz_tabs[1].next_global; - tz_tabs[3].prev_global= &tz_tabs[2].next_global; - **global_next_ptr= tz_tabs; /* Update last-global-pointer to point to pointer in last table */ - *global_next_ptr= &tz_tabs[3].next_global; + *global_next_ptr= &tz_tabs[MY_TZ_TABLES_COUNT-1].next_global; } @@ -1467,7 +1487,8 @@ TABLE_LIST fake_time_zone_tables_list; NOTE my_tz_check_n_skip_implicit_tables() function depends on fact that - elements of list created are allocated as TABLE_LIST[4] array. + elements of list created are allocated as TABLE_LIST[MY_TZ_TABLES_COUNT] + array. RETURN VALUES Returns pointer to first TABLE_LIST object, (could be 0 if time zone @@ -1483,7 +1504,8 @@ my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr) if (!time_zone_tables_exist) DBUG_RETURN(0); - if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 4))) + if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * + MY_TZ_TABLES_COUNT))) DBUG_RETURN(&fake_time_zone_tables_list); tz_init_table_list(tz_tabs, global_next_ptr); @@ -1522,9 +1544,9 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { THD *thd; TABLE_LIST *tables= 0; - TABLE_LIST tables_buff[5], **last_global_next_ptr; + TABLE_LIST tables_buff[1+MY_TZ_TABLES_COUNT], **last_global_next_ptr; TABLE *table; - TZ_NAMES_ENTRY *tmp_tzname; + Tz_names_entry *tmp_tzname; my_bool return_val= 1; int res; DBUG_ENTER("my_tz_init"); @@ -1556,7 +1578,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) tz_inited= 1; /* Add 'SYSTEM' time zone to tz_names hash */ - if (!(tmp_tzname= new (&tz_storage) TZ_NAMES_ENTRY())) + if (!(tmp_tzname= new (&tz_storage) Tz_names_entry())) { sql_print_error("Fatal error: OOM while initializing time zones"); goto end_with_cleanup; @@ -1752,7 +1774,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) { TABLE *table= 0; TIME_ZONE_INFO *tz_info; - TZ_NAMES_ENTRY *tmp_tzname; + Tz_names_entry *tmp_tzname; Time_zone *return_val= 0; int res; uint tzid, ttid; @@ -2027,7 +2049,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) } - if (!(tmp_tzname= new (&tz_storage) TZ_NAMES_ENTRY()) || + if (!(tmp_tzname= new (&tz_storage) Tz_names_entry()) || !(tmp_tzname->tz= new (&tz_storage) Time_zone_db(tz_info, &(tmp_tzname->name))) || (tmp_tzname->name.set(tz_name_buff, tz_name->length(), @@ -2174,7 +2196,7 @@ str_to_offset(const char *str, uint length, long *offset) Time_zone * my_tz_find(const String * name, TABLE_LIST *tz_tables) { - TZ_NAMES_ENTRY *tmp_tzname; + Tz_names_entry *tmp_tzname; Time_zone *result_tz= 0; long offset; @@ -2210,7 +2232,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables) else { result_tz= 0; - if ((tmp_tzname= (TZ_NAMES_ENTRY *)hash_search(&tz_names, + if ((tmp_tzname= (Tz_names_entry *)hash_search(&tz_names, (const byte *)name->ptr(), name->length()))) result_tz= tmp_tzname->tz; @@ -2262,7 +2284,7 @@ Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name) our time zone tables. Note that if we don't have tz tables on this slave, we don't even try. */ - TABLE_LIST tables[4]; + TABLE_LIST tables[MY_TZ_TABLES_COUNT]; TABLE_LIST *dummy; TABLE_LIST **dummyp= &dummy; tz_init_table_list(tables, &dummyp); diff --git a/sql/tztime.h b/sql/tztime.h index 23460a8e739..c49b9fe4592 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -68,6 +68,15 @@ extern void my_tz_free(); extern TABLE_LIST fake_time_zone_tables_list; +/* + Number of elements in table list produced by my_tz_get_table_list() + (this table list contains tables which are needed for dynamical loading + of time zone descriptions). Actually it is imlementation detail that + should not be used anywhere outside of tztime.h and tztime.cc. +*/ + +static const int MY_TZ_TABLES_COUNT= 4; + /* Check if we have pointer to the begining of list of implicitly used time zone tables, set SELECT_ACL for them and fast-forward to its end. @@ -90,9 +99,9 @@ inline bool my_tz_check_n_skip_implicit_tables(TABLE_LIST **table, { if (*table == tz_tables) { - for (int i= 0; i < 4; i++) + for (int i= 0; i < MY_TZ_TABLES_COUNT; i++) (*table)[i].grant.privilege= SELECT_ACL; - (*table)+= 3; + (*table)+= MY_TZ_TABLES_COUNT - 1; return TRUE; } return FALSE; From f28b9a34235b08f72bf3c2b8de85227958cac17d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Apr 2006 04:27:23 +0400 Subject: [PATCH 03/15] A fix and a test case for Bug#19308 "REPAIR/OPTIMIZE/ANALYZE supported in SP but not in PS": just enable them in prepared statements, the supporting functionality was implemented when they were enabled in stored procedures. mysql-test/r/ps.result: Bug#19308: test results fixed. mysql-test/r/ps_1general.result: Adjust existing test cases (ANALYZE/OPTIMIZE/REPAIR are now allowed in prepared statements. mysql-test/r/sp-dynamic.result: Adjust existing test cases (ANALYZE/OPTIMIZE/REPAIR are now allowed in prepared statements. mysql-test/t/ps.test: Add a test case for Bug#19308 "REPAIR/OPTIMIZE/ANALYZE supported in SP but not in PS" mysql-test/t/ps_1general.test: Adjust existing test cases (ANALYZE/OPTIMIZE/REPAIR are now allowed in prepared statements. sql/sql_prepare.cc: Enable ANALYZE, OPTIMIZE, REPAIR in prepared statements. --- mysql-test/r/ps.result | 101 ++++++++++++++++++++++++++++++++ mysql-test/r/ps_1general.result | 3 - mysql-test/r/sp-dynamic.result | 6 +- mysql-test/t/ps.test | 36 ++++++++++++ mysql-test/t/ps_1general.test | 3 - sql/sql_prepare.cc | 3 + 6 files changed, 143 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index b29185eaaea..fccaa9b1b66 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1056,3 +1056,104 @@ a b 1 9 3 7 drop table t1; +create table t1 (a int); +create table t2 like t1; +create table t3 like t2; +prepare stmt from "repair table t1"; +execute stmt; +Table Op Msg_type Msg_text +test.t1 repair status OK +execute stmt; +Table Op Msg_type Msg_text +test.t1 repair status OK +prepare stmt from "optimize table t1"; +execute stmt; +Table Op Msg_type Msg_text +test.t1 optimize status OK +execute stmt; +Table Op Msg_type Msg_text +test.t1 optimize status Table is already up to date +prepare stmt from "analyze table t1"; +execute stmt; +Table Op Msg_type Msg_text +test.t1 analyze status Table is already up to date +execute stmt; +Table Op Msg_type Msg_text +test.t1 analyze status Table is already up to date +prepare stmt from "repair table t1, t2, t3"; +execute stmt; +Table Op Msg_type Msg_text +test.t1 repair status OK +test.t2 repair status OK +test.t3 repair status OK +execute stmt; +Table Op Msg_type Msg_text +test.t1 repair status OK +test.t2 repair status OK +test.t3 repair status OK +prepare stmt from "optimize table t1, t2, t3"; +execute stmt; +Table Op Msg_type Msg_text +test.t1 optimize status OK +test.t2 optimize status OK +test.t3 optimize status OK +execute stmt; +Table Op Msg_type Msg_text +test.t1 optimize status Table is already up to date +test.t2 optimize status Table is already up to date +test.t3 optimize status Table is already up to date +prepare stmt from "analyze table t1, t2, t3"; +execute stmt; +Table Op Msg_type Msg_text +test.t1 analyze status Table is already up to date +test.t2 analyze status Table is already up to date +test.t3 analyze status Table is already up to date +execute stmt; +Table Op Msg_type Msg_text +test.t1 analyze status Table is already up to date +test.t2 analyze status Table is already up to date +test.t3 analyze status Table is already up to date +prepare stmt from "repair table t1, t4, t3"; +execute stmt; +Table Op Msg_type Msg_text +test.t1 repair status OK +test.t4 repair error Table 'test.t4' doesn't exist +test.t3 repair status OK +Warnings: +Error 1146 Table 'test.t4' doesn't exist +execute stmt; +Table Op Msg_type Msg_text +test.t1 repair status OK +test.t4 repair error Table 'test.t4' doesn't exist +test.t3 repair status OK +Warnings: +Error 1146 Table 'test.t4' doesn't exist +prepare stmt from "optimize table t1, t3, t4"; +execute stmt; +Table Op Msg_type Msg_text +test.t1 optimize status OK +test.t3 optimize status OK +test.t4 optimize error Table 'test.t4' doesn't exist +Warnings: +Error 1146 Table 'test.t4' doesn't exist +execute stmt; +Table Op Msg_type Msg_text +test.t1 optimize status Table is already up to date +test.t3 optimize status Table is already up to date +test.t4 optimize error Table 'test.t4' doesn't exist +Warnings: +Error 1146 Table 'test.t4' doesn't exist +prepare stmt from "analyze table t4, t1"; +execute stmt; +Table Op Msg_type Msg_text +test.t4 analyze error Table 'test.t4' doesn't exist +test.t1 analyze status Table is already up to date +Warnings: +Error 1146 Table 'test.t4' doesn't exist +execute stmt; +Table Op Msg_type Msg_text +test.t4 analyze error Table 'test.t4' doesn't exist +test.t1 analyze status Table is already up to date +Warnings: +Error 1146 Table 'test.t4' doesn't exist +deallocate prepare stmt; diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 8e22c5daa8e..3c736a508d3 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -422,13 +422,10 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye prepare stmt1 from ' select * into outfile ''data.txt'' from t1 '; execute stmt1 ; prepare stmt1 from ' optimize table t1 ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' analyze table t1 ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' checksum table t1 ' ; ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' repair table t1 ' ; -ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' restore table t1 from ''data.txt'' ' ; ERROR HY000: This command is not supported in the prepared statement protocol yet prepare stmt1 from ' handler t1 open '; diff --git a/mysql-test/r/sp-dynamic.result b/mysql-test/r/sp-dynamic.result index c00b09f90e1..d9d5706cded 100644 --- a/mysql-test/r/sp-dynamic.result +++ b/mysql-test/r/sp-dynamic.result @@ -286,12 +286,12 @@ id stmt_text status 1 select 1 supported 2 flush tables not supported 3 handler t1 open as ha not supported -4 analyze table t1 not supported +4 analyze table t1 supported 5 check table t1 not supported 6 checksum table t1 not supported 7 check table t1 not supported -8 optimize table t1 not supported -9 repair table t1 not supported +8 optimize table t1 supported +9 repair table t1 supported 10 describe extended select * from t1 supported 11 help help not supported 12 show databases supported diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 1f5f17fe976..cc7d7ef2d82 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1110,4 +1110,40 @@ select * from t1 order by 1+1; drop table t1; +# +# Bug#19308 "REPAIR/OPTIMIZE/ANALYZE supported in SP but not in PS". +# Add test coverage for the added commands. +# +create table t1 (a int); +create table t2 like t1; +create table t3 like t2; +prepare stmt from "repair table t1"; +execute stmt; +execute stmt; +prepare stmt from "optimize table t1"; +execute stmt; +execute stmt; +prepare stmt from "analyze table t1"; +execute stmt; +execute stmt; +prepare stmt from "repair table t1, t2, t3"; +execute stmt; +execute stmt; +prepare stmt from "optimize table t1, t2, t3"; +execute stmt; +execute stmt; +prepare stmt from "analyze table t1, t2, t3"; +execute stmt; +execute stmt; +prepare stmt from "repair table t1, t4, t3"; +execute stmt; +execute stmt; +prepare stmt from "optimize table t1, t3, t4"; +execute stmt; +execute stmt; +prepare stmt from "analyze table t4, t1"; +execute stmt; +execute stmt; +deallocate prepare stmt; + # End of 5.0 tests diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 89fad3fa4fb..72b69fc8d9f 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -453,13 +453,10 @@ into table t1 fields terminated by ''\t'' '; prepare stmt1 from ' select * into outfile ''data.txt'' from t1 '; execute stmt1 ; ## ---error 1295 prepare stmt1 from ' optimize table t1 ' ; ---error 1295 prepare stmt1 from ' analyze table t1 ' ; --error 1295 prepare stmt1 from ' checksum table t1 ' ; ---error 1295 prepare stmt1 from ' repair table t1 ' ; --error 1295 prepare stmt1 from ' restore table t1 from ''data.txt'' ' ; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 4fa0a2dcb6e..f7935a55572 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1753,6 +1753,9 @@ static bool check_prepared_statement(Prepared_statement *stmt, case SQLCOM_CALL: case SQLCOM_CREATE_VIEW: case SQLCOM_DROP_VIEW: + case SQLCOM_REPAIR: + case SQLCOM_ANALYZE: + case SQLCOM_OPTIMIZE: break; default: From 3010890e589de89d2f5bb4c0e2c3a0b06b827b10 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 May 2006 22:10:50 -0400 Subject: [PATCH 04/15] SECURITY FIX Bug#17667: An attacker has the opportunity to bypass query logging. This adds a new, local-only printf format specifier to our *printf functions that allows us to print known-size buffers that must not be interpreted as NUL-terminated "strings." It uses this format-specifier to print to the log, thus fixing this problem. include/my_sys.h: Add prototype for my_memmem() . mysys/Makefile.am: Add reference to new file, my_memmem.c mysys/mf_iocache2.c: Add a "%.1234b" and "%.*b" percent-code. It takes a width, just like "%s", but unlike the string-indicator, it requires the width and doesn't stop printing at NUL characters. Also, simplify the code a bit. TODO: This code should be unified with the strings/my_vnsprintf.c code in the future. sql/sql_parse.cc: The query is not a C-string, but is a sized buffer, containing any character at all, which may include NUL characters. strings/my_vsnprintf.c: Add a "%.1234b" and "%.*b" percent-code. It takes a width, just like "%s", but unlike the string-indicator, it requires the width and doesn't stop printing at NUL characters. tests/Makefile.am: We may need some of our local functions. tests/mysql_client_test.c: Add a "%.1234b" and "%.*b" percent-code. It takes a width, just like "%s", but unlike the string-indicator, it requires the width and doesn't stop printing at NUL characters. mysql-test/t/mysql_client_test.opt: New BitKeeper file ``mysql-test/t/mysql_client_test.opt'' Add '--log' server parameter. mysys/my_memmem.c: New BitKeeper file ``mysys/my_memmem.c'' Implement memmem, a black-box work-alike of the GNU memmem(), which functions like strstr() but for arbitrary blocks of memory. --- include/my_sys.h | 5 ++ mysql-test/t/mysql_client_test.opt | 1 + mysys/Makefile.am | 1 + mysys/mf_iocache2.c | 92 +++++++++++++++++++++++------- mysys/my_memmem.c | 65 +++++++++++++++++++++ sql/sql_parse.cc | 2 +- strings/my_vsnprintf.c | 9 ++- tests/Makefile.am | 2 +- tests/mysql_client_test.c | 66 +++++++++++++++++++++ 9 files changed, 220 insertions(+), 23 deletions(-) create mode 100644 mysql-test/t/mysql_client_test.opt create mode 100644 mysys/my_memmem.c diff --git a/include/my_sys.h b/include/my_sys.h index 44fe383bf4f..65a295ee39e 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -599,6 +599,11 @@ extern char *_my_strdup_with_length(const byte *from, uint length, const char *sFile, uint uLine, myf MyFlag); +/* implemented in my_memmem.c */ +extern void *my_memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen); + + #ifdef __WIN__ extern int my_access(const char *path, int amode); extern File my_sopen(const char *path, int oflag, int shflag, int pmode); diff --git a/mysql-test/t/mysql_client_test.opt b/mysql-test/t/mysql_client_test.opt new file mode 100644 index 00000000000..968ba95c6cc --- /dev/null +++ b/mysql-test/t/mysql_client_test.opt @@ -0,0 +1 @@ +--log diff --git a/mysys/Makefile.am b/mysys/Makefile.am index ee0dcb544b6..d9de36d4e45 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -55,6 +55,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_handler.c my_netware.c my_largepage.c \ + my_memmem.c \ my_windac.c my_access.c base64.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c index e181ccfb88d..f1ea21c2a47 100644 --- a/mysys/mf_iocache2.c +++ b/mysys/mf_iocache2.c @@ -252,37 +252,89 @@ uint my_b_printf(IO_CACHE *info, const char* fmt, ...) uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) { uint out_length=0; + uint minimum_width; /* as yet unimplemented */ + uint minimum_width_sign; + uint precision; /* as yet unimplemented for anything but %b */ - for (; *fmt ; fmt++) + /* + Store the location of the beginning of a format directive, for the + case where we learn we shouldn't have been parsing a format string + at all, and we don't want to lose the flag/precision/width/size + information. + */ + const char* backtrack; + + for (; *fmt != '\0'; fmt++) { - if (*fmt++ != '%') + /* Copy everything until '%' or end of string */ + const char *start=fmt; + uint length; + + for (; (*fmt != '\0') && (*fmt != '%'); fmt++) ; + + length= (uint) (fmt - start); + out_length+=length; + if (my_b_write(info, start, length)) + goto err; + + if (*fmt == '\0') /* End of format */ { - /* Copy everything until '%' or end of string */ - const char *start=fmt-1; - uint length; - for (; *fmt && *fmt != '%' ; fmt++ ) ; - length= (uint) (fmt - start); - out_length+=length; - if (my_b_write(info, start, length)) - goto err; - if (!*fmt) /* End of format */ - { - return out_length; - } - fmt++; - /* Found one '%' */ + return out_length; } + + /* + By this point, *fmt must be a percent; Keep track of this location and + skip over the percent character. + */ + DBUG_ASSERT(*fmt == '%'); + backtrack= fmt; + fmt++; + + minimum_width= 0; + precision= 0; + minimum_width_sign= 1; /* Skip if max size is used (to be compatible with printf) */ - while (my_isdigit(&my_charset_latin1, *fmt) || *fmt == '.' || *fmt == '-') + while (*fmt == '-') { fmt++; minimum_width_sign= -1; } + if (*fmt == '*') { + precision= (int) va_arg(args, int); fmt++; + } else { + while (my_isdigit(&my_charset_latin1, *fmt)) { + minimum_width=(minimum_width * 10) + (*fmt - '0'); + fmt++; + } + } + minimum_width*= minimum_width_sign; + + if (*fmt == '.') { + fmt++; + if (*fmt == '*') { + precision= (int) va_arg(args, int); + fmt++; + } else { + while (my_isdigit(&my_charset_latin1, *fmt)) { + precision=(precision * 10) + (*fmt - '0'); + fmt++; + } + } + } + if (*fmt == 's') /* String parameter */ { reg2 char *par = va_arg(args, char *); uint length = (uint) strlen(par); + /* TODO: implement minimum width and precision */ out_length+=length; if (my_b_write(info, par, length)) goto err; } + else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */ + { + char *par = va_arg(args, char *); + out_length+= precision; + if (my_b_write(info, par, precision)) + goto err; + } else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ { register int iarg; @@ -317,9 +369,9 @@ uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args) else { /* %% or unknown code */ - if (my_b_write(info, "%", 1)) - goto err; - out_length++; + if (my_b_write(info, backtrack, fmt-backtrack)) + goto err; + out_length+= fmt-backtrack; } } return out_length; diff --git a/mysys/my_memmem.c b/mysys/my_memmem.c new file mode 100644 index 00000000000..3a71d39c262 --- /dev/null +++ b/mysys/my_memmem.c @@ -0,0 +1,65 @@ +#include "my_base.h" + +/* + my_memmem, port of a GNU extension. + + Returns a pointer to the beginning of the substring, needle, or NULL if the + substring is not found in haystack. +*/ +void *my_memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen) +{ + const void *cursor; + const void *last_possible_needle_location = haystack + haystacklen - needlelen; + + /* Easy answers */ + if (needlelen > haystacklen) return(NULL); + if (needle == NULL) return(NULL); + if (haystack == NULL) return(NULL); + if (needlelen == 0) return(NULL); + if (haystacklen == 0) return(NULL); + + for (cursor = haystack; cursor <= last_possible_needle_location; cursor++) { + if (memcmp(needle, cursor, needlelen) == 0) { + return((void *) cursor); + } + } + return(NULL); +} + + + +#ifdef MAIN +#include + +int main(int argc, char *argv[]) { + char haystack[10], needle[3]; + + memmove(haystack, "0123456789", 10); + + memmove(needle, "no", 2); + assert(my_memmem(haystack, 10, needle, 2) == NULL); + + memmove(needle, "345", 3); + assert(my_memmem(haystack, 10, needle, 3) != NULL); + + memmove(needle, "789", 3); + assert(my_memmem(haystack, 10, needle, 3) != NULL); + assert(my_memmem(haystack, 9, needle, 3) == NULL); + + memmove(needle, "012", 3); + assert(my_memmem(haystack, 10, needle, 3) != NULL); + assert(my_memmem(NULL, 10, needle, 3) == NULL); + + assert(my_memmem(NULL, 10, needle, 3) == NULL); + assert(my_memmem(haystack, 0, needle, 3) == NULL); + assert(my_memmem(haystack, 10, NULL, 3) == NULL); + assert(my_memmem(haystack, 10, needle, 0) == NULL); + + assert(my_memmem(haystack, 1, needle, 3) == NULL); + + printf("success\n"); + return(0); +} + +#endif diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f9d04fc873e..ce8f6012824 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1711,7 +1711,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (alloc_query(thd, packet, packet_length)) break; // fatal error is set char *packet_end= thd->query + thd->query_length; - mysql_log.write(thd,command,"%s",thd->query); + mysql_log.write(thd,command, "%.*b", thd->query_length, thd->query); DBUG_PRINT("query",("%-.4096s",thd->query)); if (!(specialflag & SPECIAL_NO_PRIOR)) diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 0e036c2bbcd..d917e9e11b2 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -27,6 +27,7 @@ %#[l]d %#[l]u %#[l]x + %#.#b Local format; note first # is ignored and second is REQUIRED %#.#s Note first # is ignored RETURN @@ -40,7 +41,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) for (; *fmt ; fmt++) { - if (fmt[0] != '%') + if (*fmt != '%') { if (to == end) /* End of buffer */ break; @@ -95,6 +96,12 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) to=strnmov(to,par,plen); continue; } + else if (*fmt == 'b') /* Buffer parameter */ + { + char *par = va_arg(ap, char *); + to=memmove(to, par, abs(width)); + continue; + } else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */ { register long larg; diff --git a/tests/Makefile.am b/tests/Makefile.am index 131f8b1b625..ec732462ca5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,7 +42,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ LIBS = @CLIENT_LIBS@ LDADD = @CLIENT_EXTRA_LDFLAGS@ \ $(top_builddir)/libmysql/libmysqlclient.la -mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) +mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -lmysys -L../mysys mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix) insert_test_SOURCES= insert_test.c $(yassl_dummy_link_fix) select_test_SOURCES= select_test.c $(yassl_dummy_link_fix) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b1ea5f8ea06..4bd636a7ae3 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -14822,6 +14822,71 @@ static void test_bug15613() mysql_stmt_close(stmt); } +/* + Bug#17667: An attacker has the opportunity to bypass query logging. +*/ +static void test_bug17667() +{ + int rc; + myheader("test_bug17667"); + struct buffer_and_length { + const char *buffer; + const uint length; + } statements[]= { + { "drop table if exists bug17667", 29 }, + { "create table bug17667 (c varchar(20))", 37 }, + { "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 }, + { "insert into bug17667 (c) values ('NUL=\0 in value')", 50 }, + { "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 }, + { "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 }, + { "drop table bug17667", 19 }, + { NULL, 0 } }; + + struct buffer_and_length *statement_cursor; + FILE *log_file; + + for (statement_cursor= statements; statement_cursor->buffer != NULL; + statement_cursor++) { + rc= mysql_real_query(mysql, statement_cursor->buffer, + statement_cursor->length); + myquery(rc); + } + + sleep(1); /* The server may need time to flush the data to the log. */ + log_file= fopen("var/log/master.log", "r"); + if (log_file != NULL) { + + for (statement_cursor= statements; statement_cursor->buffer != NULL; + statement_cursor++) { + char line_buffer[MAX_TEST_QUERY_LENGTH*2]; + /* more than enough room for the query and some marginalia. */ + + do { + memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2); + + DIE_UNLESS(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) != + NULL); + /* If we reach EOF before finishing the statement list, then we failed. */ + + } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2, + statement_cursor->buffer, statement_cursor->length) == NULL); + } + + printf("success. All queries found intact in the log.\n"); + + } else { + fprintf(stderr, "Could not find the log file, var/log/master.log, so " + "test_bug17667 is \ninconclusive. Run test from the " + "mysql-test/mysql-test-run* program \nto set up the correct " + "environment for this test.\n\n"); + } + + if (log_file != NULL) + fclose(log_file); + +} + + /* Bug#14169: type of group_concat() result changed to blob if tmp_table was used */ @@ -15121,6 +15186,7 @@ static struct my_tests_st my_tests[]= { { "test_bug16143", test_bug16143 }, { "test_bug15613", test_bug15613 }, { "test_bug14169", test_bug14169 }, + { "test_bug17667", test_bug17667 }, { 0, 0 } }; From 521d6b3dab546f2d84dc6347afae5a115999b0bc Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 08:59:49 +0500 Subject: [PATCH 05/15] Win build fix --- client/mysql_upgrade.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 551be79fc99..3288b627554 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -307,7 +307,7 @@ int main(int argc, char **argv) b_read= my_read(check_file, chf_buffer, sizeof(chf_buffer)-1, MYF(0)); chf_buffer[b_read]= 0; my_close(check_file, MYF(0)); - if (!strcmp(chf_buffer, VERSION)) + if (!strcmp(chf_buffer, MYSQL_SERVER_VERSION)) { if (opt_verbose) puts("mysql_upgrade already done for this version"); From 33417297c5e11ff82aae7bc2d8b5a75968725905 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 09:19:54 +0200 Subject: [PATCH 06/15] Fix a bunch of non-Linux compile failures. VC++Files/mysql.sln: mysql_client_test depends on mysys. VC++Files/mysys/mysys.vcproj: Add new file missing in previous push. mysys/my_memmem.c: Fix illegal pointer arithmetics on void *. tests/Makefile.am: -L must go before -l tests/mysql_client_test.c: No declarations after statement in C code. --- VC++Files/mysql.sln | 1 + VC++Files/mysys/mysys.vcproj | 43 ++++++++++++++++++++++++++++++++++++ mysys/my_memmem.c | 5 +++-- tests/Makefile.am | 2 +- tests/mysql_client_test.c | 3 ++- 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/VC++Files/mysql.sln b/VC++Files/mysql.sln index 14f16f8fd8d..3e3e4c67e17 100644 --- a/VC++Files/mysql.sln +++ b/VC++Files/mysql.sln @@ -278,6 +278,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_client_test", "tests\mysql_client_test.vcproj", "{DA224DAB-5006-42BE-BB77-16E8BE5326D5}" ProjectSection(ProjectDependencies) = postProject {26383276-4843-494B-8BE0-8936ED3EBAAB} = {26383276-4843-494B-8BE0-8936ED3EBAAB} + {44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_test_run_new", "mysql-test\mysql_test_run_new.vcproj", "{6189F838-21C6-42A1-B2D0-9146316573F7}" diff --git a/VC++Files/mysys/mysys.vcproj b/VC++Files/mysys/mysys.vcproj index d124551e0bb..1053b605119 100644 --- a/VC++Files/mysys/mysys.vcproj +++ b/VC++Files/mysys/mysys.vcproj @@ -3188,6 +3188,49 @@ PreprocessorDefinitions=""/> + + + + + + + + + + + + + + + + + haystacklen) return(NULL); diff --git a/tests/Makefile.am b/tests/Makefile.am index ec732462ca5..ebe97393045 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,7 +42,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ LIBS = @CLIENT_LIBS@ LDADD = @CLIENT_EXTRA_LDFLAGS@ \ $(top_builddir)/libmysql/libmysqlclient.la -mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -lmysys -L../mysys +mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -L../mysys -lmysys mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix) insert_test_SOURCES= insert_test.c $(yassl_dummy_link_fix) select_test_SOURCES= select_test.c $(yassl_dummy_link_fix) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 4bd636a7ae3..b0971980168 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -14828,7 +14828,6 @@ static void test_bug15613() static void test_bug17667() { int rc; - myheader("test_bug17667"); struct buffer_and_length { const char *buffer; const uint length; @@ -14845,6 +14844,8 @@ static void test_bug17667() struct buffer_and_length *statement_cursor; FILE *log_file; + myheader("test_bug17667"); + for (statement_cursor= statements; statement_cursor->buffer != NULL; statement_cursor++) { rc= mysql_real_query(mysql, statement_cursor->buffer, From 79cc1546b23f757266dc2f4ed67317865c9d0f2f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 16:31:39 +0500 Subject: [PATCH 07/15] WL#2257 REFERENTIAL_CONSTRAINTS view added I_S.REFARENTIAL_CONSTRAINTS table mysql-test/r/information_schema.result: WL#2257 REFERENTIAL_CONSTRAINTS view result fix mysql-test/r/information_schema_db.result: WL#2257 REFERENTIAL_CONSTRAINTS view result fix mysql-test/r/information_schema_inno.result: WL#2257 REFERENTIAL_CONSTRAINTS view test case mysql-test/t/information_schema_inno.test: WL#2257 REFERENTIAL_CONSTRAINTS view test case sql/ha_innodb.cc: WL#2257 REFERENTIAL_CONSTRAINTS view --- mysql-test/r/information_schema.result | 6 +- mysql-test/r/information_schema_db.result | 1 + mysql-test/r/information_schema_inno.result | 31 ++++++++ mysql-test/t/information_schema_inno.test | 32 ++++++++ sql/ha_innodb.cc | 77 +++++++++++------- sql/sql_show.cc | 88 +++++++++++++++++++++ sql/table.h | 4 +- 7 files changed, 208 insertions(+), 31 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 5e915b5742c..002e444acca 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -50,6 +50,7 @@ KEY_COLUMN_USAGE PARTITIONS PLUGINS PROCESSLIST +REFERENTIAL_CONSTRAINTS ROUTINES SCHEMATA SCHEMA_PRIVILEGES @@ -745,7 +746,7 @@ CREATE TABLE t_crashme ( f1 BIGINT); CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1; CREATE VIEW a2 AS SELECT t_CRASHME FROM a1; count(*) -112 +113 drop view a2, a1; drop table t_crashme; select table_schema,table_name, column_name from @@ -832,6 +833,7 @@ COLUMN_PRIVILEGES TABLE_NAME select FILES TABLE_NAME select KEY_COLUMN_USAGE TABLE_NAME select PARTITIONS TABLE_NAME select +REFERENTIAL_CONSTRAINTS TABLE_NAME select STATISTICS TABLE_NAME select TABLES TABLE_NAME select TABLE_CONSTRAINTS TABLE_NAME select @@ -843,7 +845,7 @@ flush privileges; SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA; table_schema count(*) cluster 1 -information_schema 22 +information_schema 23 mysql 21 create table t1 (i int, j int); create trigger trg1 before insert on t1 for each row diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index 584e1701a14..37537e257da 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -13,6 +13,7 @@ KEY_COLUMN_USAGE PARTITIONS PLUGINS PROCESSLIST +REFERENTIAL_CONSTRAINTS ROUTINES SCHEMATA SCHEMA_PRIVILEGES diff --git a/mysql-test/r/information_schema_inno.result b/mysql-test/r/information_schema_inno.result index fb6584673f6..9bb3185c6fb 100644 --- a/mysql-test/r/information_schema_inno.result +++ b/mysql-test/r/information_schema_inno.result @@ -25,3 +25,34 @@ NULL test PRIMARY NULL test t3 id 1 NULL NULL NULL NULL NULL test t3_ibfk_1 NULL test t3 id 1 1 test t2 t1_id NULL test t3_ibfk_1 NULL test t3 t2_id 2 2 test t2 id drop table t3, t2, t1; +CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL, +PRIMARY KEY(a1, a2)) ENGINE=INNODB; +CREATE TABLE t2(b1 INT, b2 INT, INDEX (b1, b2), +CONSTRAINT A1 +FOREIGN KEY (b1, b2) REFERENCES t1(a1, a2) +ON UPDATE CASCADE ON DELETE NO ACTION) ENGINE=INNODB; +CREATE TABLE t3(b1 INT, b2 INT, INDEX (b1, b2), +CONSTRAINT A2 +FOREIGN KEY (b1, b2) REFERENCES t2(b1, b2) +ON UPDATE SET NULL ON DELETE RESTRICT) ENGINE=INNODB; +CREATE TABLE t4(b1 INT, b2 INT, INDEX (b1, b2), +CONSTRAINT A3 +FOREIGN KEY (b1, b2) REFERENCES t3(b1, b2) +ON UPDATE NO ACTION ON DELETE SET NULL) ENGINE=INNODB; +CREATE TABLE t5(b1 INT, b2 INT, INDEX (b1, b2), +CONSTRAINT A4 +FOREIGN KEY (b1, b2) REFERENCES t4(b1, b2) +ON UPDATE RESTRICT ON DELETE CASCADE) ENGINE=INNODB; +select a.CONSTRAINT_SCHEMA, b.TABLE_NAME, CONSTRAINT_TYPE, +b.CONSTRAINT_NAME, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME, +MATCH_OPTION, UPDATE_RULE, DELETE_RULE +from information_schema.TABLE_CONSTRAINTS a, +information_schema.REFERENTIAL_CONSTRAINTS b +where a.CONSTRAINT_SCHEMA = 'test' and a.CONSTRAINT_SCHEMA = b.CONSTRAINT_SCHEMA and +a.CONSTRAINT_NAME = b.CONSTRAINT_NAME; +CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_NAME UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE +test t2 FOREIGN KEY A1 test t1 NONE CASCADE NO ACTION +test t3 FOREIGN KEY A2 test t2 NONE SET NULL RESTRICT +test t4 FOREIGN KEY A3 test t3 NONE NO ACTION SET NULL +test t5 FOREIGN KEY A4 test t4 NONE RESTRICT CASCADE +drop tables t5, t4, t3, t2, t1; diff --git a/mysql-test/t/information_schema_inno.test b/mysql-test/t/information_schema_inno.test index 9cd64a54ad9..195bf57a880 100644 --- a/mysql-test/t/information_schema_inno.test +++ b/mysql-test/t/information_schema_inno.test @@ -21,3 +21,35 @@ select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; drop table t3, t2, t1; + +# +# Test for REFERENTIAL_CONSTRAINTS table +# +CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL, + PRIMARY KEY(a1, a2)) ENGINE=INNODB; +CREATE TABLE t2(b1 INT, b2 INT, INDEX (b1, b2), + CONSTRAINT A1 + FOREIGN KEY (b1, b2) REFERENCES t1(a1, a2) + ON UPDATE CASCADE ON DELETE NO ACTION) ENGINE=INNODB; +CREATE TABLE t3(b1 INT, b2 INT, INDEX (b1, b2), + CONSTRAINT A2 + FOREIGN KEY (b1, b2) REFERENCES t2(b1, b2) + ON UPDATE SET NULL ON DELETE RESTRICT) ENGINE=INNODB; +CREATE TABLE t4(b1 INT, b2 INT, INDEX (b1, b2), + CONSTRAINT A3 + FOREIGN KEY (b1, b2) REFERENCES t3(b1, b2) + ON UPDATE NO ACTION ON DELETE SET NULL) ENGINE=INNODB; +CREATE TABLE t5(b1 INT, b2 INT, INDEX (b1, b2), + CONSTRAINT A4 + FOREIGN KEY (b1, b2) REFERENCES t4(b1, b2) + ON UPDATE RESTRICT ON DELETE CASCADE) ENGINE=INNODB; + + +select a.CONSTRAINT_SCHEMA, b.TABLE_NAME, CONSTRAINT_TYPE, + b.CONSTRAINT_NAME, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME, + MATCH_OPTION, UPDATE_RULE, DELETE_RULE +from information_schema.TABLE_CONSTRAINTS a, + information_schema.REFERENTIAL_CONSTRAINTS b +where a.CONSTRAINT_SCHEMA = 'test' and a.CONSTRAINT_SCHEMA = b.CONSTRAINT_SCHEMA and +a.CONSTRAINT_NAME = b.CONSTRAINT_NAME; +drop tables t5, t4, t3, t2, t1; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 42def845174..a02361a0eac 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -5827,34 +5827,55 @@ ha_innobase::get_foreign_key_list(THD *thd, List *f_key_list) break; } - ulong length= 0; - if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { - length=17; - tmp_buff= "ON DELETE CASCADE"; - } - else if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { - length=18; - tmp_buff= "ON DELETE SET NULL"; - } - else if (foreign->type == DICT_FOREIGN_ON_DELETE_NO_ACTION) { - length=19; - tmp_buff= "ON DELETE NO ACTION"; - } - else if (foreign->type == DICT_FOREIGN_ON_UPDATE_CASCADE) { - length=17; - tmp_buff= "ON UPDATE CASCADE"; - } - else if (foreign->type == DICT_FOREIGN_ON_UPDATE_SET_NULL) { - length=18; - tmp_buff= "ON UPDATE SET NULL"; - } - else if (foreign->type == DICT_FOREIGN_ON_UPDATE_NO_ACTION) { - length=19; - tmp_buff= "ON UPDATE NO ACTION"; - } - f_key_info.constraint_method= make_lex_string(thd, - f_key_info.constraint_method, - tmp_buff, length, 1); + ulong length; + if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) + { + length=7; + tmp_buff= "CASCADE"; + } + else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) + { + length=8; + tmp_buff= "SET NULL"; + } + else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) + { + length=9; + tmp_buff= "NO ACTION"; + } + else + { + length=8; + tmp_buff= "RESTRICT"; + } + f_key_info.delete_method= make_lex_string(thd, f_key_info.delete_method, + tmp_buff, length, 1); + + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) + { + length=7; + tmp_buff= "CASCADE"; + } + else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) + { + length=8; + tmp_buff= "SET NULL"; + } + else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) + { + length=9; + tmp_buff= "NO ACTION"; + } + else + { + length=8; + tmp_buff= "RESTRICT"; + } + f_key_info.update_method= make_lex_string(thd, f_key_info.update_method, + tmp_buff, length, 1); + + FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *) thd->memdup((gptr) &f_key_info, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 95433828a1e..5e54040f0ae 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4231,6 +4231,75 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) } +/* + Fill and store records into I_S.referential_constraints table + + SYNOPSIS + get_referential_constraints_record() + thd thread handle + tables table list struct(processed table) + table I_S table + res 1 means the error during opening of the processed table + 0 means processed table is opened without error + base_name db name + file_name table name + + RETURN + 0 ok + # error +*/ + +static int +get_referential_constraints_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, const char *file_name) +{ + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_referential_constraints_record"); + + if (res) + { + if (!tables->view) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + thd->net.last_errno, thd->net.last_error); + thd->clear_error(); + DBUG_RETURN(0); + } + if (!tables->view) + { + List f_key_list; + TABLE *show_table= tables->table; + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); + + show_table->file->get_foreign_key_list(thd, &f_key_list); + FOREIGN_KEY_INFO *f_key_info; + List_iterator_fast it(f_key_list); + while ((f_key_info= it++)) + { + restore_record(table, s->default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[9]->store(file_name, strlen(file_name), cs); + table->field[2]->store(f_key_info->forein_id->str, + f_key_info->forein_id->length, cs); + table->field[4]->store(f_key_info->referenced_db->str, + f_key_info->referenced_db->length, cs); + table->field[5]->store(f_key_info->referenced_table->str, + f_key_info->referenced_table->length, cs); + table->field[6]->store(STRING_WITH_LEN("NONE"), cs); + table->field[7]->store(f_key_info->update_method->str, + f_key_info->update_method->length, cs); + table->field[8]->store(f_key_info->delete_method->str, + f_key_info->delete_method->length, cs); + if (schema_table_store_record(thd, table)) + DBUG_RETURN(1); + } + } + DBUG_RETURN(0); +} + + /* Find schema_tables elment by name @@ -5160,6 +5229,22 @@ ST_FIELD_INFO files_fields_info[]= {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; +ST_FIELD_INFO referential_constraints_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}, + {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, + {"UNIQUE_CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"UNIQUE_CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"MATCH_OPTION", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"UPDATE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"DELETE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} +}; + + /* Description of ST_FIELD_INFO in table.h @@ -5195,6 +5280,9 @@ ST_SCHEMA_TABLE schema_tables[]= fill_plugins, make_old_format, 0, -1, -1, 0}, {"PROCESSLIST", processlist_fields_info, create_schema_table, fill_schema_processlist, make_old_format, 0, -1, -1, 0}, + {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info, + create_schema_table, get_all_tables, 0, get_referential_constraints_record, + 1, 9, 0}, {"ROUTINES", proc_fields_info, create_schema_table, fill_schema_proc, make_proc_old_format, 0, -1, -1, 0}, {"SCHEMATA", schema_fields_info, create_schema_table, diff --git a/sql/table.h b/sql/table.h index aec9a7115e6..85d49444b29 100644 --- a/sql/table.h +++ b/sql/table.h @@ -335,7 +335,8 @@ typedef struct st_foreign_key_info LEX_STRING *forein_id; LEX_STRING *referenced_db; LEX_STRING *referenced_table; - LEX_STRING *constraint_method; + LEX_STRING *update_method; + LEX_STRING *delete_method; List foreign_fields; List referenced_fields; } FOREIGN_KEY_INFO; @@ -359,6 +360,7 @@ enum enum_schema_tables SCH_PARTITIONS, SCH_PLUGINS, SCH_PROCESSLIST, + SCH_REFERENTIAL_CONSTRAINTS, SCH_PROCEDURES, SCH_SCHEMATA, SCH_SCHEMA_PRIVILEGES, From e8770dfe76a1244fccf2ca55e44e5b7b4eb5875d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 09:13:58 -0400 Subject: [PATCH 08/15] Fix spelling in comments as requested by Osku This will make charset code easier to understand include/m_ctype.h: Fix spelling in comments mysql-test/t/cast.test: Fix spelling in comments mysql-test/t/query_cache.test: Fix spelling in comments sql/sql_string.cc: Fix spelling in comments strings/CHARSET_INFO.txt: Fix spelling in comments --- include/m_ctype.h | 6 +++--- mysql-test/t/cast.test | 2 +- mysql-test/t/query_cache.test | 2 +- sql/sql_string.cc | 2 +- strings/CHARSET_INFO.txt | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 913272b2a11..40cadad0017 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -176,7 +176,7 @@ typedef struct my_charset_handler_st uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length); uint (*numcells)(struct charset_info_st *, const char *b, const char *e); - /* Unicode convertion */ + /* Unicode conversion */ int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc, const unsigned char *s,const unsigned char *e); int (*wc_mb)(struct charset_info_st *cs,my_wc_t wc, @@ -186,7 +186,7 @@ typedef struct my_charset_handler_st int (*ctype)(struct charset_info_st *cs, int *ctype, const unsigned char *s, const unsigned char *e); - /* Functions for case and sort convertion */ + /* Functions for case and sort conversion */ void (*caseup_str)(struct charset_info_st *, char *); void (*casedn_str)(struct charset_info_st *, char *); uint (*caseup)(struct charset_info_st *, char *src, uint srclen, @@ -204,7 +204,7 @@ typedef struct my_charset_handler_st void (*fill)(struct charset_info_st *, char *to, uint len, int fill); - /* String-to-number convertion routines */ + /* String-to-number conversion routines */ long (*strntol)(struct charset_info_st *, const char *s, uint l, int base, char **e, int *err); ulong (*strntoul)(struct charset_info_st *, const char *s, uint l, diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index 533da542855..b733a23f398 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -47,7 +47,7 @@ select cast('1a' as signed); select cast('' as signed); # -# Character set convertion +# Character set conversion # set names binary; select cast(_latin1'test' as char character set latin2); diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 7596a7ba708..e2ff20e6ecc 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -207,7 +207,7 @@ show status like "Qcache_queries_in_cache"; drop table t1; # -# Charset convertion (cp1251_koi8 always present) +# Charset conversion (cp1251_koi8 always present) # create table t1 (a char(1) not null collate koi8r_general_ci); insert into t1 values(_koi8r"á"); diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 79228be8a76..19ee9f259dc 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -331,7 +331,7 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length, return copy_aligned(str, arg_length, offset, cs); } - /* Copy with charset convertion */ + /* Copy with charset conversion */ bool String::copy(const char *str, uint32 arg_length, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors) diff --git a/strings/CHARSET_INFO.txt b/strings/CHARSET_INFO.txt index f7a10f95880..40f171440a4 100644 --- a/strings/CHARSET_INFO.txt +++ b/strings/CHARSET_INFO.txt @@ -172,7 +172,7 @@ mb_wc - converts the left multibyte sequence into it Unicode code. mc_mb - converts the given Unicode code into multibyte sequence. -Case and sort convertion +Case and sort conversion ------------------------ caseup_str - converts the given 0-terminated string into the upper case casedn_str - converts the given 0-terminated string into the lower case @@ -227,4 +227,4 @@ hash_sort() - calculates hash value taking in account the collation rules, e.g. case-insensitivity, accent sensitivity, etc. - \ No newline at end of file + From 28d799f1009b50d739e62c43565ecb2cea97450c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 13:42:35 -0400 Subject: [PATCH 09/15] An update to as-yet unused new feature of snprintf, which was added to bring our sprintf()-alike in sync with our fprintf()-alike features. strings/my_vsnprintf.c: Advance the destination pointer properly. Also, pay attention to the "n" in snprintf() -- never write too much. --- strings/my_vsnprintf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index d917e9e11b2..e4302f50c58 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -99,7 +99,11 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) else if (*fmt == 'b') /* Buffer parameter */ { char *par = va_arg(ap, char *); - to=memmove(to, par, abs(width)); + DBUG_ASSERT(to <= end); + if (to + abs(width) + 1 > end) + width= end - to - 1; /* sign doesn't matter */ + memmove(to, par, abs(width)); + to+= width; continue; } else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */ From d6c258848266cb2868aec8d17c9921856c9d1bb3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 13:56:43 -0400 Subject: [PATCH 10/15] Manually merged --- sql/sql_parse.cc | 506 ++++++++++++++++++++++++++------------ tests/mysql_client_test.c | 38 ++- 2 files changed, 379 insertions(+), 165 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 196e723299a..b1b498b356d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -17,22 +17,16 @@ #define MYSQL_LEX 1 #include "mysql_priv.h" #include "sql_repl.h" +#include "rpl_filter.h" #include "repl_failsafe.h" #include #include #include -#ifdef HAVE_INNOBASE_DB -#include "ha_innodb.h" -#endif - -#ifdef HAVE_NDBCLUSTER_DB -#include "ha_ndbcluster.h" -#endif - #include "sp_head.h" #include "sp.h" #include "sp_cache.h" +#include "event.h" #ifdef HAVE_OPENSSL /* @@ -74,19 +68,41 @@ static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_multi_update_lock(THD *thd); static void remove_escape(char *name); -static bool append_file_to_dir(THD *thd, const char **filename_ptr, - const char *table_name); const char *any_db="*any*"; // Special symbol for check_access -const char *command_name[]={ - "Sleep", "Quit", "Init DB", "Query", "Field List", "Create DB", - "Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist", - "Connect","Kill","Debug","Ping","Time","Delayed insert","Change user", - "Binlog Dump","Table Dump", "Connect Out", "Register Slave", - "Prepare", "Execute", "Long Data", "Close stmt", - "Reset stmt", "Set option", "Fetch", - "Error" // Last command number +LEX_STRING command_name[]={ + (char *)STRING_WITH_LEN("Sleep"), + (char *)STRING_WITH_LEN("Quit"), + (char *)STRING_WITH_LEN("Init DB"), + (char *)STRING_WITH_LEN("Query"), + (char *)STRING_WITH_LEN("Field List"), + (char *)STRING_WITH_LEN("Create DB"), + (char *)STRING_WITH_LEN("Drop DB"), + (char *)STRING_WITH_LEN("Refresh"), + (char *)STRING_WITH_LEN("Shutdown"), + (char *)STRING_WITH_LEN("Statistics"), + (char *)STRING_WITH_LEN("Processlist"), + (char *)STRING_WITH_LEN("Connect"), + (char *)STRING_WITH_LEN("Kill"), + (char *)STRING_WITH_LEN("Debug"), + (char *)STRING_WITH_LEN("Ping"), + (char *)STRING_WITH_LEN("Time"), + (char *)STRING_WITH_LEN("Delayed insert"), + (char *)STRING_WITH_LEN("Change user"), + (char *)STRING_WITH_LEN("Binlog Dump"), + (char *)STRING_WITH_LEN("Table Dump"), + (char *)STRING_WITH_LEN("Connect Out"), + (char *)STRING_WITH_LEN("Register Slave"), + (char *)STRING_WITH_LEN("Prepare"), + (char *)STRING_WITH_LEN("Execute"), + (char *)STRING_WITH_LEN("Long Data"), + (char *)STRING_WITH_LEN("Close stmt"), + (char *)STRING_WITH_LEN("Reset stmt"), + (char *)STRING_WITH_LEN("Set option"), + (char *)STRING_WITH_LEN("Fetch"), + (char *)STRING_WITH_LEN("Daemon"), + (char *)STRING_WITH_LEN("Error") // Last command number }; const char *xa_state_names[]={ @@ -101,10 +117,6 @@ static void test_signal(int sig_ptr) #if !defined( DBUG_OFF) MessageBox(NULL,"Test signal","DBUG",MB_OK); #endif -#if defined(OS2) - fprintf(stderr, "Test signal %d\n", sig_ptr); - fflush(stderr); -#endif } static void init_signals(void) { @@ -155,7 +167,7 @@ static bool end_active_trans(THD *thd) DBUG_RETURN(error); } -static bool begin_trans(THD *thd) +bool begin_trans(THD *thd) { int error=0; if (unlikely(thd->in_sub_stmt)) @@ -189,7 +201,8 @@ static bool begin_trans(THD *thd) */ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables) { - return table_rules_on && tables && !tables_ok(thd,tables); + return rpl_filter->is_on() && tables && !thd->spcont && + !rpl_filter->tables_ok(thd->db, tables); } #endif @@ -327,7 +340,7 @@ int check_user(THD *thd, enum enum_server_command command, if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323) { net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); - mysql_log.write(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); + general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } if (passwd_len != 0 && @@ -361,9 +374,9 @@ int check_user(THD *thd, enum enum_server_command command, net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE, thd->main_security_ctx.user, thd->main_security_ctx.host_or_ip); - mysql_log.write(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE), - thd->main_security_ctx.user, - thd->main_security_ctx.host_or_ip); + general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE), + thd->main_security_ctx.user, + thd->main_security_ctx.host_or_ip); DBUG_RETURN(-1); } /* We have to read very specific packet size */ @@ -411,14 +424,14 @@ int check_user(THD *thd, enum enum_server_command command, } /* Why logging is performed before all checks've passed? */ - mysql_log.write(thd, command, - (thd->main_security_ctx.priv_user == - thd->main_security_ctx.user ? - (char*) "%s@%s on %s" : - (char*) "%s@%s as anonymous on %s"), - thd->main_security_ctx.user, - thd->main_security_ctx.host_or_ip, - db ? db : (char*) ""); + general_log_print(thd, command, + (thd->main_security_ctx.priv_user == + thd->main_security_ctx.user ? + (char*) "%s@%s on %s" : + (char*) "%s@%s as anonymous on %s"), + thd->main_security_ctx.user, + thd->main_security_ctx.host_or_ip, + db ? db : (char*) ""); /* This is the default access rights for the current database. It's @@ -465,17 +478,17 @@ int check_user(THD *thd, enum enum_server_command command, else if (res == 2) // client gave short hash, server has long hash { net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); - mysql_log.write(thd,COM_CONNECT,ER(ER_NOT_SUPPORTED_AUTH_MODE)); + general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } net_printf_error(thd, ER_ACCESS_DENIED_ERROR, thd->main_security_ctx.user, thd->main_security_ctx.host_or_ip, passwd_len ? ER(ER_YES) : ER(ER_NO)); - mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR), - thd->main_security_ctx.user, - thd->main_security_ctx.host_or_ip, - passwd_len ? ER(ER_YES) : ER(ER_NO)); + general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR), + thd->main_security_ctx.user, + thd->main_security_ctx.host_or_ip, + passwd_len ? ER(ER_YES) : ER(ER_NO)); DBUG_RETURN(-1); #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -648,6 +661,9 @@ void init_update_queries(void) uc_update_queries[SQLCOM_DROP_INDEX]=1; uc_update_queries[SQLCOM_CREATE_VIEW]=1; uc_update_queries[SQLCOM_DROP_VIEW]=1; + uc_update_queries[SQLCOM_CREATE_EVENT]=1; + uc_update_queries[SQLCOM_ALTER_EVENT]=1; + uc_update_queries[SQLCOM_DROP_EVENT]=1; } bool is_update_query(enum enum_sql_command command) @@ -1087,7 +1103,7 @@ pthread_handler_t handle_one_connection(void *arg) pthread_detach_this_thread(); -#if !defined( __WIN__) && !defined(OS2) // Win32 calls this in pthread_create +#if !defined( __WIN__) // Win32 calls this in pthread_create /* The following calls needs to be done before we call DBUG_ macros */ if (!(test_flags & TEST_NO_THREADS) & my_thread_init()) { @@ -1111,7 +1127,7 @@ pthread_handler_t handle_one_connection(void *arg) #if defined(__WIN__) init_signals(); -#elif !defined(OS2) && !defined(__NETWARE__) +#elif !defined(__NETWARE__) sigset_t set; VOID(sigemptyset(&set)); // Get mask in use VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals)); @@ -1235,7 +1251,7 @@ pthread_handler_t handle_bootstrap(void *arg) #ifndef EMBEDDED_LIBRARY pthread_detach_this_thread(); thd->thread_stack= (char*) &thd; -#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) +#if !defined(__WIN__) && !defined(__NETWARE__) sigset_t set; VOID(sigemptyset(&set)); // Get mask in use VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals)); @@ -1249,6 +1265,7 @@ pthread_handler_t handle_bootstrap(void *arg) thd->version=refresh_version; thd->security_ctx->priv_user= thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME)); + thd->security_ctx->priv_host[0]=0; buff= (char*) thd->net.buff; thd->init_for_queries(); @@ -1588,7 +1605,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, packet, strlen(packet), thd->charset()); if (!mysql_change_db(thd, tmp.str, FALSE)) { - mysql_log.write(thd,command,"%s",thd->db); + general_log_print(thd, command, "%s",thd->db); send_ok(thd); } break; @@ -1736,7 +1753,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (alloc_query(thd, packet, packet_length)) break; // fatal error is set char *packet_end= thd->query + thd->query_length; - mysql_log.write(thd,command, "%.*b", thd->query_length, thd->query); + general_log_print(thd, command, "%.*b", thd->query_length, thd->query); DBUG_PRINT("query",("%-.4096s",thd->query)); if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1792,8 +1809,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, TABLE_LIST table_list; LEX_STRING conv_name; /* Saved variable value */ - my_bool old_innodb_table_locks= - IF_INNOBASE_DB(thd->variables.innodb_table_locks, FALSE); + my_bool old_innodb_table_locks= thd->variables.innodb_table_locks; + + /* used as fields initializator */ lex_start(thd, 0, 0); @@ -1823,7 +1841,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->query_length= strlen(packet); // for simplicity: don't optimize if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1))) break; - mysql_log.write(thd,command,"%s %s",table_list.table_name, fields); + general_log_print(thd, command, "%s %s", table_list.table_name, fields); if (lower_case_table_names) my_casedn_str(files_charset_info, table_list.table_name); remove_escape(table_list.table_name); // This can't have wildcards @@ -1852,7 +1870,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif case COM_QUIT: /* We don't calculate statistics for this command */ - mysql_log.write(thd,command,NullS); + general_log_print(thd, command, NullS); net->error=0; // Don't give 'abort' message error=TRUE; // End server break; @@ -1872,7 +1890,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } if (check_access(thd,CREATE_ACL,db,0,1,0,is_schema_db(db))) break; - mysql_log.write(thd,command,packet); + general_log_print(thd, command, packet); bzero(&create_info, sizeof(create_info)); mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db), &create_info, 0); @@ -1897,7 +1915,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); break; } - mysql_log.write(thd,command,db); + general_log_print(thd, command, db); mysql_rm_db(thd, db, 0, 0); break; } @@ -1921,7 +1939,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, kill_zombie_dump_threads(slave_server_id); thd->server_id = slave_server_id; - mysql_log.write(thd, command, "Log: '%s' Pos: %ld", packet+10, + general_log_print(thd, command, "Log: '%s' Pos: %ld", packet+10, (long) pos); mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags); unregister_slave(thd,1,1); @@ -1939,7 +1957,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ulong options= (ulong) (uchar) packet[0]; if (check_global_access(thd,RELOAD_ACL)) break; - mysql_log.write(thd,command,NullS); + general_log_print(thd, command, NullS); if (!reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, ¬_used)) send_ok(thd); break; @@ -1967,14 +1985,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } DBUG_PRINT("quit",("Got shutdown command for level %u", level)); - mysql_log.write(thd,command,NullS); + general_log_print(thd, command, NullS); send_eof(thd); #ifdef __WIN__ sleep(1); // must wait after eof() #endif -#ifndef OS2 send_eof(thd); // This is for 'quit request' -#endif close_connection(thd, 0, 1); close_thread_tables(thd); // Free before kill kill_mysql(); @@ -1984,7 +2000,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif case COM_STATISTICS: { - mysql_log.write(thd,command,NullS); + general_log_print(thd, command, NullS); statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS], &LOCK_status); #ifndef EMBEDDED_LIBRARY @@ -1998,7 +2014,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, uptime, (int) thread_count, (ulong) thd->query_id, (ulong) thd->status_var.long_query_count, - thd->status_var.opened_tables, refresh_version, cached_tables(), + thd->status_var.opened_tables, refresh_version, + cached_open_tables(), (uptime ? (ulonglong2double(thd->query_id) / (double) uptime) : (double) 0)); #ifdef SAFEMALLOC @@ -2023,7 +2040,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (!thd->security_ctx->priv_user[0] && check_global_access(thd, PROCESS_ACL)) break; - mysql_log.write(thd,command,NullS); + general_log_print(thd, command, NullS); mysqld_list_processes(thd, thd->security_ctx->master_access & PROCESS_ACL ? NullS : thd->security_ctx->priv_user, 0); @@ -2060,7 +2077,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (check_global_access(thd, SUPER_ACL)) break; /* purecov: inspected */ mysql_print_status(); - mysql_log.write(thd,command,NullS); + general_log_print(thd, command, NullS); send_eof(thd); break; case COM_SLEEP: @@ -2115,6 +2132,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, void log_slow_statement(THD *thd) { time_t start_of_query; + DBUG_ENTER("log_slow_statement"); /* The following should never be true with our current code base, @@ -2122,7 +2140,7 @@ void log_slow_statement(THD *thd) statement in a trigger or stored function */ if (unlikely(thd->in_sub_stmt)) - return; // Don't set time for sub stmt + DBUG_VOID_RETURN; // Don't set time for sub stmt start_of_query= thd->start_time; thd->end_time(); // Set start time @@ -2142,9 +2160,10 @@ void log_slow_statement(THD *thd) (specialflag & SPECIAL_LOG_QUERIES_NOT_USING_INDEXES))) { thd->status_var.long_query_count++; - mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query); + slow_log_print(thd, thd->query, thd->query_length, start_of_query); } } + DBUG_VOID_RETURN; } @@ -2169,6 +2188,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, case SCH_TABLES: case SCH_VIEWS: case SCH_TRIGGERS: + case SCH_EVENTS: #ifdef DONT_ALLOW_SHOW_COMMANDS my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */ @@ -2243,6 +2263,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, case SCH_STATUS: case SCH_PROCEDURES: case SCH_CHARSETS: + case SCH_ENGINES: case SCH_COLLATIONS: case SCH_COLLATION_CHARACTER_SET_APPLICABILITY: case SCH_USER_PRIVILEGES: @@ -2355,6 +2376,9 @@ mysql_execute_command(THD *thd) /* Saved variable value */ DBUG_ENTER("mysql_execute_command"); thd->net.no_send_error= 0; +#ifdef WITH_PARTITION_STORAGE_ENGINE + thd->work_part_info= 0; +#endif /* In many cases first table of main SELECT_LEX have special meaning => @@ -2444,6 +2468,9 @@ mysql_execute_command(THD *thd) statistic_increment(thd->status_var.com_stat[lex->sql_command], &LOCK_status); + if (lex->binlog_row_based_if_mixed) + thd->set_current_stmt_binlog_row_based_if_mixed(); + switch (lex->sql_command) { case SQLCOM_SELECT: { @@ -2459,11 +2486,15 @@ mysql_execute_command(THD *thd) if (all_tables) { if (lex->orig_sql_command != SQLCOM_SHOW_STATUS_PROC && - lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC) + lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC && + lex->orig_sql_command != SQLCOM_SHOW_EVENTS) res= check_table_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, all_tables, 0); + else if (lex->orig_sql_command == SQLCOM_SHOW_EVENTS) + res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0, + is_schema_db(thd->lex->select_lex.db)); } else res= check_access(thd, @@ -2708,29 +2739,20 @@ mysql_execute_command(THD *thd) res = load_master_data(thd); break; #endif /* HAVE_REPLICATION */ -#ifdef HAVE_NDBCLUSTER_DB - case SQLCOM_SHOW_NDBCLUSTER_STATUS: - { - res = ndbcluster_show_status(thd); - break; - } -#endif -#ifdef HAVE_INNOBASE_DB - case SQLCOM_SHOW_INNODB_STATUS: - { - if (check_global_access(thd, SUPER_ACL)) - goto error; - res = innodb_show_status(thd); - break; - } - case SQLCOM_SHOW_MUTEX_STATUS: + case SQLCOM_SHOW_ENGINE_STATUS: { if (check_global_access(thd, SUPER_ACL)) goto error; - res = innodb_mutex_show_status(thd); + res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS); + break; + } + case SQLCOM_SHOW_ENGINE_MUTEX: + { + if (check_global_access(thd, SUPER_ACL)) + goto error; + res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX); break; } -#endif #ifdef HAVE_REPLICATION case SQLCOM_LOAD_MASTER_TABLE: { @@ -2897,11 +2919,20 @@ mysql_execute_command(THD *thd) else { /* regular create */ - if (lex->name) + if (lex->like_name) res= mysql_create_like_table(thd, create_table, &lex->create_info, - (Table_ident *)lex->name); + lex->like_name); else { +#ifdef WITH_PARTITION_STORAGE_ENGINE + partition_info *part_info= thd->lex->part_info; + if (part_info && !(part_info= thd->lex->part_info->get_clone())) + { + res= -1; + goto end_with_restore_list; + } + thd->work_part_info= part_info; +#endif res= mysql_create_table(thd, create_table->db, create_table->table_name, &lex->create_info, lex->create_list, @@ -2979,6 +3010,11 @@ end_with_restore_list: #else { ulong priv=0; + ulong priv_needed= ALTER_ACL; + /* We also require DROP priv for ALTER TABLE ... DROP PARTITION */ + if (lex->alter_info.flags & ALTER_DROP_PARTITION) + priv_needed|= DROP_ACL; + if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name); @@ -3003,7 +3039,7 @@ end_with_restore_list: else select_lex->db= first_table->db; } - if (check_access(thd, ALTER_ACL, first_table->db, + if (check_access(thd, priv_needed, first_table->db, &first_table->grant.privilege, 0, 0, test(first_table->schema_table)) || check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0, @@ -3014,7 +3050,7 @@ end_with_restore_list: goto error; /* purecov: inspected */ if (grant_option) { - if (check_grant(thd, ALTER_ACL, all_tables, 0, UINT_MAX, 0)) + if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0)) goto error; if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL)) { // Rename of table @@ -3079,7 +3115,7 @@ end_with_restore_list: } } query_cache_invalidate3(thd, first_table, 0); - if (end_active_trans(thd) || mysql_rename_tables(thd, first_table)) + if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0)) goto error; break; } @@ -3144,8 +3180,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, 0, FALSE); } } select_lex->table_list.first= (byte*) first_table; @@ -3178,8 +3214,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, 0, FALSE); } } select_lex->table_list.first= (byte*) first_table; @@ -3203,8 +3239,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, 0, FALSE); } } select_lex->table_list.first= (byte*) first_table; @@ -3492,13 +3528,16 @@ end_with_restore_list: case SQLCOM_SHOW_STORAGE_ENGINES: res= mysqld_show_storage_engines(thd); break; + case SQLCOM_SHOW_AUTHORS: + res= mysqld_show_authors(thd); + break; case SQLCOM_SHOW_PRIVILEGES: res= mysqld_show_privileges(thd); break; case SQLCOM_SHOW_COLUMN_TYPES: res= mysqld_show_column_types(thd); break; - case SQLCOM_SHOW_LOGS: + case SQLCOM_SHOW_ENGINE_LOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */ @@ -3507,7 +3546,7 @@ end_with_restore_list: { if (grant_option && check_access(thd, FILE_ACL, any_db,0,0,0,0)) goto error; - res= mysqld_show_logs(thd); + res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS); break; } #endif @@ -3626,9 +3665,9 @@ end_with_restore_list: above was not called. So we have to check rules again here. */ #ifdef HAVE_REPLICATION - if (thd->slave_thread && - (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || - !db_ok_with_wild_table(lex->name))) + if (thd->slave_thread && + (!rpl_filter->db_ok(lex->name) || + !rpl_filter->db_ok_with_wild_table(lex->name))) { my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; @@ -3661,8 +3700,8 @@ end_with_restore_list: */ #ifdef HAVE_REPLICATION if (thd->slave_thread && - (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || - !db_ok_with_wild_table(lex->name))) + (!rpl_filter->db_ok(lex->name) || + !rpl_filter->db_ok_with_wild_table(lex->name))) { my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; @@ -3679,6 +3718,48 @@ end_with_restore_list: res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0); break; } + case SQLCOM_RENAME_DB: + { + LEX_STRING *olddb, *newdb; + List_iterator db_list(lex->db_list); + olddb= db_list++; + newdb= db_list++; + if (end_active_trans(thd)) + { + res= 1; + break; + } +#ifdef HAVE_REPLICATION + if (thd->slave_thread && + (!rpl_filter->db_ok(olddb->str) || + !rpl_filter->db_ok(newdb->str) || + !rpl_filter->db_ok_with_wild_table(olddb->str) || + !rpl_filter->db_ok_with_wild_table(newdb->str))) + { + res= 1; + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); + break; + } +#endif + if (check_access(thd,ALTER_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) || + check_access(thd,DROP_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) || + check_access(thd,CREATE_ACL,newdb->str,0,1,0,is_schema_db(newdb->str))) + { + res= 1; + break; + } + if (thd->locked_tables || thd->active_transaction()) + { + res= 1; + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); + goto error; + } + res= mysql_rename_db(thd, olddb, newdb); + if (!res) + send_ok(thd); + break; + } case SQLCOM_ALTER_DB: { char *db= lex->name ? lex->name : thd->db; @@ -3689,7 +3770,7 @@ end_with_restore_list: } if (!strip_sp(db) || check_db_name(db)) { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), db); break; } /* @@ -3701,8 +3782,8 @@ end_with_restore_list: */ #ifdef HAVE_REPLICATION if (thd->slave_thread && - (!db_ok(db, replicate_do_db, replicate_ignore_db) || - !db_ok_with_wild_table(db))) + (!rpl_filter->db_ok(db) || + !rpl_filter->db_ok_with_wild_table(db))) { my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; @@ -3726,11 +3807,83 @@ end_with_restore_list: my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } - if (check_access(thd,SELECT_ACL,lex->name,0,1,0,is_schema_db(lex->name))) - break; res=mysqld_show_create_db(thd,lex->name,&lex->create_info); break; } + case SQLCOM_CREATE_EVENT: + case SQLCOM_ALTER_EVENT: + case SQLCOM_DROP_EVENT: + { + uint rows_affected= 1; + DBUG_ASSERT(lex->et); + do { + if (! lex->et->dbname.str) + { + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); + res= true; + break; + } + + if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 0, + is_schema_db(lex->et->dbname.str))) + break; + + if (end_active_trans(thd)) + { + res= -1; + break; + } + + switch (lex->sql_command) { + case SQLCOM_CREATE_EVENT: + res= evex_create_event(thd, lex->et, (uint) lex->create_info.options, + &rows_affected); + break; + case SQLCOM_ALTER_EVENT: + res= evex_update_event(thd, lex->et, lex->spname, &rows_affected); + break; + case SQLCOM_DROP_EVENT: + res= evex_drop_event(thd, lex->et, lex->drop_if_exists, &rows_affected); + default:; + } + DBUG_PRINT("info", ("CREATE/ALTER/DROP returned error code=%d af_rows=%d", + res, rows_affected)); + if (!res) + send_ok(thd, rows_affected); + + /* lex->unit.cleanup() is called outside, no need to call it here */ + } while (0); + if (!thd->spcont) + { + lex->et->free_sphead_on_delete= true; + lex->et->free_sp(); + lex->et->deinit_mutexes(); + } + + break; + } + case SQLCOM_SHOW_CREATE_EVENT: + { + DBUG_ASSERT(lex->spname); + DBUG_ASSERT(lex->et); + if (! lex->spname->m_db.str) + { + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); + res= true; + break; + } + if (check_access(thd, EVENT_ACL, lex->spname->m_db.str, 0, 0, 0, + is_schema_db(lex->spname->m_db.str))) + break; + + if (lex->spname->m_name.length > NAME_LEN) + { + my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); + goto error; + } + res= evex_show_create_event(thd, lex->spname, lex->et->definer); + break; + } case SQLCOM_CREATE_FUNCTION: // UDF function { if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0)) @@ -3761,10 +3914,8 @@ end_with_restore_list: if (!(res= mysql_create_user(thd, lex->users_list))) { if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); send_ok(thd); } break; @@ -3780,8 +3931,8 @@ end_with_restore_list: { if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } send_ok(thd); } @@ -3798,8 +3949,8 @@ end_with_restore_list: { if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } send_ok(thd); } @@ -3814,8 +3965,8 @@ end_with_restore_list: { if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } send_ok(thd); } @@ -3894,8 +4045,8 @@ end_with_restore_list: if (!res && mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } } else @@ -3914,8 +4065,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } if (lex->sql_command == SQLCOM_GRANT) { @@ -3954,8 +4105,8 @@ end_with_restore_list: { if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, 0, FALSE); } } send_ok(thd); @@ -4295,12 +4446,12 @@ end_with_restore_list: db, name, lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1)) { - close_thread_tables(thd); if (sp_grant_privileges(thd, db, name, lex->sql_command == SQLCOM_CREATE_PROCEDURE)) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_PROC_AUTO_GRANT_FAIL, ER(ER_PROC_AUTO_GRANT_FAIL)); + close_thread_tables(thd); } #endif send_ok(thd); @@ -4518,8 +4669,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } send_ok(thd); break; @@ -4603,8 +4754,8 @@ end_with_restore_list: if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } send_ok(thd); break; @@ -4728,8 +4879,8 @@ end_with_restore_list: buff.append(STRING_WITH_LEN(" AS ")); buff.append(first_table->source.str, first_table->source.length); - Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::STMT_QUERY_TYPE, + buff.ptr(), buff.length(), FALSE, FALSE); } break; } @@ -4742,8 +4893,8 @@ end_with_restore_list: mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } break; } @@ -4937,6 +5088,30 @@ end_with_restore_list: case SQLCOM_XA_RECOVER: res= mysql_xa_recover(thd); break; + case SQLCOM_ALTER_TABLESPACE: + if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0, thd->db ? is_schema_db(thd->db) : 0)) + break; + if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info))) + send_ok(thd); + break; + case SQLCOM_INSTALL_PLUGIN: + if (! (res= mysql_install_plugin(thd, &thd->lex->comment, + &thd->lex->ident))) + send_ok(thd); + break; + case SQLCOM_UNINSTALL_PLUGIN: + if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment))) + send_ok(thd); + break; + case SQLCOM_BINLOG_BASE64_EVENT: + { +#ifndef EMBEDDED_LIBRARY + mysql_client_binlog_statement(thd); +#else /* EMBEDDED_LIBRARY */ + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded"); +#endif /* EMBEDDED_LIBRARY */ + break; + } default: #ifndef EMBEDDED_LIBRARY DBUG_ASSERT(0); /* Impossible */ @@ -4944,10 +5119,12 @@ end_with_restore_list: send_ok(thd); break; } + +end: thd->proc_info="query end"; - /* Two binlog-related cleanups: */ /* + Binlog-related cleanup: Reset system variables temporarily modified by SET ONE SHOT. Exception: If this is a SET, do nothing. This is to allow @@ -4958,6 +5135,7 @@ end_with_restore_list: */ if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION) reset_one_shot_variables(thd); + thd->reset_current_stmt_binlog_row_based(); /* The return value for ROW_COUNT() is "implementation dependent" if the @@ -4973,7 +5151,8 @@ end_with_restore_list: DBUG_RETURN(res || thd->net.report_error); error: - DBUG_RETURN(1); + res= 1; // would be better to set res=1 before "goto error" + goto end; } @@ -5649,7 +5828,6 @@ void mysql_init_multi_delete(LEX *lex) lex->query_tables_last= &lex->query_tables; } - /* When you modify mysql_parse(), you may need to mofify mysql_test_parse_for_slave() in this same file. @@ -5679,11 +5857,16 @@ void mysql_parse(THD *thd, char *inBuf, uint length) { if (thd->net.report_error) { - if (thd->lex->sphead) - { - delete thd->lex->sphead; - thd->lex->sphead= NULL; - } + delete lex->sphead; + lex->sphead= NULL; + if (lex->et) + { + lex->et->free_sphead_on_delete= true; + /* alloced on thd->mem_root so no real memory free but dtor call */ + lex->et->free_sp(); + lex->et->deinit_mutexes(); + lex->et= NULL; + } } else { @@ -5713,11 +5896,18 @@ void mysql_parse(THD *thd, char *inBuf, uint length) thd->is_fatal_error)); query_cache_abort(&thd->net); lex->unit.cleanup(); - if (thd->lex->sphead) + if (lex->sphead) { /* Clean up after failed stored procedure/function */ - delete thd->lex->sphead; - thd->lex->sphead= NULL; + delete lex->sphead; + lex->sphead= NULL; + } + if (lex->et) + { + lex->et->free_sphead_on_delete= true; + lex->et->free_sp(); + lex->et->deinit_mutexes(); + lex->et= NULL; } } thd->proc_info="freeing items"; @@ -5842,10 +6032,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, */ char buf[32]; my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length); - push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DEPRECATED_SYNTAX, - ER(ER_WARN_DEPRECATED_SYNTAX), - buf, "TIMESTAMP"); + WARN_DEPRECATED(thd, "5.2", buf, "'TIMESTAMP'"); } if (!(new_field= new create_field()) || @@ -5974,12 +6161,16 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (!table) DBUG_RETURN(0); // End of memory alias_str= alias ? alias->str : table->table.str; - if (check_table_name(table->table.str,table->table.length) || - table->db.str && check_db_name(table->db.str)) + if (check_table_name(table->table.str,table->table.length)) { my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); DBUG_RETURN(0); } + if (table->db.str && check_db_name(table->db.str)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str); + DBUG_RETURN(0); + } if (!alias) /* Alias is case sensitive */ { @@ -6596,7 +6787,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, { /* Flush the normal query log, the update log, the binary log, - the slow query log, and the relay log (if it exists). + the slow query log, the relay log (if it exists) and the log + tables. */ /* @@ -6606,15 +6798,17 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, than it would help them) */ tmp_write_to_binlog= 0; - mysql_log.new_file(1); - mysql_slow_log.new_file(1); mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); #ifdef HAVE_REPLICATION pthread_mutex_lock(&LOCK_active_mi); rotate_relay_log(active_mi); pthread_mutex_unlock(&LOCK_active_mi); #endif - if (ha_flush_logs()) + + /* flush slow and general logs */ + logger.flush_logs(thd); + + if (ha_flush_logs(NULL)) result=1; if (flush_error_log()) result=1; @@ -6738,6 +6932,8 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) I_List_iterator it(threads); while ((tmp=it++)) { + if (tmp->command == COM_DAEMON) + continue; if (tmp->thread_id == id) { pthread_mutex_lock(&tmp->LOCK_delete); // Lock from delete @@ -6767,8 +6963,8 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) /* If pointer is not a null pointer, append filename to it */ -static bool append_file_to_dir(THD *thd, const char **filename_ptr, - const char *table_name) +bool append_file_to_dir(THD *thd, const char **filename_ptr, + const char *table_name) { char buff[FN_REFLEN],*ptr, *end; if (!*filename_ptr) @@ -6908,7 +7104,7 @@ bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys) HA_CREATE_INFO create_info; DBUG_ENTER("mysql_create_index"); bzero((char*) &create_info,sizeof(create_info)); - create_info.db_type=DB_TYPE_DEFAULT; + create_info.db_type= (handlerton*) &default_hton; create_info.default_table_charset= thd->variables.collation_database; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name, &create_info, table_list, @@ -6924,7 +7120,7 @@ bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) HA_CREATE_INFO create_info; DBUG_ENTER("mysql_drop_index"); bzero((char*) &create_info,sizeof(create_info)); - create_info.db_type=DB_TYPE_DEFAULT; + create_info.db_type= (handlerton*) &default_hton; create_info.default_table_charset= thd->variables.collation_database; alter_info->clear(); alter_info->flags= ALTER_DROP_INDEX; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 4bd636a7ae3..9bc24c17824 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -1213,7 +1213,7 @@ static void test_tran_bdb() /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */ rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction( " - "col1 int , col2 varchar(30)) TYPE= BDB"); + "col1 int , col2 varchar(30)) ENGINE= BDB"); myquery(rc); /* insert a row and commit the transaction */ @@ -1286,7 +1286,7 @@ static void test_tran_innodb() /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */ rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction(col1 int, " - "col2 varchar(30)) TYPE= InnoDB"); + "col2 varchar(30)) ENGINE= InnoDB"); myquery(rc); /* insert a row and commit the transaction */ @@ -9810,7 +9810,7 @@ static void test_derived() myquery(rc); rc= mysql_query(mysql, "create table t1 (id int(8), primary key (id)) \ -TYPE=InnoDB DEFAULT CHARSET=utf8"); +ENGINE=InnoDB DEFAULT CHARSET=utf8"); myquery(rc); rc= mysql_query(mysql, "insert into t1 values (1)"); @@ -9858,16 +9858,16 @@ static void test_xjoin() rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4"); myquery(rc); - rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) TYPE=InnoDB DEFAULT CHARSET=utf8"); + rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8"); myquery(rc); - rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) TYPE=InnoDB DEFAULT CHARSET=utf8"); + rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8"); myquery(rc); - rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) TYPE=InnoDB DEFAULT CHARSET=utf8;"); + rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); myquery(rc); - rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) TYPE=InnoDB DEFAULT CHARSET=utf8"); + rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8"); myquery(rc); rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)"); @@ -14401,7 +14401,7 @@ static void test_bug14210() itself is not InnoDB related. In case the table is MyISAM this test is harmless. */ - mysql_query(mysql, "create table t1 (a varchar(255)) type=InnoDB"); + mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB"); rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))"); myquery(rc); rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384"); @@ -14758,6 +14758,24 @@ static void test_bug16143() } +/* Bug #16144: mysql_stmt_attr_get type error */ + +static void test_bug16144() +{ + const my_bool flag_orig= (my_bool) 0xde; + my_bool flag= flag_orig; + MYSQL_STMT *stmt; + myheader("test_bug16144"); + + /* Check that attr_get returns correct data on little and big endian CPUs */ + stmt= mysql_stmt_init(mysql); + mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag); + mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag); + DIE_UNLESS(flag == flag_orig); + + mysql_stmt_close(stmt); +} + /* Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong field length" @@ -15180,10 +15198,11 @@ static struct my_tests_st my_tests[]= { { "test_bug13488", test_bug13488 }, { "test_bug13524", test_bug13524 }, { "test_bug14845", test_bug14845 }, - { "test_bug15510", test_bug15510 }, { "test_opt_reconnect", test_opt_reconnect }, + { "test_bug15510", test_bug15510}, { "test_bug12744", test_bug12744 }, { "test_bug16143", test_bug16143 }, + { "test_bug16144", test_bug16144 }, { "test_bug15613", test_bug15613 }, { "test_bug14169", test_bug14169 }, { "test_bug17667", test_bug17667 }, @@ -15300,7 +15319,6 @@ int main(int argc, char **argv) { struct my_tests_st *fptr; - DEBUGGER_OFF; MY_INIT(argv[0]); load_defaults("my", client_test_load_default_groups, &argc, &argv); From 567ae0ca263804313d6911f953707ebf30fa9c26 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 15:07:00 -0400 Subject: [PATCH 11/15] More merging assistence. Logging behavior changed in early 5.1. (The filename was never right, but the "opt" file is unnecessary in 5.0 anyway.) mysql-test/t/mysql_client_test-master.opt: Logging behavior changed in early 5.1. --- mysql-test/t/mysql_client_test-master.opt | 1 + mysql-test/t/mysql_client_test.opt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 mysql-test/t/mysql_client_test-master.opt delete mode 100644 mysql-test/t/mysql_client_test.opt diff --git a/mysql-test/t/mysql_client_test-master.opt b/mysql-test/t/mysql_client_test-master.opt new file mode 100644 index 00000000000..3711946168d --- /dev/null +++ b/mysql-test/t/mysql_client_test-master.opt @@ -0,0 +1 @@ +--log --log-output=FILE diff --git a/mysql-test/t/mysql_client_test.opt b/mysql-test/t/mysql_client_test.opt deleted file mode 100644 index 968ba95c6cc..00000000000 --- a/mysql-test/t/mysql_client_test.opt +++ /dev/null @@ -1 +0,0 @@ ---log From 91a9b237ee4addb5007d87b92914c8d9a7cd06b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 23:08:22 +0400 Subject: [PATCH 12/15] WL#3148: Modifying sizes of i_s.processlist columns ('time', 'info'). mysql-test/r/information_schema.result: Fixing test case result (after modifying the size of the i_s.processlist.info column). sql/mysql_priv.h: Defined new constant used as the size of the i_s.processlist.info column. sql/sql_show.cc: Modifying sizes of i_s.processlist columns ('time', 'info'). --- mysql-test/r/information_schema.result | 1 + sql/mysql_priv.h | 2 ++ sql/sql_show.cc | 11 ++++------- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 5e915b5742c..967507740be 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -759,6 +759,7 @@ information_schema PARTITIONS PARTITION_EXPRESSION information_schema PARTITIONS SUBPARTITION_EXPRESSION information_schema PARTITIONS PARTITION_DESCRIPTION information_schema PLUGINS PLUGIN_DESCRIPTION +information_schema PROCESSLIST INFO information_schema ROUTINES ROUTINE_DEFINITION information_schema ROUTINES SQL_MODE information_schema TRIGGERS ACTION_CONDITION diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index bc398b3d20a..749a968a5af 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -177,6 +177,8 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; /* Characters shown for the command in 'show processlist' */ #define PROCESS_LIST_WIDTH 100 +/* Characters shown for the command in 'information_schema.processlist' */ +#define PROCESS_LIST_INFO_WIDTH 65535 /* Time handling defaults */ #define TIMESTAMP_MAX_YEAR 2038 diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 95433828a1e..9976f0e1cfa 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1553,15 +1553,11 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) TABLE *table= tables->table; CHARSET_INFO *cs= system_charset_info; char *user; - bool verbose; - ulong max_query_length; time_t now= time(0); DBUG_ENTER("fill_process_list"); user= thd->security_ctx->master_access & PROCESS_ACL ? NullS : thd->security_ctx->priv_user; - verbose= thd->lex->verbose; - max_query_length= PROCESS_LIST_WIDTH; VOID(pthread_mutex_lock(&LOCK_thread_count)); @@ -1645,7 +1641,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) if (tmp->query) { table->field[7]->store(tmp->query, - min(max_query_length, tmp->query_length), cs); + min(PROCESS_LIST_INFO_WIDTH, + tmp->query_length), cs); table->field[7]->set_notnull(); } @@ -5096,9 +5093,9 @@ ST_FIELD_INFO processlist_fields_info[]= {"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host"}, {"DB", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Db"}, {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command"}, - {"TIME", 4, MYSQL_TYPE_LONG, 0, 0, "Time"}, + {"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time"}, {"STATE", 30, MYSQL_TYPE_STRING, 0, 1, "State"}, - {"INFO", PROCESS_LIST_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"}, + {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; From 3065eeb3f8cff732e1a462b58996105881c7ca88 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 May 2006 09:06:22 +0200 Subject: [PATCH 13/15] Windows build fixes for CMake mysys/cmakelists.txt: Add new file to build. tests/cmakelists.txt: Add new dependency on mysys --- mysys/cmakelists.txt | 2 +- tests/cmakelists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysys/cmakelists.txt b/mysys/cmakelists.txt index 5a3b8f1657e..4aa99a70121 100644 --- a/mysys/cmakelists.txt +++ b/mysys/cmakelists.txt @@ -26,4 +26,4 @@ ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_m my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c - thr_rwlock.c tree.c typelib.c my_vle.c base64.c) + thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c) diff --git a/tests/cmakelists.txt b/tests/cmakelists.txt index c9b0b8735a2..46c42d461f3 100644 --- a/tests/cmakelists.txt +++ b/tests/cmakelists.txt @@ -6,4 +6,4 @@ ADD_DEFINITIONS("-DMYSQL_CLIENT") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) ADD_EXECUTABLE(mysql_client_test mysql_client_test.c) -TARGET_LINK_LIBRARIES(mysql_client_test dbug mysqlclient yassl taocrypt zlib wsock32) +TARGET_LINK_LIBRARIES(mysql_client_test dbug mysys mysqlclient yassl taocrypt zlib wsock32) From 219d5cf225bf1b1eaa29666aaeb781cbc2a3ee41 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 May 2006 23:25:01 +0400 Subject: [PATCH 14/15] Applied innodb-4.1-ss26 snapshot. Fixed BUG#19366: "consistent_snapshot.test fails". innobase/include/dict0dict.ic: Applied innodb-4.1-ss26 snapshot. Remove too strict assertions from some dict_table_t accessor functions (Bug#19366). --- innobase/include/dict0dict.ic | 2 -- 1 file changed, 2 deletions(-) diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index 85e4aaf1a05..4c1a88cfd1b 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -93,7 +93,6 @@ dict_table_get_n_user_cols( { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); return(table->n_cols - DATA_N_SYS_COLS); } @@ -127,7 +126,6 @@ dict_table_get_n_cols( { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); return(table->n_cols); } From 861b68def4bf4a5d477363027a448d906f7bf9a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 May 2006 00:32:34 +0400 Subject: [PATCH 15/15] Applied innodb-5.0-ss521 snapshot. Fixed BUG#19366: "consistent_snapshot.test fails". innobase/include/dict0dict.ic: Applied innodb-5.0-ss521 snapshot. Remove too strict assertions from some dict_table_t accessor functions (bug #19366). --- innobase/include/dict0dict.ic | 2 -- 1 file changed, 2 deletions(-) diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index 928a693f860..861da5d057a 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -92,7 +92,6 @@ dict_table_get_n_user_cols( { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); return(table->n_cols - DATA_N_SYS_COLS); } @@ -126,7 +125,6 @@ dict_table_get_n_cols( { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); return(table->n_cols); }