From a43c40f10f264c236f9cbe02ad1b9b63787bcecd Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Mon, 30 Aug 2004 21:47:52 +0300 Subject: [PATCH 01/10] fixed printing of stored procedure functions names (BUG#5149) --- mysql-test/r/view.result | 10 ++++++++++ mysql-test/t/view.test | 10 ++++++++++ sql/item_func.cc | 15 ++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 18da4882894..28162334546 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1166,3 +1166,13 @@ Table Create Table v3 CREATE VIEW `test`.`v3` AS select `v1`.`col1` AS `a`,`v2`.`col1` AS `b` from `test`.`v1` join `test`.`v2` where (`v1`.`col1` = `v2`.`col1`) drop view v3, v2, v1; drop table t2, t1; +create function `f``1` () returns int return 5; +create view v1 as select test.`f``1` (); +show create view v1; +Table Create Table +v1 CREATE VIEW `test`.`v1` AS select `test`.`f``1`() AS `test.``f````1`` ()` +select * from v1; +test.`f``1` () +5 +drop view v1; +drop function `f``1`; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index e73133afa67..4f5a6f3ddc4 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1106,3 +1106,13 @@ select * from v3; show create view v3; drop view v3, v2, v1; drop table t2, t1; + +# +# VIEW based on functions with complex names +# +create function `f``1` () returns int return 5; +create view v1 as select test.`f``1` (); +show create view v1; +select * from v1; +drop view v1; +drop function `f``1`; diff --git a/sql/item_func.cc b/sql/item_func.cc index c2c93586af8..f5a9d9ef9bc 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3270,9 +3270,22 @@ Item_func_sp::Item_func_sp(sp_name *name, List &list) const char * Item_func_sp::func_name() const { - return m_name->m_name.str; + THD * thd= current_thd; + uint len= ((m_name->m_db.length + + m_name->m_name.length)*2 + //characters*quoting + 2 + // ` and ` + 1 + // . + 1); // end of string + String qname(alloc_root(&thd->mem_root, len), len, + system_charset_info); + qname.length(0); + append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length); + qname.append('.'); + append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length); + return qname.ptr(); } + int Item_func_sp::execute(Item **itp) { From 7682b10ee84461f03a33cacbcec1bbe36f6e3f87 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Mon, 30 Aug 2004 22:52:50 +0300 Subject: [PATCH 02/10] fixed case when real length very close to calculated (BUG#5150) --- mysql-test/r/view.result | 7 +++++++ mysql-test/t/view.test | 9 +++++++++ sql/item_func.cc | 6 ++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 28162334546..193adac7533 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1176,3 +1176,10 @@ test.`f``1` () 5 drop view v1; drop function `f``1`; +create function x () returns int return 5; +create view v1 as select x (); +select * from v1; +x () +5 +drop view v1; +drop function x; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 4f5a6f3ddc4..cc659a59f6d 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1116,3 +1116,12 @@ show create view v1; select * from v1; drop view v1; drop function `f``1`; + +# +# tested problem when function name length close to ALIGN_SIZE +# +create function x () returns int return 5; +create view v1 as select x (); +select * from v1; +drop view v1; +drop function x; diff --git a/sql/item_func.cc b/sql/item_func.cc index f5a9d9ef9bc..b5af98b6caf 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3271,12 +3271,14 @@ const char * Item_func_sp::func_name() const { THD * thd= current_thd; + /* Calculate length to avoud reallocation of string for sure */ uint len= ((m_name->m_db.length + m_name->m_name.length)*2 + //characters*quoting 2 + // ` and ` 1 + // . - 1); // end of string - String qname(alloc_root(&thd->mem_root, len), len, + 1 + // end of string + ALIGN_SIZE(1)); // to avoid String reallocation + String qname((char *)alloc_root(&thd->mem_root, len), len, system_charset_info); qname.length(0); append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length); From 392c306969d8d07b9d3f5d0f1a77d531752f7371 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Tue, 31 Aug 2004 10:06:38 +0300 Subject: [PATCH 03/10] fixed open_and_lock_tables result processing (all open_and_lock_tables revision) fixed printing of COLLATE operation (BUG#5155) --- mysql-test/r/case.result | 2 +- mysql-test/r/func_if.result | 2 +- mysql-test/r/func_in.result | 2 +- mysql-test/r/func_str.result | 2 +- mysql-test/r/func_test.result | 2 +- mysql-test/r/view.result | 10 ++++++++++ mysql-test/t/view.test | 10 ++++++++++ sql/item_strfunc.cc | 12 ++++++++++++ sql/item_strfunc.h | 2 +- sql/sp_head.cc | 8 ++++---- sql/sql_base.cc | 1 + sql/sql_delete.cc | 4 ++-- sql/sql_help.cc | 5 +---- sql/sql_load.cc | 7 ++++--- sql/sql_parse.cc | 3 +-- sql/sql_prepare.cc | 19 ++++++++----------- sql/sql_show.cc | 26 ++++++++++++++++++-------- sql/sql_update.cc | 4 ++-- 18 files changed, 79 insertions(+), 42 deletions(-) diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index dba21877644..75d0c9a7e3b 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -141,7 +141,7 @@ COALESCE('a' COLLATE latin1_bin,'b'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select coalesce(1) AS `COALESCE(1)`,coalesce(1.0) AS `COALESCE(1.0)`,coalesce(_latin1'a') AS `COALESCE('a')`,coalesce(1,1.0) AS `COALESCE(1,1.0)`,coalesce(1,_latin1'1') AS `COALESCE(1,'1')`,coalesce(1.1,_latin1'1') AS `COALESCE(1.1,'1')`,coalesce((_latin1'a' collate _latin1'latin1_bin'),_latin1'b') AS `COALESCE('a' COLLATE latin1_bin,'b')` +Note 1003 select coalesce(1) AS `COALESCE(1)`,coalesce(1.0) AS `COALESCE(1.0)`,coalesce(_latin1'a') AS `COALESCE('a')`,coalesce(1,1.0) AS `COALESCE(1,1.0)`,coalesce(1,_latin1'1') AS `COALESCE(1,'1')`,coalesce(1.1,_latin1'1') AS `COALESCE(1.1,'1')`,coalesce((_latin1'a' collate latin1_bin),_latin1'b') AS `COALESCE('a' COLLATE latin1_bin,'b')` SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 36bd9a36d1c..f0445199744 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -43,7 +43,7 @@ explain extended select if(u=1,st,binary st) s from t1 where st like "%a%" order id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where; Using filesort Warnings: -Note 1003 select if((`test`.`t1`.`u` = 1),`test`.`t1`.`st`,(`test`.`t1`.`st` collate _latin1'BINARY')) AS `s` from `test`.`t1` where (`test`.`t1`.`st` like _latin1'%a%') order by if((`test`.`t1`.`u` = 1),`test`.`t1`.`st`,(`test`.`t1`.`st` collate _latin1'BINARY')) +Note 1003 select if((`test`.`t1`.`u` = 1),`test`.`t1`.`st`,(`test`.`t1`.`st` collate BINARY)) AS `s` from `test`.`t1` where (`test`.`t1`.`st` like _latin1'%a%') order by if((`test`.`t1`.`u` = 1),`test`.`t1`.`st`,(`test`.`t1`.`st` collate BINARY)) select nullif(u=0, 'test') from t1; nullif(u=0, 'test') NULL diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index 025ea02e454..f264103390d 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -146,7 +146,7 @@ explain extended select * from t1 where 'a' in (a,b,c collate latin1_bin); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where Warnings: -Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (_latin1'a' in (`test`.`t1`.`a`,`test`.`t1`.`b`,(`test`.`t1`.`c` collate _latin1'latin1_bin'))) +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (_latin1'a' in (`test`.`t1`.`a`,`test`.`t1`.`b`,(`test`.`t1`.`c` collate latin1_bin))) drop table t1; select '1.0' in (1,2); '1.0' in (1,2) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index e07ee4f0add..6495b81c195 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -638,7 +638,7 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,(_latin1'HE' collate _latin1'BINARY') AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate _latin1'latin1_bin'),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")` +Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,(_latin1'HE' collate BINARY) AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate latin1_bin),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")` SELECT lpad(12345, 5, "#"); lpad(12345, 5, "#") 12345 diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result index a969bf390bc..6f8bc702a80 100644 --- a/mysql-test/r/func_test.result +++ b/mysql-test/r/func_test.result @@ -108,7 +108,7 @@ explain extended select _koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select (_koi8r'a' = (_koi8r'A' collate _latin1'koi8r_general_ci')) AS `_koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci` +Note 1003 select (_koi8r'a' = (_koi8r'A' collate koi8r_general_ci)) AS `_koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci` select _koi8r'a' = _koi8r'A' COLLATE koi8r_bin; _koi8r'a' = _koi8r'A' COLLATE koi8r_bin 0 diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 193adac7533..14df4f1846d 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1183,3 +1183,13 @@ x () 5 drop view v1; drop function x; +create table t2 (col1 char collate latin1_german2_ci); +create view v2 as select col1 collate latin1_german1_ci from t2; +show create view v2; +Table Create Table +v2 CREATE VIEW `test`.`v2` AS select (`test`.`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `test`.`t2` +show create view v2; +Table Create Table +v2 CREATE VIEW `test`.`v2` AS select (`test`.`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `test`.`t2` +drop view v2; +drop table t2; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index cc659a59f6d..d4209cc3cb8 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1125,3 +1125,13 @@ create view v1 as select x (); select * from v1; drop view v1; drop function x; + +# +# VIEW with collation +# +create table t2 (col1 char collate latin1_german2_ci); +create view v2 as select col1 collate latin1_german1_ci from t2; +show create view v2; +show create view v2; +drop view v2; +drop table t2; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index d3493e1fad1..5f2c37dd8a7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2274,6 +2274,18 @@ bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const return 1; } + +void Item_func_set_collation::print(String *str) +{ + str->append('('); + args[0]->print(str); + str->append(" collate ", 9); + DBUG_ASSERT(args[1]->basic_const_item() && + args[1]->type() == Item::STRING_ITEM); + args[1]->str_value.print(str); + str->append(')'); +} + String *Item_func_charset::val_str(String *str) { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 08123370bc6..df8861b2ee0 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -635,7 +635,7 @@ public: void fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "collate"; } - void print(String *str) { print_op(str); } + void print(String *str); }; class Item_func_charset :public Item_str_func diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fd95767b7cd..c7cd49d26f5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1192,7 +1192,7 @@ sp_instr_set::execute(THD *thd, uint *nextp) if (tables && ((res= check_table_access(thd, SELECT_ACL, tables, 0)) || (res= open_and_lock_tables(thd, tables)))) - DBUG_RETURN(-1); + DBUG_RETURN(res); it= sp_eval_func_item(thd, m_value, m_type); if (! it) @@ -1293,7 +1293,7 @@ sp_instr_jump_if::execute(THD *thd, uint *nextp) if (tables && ((res= check_table_access(thd, SELECT_ACL, tables, 0)) || (res= open_and_lock_tables(thd, tables)))) - DBUG_RETURN(-1); + DBUG_RETURN(res); it= sp_eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); if (!it) @@ -1350,7 +1350,7 @@ sp_instr_jump_if_not::execute(THD *thd, uint *nextp) if (tables && ((res= check_table_access(thd, SELECT_ACL, tables, 0)) || (res= open_and_lock_tables(thd, tables)))) - DBUG_RETURN(-1); + DBUG_RETURN(res); it= sp_eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); if (! it) @@ -1406,7 +1406,7 @@ sp_instr_freturn::execute(THD *thd, uint *nextp) if (tables && ((res= check_table_access(thd, SELECT_ACL, tables, 0)) || (res= open_and_lock_tables(thd, tables)))) - DBUG_RETURN(-1); + DBUG_RETURN(res); it= sp_eval_func_item(thd, m_value, m_type); if (! it) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d1fd5fd02cc..5ae385ca313 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1751,6 +1751,7 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) RETURN 0 - ok -1 - error + 1 - error reported to user NOTE The lock will automaticly be freed by close_thread_tables() diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 910b673dc32..00ce016a550 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -39,8 +39,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, ha_rows deleted; DBUG_ENTER("mysql_delete"); - if ((open_and_lock_tables(thd, table_list))) - DBUG_RETURN(-1); + if ((error= open_and_lock_tables(thd, table_list))) + DBUG_RETURN(error); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 85d5271d4c3..8fc0671c808 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -640,11 +640,8 @@ int mysqld_help(THD *thd, const char *mask) uint mlen= strlen(mask); MEM_ROOT *mem_root= &thd->mem_root; - if (open_and_lock_tables(thd, tables)) - { - res= -1; + if (res= open_and_lock_tables(thd, tables)) goto end; - } /* Init tables and fields to be usable from items diff --git a/sql/sql_load.cc b/sql/sql_load.cc index fa3adf236fe..b629493a692 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -99,8 +99,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, loaded is located */ char *tdb= thd->db ? thd->db : db; // Result is never null - bool transactional_table, log_delayed; ulong skip_lines= ex->skip_lines; + int res; + bool transactional_table, log_delayed; DBUG_ENTER("mysql_load"); #ifdef EMBEDDED_LIBRARY @@ -114,8 +115,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_RETURN(-1); } table_list->lock_type= lock_type; - if (open_and_lock_tables(thd, table_list)) - DBUG_RETURN(-1); + if ((res= open_and_lock_tables(thd, table_list))) + DBUG_RETURN(res); /* TODO: add key check when we will support VIEWs in LOAD */ if (!table_list->updatable) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 58385c67493..3abb2b957bc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2136,7 +2136,7 @@ mysql_execute_command(THD *thd) case SQLCOM_DO: if (all_tables && ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || - (res= open_and_lock_tables(thd, all_tables)))) + (res= open_and_lock_tables(thd, all_tables)))) break; res= mysql_do(thd, *lex->insert_list); @@ -2400,7 +2400,6 @@ mysql_execute_command(THD *thd) if (!(res= open_and_lock_tables(thd, select_tables))) { - res= -1; // If error if ((result= new select_create(create_table, &lex->create_info, lex->create_list, diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 452804240b6..a65a8c79daa 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -897,10 +897,10 @@ static int mysql_test_insert(Prepared_statement *stmt, tables & preparation procedure */ thd->allocate_temporary_memory_pool_for_ps_preparing(); - if (open_and_lock_tables(thd, table_list)) + if ((res= open_and_lock_tables(thd, table_list))) { thd->free_temporary_memory_pool_for_ps_preparing(); - DBUG_RETURN(-1); + DBUG_RETURN(res); } if ((values= its++)) @@ -969,9 +969,7 @@ static int mysql_test_update(Prepared_statement *stmt, */ thd->allocate_temporary_memory_pool_for_ps_preparing(); - if (open_and_lock_tables(thd, table_list)) - res= -1; - else + if (!(res= open_and_lock_tables(thd, table_list))) { if (!(res= mysql_prepare_update(thd, table_list, &select->where, @@ -1030,9 +1028,7 @@ static int mysql_test_delete(Prepared_statement *stmt, */ thd->allocate_temporary_memory_pool_for_ps_preparing(); - if (open_and_lock_tables(thd, table_list)) - res= -1; - else + if (!(res= open_and_lock_tables(thd, table_list))) { res= mysql_prepare_delete(thd, table_list, &lex->select_lex.where); lex->unit.cleanup(); @@ -1065,6 +1061,7 @@ static int mysql_test_select(Prepared_statement *stmt, THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX_UNIT *unit= &lex->unit; + int res; DBUG_ENTER("mysql_test_select"); @@ -1084,11 +1081,11 @@ static int mysql_test_select(Prepared_statement *stmt, tables & preparation procedure */ thd->allocate_temporary_memory_pool_for_ps_preparing(); - if (open_and_lock_tables(thd, tables)) + if ((res= open_and_lock_tables(thd, tables))) { - send_error(thd); goto err; } + res= 1; thd->used_tables= 0; // Updated by setup_fields @@ -1126,7 +1123,7 @@ err_prep: unit->cleanup(); err: thd->free_temporary_memory_pool_for_ps_preparing(); - DBUG_RETURN(1); + DBUG_RETURN(res); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index fa8b81f8ea2..7298d1d5249 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -497,6 +497,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) TABLE *table; Protocol *protocol= thd->protocol; TIME time; + int res; DBUG_ENTER("mysqld_extend_show_tables"); (void) sprintf(path,"%s/%s",mysql_data_home,db); @@ -554,13 +555,18 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) table_list.select_lex= &thd->lex->select_lex; if (lower_case_table_names) my_casedn_str(files_charset_info, file_name); - if (open_and_lock_tables(thd, &table_list)) + if ((res= open_and_lock_tables(thd, &table_list))) { for (uint i=2 ; i < field_list.elements ; i++) protocol->store_null(); - // Send error to Comment field - protocol->store(thd->net.last_error, system_charset_info); - thd->clear_error(); + // Send error to Comment field if possible + if (res < 0) + { + protocol->store(thd->net.last_error, system_charset_info); + thd->clear_error(); + } + else + DBUG_RETURN(1) } else if (table_list.view) { @@ -695,14 +701,16 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, char tmp[MAX_FIELD_WIDTH]; Item *item; Protocol *protocol= thd->protocol; + int res; DBUG_ENTER("mysqld_show_fields"); DBUG_PRINT("enter",("db: %s table: %s",table_list->db, table_list->real_name)); table_list->lock_type= TL_UNLOCK; - if (open_and_lock_tables(thd, table_list)) + if ((res= open_and_lock_tables(thd, table_list))) { - send_error(thd); + if (res < 0) + send_error(thd); DBUG_RETURN(1); } table= table_list->table; @@ -836,14 +844,16 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) Protocol *protocol= thd->protocol; char buff[2048]; String buffer(buff, sizeof(buff), system_charset_info); + int res; DBUG_ENTER("mysqld_show_create"); DBUG_PRINT("enter",("db: %s table: %s",table_list->db, table_list->real_name)); /* Only one table for now, but VIEW can involve several tables */ - if (open_and_lock_tables(thd, table_list)) + if ((res= open_and_lock_tables(thd, table_list))) { - send_error(thd); + if (res < 0) + send_error(thd); DBUG_RETURN(1); } /* TODO: add environment variables show when it become possible */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 61fb4b97200..a27244e1055 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -113,8 +113,8 @@ int mysql_update(THD *thd, LINT_INIT(used_index); LINT_INIT(timestamp_query_id); - if ((open_and_lock_tables(thd, table_list))) - DBUG_RETURN(-1); + if ((error= open_and_lock_tables(thd, table_list))) + DBUG_RETURN(error); thd->proc_info="init"; table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); From 771c2998edf3a954c037a1fa262e0bd29ed8034e Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Tue, 31 Aug 2004 11:58:45 +0300 Subject: [PATCH 04/10] ORDER clause printing fixed (BUG#5156) --- mysql-test/r/subselect.result | 4 ++-- mysql-test/r/view.result | 9 +++++++++ mysql-test/t/view.test | 10 ++++++++++ sql/sql_lex.cc | 9 ++++++++- sql/sql_parse.cc | 1 + sql/sql_select.cc | 4 +++- sql/table.h | 3 +++ 7 files changed, 36 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 80dd5c4077a..cdde932f851 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -186,7 +186,7 @@ id select_type table type possible_keys key key_len ref rows Extra 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 NULL UNION RESULT ALL NULL NULL NULL NULL NULL Warnings: -Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` AS `a` from `test`.`t3` order by `test`.`t3`.`a` desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) AS `max(t2.a)*4` from `test`.`t2`)) order by `test`.`t4`.`a`) +Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` AS `a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) AS `max(t2.a)*4` from `test`.`t2`)) order by `test`.`t4`.`a`) select (select a from t3 where a 1)) `tt` +Note 1003 select (select `test`.`t3`.`a` AS `a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt` select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1); a 2 diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 14df4f1846d..8ed85e611a6 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1193,3 +1193,12 @@ Table Create Table v2 CREATE VIEW `test`.`v2` AS select (`test`.`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `test`.`t2` drop view v2; drop table t2; +create table t1 (a int); +insert into t1 values (1), (2); +create view v1 as select 5 from t1 order by 1; +select * from v1; +5 +5 +5 +drop view v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index d4209cc3cb8..3bb995f8022 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1135,3 +1135,13 @@ show create view v2; show create view v2; drop view v2; drop table t2; + +# +# order by refers on integer field +# +create table t1 (a int); +insert into t1 values (1), (2); +create view v1 as select 5 from t1 order by 1; +select * from v1; +drop view v1; +drop table t1; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 31c175fee88..dc69a41b090 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1470,7 +1470,14 @@ void st_select_lex::print_order(String *str, ORDER *order) { for (; order; order= order->next) { - (*order->item)->print(str); + if (order->counter_used) + { + char buffer[20]; + my_snprintf(buffer, 20, "%u", order->counter); + str->append(buffer); + } + else + (*order->item)->print(str); if (!order->asc) str->append(" desc", 5); if (order->next) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3abb2b957bc..54156459f86 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4935,6 +4935,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc) order->asc = asc; order->free_me=0; order->used=0; + order->counter_used= 0; list.link_in_list((byte*) order,(byte**) &order->next); DBUG_RETURN(0); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1768f332fd3..3ecda7284c8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10066,8 +10066,10 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, thd->where); return 1; } - order->item= ref_pointer_array + count-1; + order->item= ref_pointer_array + count - 1; order->in_field_list= 1; + order->counter= count; + order->counter_used= 1; return 0; } uint counter; diff --git a/sql/table.h b/sql/table.h index dd41ab79b7b..68c7febb5b6 100644 --- a/sql/table.h +++ b/sql/table.h @@ -29,9 +29,12 @@ typedef struct st_order { Item **item; /* Point at item in select fields */ Item *item_ptr; /* Storage for initial item */ Item **item_copy; /* For SPs; the original item ptr */ + int counter; /* position in SELECT list, correct + only if counter_used is true*/ bool asc; /* true if ascending */ bool free_me; /* true if item isn't shared */ bool in_field_list; /* true if in select field list */ + bool counter_used; /* parapeter was counter of columns */ Field *field; /* If tmp-table group */ char *buff; /* If tmp-table group */ table_map used,depend_map; From 56d8567a3d144b9e1ae5bc4cda54e546a6094a98 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 1 Sep 2004 19:00:41 +0300 Subject: [PATCH 05/10] adding mysql.proc to table list if view contains stored procedures (BUG#5151) --- mysql-test/r/view.result | 19 +++++++++++++++++-- mysql-test/t/view.test | 18 +++++++++++++++++- sql/item_func.cc | 3 ++- sql/sp.cc | 14 ++++++++++---- sql/sql_lex.h | 1 + sql/sql_parse.cc | 2 +- sql/sql_view.cc | 35 +++++++++++++++++++++++++++++++---- 7 files changed, 79 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 8ed85e611a6..e0124597d36 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -940,7 +940,7 @@ grant update,select(b) on mysqltest.t2 to mysqltest_1@localhost; create view v4 as select b+1 from mysqltest.t2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; drop database mysqltest; -drop view v1,v2; +drop view v1,v2,v4; set sql_mode='ansi'; create table t1 ("a*b" int); create view v1 as select "a*b" from t1; @@ -1040,7 +1040,6 @@ CREATE VIEW v02 AS SELECT * FROM DUAL; ERROR HY000: No tables used SHOW TABLES; Tables_in_test table_type -v4 VIEW CREATE VIEW v1 AS SELECT EXISTS (SELECT 1 UNION SELECT 2); select * from v1; EXISTS (SELECT 1 UNION SELECT 2) @@ -1202,3 +1201,19 @@ select * from v1; 5 drop view v1; drop table t1; +create function x1 () returns int return 5; +create table t1 (s1 int); +create view v1 as select x1() from t1; +drop function x1; +select * from v1; +ERROR 42000: FUNCTION test.x1 does not exist +show table status; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL +v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view +show table status; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL +v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view +drop view v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 3bb995f8022..690c4e0d64c 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -849,7 +849,7 @@ create view v4 as select b+1 from mysqltest.t2; connection root; REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; drop database mysqltest; -drop view v1,v2; +drop view v1,v2,v4; # # VIEW fields quoting @@ -1145,3 +1145,19 @@ create view v1 as select 5 from t1 order by 1; select * from v1; drop view v1; drop table t1; + +# +# VIEW over droped function +# +create function x1 () returns int return 5; +create table t1 (s1 int); +create view v1 as select x1() from t1; +drop function x1; +-- error 1304 +select * from v1; +--replace_column 12 # 13 # +show table status; +--replace_column 12 # 13 # +show table status; +drop view v1; +drop table t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index b5af98b6caf..f9ab1886a23 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3270,7 +3270,7 @@ Item_func_sp::Item_func_sp(sp_name *name, List &list) const char * Item_func_sp::func_name() const { - THD * thd= current_thd; + THD *thd= current_thd; /* Calculate length to avoud reallocation of string for sure */ uint len= ((m_name->m_db.length + m_name->m_name.length)*2 + //characters*quoting @@ -3280,6 +3280,7 @@ Item_func_sp::func_name() const ALIGN_SIZE(1)); // to avoid String reallocation String qname((char *)alloc_root(&thd->mem_root, len), len, system_charset_info); + qname.length(0); append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length); qname.append('.'); diff --git a/sql/sp.cc b/sql/sp.cc index b881eeb78d9..a69f18e10be 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -93,10 +93,15 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, key[128]= type; keylen= sizeof(key); - for (table= thd->open_tables ; table ; table= table->next) - if (strcmp(table->table_cache_key, "mysql") == 0 && - strcmp(table->real_name, "proc") == 0) - break; + if (thd->lex->proc_table) + table= thd->lex->proc_table->table; + else + { + for (table= thd->open_tables ; table ; table= table->next) + if (strcmp(table->table_cache_key, "mysql") == 0 && + strcmp(table->real_name, "proc") == 0) + break; + } if (table) *opened= FALSE; else @@ -954,6 +959,7 @@ sp_cache_functions(THD *thd, LEX *lex) LEX *newlex= new st_lex; thd->lex= newlex; + newlex->proc_table= oldlex->proc_table; // hint if mysql.oper is opened name.m_name.str= strchr(name.m_qname.str, '.'); name.m_db.length= name.m_name.str - name.m_qname.str; name.m_db.str= strmake_root(&thd->mem_root, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 84b5cf3454b..1c479444485 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -641,6 +641,7 @@ typedef struct st_lex TABLE_LIST *query_tables; /* global list of all tables in this query */ /* last element next_global of previous list */ TABLE_LIST **query_tables_last; + TABLE_LIST *proc_table; /* refer to mysql.proc if it was opened by VIEW */ List col_list; List ref_list; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 54156459f86..d0ac3cfbc6a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4246,7 +4246,7 @@ mysql_init_query(THD *thd, uchar *buf, uint length, bool lexonly) lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; - lex->query_tables= 0; + lex->proc_table= lex->query_tables= 0; lex->query_tables_last= &lex->query_tables; lex->variables_used= 0; lex->select_lex.parent_lex= lex; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 3f0e0db1724..17c5951d5cd 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -520,6 +520,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, my_bool mysql_make_view(File_parser *parser, TABLE_LIST *table) { + bool include_proc_table= 0; DBUG_ENTER("mysql_make_view"); if (table->view) @@ -612,10 +613,25 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) table->belong_to_view : table); - /* move SP to main LEX */ - sp_merge_funs(old_lex, lex); - if (lex->spfuns.array.buffer) - hash_free(&lex->spfuns); + if (lex->spfuns.records) + { + /* move SP to main LEX */ + sp_merge_funs(old_lex, lex); + if (lex->spfuns.array.buffer) + hash_free(&lex->spfuns); + if (old_lex->proc_table == 0 && + (old_lex->proc_table= + (TABLE_LIST*)thd->calloc(sizeof(TABLE_LIST))) != 0) + { + TABLE_LIST *table= old_lex->proc_table; + table->db= (char*)"mysql"; + table->db_length= 5; + table->real_name= table->alias= (char*)"proc"; + table->real_name_length= 4; + table->cacheable_table= 1; + include_proc_table= 1; + } + } old_next= table->next_global; if ((table->next_global= lex->query_tables)) @@ -742,6 +758,17 @@ ok: lex->all_selects_list->link_prev= (st_select_lex_node**)&old_lex->all_selects_list; + if (include_proc_table) + { + TABLE_LIST *proc= old_lex->proc_table; + if((proc->next_global= table->next_global)) + { + table->next_global->prev_global= &proc->next_global; + } + proc->prev_global= &table->next_global; + table->next_global= proc; + } + thd->lex= old_lex; DBUG_RETURN(0); From 80a28d458ad655d054d8b5d6b5085ebb2e74f9ee Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 1 Sep 2004 20:30:48 +0300 Subject: [PATCH 06/10] fixed printing of real constants (BUG#5160) --- mysql-test/r/view.result | 5 +++++ mysql-test/t/view.test | 7 +++++++ sql/item.cc | 15 +++++++++++++++ sql/item.h | 8 +++++--- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index e0124597d36..9164eb1b8c4 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1217,3 +1217,8 @@ t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view drop view v1; drop table t1; +create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1; +show create view v1; +Table Create Table +v1 CREATE VIEW `test`.`v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1` +drop view v1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 690c4e0d64c..89841312cd6 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1161,3 +1161,10 @@ show table status; show table status; drop view v1; drop table t1; + +# +# VIEW with floating point (long bumber) as column +# +create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1; +show create view v1; +drop view v1; diff --git a/sql/item.cc b/sql/item.cc index 138ab384caf..5b1f0aa39ab 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1756,6 +1756,21 @@ int Item_real::save_in_field(Field *field, bool no_conversions) return field->store(nr); } + +void Item_real::print(String *str) +{ + if (presentation) + { + str->append(presentation); + return; + } + char buffer[20]; + String num(buffer, sizeof(buffer), &my_charset_bin); + num.set(value, decimals, &my_charset_bin); + str->append(num); +} + + /**************************************************************************** ** varbinary item ** In string context this is a binary string diff --git a/sql/item.h b/sql/item.h index 4030c0fc097..725ac4e733d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -698,12 +698,13 @@ public: class Item_real :public Item_num { + char *presentation; public: double value; // Item_real() :value(0) {} Item_real(const char *str_arg, uint length) :value(my_atof(str_arg)) { - name=(char*) str_arg; + presentation= name=(char*) str_arg; decimals=(uint8) nr_of_decimals(str_arg); max_length=length; fixed= 1; @@ -711,12 +712,12 @@ public: Item_real(const char *str,double val_arg,uint decimal_par,uint length) :value(val_arg) { - name=(char*) str; + presentation= name=(char*) str; decimals=(uint8) decimal_par; max_length=length; fixed= 1; } - Item_real(double value_par) :value(value_par) { fixed= 1; } + Item_real(double value_par) :presentation(0), value(value_par) { fixed= 1; } int save_in_field(Field *field, bool no_conversions); enum Type type() const { return REAL_ITEM; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } @@ -732,6 +733,7 @@ public: void cleanup() {} Item *new_item() { return new Item_real(name,value,decimals,max_length); } Item_num *neg() { value= -value; return this; } + void print(String *str); }; From d38bd725ef097ef9056f2664b34362f67fc27ac8 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 1 Sep 2004 22:48:59 +0300 Subject: [PATCH 07/10] system charset (with wich VIEW printed) saved in .frm and restored before parsing view (BUG#5163) --- mysql-test/r/view.result | 8 ++++++++ mysql-test/t/view.test | 10 ++++++++++ sql/sql_view.cc | 36 +++++++++++++++++++++++++++++------- sql/table.h | 1 + 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 9164eb1b8c4..305c72cb063 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1222,3 +1222,11 @@ show create view v1; Table Create Table v1 CREATE VIEW `test`.`v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1` drop view v1; +create table tü (cü char); +create view vü as select cü from tü; +insert into vü values ('ü'); +select * from vü; +cü +ü +drop view vü; +drop table tü; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 89841312cd6..28fb40d4045 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1168,3 +1168,13 @@ drop table t1; create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1; show create view v1; drop view v1; + +# +# VIEWs with national characters +# +create table tü (cü char); +create view vü as select cü from tü; +insert into vü values ('ü'); +select * from vü; +drop view vü; +drop table tü; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 17c5951d5cd..c27ca9e1c09 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -318,8 +318,10 @@ err: } -// index of revision number in following table -static const int revision_number_position= 4; +/* index of revision number in following table */ +static const int revision_number_position= 5; +/* index of last required parameter for making view */ +static const int last_parameter= 8; static char *view_field_names[]= { @@ -327,6 +329,7 @@ static char *view_field_names[]= (char*)"md5", (char*)"updatable", (char*)"algorithm", + (char*)"syscharset", (char*)"revision", (char*)"timestamp", (char*)"create-version", @@ -343,13 +346,15 @@ static File_option view_parameters[]= FILE_OPTIONS_ULONGLONG}, {{view_field_names[3], 9}, offsetof(TABLE_LIST, algorithm), FILE_OPTIONS_ULONGLONG}, - {{view_field_names[4], 8}, offsetof(TABLE_LIST, revision), + {{view_field_names[4], 10}, offsetof(TABLE_LIST, syscharset), + FILE_OPTIONS_STRING}, + {{view_field_names[5], 8}, offsetof(TABLE_LIST, revision), FILE_OPTIONS_REV}, - {{view_field_names[5], 9}, offsetof(TABLE_LIST, timestamp), + {{view_field_names[6], 9}, offsetof(TABLE_LIST, timestamp), FILE_OPTIONS_TIMESTAMP}, - {{view_field_names[6], 14}, offsetof(TABLE_LIST, file_version), + {{view_field_names[7], 14}, offsetof(TABLE_LIST, file_version), FILE_OPTIONS_ULONGLONG}, - {{view_field_names[7], 6}, offsetof(TABLE_LIST, source), + {{view_field_names[8], 6}, offsetof(TABLE_LIST, source), FILE_OPTIONS_ESTRING}, {{NULL, 0}, 0, FILE_OPTIONS_STRING} @@ -468,6 +473,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->query.length= str.length()-1; // we do not need last \0 view->source.str= thd->query; view->source.length= thd->query_length; + view->syscharset.str= (char *)system_charset_info->csname; + view->syscharset.length= strlen(view->syscharset.str); view->file_version= 1; view->calc_md5(md5); view->md5.str= md5; @@ -552,7 +559,8 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) TODO: when VIEWs will be stored in cache, table mem_root should be used here */ - if (parser->parse((gptr)table, &thd->mem_root, view_parameters, 6)) + if (parser->parse((gptr)table, &thd->mem_root, view_parameters, + last_parameter)) goto err; /* @@ -604,7 +612,21 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) */ thd->options&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES); + CHARSET_INFO *save_cs= thd->variables.character_set_client; + if (!table->syscharset.length) + thd->variables.character_set_client= system_charset_info; + else + { + if (!(thd->variables.character_set_client= + get_charset_by_csname(table->syscharset.str, + MY_CS_PRIMARY, MYF(MY_WME)))) + { + thd->variables.character_set_client= save_cs; + goto err; + } + } res= yyparse((void *)thd); + thd->variables.character_set_client= save_cs; thd->options= options; } if (!res && !thd->is_fatal_error) diff --git a/sql/table.h b/sql/table.h index 68c7febb5b6..93a7b8f7cf5 100644 --- a/sql/table.h +++ b/sql/table.h @@ -224,6 +224,7 @@ typedef struct st_table_list LEX_STRING view_db; /* save view database */ LEX_STRING view_name; /* save view name */ LEX_STRING timestamp; /* GMT time stamp of last operation */ + LEX_STRING syscharset; /* charset of VIEW query text*/ ulonglong file_version; /* version of file's field set */ ulonglong updatable_view; /* VIEW can be updated */ ulonglong revision; /* revision control number */ From d1b667bdd12af231c3e4984baf6071828ee0ce0c Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 1 Sep 2004 23:27:40 +0300 Subject: [PATCH 08/10] fixed staistic of subquery if outer field resolved in merged view (BUG#5247) --- mysql-test/r/view.result | 8 ++++++++ mysql-test/t/view.test | 10 ++++++++++ sql/item.cc | 40 ++++++++++++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 305c72cb063..b6d7b881498 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1230,3 +1230,11 @@ c ü drop view vü; drop table tü; +create table t1 (a int, b int); +insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10); +create view v1(c) as select a+1 from t1 where b >= 4; +select c from v1 where exists (select * from t1 where a=2 and b=c); +c +4 +drop view v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 28fb40d4045..506fdf8f5d8 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1178,3 +1178,13 @@ insert into v select * from vü; drop view vü; drop table tü; + +# +# problem with used_tables() of outer reference resolved in VIEW +# +create table t1 (a int, b int); +insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10); +create view v1(c) as select a+1 from t1 where b >= 4; +select c from v1 where exists (select * from t1 where a=2 and b=c); +drop view v1; +drop table t1; diff --git a/sql/item.cc b/sql/item.cc index 5b1f0aa39ab..e1c57a0540d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1302,11 +1302,21 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) table_list, ref, 0, 1)) != not_found_field) { - if (tmp && tmp != view_ref_found) - { - prev_subselect_item->used_tables_cache|= tmp->table->map; - prev_subselect_item->const_item_cache= 0; - } + if (tmp) + { + if (tmp != view_ref_found) + { + prev_subselect_item->used_tables_cache|= tmp->table->map; + prev_subselect_item->const_item_cache= 0; + } + else + { + prev_subselect_item->used_tables_cache|= + (*ref)->used_tables(); + prev_subselect_item->const_item_cache&= + (*ref)->const_item(); + } + } break; } if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && @@ -2029,11 +2039,21 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) table_list, reference, 0, 1)) != not_found_field) { - if (tmp && tmp != view_ref_found) - { - prev_subselect_item->used_tables_cache|= tmp->table->map; - prev_subselect_item->const_item_cache= 0; - } + if (tmp) + { + if (tmp != view_ref_found) + { + prev_subselect_item->used_tables_cache|= tmp->table->map; + prev_subselect_item->const_item_cache= 0; + } + else + { + prev_subselect_item->used_tables_cache|= + (*reference)->used_tables(); + prev_subselect_item->const_item_cache&= + (*reference)->const_item(); + } + } break; } From 36667b6a91517f682b43c88a4d6c9144f3965f43 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Thu, 2 Sep 2004 00:11:40 +0300 Subject: [PATCH 09/10] fixed printing of characters casting operartion (BUG#5264) --- mysql-test/r/view.result | 8 ++++++++ mysql-test/t/view.test | 8 ++++++++ sql/item_timefunc.cc | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index b6d7b881498..6129850b9dc 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1238,3 +1238,11 @@ c 4 drop view v1; drop table t1; +create view v1 as select cast(1 as char(3)); +show create view v1; +Table Create Table +v1 CREATE VIEW `test`.`v1` AS select cast(1 as char(3) charset latin1) AS `cast(1 as char(3))` +select * from v1; +cast(1 as char(3)) +1 +drop view v1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 506fdf8f5d8..3b1d4a0b362 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1188,3 +1188,11 @@ create view v1(c) as select a+1 from t1 where b >= 4; select c from v1 where exists (select * from t1 where a=2 and b=c); drop view v1; drop table t1; + +# +# view with cast operation +# +create view v1 as select cast(1 as char(3)); +show create view v1; +select * from v1; +drop view v1; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 5aa14010058..0e7594a1d98 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2011,7 +2011,7 @@ void Item_char_typecast::print(String *str) if (cast_cs) { str->append(" charset ", 9); - str->append(cast_cs->name); + str->append(cast_cs->csname); } str->append(')'); } From 1410ac22c4d1df1ccb5463ff4f3738f5b33692b2 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Thu, 2 Sep 2004 07:40:48 +0300 Subject: [PATCH 10/10] fixed bug handling in views (BUG#5276) --- mysql-test/r/view.result | 7 +++++++ mysql-test/t/view.test | 11 +++++++++++ sql/sql_base.cc | 4 ++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 6129850b9dc..449144e3770 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1246,3 +1246,10 @@ select * from v1; cast(1 as char(3)) 1 drop view v1; +create view v1 as select 'a',1; +create view v2 as select * from v1 union all select * from v1; +create view v3 as select * from v2 where 1 = (select `1` from v2); +create view v4 as select * from v3; +select * from v4; +ERROR 21000: Subquery returns more than 1 row +drop view v4, v3, v2, v1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 3b1d4a0b362..a44624d4df9 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1196,3 +1196,14 @@ create view v1 as select cast(1 as char(3)); show create view v1; select * from v1; drop view v1; + +# +# bug handlimg from VIEWs +# +create view v1 as select 'a',1; +create view v2 as select * from v1 union all select * from v1; +create view v3 as select * from v2 where 1 = (select `1` from v2); +create view v4 as select * from v3; +-- error 1242 +select * from v4; +drop view v4, v3, v2, v1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5ae385ca313..c76a4849776 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1761,9 +1761,9 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("open_and_lock_tables"); uint counter; - if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter)) + if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter) + || mysql_handle_derived(thd->lex)) DBUG_RETURN(thd->net.report_error ? -1 : 1); /* purecov: inspected */ - DBUG_RETURN(mysql_handle_derived(thd->lex)); }