From 9f92c88f4379e26bc3f03b83ac7727396703febf Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 6 Sep 2005 18:06:06 -0600 Subject: [PATCH 01/21] A few changes to fix compiling on Windows VC++Files/mysql.sln: Added instance manager project VC++Files/mysys/mysys.vcproj: Added mf_unixpath.c scripts/make_win_src_distribution.sh: Updated to include server-tools folder (which includes IM) server-tools/instance-manager/instance.cc: fixed typo server-tools/instance-manager/mysqlmanager.vcproj: fixed up all the filenames in the IM project --- VC++Files/mysql.sln | 37 +++++ VC++Files/mysys/mysys.vcproj | 3 + scripts/make_win_src_distribution.sh | 2 +- server-tools/instance-manager/instance.cc | 2 +- .../instance-manager/mysqlmanager.vcproj | 148 +++++++++++++----- 5 files changed, 155 insertions(+), 37 deletions(-) diff --git a/VC++Files/mysql.sln b/VC++Files/mysql.sln index fc75dc24723..5b062a31aab 100755 --- a/VC++Files/mysql.sln +++ b/VC++Files/mysql.sln @@ -277,6 +277,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_test_run_new", "mysql {D2B00DE0-F6E9-40AF-B90D-A257D014F098} = {D2B00DE0-F6E9-40AF-B90D-A257D014F098} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlmanager", "server-tools\instance-manager\mysqlmanager.vcproj", "{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}" + ProjectSection(ProjectDependencies) = postProject + {EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859} + {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} = {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} + {DB28DE80-837F-4497-9AA9-CC0A20584C98} = {DB28DE80-837F-4497-9AA9-CC0A20584C98} + {8762A9B8-72A9-462E-A9A2-F3265081F8AF} = {8762A9B8-72A9-462E-A9A2-F3265081F8AF} + {F74653C4-8003-4A79-8F53-FC69E0AD7A9B} = {F74653C4-8003-4A79-8F53-FC69E0AD7A9B} + {44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF} + {FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE} + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution classic = classic @@ -1204,6 +1215,32 @@ Global {6189F838-21C6-42A1-B2D0-9146316573F7}.pro nt.Build.0 = Release|Win32 {6189F838-21C6-42A1-B2D0-9146316573F7}.Release.ActiveCfg = Release|Win32 {6189F838-21C6-42A1-B2D0-9146316573F7}.Release.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.classic.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.classic.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.classic nt.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.classic nt.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Debug.ActiveCfg = Debug|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Debug.Build.0 = Debug|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Embedded_Classic.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Embedded_Classic.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Embedded_Debug.ActiveCfg = Debug|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Embedded_Debug.Build.0 = Debug|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Embedded_Pro.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Embedded_Pro.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Embedded_Release.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Embedded_Release.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Max.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Max.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Max nt.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Max nt.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.nt.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.nt.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro nt.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro nt.Build.0 = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Release.ActiveCfg = Release|Win32 + {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/VC++Files/mysys/mysys.vcproj b/VC++Files/mysys/mysys.vcproj index 3d53fd3923c..87e9338e811 100755 --- a/VC++Files/mysys/mysys.vcproj +++ b/VC++Files/mysys/mysys.vcproj @@ -1638,6 +1638,9 @@ PreprocessorDefinitions=""/> + + + RelativePath=".\buffer.cpp"> + RelativePath="..\..\sql\client.c"> + + + + + + + RelativePath=".\command.cpp"> + RelativePath=".\commands.cpp"> + RelativePath="..\..\libmysql\get_password.c"> + + + + + + - - + RelativePath=".\guardian.cpp"> + RelativePath=".\instance.cpp"> + RelativePath=".\instance_map.cpp"> + RelativePath=".\instance_options.cpp"> + RelativePath=".\listener.cpp"> + RelativePath=".\log.cpp"> + RelativePath=".\manager.cpp"> + RelativePath=".\messages.cpp"> + RelativePath="..\..\sql\mini_client_errors.c"> + + + + + + + RelativePath=".\mysql_connection.cpp"> + + + + + + + RelativePath=".\mysqlmanager.cpp"> + RelativePath="..\..\sql\net_serv.cpp"> + + + + + + + RelativePath=".\options.cpp"> + RelativePath="..\..\sql\pack.c"> + + + + + + + RelativePath=".\parse.cpp"> + RelativePath=".\parse_output.cpp"> + RelativePath="..\..\sql\password.c"> + + + + + + + RelativePath=".\priv.cpp"> + RelativePath=".\protocol.cpp"> + RelativePath="..\..\sql\sql_state.c"> + RelativePath=".\thread_registry.cpp"> - - + RelativePath=".\user_map.cpp"> From b3dc4ea3e3f13127a689a6189517f1bfe35d7c65 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 Sep 2005 02:46:35 +0400 Subject: [PATCH 02/21] Fix bug #12993 View column rename broken in subselect When view column aliased in subselect alias is set on ref which represents field. When tmp table is created for subselect, it takes name of original field not ref. Because of this alias on view column in subselect is lost. Which results in reported error. Now when alias is set on ref, it's set on ref real item too. mysql-test/r/view.result: Test case for bug #12993 View column rename broken in subselect mysql-test/t/view.test: Test case for bug #12993 View column rename broken in subselect sql/sql_base.cc: Fix bug #12993 View column rename broken in subselect Now when alias is set on ref, it's set on ref real item too. --- mysql-test/r/view.result | 6 ++++++ mysql-test/t/view.test | 9 +++++++++ sql/sql_base.cc | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 558977a6d2d..707848682a0 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2186,3 +2186,9 @@ r_object_id users_names 120001a080000542 guser02 drop view v1, v2; drop table t1, t2; +create table t1(f1 char(1)); +create view v1 as select * from t1; +select * from (select f1 as f2 from v1) v where v.f2='a'; +f2 +drop view v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 7cca98391a8..cd81dc80bf2 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2059,3 +2059,12 @@ order by users_names; drop view v1, v2; drop table t1, t2; + +# +# Bug #12993 View column rename broken in subselect +# +create table t1(f1 char(1)); +create view v1 as select * from t1; +select * from (select f1 as f2 from v1) v where v.f2='a'; +drop view v1; +drop table t1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8a5c5643ce2..48b90e9f044 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2648,10 +2648,15 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list, *ref != NULL means that *ref contains the item that we need to replace. If the item was aliased by the user, set the alias to the replacing item. + We need to set alias on both ref itself and on ref real item. */ if (*ref && !(*ref)->is_autogenerated_name) + { item->set_name((*ref)->name, (*ref)->name_length, system_charset_info); + item->real_item()->set_name((*ref)->name, (*ref)->name_length, + system_charset_info); + } if (register_tree_change) thd->change_item_tree(ref, item); else From d2789003b3b816db8b4ceea64518ecf9a7c3ad66 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 Sep 2005 17:01:17 +0300 Subject: [PATCH 03/21] Fix for BUG#6808. The problem was in that add_table_to_list was testing for duplicate tables in a list of tables that included the created view. mysql-test/r/view.result: Test for BUG#6808 mysql-test/t/view.test: Test for BUG#6808 sql/sql_parse.cc: When testing for table name uniquness, skip the first table the current statement is CREATE VIEW. Notice that the first table is skipped differently for CREATE TABLE ... SELECT ... statements, so we don't have to handle that case here (see production 'create_select', the call 'to save_and_clear'). --- mysql-test/r/view.result | 8 ++++++-- mysql-test/t/view.test | 13 +++++++++++-- sql/sql_parse.cc | 5 ++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 558977a6d2d..5ac6759f1a3 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1146,11 +1146,11 @@ create view v2 as select * from v1; alter view v1 as select * from v2; ERROR 42S02: Table 'test.v1' doesn't exist alter view v1 as select * from v1; -ERROR 42000: Not unique table/alias: 'v1' +ERROR 42S02: Table 'test.v1' doesn't exist create or replace view v1 as select * from v2; ERROR 42S02: Table 'test.v1' doesn't exist create or replace view v1 as select * from v1; -ERROR 42000: Not unique table/alias: 'v1' +ERROR 42S02: Table 'test.v1' doesn't exist drop view v2,v1; drop table t1; create table t1 (a int); @@ -2186,3 +2186,7 @@ r_object_id users_names 120001a080000542 guser02 drop view v1, v2; drop table t1, t2; +create table t1 (s1 int); +create view abc as select * from t1 as abc; +drop table t1; +drop view abc; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 7cca98391a8..33b77d80020 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1083,11 +1083,11 @@ create view v1 as select * from t1; create view v2 as select * from v1; -- error 1146 alter view v1 as select * from v2; --- error 1066 +-- error 1146 alter view v1 as select * from v1; -- error 1146 create or replace view v1 as select * from v2; --- error 1066 +-- error 1146 create or replace view v1 as select * from v1; drop view v2,v1; drop table t1; @@ -2059,3 +2059,12 @@ order by users_names; drop view v1, v2; drop table t1, t2; + +# +# Bug #6808 - Views: CREATE VIEW v ... FROM t AS v fails +# + +create table t1 (s1 int); +create view abc as select * from t1 as abc; +drop table t1; +drop view abc; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5d0070667c2..c421c4a91a7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6059,7 +6059,10 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, /* check that used name is unique */ if (lock_type != TL_IGNORE) { - for (TABLE_LIST *tables=(TABLE_LIST*) table_list.first ; + TABLE_LIST *first_table= (TABLE_LIST*) table_list.first; + if (lex->sql_command == SQLCOM_CREATE_VIEW) + first_table= first_table ? first_table->next_local : NULL; + for (TABLE_LIST *tables= first_table ; tables ; tables=tables->next_local) { From 00d77fdd75aa132249594a16db2c674f3642b28d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 Sep 2005 18:02:17 -0700 Subject: [PATCH 04/21] Made changes to add federated CONNECTION information to the .frm file (per Monty's patch). Remove references to the "COMMENT" field. WL#2414 mysql-test/r/federated.result: alter from "COMMENT=" to "CONNECTION=" mysql-test/r/federated_archive.result: change "COMMENT=" to "CONNECTION=" mysql-test/t/federated.test: change from "COMMENT=" to "CONNECTION=" mysql-test/t/federated_archive.test: change from "COMMENT=" to "CONNECTION=" sql/ha_federated.cc: Change parsing of char* table->s->comment to LEX_STRING table->s->connect_string (per Monty's patch) sql/handler.h: added LEX_STRING "connection_string" (per Monty's patch) sql/sql_yacc.yy: added setting of "connect_string" string and length sql/table.cc: Modifying frm file to store connecting information (code change came from Monty). sql/table.h: added connect_string sql/unireg.cc: Storing information on connection_string (code came from Monty). --- mysql-test/r/federated.result | 48 +++++++++++++-------------- mysql-test/r/federated_archive.result | 2 +- mysql-test/t/federated.test | 48 +++++++++++++-------------- mysql-test/t/federated_archive.test | 2 +- sql/ha_federated.cc | 36 +++++++++++--------- sql/handler.h | 2 ++ sql/sql_yacc.yy | 1 + sql/table.cc | 32 ++++++++++++++---- sql/table.h | 1 + sql/unireg.cc | 9 +++++ 10 files changed, 110 insertions(+), 71 deletions(-) diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index 7692991c112..cb58f12bbc0 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -25,28 +25,28 @@ CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1'; -ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1:@/too/many/items/federated/t1' is not in the correct format +CONNECTION='mysql://root@127.0.0.1:@/too/many/items/federated/t1'; +ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1:@/too/many/items/federated/t1ее' is not in the correct format CREATE TABLE federated.t1 ( `id` int(20) NOT NULL, `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1'; +CONNECTION='mysql://root@127.0.0.1'; ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1' is not in the correct format CREATE TABLE federated.t1 ( `id` int(20) NOT NULL, `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t3'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t3'; ERROR HY000: Can't create federated table. Foreign data src error : ': 1146 : Table 'federated.t3' doesn't exist' CREATE TABLE federated.t1 ( `id` int(20) NOT NULL, `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://user:pass@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://user:pass@127.0.0.1:SLAVE_PORT/federated/t1'; ERROR HY000: Unable to connect to foreign data source - database ' database federated username user hostname 127.0.0.1'! DROP TABLE IF EXISTS federated.t1; Warnings: @@ -56,7 +56,7 @@ CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t1 (id, name) VALUES (2, 'fee'); SELECT * FROM federated.t1; @@ -73,7 +73,7 @@ CREATE TABLE federated.t2 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t2 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t2 (id, name) VALUES (2, 'fee'); SELECT * FROM federated.t2; @@ -98,7 +98,7 @@ CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1%'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1%'; INSERT INTO federated.t1 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t1 (id, name) VALUES (2, 'fee'); SELECT * FROM federated.t1; @@ -112,7 +112,7 @@ CREATE TABLE federated.`t1%` ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1%'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1%'; INSERT INTO federated.`t1%` (id, name) VALUES (1, 'foo'); INSERT INTO federated.`t1%` (id, name) VALUES (2, 'fee'); SELECT * FROM federated.`t1%`; @@ -139,7 +139,7 @@ CREATE TABLE federated.t1 ( `created` datetime default '2004-04-04 04:04:04', PRIMARY KEY (`id`)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (name, other) VALUES ('First Name', 11111); INSERT INTO federated.t1 (name, other) VALUES ('Second Name', 22222); INSERT INTO federated.t1 (name, other) VALUES ('Third Name', 33333); @@ -279,7 +279,7 @@ key name(`name`), key other(`other`), key created(`created`)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (name, other, created) VALUES ('First Name', 11111, '2004-01-01 01:01:01'); INSERT INTO federated.t1 (name, other, created) @@ -419,7 +419,7 @@ CREATE TABLE federated.t1 ( PRIMARY KEY (`id`) ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (name, other) VALUES ('First Name', 11111); INSERT INTO federated.t1 (name, other) VALUES ('Second Name', NULL); INSERT INTO federated.t1 (name, other) VALUES ('Third Name', 33333); @@ -484,7 +484,7 @@ PRIMARY KEY (`id`), KEY nameoth (name, other)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (name, other) VALUES ('First Name', '1111'); INSERT INTO federated.t1 (name, other) VALUES ('Second Name', '2222'); INSERT INTO federated.t1 (name, other) VALUES ('Third Name', '3333'); @@ -524,7 +524,7 @@ KEY bincol(bincol), KEY floatval(floatval)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (name, bincol, floatval, other) VALUES ('first', 0x65, 11.11, 1111); INSERT INTO federated.t1 (name, bincol, floatval, other) @@ -589,7 +589,7 @@ key col2(col2), key col3(col3), key col4(col4)) ENGINE="FEDERATED" - COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (col1, col2, col3, col4) VALUES (1, 'one One', 11, 1111); INSERT INTO federated.t1 (col1, col2, col3, col4) @@ -798,7 +798,7 @@ key 3key(`col2`,`col3`,`col4`), key 2key (`col3`,`col4`), key col4(col4)) ENGINE="FEDERATED" - COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (col1, col2, col3, col4) VALUES ('aaaa', 'aaaaaaaaaaaaaaaaaaa', 'ababababab', 'acacacacacacacac'); INSERT INTO federated.t1 (col1, col2, col3, col4) @@ -898,7 +898,7 @@ CREATE TABLE federated.t1 ( primary key (`col1`, `col2`, `col3`)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 VALUES ('a00', '110', 'cc0'); INSERT INTO federated.t1 VALUES ('aaa', '111', 'ccc'); INSERT INTO federated.t1 VALUES ('bbb', '222', 'yyy'); @@ -933,7 +933,7 @@ CREATE TABLE federated.t1 ( `other` int) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 values (NULL, NULL, NULL, NULL); INSERT INTO federated.t1 values (); INSERT INTO federated.t1 (id) VALUES (1); @@ -968,7 +968,7 @@ CREATE TABLE federated.t1 ( PRIMARY KEY (blurb_id)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 VALUES (1, " MySQL supports a number of column types in several categories: numeric types, date and time types, and string (character) types. This chapter first gives an overview of these column types, and then provides a more detailed description of the properties of the types in each category, and a summary of the column type storage requirements. The overview is intentionally brief. The more detailed descriptions should be consulted for additional information about particular column types, such as the allowable formats in which you can specify values."); INSERT INTO federated.t1 VALUES (2, "All arithmetic is done using signed BIGINT or DOUBLE values, so you should not use unsigned big integers larger than 9223372036854775807 (63 bits) except with bit functions! If you do that, some of the last digits in the result may be wrong because of rounding errors when converting a BIGINT value to a DOUBLE."); INSERT INTO federated.t1 VALUES (3, " A floating-point number. p represents the precision. It can be from 0 to 24 for a single-precision floating-point number and from 25 to 53 for a double-precision floating-point number. These types are like the FLOAT and DOUBLE types described immediately following. FLOAT(p) has the same range as the corresponding FLOAT and DOUBLE types, but the display size and number of decimals are undefined. "); @@ -994,7 +994,7 @@ PRIMARY KEY (a), KEY (b)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 VALUES (3,3,3),(1,1,1),(2,2,2),(4,4,4); DROP TABLE IF EXISTS federated.t1; CREATE TABLE federated.t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8 @@ -1252,7 +1252,7 @@ int, i999 int, i1000 int, b varchar(256)) row_format=dynamic ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1322,7 +1322,7 @@ PRIMARY KEY(id), index(code), index(fileguts(10))) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (code, fileguts, creation_date) VALUES ('ASDFWERQWETWETAWETA', '*()w*09*$()*#)(*09*^90*d)(*s()d8g)(s*ned)(*)(s*d)(*hn(d*)(*sbn)D((#$*(#*%%&#&^$#&#&#&#&^&#*&*#$*&^*(&#(&Q*&&(*!&!(*&*(#&*(%&#*###[[', '2003-03-03 03:03:03'); INSERT INTO federated.t1 (code, fileguts, creation_date) VALUES ('DEUEUEUEUEUEUEUEUEU', '*()w*09*$()*#)(*09*^90*d)(*s()d8g)(s*ned)(*)(s*d)(*hn(d*)(*sbn)D((#$*(#*%%&#&^$#&#&#&#&^&#*&*#$*&^*(&#(&Q*&&(*!&!(*&*(#&*(%&#*###[[', '2004-04-04 04:04:04'); INSERT INTO federated.t1 (code, fileguts, creation_date) VALUES ('DEUEUEUEUEUEUEUEUEU', 'jimbob', '2004-04-04 04:04:04'); @@ -1340,7 +1340,7 @@ DROP TABLE IF EXISTS federated.t1; CREATE TABLE federated.t1 ( `a` BLOB) ENGINE="FEDERATED" -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 VALUES (0x00); INSERT INTO federated.t1 VALUES (0x0001); INSERT INTO federated.t1 VALUES (0x0100); @@ -1378,7 +1378,7 @@ CREATE TABLE federated.t1 ( PRIMARY KEY (`id`), KEY (country_id) ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; INSERT INTO federated.t1 (name, country_id, other) VALUES ('Kumar', 1, 11111); INSERT INTO federated.t1 (name, country_id, other) VALUES ('Lenz', 2, 22222); INSERT INTO federated.t1 (name, country_id, other) VALUES ('Marizio', 3, 33333); diff --git a/mysql-test/r/federated_archive.result b/mysql-test/r/federated_archive.result index f0eded42c38..5fc9bfadeb6 100644 --- a/mysql-test/r/federated_archive.result +++ b/mysql-test/r/federated_archive.result @@ -21,7 +21,7 @@ CREATE TABLE federated.t1 ( PRIMARY KEY (`id`) ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/archive_table'; +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/archive_table'; INSERT INTO federated.t1 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t1 (id, name) VALUES (2, 'bar'); SELECT * FROM federated.t1; diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index 255b9dc22d7..28091676dd7 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -17,7 +17,7 @@ CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:@/too/many/items/federated/t1'; # test not enough items (malformed) in the comment string url --error 1432 @@ -26,7 +26,7 @@ CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1'; + CONNECTION='mysql://root@127.0.0.1'; # test non-existant table --replace_result $SLAVE_MYPORT SLAVE_PORT @@ -36,7 +36,7 @@ eval CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t3'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t3'; # test bad user/password --replace_result $SLAVE_MYPORT SLAVE_PORT @@ -46,7 +46,7 @@ eval CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://user:pass@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://user:pass@127.0.0.1:$SLAVE_MYPORT/federated/t1'; DROP TABLE IF EXISTS federated.t1; # # correct connection, same named tables @@ -56,7 +56,7 @@ eval CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t1 (id, name) VALUES (2, 'fee'); @@ -73,7 +73,7 @@ eval CREATE TABLE federated.t2 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t2 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t2 (id, name) VALUES (2, 'fee'); @@ -100,7 +100,7 @@ eval CREATE TABLE federated.t1 ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1%'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1%'; INSERT INTO federated.t1 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t1 (id, name) VALUES (2, 'fee'); @@ -115,7 +115,7 @@ eval CREATE TABLE federated.`t1%` ( `name` varchar(32) NOT NULL default '' ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1%'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1%'; INSERT INTO federated.`t1%` (id, name) VALUES (1, 'foo'); INSERT INTO federated.`t1%` (id, name) VALUES (2, 'fee'); @@ -146,7 +146,7 @@ eval CREATE TABLE federated.t1 ( `created` datetime default '2004-04-04 04:04:04', PRIMARY KEY (`id`)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (name, other) VALUES ('First Name', 11111); INSERT INTO federated.t1 (name, other) VALUES ('Second Name', 22222); @@ -213,7 +213,7 @@ eval CREATE TABLE federated.t1 ( key other(`other`), key created(`created`)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (name, other, created) VALUES ('First Name', 11111, '2004-01-01 01:01:01'); @@ -284,7 +284,7 @@ eval CREATE TABLE federated.t1 ( PRIMARY KEY (`id`) ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (name, other) VALUES ('First Name', 11111); INSERT INTO federated.t1 (name, other) VALUES ('Second Name', NULL); @@ -333,7 +333,7 @@ eval CREATE TABLE federated.t1 ( KEY nameoth (name, other)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (name, other) VALUES ('First Name', '1111'); INSERT INTO federated.t1 (name, other) VALUES ('Second Name', '2222'); @@ -372,7 +372,7 @@ eval CREATE TABLE federated.t1 ( KEY floatval(floatval)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (name, bincol, floatval, other) VALUES ('first', 0x65, 11.11, 1111); @@ -421,7 +421,7 @@ eval CREATE TABLE federated.t1 ( key col3(col3), key col4(col4)) ENGINE="FEDERATED" - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (col1, col2, col3, col4) VALUES (1, 'one One', 11, 1111); @@ -515,7 +515,7 @@ eval CREATE TABLE federated.t1 ( key 2key (`col3`,`col4`), key col4(col4)) ENGINE="FEDERATED" - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (col1, col2, col3, col4) VALUES ('aaaa', 'aaaaaaaaaaaaaaaaaaa', 'ababababab', 'acacacacacacacac'); @@ -567,7 +567,7 @@ eval CREATE TABLE federated.t1 ( primary key (`col1`, `col2`, `col3`)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 VALUES ('a00', '110', 'cc0'); INSERT INTO federated.t1 VALUES ('aaa', '111', 'ccc'); @@ -606,7 +606,7 @@ eval CREATE TABLE federated.t1 ( `other` int) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; # these both should be the same INSERT INTO federated.t1 values (NULL, NULL, NULL, NULL); @@ -640,7 +640,7 @@ eval CREATE TABLE federated.t1 ( PRIMARY KEY (blurb_id)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 VALUES (1, " MySQL supports a number of column types in several categories: numeric types, date and time types, and string (character) types. This chapter first gives an overview of these column types, and then provides a more detailed description of the properties of the types in each category, and a summary of the column type storage requirements. The overview is intentionally brief. The more detailed descriptions should be consulted for additional information about particular column types, such as the allowable formats in which you can specify values."); INSERT INTO federated.t1 VALUES (2, "All arithmetic is done using signed BIGINT or DOUBLE values, so you should not use unsigned big integers larger than 9223372036854775807 (63 bits) except with bit functions! If you do that, some of the last digits in the result may be wrong because of rounding errors when converting a BIGINT value to a DOUBLE."); @@ -667,7 +667,7 @@ eval CREATE TABLE federated.t1 ( KEY (b)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 VALUES (3,3,3),(1,1,1),(2,2,2),(4,4,4); @@ -931,7 +931,7 @@ int, i999 int, i1000 int, b varchar(256)) row_format=dynamic ENGINE="FEDERATED" DEFAULT CHARSET=latin1 -COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1000,7 +1000,7 @@ eval CREATE TABLE federated.t1 ( index(code), index(fileguts(10))) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (code, fileguts, creation_date) VALUES ('ASDFWERQWETWETAWETA', '*()w*09*$()*#)(*09*^90*d)(*s()d8g)(s*ned)(*)(s*d)(*hn(d*)(*sbn)D((#$*(#*%%&#&^$#&#&#&#&^&#*&*#$*&^*(&#(&Q*&&(*!&!(*&*(#&*(%&#*###[[', '2003-03-03 03:03:03'); INSERT INTO federated.t1 (code, fileguts, creation_date) VALUES ('DEUEUEUEUEUEUEUEUEU', '*()w*09*$()*#)(*09*^90*d)(*s()d8g)(s*ned)(*)(s*d)(*hn(d*)(*sbn)D((#$*(#*%%&#&^$#&#&#&#&^&#*&*#$*&^*(&#(&Q*&&(*!&!(*&*(#&*(%&#*###[[', '2004-04-04 04:04:04'); INSERT INTO federated.t1 (code, fileguts, creation_date) VALUES ('DEUEUEUEUEUEUEUEUEU', 'jimbob', '2004-04-04 04:04:04'); @@ -1019,7 +1019,7 @@ DROP TABLE IF EXISTS federated.t1; eval CREATE TABLE federated.t1 ( `a` BLOB) ENGINE="FEDERATED" -COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 VALUES (0x00); INSERT INTO federated.t1 VALUES (0x0001); @@ -1031,7 +1031,7 @@ SELECT HEX(a) FROM federated.t1; # --replace_result $SLAVE_MYPORT SLAVE_PORT # eval CREATE TABLE federated.t1 # (a char(20)) charset=cp1251 -# ENGINE="FEDERATED" COMMENT="mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1"; +# ENGINE="FEDERATED" CONNECTION="mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1"; # # # connection slave; # DROP TABLE IF EXISTS federated.t1; @@ -1093,7 +1093,7 @@ eval CREATE TABLE federated.t1 ( PRIMARY KEY (`id`), KEY (country_id) ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; INSERT INTO federated.t1 (name, country_id, other) VALUES ('Kumar', 1, 11111); INSERT INTO federated.t1 (name, country_id, other) VALUES ('Lenz', 2, 22222); diff --git a/mysql-test/t/federated_archive.test b/mysql-test/t/federated_archive.test index facddebf558..df0d8c5cca1 100644 --- a/mysql-test/t/federated_archive.test +++ b/mysql-test/t/federated_archive.test @@ -25,7 +25,7 @@ eval CREATE TABLE federated.t1 ( PRIMARY KEY (`id`) ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 - COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/archive_table'; + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/archive_table'; INSERT INTO federated.t1 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t1 (id, name) VALUES (2, 'bar'); diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 96cb81fe3ec..02a110811c0 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -518,7 +518,7 @@ error: /* - Parse connection info from table->s->comment + Parse connection info from table->s->connect_string SYNOPSIS parse_url() @@ -563,7 +563,14 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, DBUG_ENTER("ha_federated::parse_url"); share->port= 0; - share->scheme= my_strdup(table->s->comment, MYF(0)); + DBUG_PRINT("info", ("Length %d \n", table->s->connect_string.length)); + DBUG_PRINT("info", ("String %.*s \n", table->s->connect_string.length, + table->s->connect_string.str)); + share->scheme= my_strdup_with_length(table->s->connect_string.str, + table->s->connect_string.length+1, + MYF(0)); + // Add a null for later termination of table name + share->scheme[table->s->connect_string.length]= 0; DBUG_PRINT("info",("parse_url alloced share->scheme %lx", share->scheme)); /* @@ -673,7 +680,8 @@ error: my_free((gptr) share->scheme, MYF(0)); share->scheme= 0; } - my_error(error_num, MYF(0), table->s->comment); + /* FIXME: table->s->connect_string is NOT null terminated */ + my_error(error_num, MYF(0), "invalid connection string"); DBUG_RETURN(error_num); } @@ -1313,7 +1321,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) &share, sizeof(*share), &tmp_table_name, tmp_table_name_length+ 1, &select_query, - query.length()+strlen(table->s->comment)+1, + query.length()+table->s->connect_string.length+1, NullS))) { pthread_mutex_unlock(&federated_mutex); @@ -1918,11 +1926,9 @@ int ha_federated::delete_row(const byte *buf) String delete_string(delete_buffer, sizeof(delete_buffer), &my_charset_bin); String data_string(data_buffer, sizeof(data_buffer), &my_charset_bin); - delete_string.length(0); - data_string.length(0); - DBUG_ENTER("ha_federated::delete_row"); + delete_string.length(0); delete_string.append(FEDERATED_DELETE); delete_string.append(FEDERATED_FROM); delete_string.append(FEDERATED_BTICK); @@ -1932,9 +1938,11 @@ int ha_federated::delete_row(const byte *buf) for (Field **field= table->field; *field; field++) { - delete_string.append((*field)->field_name); + Field *cur_field= *field; + data_string.length(0); + delete_string.append(cur_field->field_name); - if ((*field)->is_null()) + if (cur_field->is_null()) { delete_string.append(FEDERATED_IS); data_string.append(FEDERATED_NULL); @@ -1942,16 +1950,14 @@ int ha_federated::delete_row(const byte *buf) else { delete_string.append(FEDERATED_EQ); - (*field)->val_str(&data_string); - (*field)->quote_data(&data_string); + cur_field->val_str(&data_string); + cur_field->quote_data(&data_string); } delete_string.append(data_string); - data_string.length(0); - - if (*(field + 1)) - delete_string.append(FEDERATED_AND); + delete_string.append(FEDERATED_AND); } + delete_string.length(delete_string.length()-5); // Remove trailing AND delete_string.append(FEDERATED_LIMIT1); DBUG_PRINT("info", diff --git a/sql/handler.h b/sql/handler.h index 811791a498b..f1f9ab904d1 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -209,6 +209,7 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, #define HA_CREATE_USED_ROW_FORMAT (1L << 15) #define HA_CREATE_USED_COMMENT (1L << 16) #define HA_CREATE_USED_PASSWORD (1L << 17) +#define HA_CREATE_USED_CONNECTION (1L << 18) typedef ulonglong my_xid; // this line is the same as in log_event.h #define MYSQL_XID_PREFIX "MySQLXid" @@ -382,6 +383,7 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, typedef struct st_ha_create_information { CHARSET_INFO *table_charset, *default_table_charset; + LEX_STRING connect_string; const char *comment,*password; const char *data_file_name, *index_file_name; const char *alias; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 520b6190410..ebf270766be 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2694,6 +2694,7 @@ create_table_option: | INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR; } | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR; } + | CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length; Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; } ; default_charset: diff --git a/sql/table.cc b/sql/table.cc index 9d681141b1b..6ac5e07daf1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -71,7 +71,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, uint rec_buff_length,n_length,int_length,records,key_parts,keys, interval_count,interval_parts,read_length,db_create_options; uint key_info_length, com_length; - ulong pos; + ulong pos, record_offset; char index_file[FN_REFLEN], *names, *keynames, *comment_pos; uchar head[288],*disk_buff,new_field_pack_flag; my_string record; @@ -321,11 +321,12 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, rec_buff_length * records))) goto err; /* purecov: inspected */ share->default_values= (byte *) record; + + record_offset= (ulong) (uint2korr(head+6)+ + ((uint2korr(head+14) == 0xffff ? + uint4korr(head+47) : uint2korr(head+14)))); if (my_pread(file,(byte*) record, (uint) share->reclength, - (ulong) (uint2korr(head+6)+ - ((uint2korr(head+14) == 0xffff ? - uint4korr(head+47) : uint2korr(head+14)))), - MYF(MY_NABP))) + record_offset, MYF(MY_NABP))) goto err; /* purecov: inspected */ if (records == 1) @@ -342,6 +343,19 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, outparam->record[1]= outparam->record[0]; // Safety } + if ((n_length= uint2korr(head+55))) + { + /* Read extra block information */ + char *buff; + if (!(buff= alloc_root(&outparam->mem_root, n_length))) + goto err; + if (my_pread(file, buff, n_length, record_offset + share->reclength, + MYF(MY_NABP))) + goto err; + share->connect_string.length= uint2korr(buff); + share->connect_string.str= buff+2; + } + #ifdef HAVE_purify /* We need this because when we read var-length rows, we are not updating @@ -1350,10 +1364,15 @@ File create_frm(THD *thd, my_string name, const char *db, ulong length; char fill[IO_SIZE]; int create_flags= O_RDWR | O_TRUNC; + uint extra_size; if (create_info->options & HA_LEX_CREATE_TMP_TABLE) create_flags|= O_EXCL | O_NOFOLLOW; + extra_size= 0; + if (create_info->connect_string.length) + extra_size= 2+create_info->connect_string.length; + #if SIZEOF_OFF_T > 4 /* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */ if (create_info->max_rows > ~(ulong) 0) @@ -1381,7 +1400,7 @@ File create_frm(THD *thd, my_string name, const char *db, fileinfo[4]=1; int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ key_length=keys*(7+NAME_LEN+MAX_REF_PARTS*9)+16; - length=(ulong) next_io_size((ulong) (IO_SIZE+key_length+reclength)); + length= next_io_size((ulong) (IO_SIZE+key_length+reclength+extra_size)); int4store(fileinfo+10,length); tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff; int2store(fileinfo+14,tmp_key_length); @@ -1403,6 +1422,7 @@ File create_frm(THD *thd, my_string name, const char *db, int4store(fileinfo+47, key_length); tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store int4store(fileinfo+51, tmp); + int2store(fileinfo+55, extra_size); bzero(fill,IO_SIZE); for (; length > IO_SIZE ; length-= IO_SIZE) { diff --git a/sql/table.h b/sql/table.h index d7c14e1938a..8fd8dcc0bf8 100644 --- a/sql/table.h +++ b/sql/table.h @@ -126,6 +126,7 @@ typedef struct st_table_share const char *db; /* Pointer to db */ const char *table_name; /* Table name (for open) */ const char *path; /* Path to .frm file (from datadir) */ + LEX_STRING connect_string; key_map keys_in_use; /* Keys in use for table */ key_map keys_for_keyread; ulong avg_row_length; /* create information */ diff --git a/sql/unireg.cc b/sql/unireg.cc index a89d89426a6..18905c5368d 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -149,6 +149,15 @@ bool mysql_create_frm(THD *thd, my_string file_name, if (make_empty_rec(thd,file,create_info->db_type,create_info->table_options, create_fields,reclength, data_offset)) goto err; + if (create_info->connect_string.length) + { + char buff[2]; + int2store(buff,create_info->connect_string.length); + if (my_write(file, buff, sizeof(buff), MYF(MY_NABP)) || + my_write(file, create_info->connect_string.str, + create_info->connect_string.length, MYF(MY_NABP))) + goto err; + } VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0))); if (my_write(file,(byte*) forminfo,288,MYF_RW) || From b51879f1695e9a98bfb898b7688bf7c28932ad8c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 10:03:50 +0200 Subject: [PATCH 05/21] minor compile error fix --- ndb/src/ndbapi/SignalSender.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ndb/src/ndbapi/SignalSender.cpp b/ndb/src/ndbapi/SignalSender.cpp index 327f34f178a..a29fe68937b 100644 --- a/ndb/src/ndbapi/SignalSender.cpp +++ b/ndb/src/ndbapi/SignalSender.cpp @@ -272,7 +272,9 @@ SignalSender::execNodeStatus(void* signalSender, NdbCondition_Signal(ss->m_cond); } +#if __SUNPRO_CC != 0x560 template SimpleSignal* SignalSender::waitFor(unsigned, WaitForNode&); template SimpleSignal* SignalSender::waitFor(unsigned, WaitForAny&); +#endif template class Vector; From e7b5b5c8a59b855eac924f6e1344c15d6551e004 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 10:15:48 +0200 Subject: [PATCH 06/21] sql_prepare.cc: VC6 can't handle initializing const in declaration sql/sql_prepare.cc: VC6 can't handle initializing const in declaration --- sql/sql_prepare.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 879ea626494..624eccd2d67 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -118,9 +118,18 @@ public: bool deallocate(); /* Possible values of flags */ +#if defined(_MSC_VER) && _MSC_VER < 1300 + static const int IS_IN_USE; +#else static const int IS_IN_USE= 1; +#endif }; +/* VC6 can't handle initializing in declaration */ +#if defined(_MSC_VER) && _MSC_VER < 1300 +const int Prepared_statement::IS_IN_USE= 1; +#endif + /****************************************************************************** Implementation ******************************************************************************/ From 902932a1e86ea728a8cc62d2ab5b1e0544d797ae Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 12:50:21 +0200 Subject: [PATCH 07/21] Fixed BUG#13133: Local variables in stored procedures are not initialized correctly. Have to init. all local variables in their frames, not just once at the beginning of invocation. mysql-test/r/sp.result: New test case for BUG#13133. mysql-test/t/sp.test: New test case for BUG#13133. sql/sp_head.cc: Just init. local variable slots in the fram to NULL. (Real init. will be done in each block.) sql/sp_pcontext.cc: Removed isset flag, since it's not used. sql/sp_pcontext.h: Removed isset flag, since it's not used. sql/sql_yacc.yy: Initialize local variables in the block to null, or the default value, given. (Untabifed block too.) --- mysql-test/r/sp.result | 39 +++++++++++++++++++++++++ mysql-test/t/sp.test | 45 +++++++++++++++++++++++++++++ sql/sp_head.cc | 35 ++++++----------------- sql/sp_pcontext.cc | 1 - sql/sp_pcontext.h | 10 ------- sql/sql_yacc.yy | 65 +++++++++++++++++++----------------------- 6 files changed, 123 insertions(+), 72 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index cb696f93f79..4454f818efb 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3225,4 +3225,43 @@ select @var| @var abcdabcd drop procedure bug12849_2| +drop procedure if exists bug131333| +drop function if exists bug131333| +create procedure bug131333() +begin +begin +declare a int; +select a; +set a = 1; +select a; +end; +begin +declare b int; +select b; +end; +end| +create function bug131333() +returns int +begin +begin +declare a int; +set a = 1; +end; +begin +declare b int; +return b; +end; +end| +call bug131333()| +a +NULL +a +1 +b +NULL +select bug131333()| +bug131333() +NULL +drop procedure bug131333| +drop function bug131333| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 3d315fa12df..2b705329961 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4063,6 +4063,51 @@ call bug12849_2(@var)| select @var| drop procedure bug12849_2| +# +# BUG#13133: Local variables in stored procedures are not initialized correctly. +# +--disable_warnings +drop procedure if exists bug131333| +drop function if exists bug131333| +--enable_warnings +create procedure bug131333() +begin + begin + declare a int; + + select a; + set a = 1; + select a; + end; + begin + declare b int; + + select b; + end; +end| + +create function bug131333() + returns int +begin + begin + declare a int; + + set a = 1; + end; + begin + declare b int; + + return b; + end; +end| + +call bug131333()| +select bug131333()| + +drop procedure bug131333| +drop function bug131333| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 0444499de48..a11907373cd 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1078,7 +1078,6 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; uint i; - Item_null *nit; int ret= -1; // Assume error if (argcount != params) @@ -1109,22 +1108,15 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) nctx->push_item(it); } + /* The rest of the frame are local variables which are all IN. - Default all variables to null (those with default clauses will - be set by an set instruction). + Push NULLs to get the right size (and make the reuse mechanism work) - + the will be initialized by set instructions in each frame. */ - - nit= NULL; // Re-use this, and only create if needed for (; i < csize ; i++) - { - if (! nit) - { - if (!(nit= new Item_null())) - DBUG_RETURN(-1); - } - nctx->push_item(nit); - } + nctx->push_item(NULL); + thd->spcont= nctx; binlog_save_options= thd->options; @@ -1321,23 +1313,14 @@ int sp_head::execute_procedure(THD *thd, List *args) close_thread_tables(thd, 0, 0); DBUG_PRINT("info",(" %.*s: eval args done", m_name.length, m_name.str)); + /* The rest of the frame are local variables which are all IN. - Default all variables to null (those with default clauses will - be set by an set instruction). + Push NULLs to get the right size (and make the reuse mechanism work) - + the will be initialized by set instructions in each frame. */ for (; i < csize ; i++) - { - if (! nit) - { - if (!(nit= new Item_null())) - { - ret= -1; - break; - } - } - nctx->push_item(nit); - } + nctx->push_item(NULL); } thd->spcont= nctx; diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 0de7fe212c0..f873b676925 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -184,7 +184,6 @@ sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type, p->type= type; p->mode= mode; p->offset= current_pvars(); - p->isset= (mode == sp_param_out ? FALSE : TRUE); p->dflt= NULL; insert_dynamic(&m_pvar, (gptr)&p); } diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 196f9ccb24b..bd2259cb6fb 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -35,7 +35,6 @@ typedef struct sp_pvar enum enum_field_types type; sp_param_mode_t mode; uint offset; // Offset in current frame - my_bool isset; Item *dflt; } sp_pvar_t; @@ -147,15 +146,6 @@ class sp_pcontext : public Sql_alloc p->type= type; } - inline void - set_isset(uint i, my_bool val) - { - sp_pvar_t *p= find_pvar(i); - - if (p) - p->isset= val; - } - inline void set_default(uint i, Item *it) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 520b6190410..104f9ca8445 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1657,42 +1657,41 @@ sp_decls: ; sp_decl: - DECLARE_SYM sp_decl_idents type + DECLARE_SYM sp_decl_idents type { Lex->sphead->reset_lex(YYTHD); } sp_opt_default - { - LEX *lex= Lex; - sp_pcontext *ctx= lex->spcont; - uint max= ctx->context_pvars(); - enum enum_field_types type= (enum enum_field_types)$3; - Item *it= $5; + { + LEX *lex= Lex; + sp_pcontext *ctx= lex->spcont; + uint max= ctx->context_pvars(); + enum enum_field_types type= (enum enum_field_types)$3; + Item *it= $5; + bool has_default= (it != NULL); - for (uint i = max-$2 ; i < max ; i++) - { - ctx->set_type(i, type); - if (! it) - ctx->set_isset(i, FALSE); - else - { - sp_instr_set *in= new sp_instr_set(lex->sphead->instructions(), - ctx, - ctx->pvar_context2index(i), - it, type, lex, - (i == max - 1)); + for (uint i = max-$2 ; i < max ; i++) + { + sp_instr_set *in; - /* - The last instruction is assigned to be responsible for - freeing LEX. - */ - lex->sphead->add_instr(in); - ctx->set_isset(i, TRUE); - ctx->set_default(i, it); - } - } + ctx->set_type(i, type); + if (! has_default) + it= new Item_null(); /* QQ Set to the type with null_value? */ + in = new sp_instr_set(lex->sphead->instructions(), + ctx, + ctx->pvar_context2index(i), + it, type, lex, + (i == max - 1)); + + /* + The last instruction is assigned to be responsible for + freeing LEX. + */ + lex->sphead->add_instr(in); + ctx->set_default(i, it); + } lex->sphead->restore_lex(YYTHD); - $$.vars= $2; - $$.conds= $$.hndlrs= $$.curs= 0; - } + $$.vars= $2; + $$.conds= $$.hndlrs= $$.curs= 0; + } | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond { LEX *lex= Lex; @@ -2268,7 +2267,6 @@ sp_fetch_list: sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction(); i->add_to_varlist(spv); - spv->isset= TRUE; } } | @@ -2290,7 +2288,6 @@ sp_fetch_list: sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction(); i->add_to_varlist(spv); - spv->isset= TRUE; } } ; @@ -5894,7 +5891,6 @@ select_var_ident: else { ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset,t->type)); - t->isset= TRUE; } } ; @@ -7925,7 +7921,6 @@ sys_option_value: sp_set= new sp_instr_set(lex->sphead->instructions(), ctx, spv->offset, it, spv->type, lex, TRUE); lex->sphead->add_instr(sp_set); - spv->isset= TRUE; } } | option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types From dd51642361262ecb1cbe2088aee332244768ce29 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 15:15:38 +0400 Subject: [PATCH 08/21] Fix for Bug #13124 Stored Procedure using SELECT INTO crashes server mysql-test/r/sp.result: added a test mysql-test/t/sp.test: corrected result file sql/item.cc: check for NULL value before copying string --- mysql-test/r/sp.result | 8 ++++++++ mysql-test/t/sp.test | 15 +++++++++++++++ sql/item.cc | 7 ++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index cb696f93f79..d0a63e82999 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3225,4 +3225,12 @@ select @var| @var abcdabcd drop procedure bug12849_2| +drop procedure if exists bug13124| +create procedure bug13124() +begin +declare y integer; +set @x=y; +end| +call bug13124()| +drop procedure bug13124| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 3d315fa12df..15554801c9c 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4063,6 +4063,21 @@ call bug12849_2(@var)| select @var| drop procedure bug12849_2| +# +# Bug #13124 Stored Procedure using SELECT INTO crashes server +# + +--disable_warnings +drop procedure if exists bug13124| +--enable_warnings +create procedure bug13124() +begin + declare y integer; + set @x=y; +end| +call bug13124()| +drop procedure bug13124| + # # BUG#NNNN: New bug synopsis # diff --git a/sql/item.cc b/sql/item.cc index e7da646ae73..d18d0143d2c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -818,6 +818,8 @@ String *Item_splocal::val_str(String *sp) DBUG_ASSERT(fixed); Item *it= this_item(); String *ret= it->val_str(sp); + + null_value= it->null_value; /* This way we mark returned value of val_str as const, so that various functions (e.g. CONCAT) won't try to @@ -833,9 +835,12 @@ String *Item_splocal::val_str(String *sp) This is intended behaviour of Item_func_concat. Comments to Item_param class contain some more details on the topic. */ + + if (!ret) + return NULL; + str_value_ptr.set(ret->ptr(), ret->length(), ret->charset()); - null_value= it->null_value; return &str_value_ptr; } From d3f0c6257247cd5dde3d3e936f35d0899f49f8cb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 16:41:39 +0500 Subject: [PATCH 09/21] Print a dummy section in order not to interference with /etc/my.cnf and ~/.my.cnf [client] section. --- mysql-test/t/mysqldump.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index c34840b0725..591e320cbe4 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -766,10 +766,10 @@ DROP TABLE t1, t2; # Bugs #9136, #12917: problems with --defaults-extra-file option # ---exec echo "[client]" > $MYSQL_TEST_DIR/var/tmp/tmp.cnf +--exec echo "[mysqltest1]" > $MYSQL_TEST_DIR/var/tmp/tmp.cnf --exec echo "port=1234" >> $MYSQL_TEST_DIR/var/tmp/tmp.cnf ---exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQL_TEST_DIR/var/tmp/tmp.cnf client ---exec $MYSQL_MY_PRINT_DEFAULTS -e $MYSQL_TEST_DIR/var/tmp/tmp.cnf client +--exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQL_TEST_DIR/var/tmp/tmp.cnf mysqltest1 +--exec $MYSQL_MY_PRINT_DEFAULTS -e $MYSQL_TEST_DIR/var/tmp/tmp.cnf mysqltest1 --exec rm $MYSQL_TEST_DIR/var/tmp/tmp.cnf # From 738ee005032bdf709d10847953e454ef1ae0793c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 14:36:43 +0200 Subject: [PATCH 10/21] Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement Solution for 5.0. Changed calls to open_table(). Requested to ignore flush at places where the command did already lock tables. This could happen in CREATE ... SELECT and ALTER TABLE. No test case. The bug can only be triggered by true concurrency. The stress test suite provides a test case for this. sql/sql_base.cc: Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement Solution for 5.0. Changed open_table() so that ignoring flush requests is dependend on the 'flags' parameter as ignoring drop request was already. This aims for consistent behaviour. sql/sql_table.cc: Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement Solution for 5.0. Changed calls to open_table(). Requested to ignore flush at places where the command did already lock tables. This could happen in CREATE ... SELECT and ALTER TABLE. --- sql/sql_base.cc | 28 +++++++++++++++------------- sql/sql_table.cc | 6 ++++-- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 766840e667c..ea5ebede9c8 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1030,23 +1030,23 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) SYNOPSIS open_table() - thd Thread context - table_list Open first table in list - refresh Pointer to memory that will be set to 1 if - we need to close all tables and reopen them - If this is a NULL pointer, then the is no version - number checking and the table is not put in the - thread-open-list - flags Bitmap of flags to modify how open works: - MYSQL_LOCK_IGNORE_FLUSH - Open table even if someone - has done a flush or namelock on it. + thd Thread context. + table_list Open first table in list. + refresh INOUT Pointer to memory that will be set to 1 if + we need to close all tables and reopen them. + If this is a NULL pointer, then the table is not + put in the thread-open-list. + flags Bitmap of flags to modify how open works: + MYSQL_LOCK_IGNORE_FLUSH - Open table even if + someone has done a flush or namelock on it. + No version number checking is done. IMPLEMENTATION Uses a cache of open tables to find a table not in use. RETURN NULL Open failed. If refresh is set then one should close - all other tables and retry the open + all other tables and retry the open. # Success. Pointer to TABLE object for open table. */ @@ -1201,10 +1201,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (!thd->open_tables) thd->version=refresh_version; - else if (thd->version != refresh_version && refresh) + else if ((thd->version != refresh_version) && + ! (flags & MYSQL_LOCK_IGNORE_FLUSH)) { /* Someone did a refresh while thread was opening tables */ - *refresh=1; + if (refresh) + *refresh=1; VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(0); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 611ab0f16aa..16926200c4c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1756,7 +1756,8 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, create_info, *extra_fields, *keys, 0, select_field_count)) { - if (!(table= open_table(thd, create_table, thd->mem_root, (bool*)0, 0))) + if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0, + MYSQL_LOCK_IGNORE_FLUSH))) quick_rm_table(create_info->db_type, create_table->db, table_case_name(create_info, create_table->table_name)); } @@ -3579,7 +3580,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, bzero((void*) &tbl, sizeof(tbl)); tbl.db= new_db; tbl.table_name= tbl.alias= tmp_name; - new_table= open_table(thd, &tbl, thd->mem_root, 0, 0); + new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0, + MYSQL_LOCK_IGNORE_FLUSH); } else { From b6aba9db707da87500176693e41657a6ea1398e3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 15:32:42 +0200 Subject: [PATCH 11/21] Fixed BUG#12379: PROCEDURE with HANDLER calling FUNCTION with error get strange result according to Monty's suggestions, fixing the SELECT behaviour on errors with SP handlers. Note that some warnings from SELECT still shows up when the handler has caught - this is an effect of another known bug (BUG#7049). mysql-test/r/sp.result: New test cases for BUG#12379. mysql-test/t/sp.test: New test cases for BUG#12379. sql/sql_class.cc: Abort selects on errors more graceful with SP handlers. sql/sql_class.h: Abort selects on errors more graceful with SP handlers. --- mysql-test/r/sp.result | 59 ++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 55 +++++++++++++++++++++++++++++++++++++++ sql/sql_class.cc | 28 +++++++++++++++++++- sql/sql_class.h | 4 ++- 4 files changed, 144 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 4454f818efb..3d48a9f2803 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3264,4 +3264,63 @@ bug131333() NULL drop procedure bug131333| drop function bug131333| +drop function if exists bug12379| +drop procedure if exists bug12379_1| +drop procedure if exists bug12379_2| +drop procedure if exists bug12379_3| +drop table if exists t3| +create table t3 (c1 char(1) primary key not null)| +create function bug12379() +returns integer +begin +insert into t3 values('X'); +insert into t3 values('X'); +return 0; +end| +create procedure bug12379_1() +begin +declare exit handler for sqlexception select 42; +select bug12379(); +END| +create procedure bug12379_2() +begin +declare exit handler for sqlexception begin end; +select bug12379(); +end| +create procedure bug12379_3() +begin +select bug12379(); +end| +select bug12379()| +ERROR 23000: Duplicate entry 'X' for key 1 +select 1| +1 +1 +call bug12379_1()| +bug12379() +42 +42 +Warnings: +Error 1062 Duplicate entry 'X' for key 1 +Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes +select 2| +2 +2 +call bug12379_2()| +bug12379() +Warnings: +Error 1062 Duplicate entry 'X' for key 1 +Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes +select 3| +3 +3 +call bug12379_3()| +ERROR 23000: Duplicate entry 'X' for key 1 +select 4| +4 +4 +drop function bug12379| +drop procedure bug12379_1| +drop procedure bug12379_2| +drop procedure bug12379_3| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 2b705329961..7a9738e8ada 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4108,6 +4108,61 @@ drop procedure bug131333| drop function bug131333| +# +# BUG#12379: PROCEDURE with HANDLER calling FUNCTION with error get +# strange result +# +--disable_warnings +drop function if exists bug12379| +drop procedure if exists bug12379_1| +drop procedure if exists bug12379_2| +drop procedure if exists bug12379_3| +drop table if exists t3| +--enable_warnings + +create table t3 (c1 char(1) primary key not null)| + +create function bug12379() + returns integer +begin + insert into t3 values('X'); + insert into t3 values('X'); + return 0; +end| + +create procedure bug12379_1() +begin + declare exit handler for sqlexception select 42; + + select bug12379(); +END| +create procedure bug12379_2() +begin + declare exit handler for sqlexception begin end; + + select bug12379(); +end| +create procedure bug12379_3() +begin + select bug12379(); +end| + +--error 1062 +select bug12379()| +select 1| +call bug12379_1()| +select 2| +call bug12379_2()| +select 3| +--error 1062 +call bug12379_3()| +select 4| + +drop function bug12379| +drop procedure bug12379_1| +drop procedure bug12379_2| +drop procedure bug12379_3| + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 975014b9780..2699a4fa628 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -865,9 +865,34 @@ sql_exchange::sql_exchange(char *name,bool flag) bool select_send::send_fields(List &list, uint flags) { - return thd->protocol->send_fields(&list, flags); + bool res; + if (!(res= thd->protocol->send_fields(&list, flags))) + status= 1; + return res; } +void select_send::abort() +{ + DBUG_ENTER("select_send::abort"); + if (status && thd->spcont && + thd->spcont->find_handler(thd->net.last_errno, + MYSQL_ERROR::WARN_LEVEL_ERROR)) + { + /* + Executing stored procedure without a handler. + Here we should actually send an error to the client, + but as an error will break a multiple result set, the only thing we + can do for now is to nicely end the current data set and remembering + the error so that the calling routine will abort + */ + thd->net.report_error= 0; + send_eof(); + thd->net.report_error= 1; // Abort SP + } + DBUG_VOID_RETURN; +} + + /* Send data to client. Returns 0 if ok */ bool select_send::send_data(List &items) @@ -930,6 +955,7 @@ bool select_send::send_eof() if (!thd->net.report_error) { ::send_eof(thd); + status= 0; return 0; } else diff --git a/sql/sql_class.h b/sql/sql_class.h index a0c61944c6a..1a215d39841 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1658,12 +1658,14 @@ public: class select_send :public select_result { + int status; public: - select_send() {} + select_send() :status(0) {} bool send_fields(List &list, uint flags); bool send_data(List &items); bool send_eof(); bool simple_select() { return 1; } + void abort(); }; From 1485e9236c849008b459f407f9bdfe78bc0b13ff Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 17:06:14 +0200 Subject: [PATCH 12/21] BUG#12526 yassl: Crashes in "integer.cpp" - Avoid problem with "Sun C++ 5.6 2004/07/15" extra/yassl/taocrypt/src/integer.cpp: - Remove "inline" from the more advanced functions of class portable --- extra/yassl/taocrypt/src/integer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index 71324b04b92..01bd5b2ec94 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -568,13 +568,13 @@ public: static word Add(word *C, const word *A, const word *B, unsigned int N); static word Subtract(word *C, const word *A, const word*B, unsigned int N); - static inline void Multiply2(word *C, const word *A, const word *B); - static inline word Multiply2Add(word *C, const word *A, const word *B); + static void Multiply2(word *C, const word *A, const word *B); + static word Multiply2Add(word *C, const word *A, const word *B); static void Multiply4(word *C, const word *A, const word *B); static void Multiply8(word *C, const word *A, const word *B); static inline unsigned int MultiplyRecursionLimit() {return 8;} - static inline void Multiply2Bottom(word *C, const word *A, const word *B); + static void Multiply2Bottom(word *C, const word *A, const word *B); static void Multiply4Bottom(word *C, const word *A, const word *B); static void Multiply8Bottom(word *C, const word *A, const word *B); static inline unsigned int MultiplyBottomRecursionLimit() {return 8;} @@ -668,7 +668,7 @@ void Portable::Multiply2(word *C, const word *A, const word *B) C[3] = t.GetHighHalf(); } -inline void Portable::Multiply2Bottom(word *C, const word *A, const word *B) +void Portable::Multiply2Bottom(word *C, const word *A, const word *B) { DWord t = DWord::Multiply(A[0], B[0]); C[0] = t.GetLowHalf(); From 02fce1c316e7a33748eb7ccf13a49fbaa2926ee6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 18:11:51 +0300 Subject: [PATCH 13/21] Merged code. Removed unneccessary repeating. --- sql/sql_analyse.cc | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index c2cb427a5eb..d2237c24139 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -788,24 +788,22 @@ void field_real::get_opt_type(String *answer, if (!max_notzero_dec_len) { + int len= (int) max_length - ((item->decimals == NOT_FIXED_DEC) ? + 0 : (item->decimals + 1)); + if (min_arg >= -128 && max_arg <= (min_arg >= 0 ? 255 : 127)) - sprintf(buff, "TINYINT(%d)", (int) max_length - - ((item->decimals == NOT_FIXED_DEC) ? 0 : (item->decimals + 1))); + sprintf(buff, "TINYINT(%d)", len); else if (min_arg >= INT_MIN16 && max_arg <= (min_arg >= 0 ? UINT_MAX16 : INT_MAX16)) - sprintf(buff, "SMALLINT(%d)", (int) max_length - - ((item->decimals == NOT_FIXED_DEC) ? 0 : (item->decimals + 1))); + sprintf(buff, "SMALLINT(%d)", len); else if (min_arg >= INT_MIN24 && max_arg <= (min_arg >= 0 ? UINT_MAX24 : INT_MAX24)) - sprintf(buff, "MEDIUMINT(%d)", (int) max_length - - ((item->decimals == NOT_FIXED_DEC) ? 0 : (item->decimals + 1))); + sprintf(buff, "MEDIUMINT(%d)", len); else if (min_arg >= INT_MIN32 && max_arg <= (min_arg >= 0 ? UINT_MAX32 : INT_MAX32)) - sprintf(buff, "INT(%d)", (int) max_length - - ((item->decimals == NOT_FIXED_DEC) ? 0 : (item->decimals + 1))); + sprintf(buff, "INT(%d)", len); else - sprintf(buff, "BIGINT(%d)", (int) max_length - - ((item->decimals == NOT_FIXED_DEC) ? 0 : (item->decimals + 1))); + sprintf(buff, "BIGINT(%d)", len); answer->append(buff, (uint) strlen(buff)); if (min_arg >= 0) answer->append(" UNSIGNED"); From d1bc788ed1feb05d3b511aea5ae614b3b6851fc6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 19:59:26 +0400 Subject: [PATCH 14/21] after-merge fix --- mysql-test/t/sp.test | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 0d0fcee7449..a1e2bf8aa32 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4107,21 +4107,6 @@ select bug131333()| drop procedure bug131333| drop function bug131333| -# -# Bug #13124 Stored Procedure using SELECT INTO crashes server -# - ---disable_warnings -drop procedure if exists bug13124| ---enable_warnings -create procedure bug13124() -begin - declare y integer; - set @x=y; -end| -call bug13124()| -drop procedure bug13124| - # # BUG#12379: PROCEDURE with HANDLER calling FUNCTION with error get # strange result @@ -4177,6 +4162,21 @@ drop procedure bug12379_1| drop procedure bug12379_2| drop procedure bug12379_3| +# +# Bug #13124 Stored Procedure using SELECT INTO crashes server +# + +--disable_warnings +drop procedure if exists bug13124| +--enable_warnings +create procedure bug13124() +begin + declare y integer; + set @x=y; +end| +call bug13124()| +drop procedure bug13124| + # # BUG#NNNN: New bug synopsis # From 21f4f6cfba558f98e3146a967c7953abe691e717 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 19:32:37 +0200 Subject: [PATCH 15/21] after pull review - many bugs in mysqldump --routines mysql-test/r/mysqldump.result: updated mysql-test/t/mysqldump.test: cleanup, new test --- client/mysqldump.c | 63 +++++++++++++---------------------- mysql-test/r/mysqldump.result | 48 ++++++++++++++------------ mysql-test/t/mysqldump.test | 49 ++++++++++++++------------- 3 files changed, 76 insertions(+), 84 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index e1218d1bc69..2f7040afb05 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1193,12 +1193,11 @@ static void print_xml_row(FILE *xml_file, const char *row_name, static uint dump_routines_for_db (char *db) { - char query_buff[512], routine_type[10]; - char db_name_buff[NAME_LEN+3], name_buff[NAME_LEN+3]; + char query_buff[512], *routine_type[]={"FUNCTION", "PROCEDURE"}; + char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3], *routine_name; int i; FILE *sql_file = md_result_file; - MYSQL_RES *routine_res= NULL; - MYSQL_RES *routine_list_res= NULL; + MYSQL_RES *routine_res, *routine_list_res; MYSQL_ROW row, routine_list_row; DBUG_ENTER("dump_routines_for_db"); @@ -1211,23 +1210,20 @@ static uint dump_routines_for_db (char *db) fprintf(sql_file, "\n--\n-- Dumping routines for database '%s'\n--\n", db); /* - not using "mysql_query_with_error_report" because of privileges + not using "mysql_query_with_error_report" because we may have not + enough privileges to lock mysql.proc. */ - if (opt_lock) + if (lock_tables) mysql_query(sock, "LOCK TABLES mysql.proc READ"); - fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n"); fprintf(sql_file, "DELIMITER //\n"); /* 0, retrieve and dump functions, 1, procedures */ for (i=0; i <= 1; i++) { - my_snprintf(routine_type, sizeof(routine_type), - "%s", i == 0 ? "FUNCTION" : "PROCEDURE"); - my_snprintf(query_buff, sizeof(query_buff), "SHOW %s STATUS WHERE Db = '%s'", - routine_type, db_name_buff); + routine_type[i], db_name_buff); if (mysql_query_with_error_report(sock, &routine_list_res, query_buff)) DBUG_RETURN(1); @@ -1237,11 +1233,11 @@ static uint dump_routines_for_db (char *db) while((routine_list_row= mysql_fetch_row(routine_list_res))) { - DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type, name_buff)); - mysql_real_escape_string(sock, name_buff, - routine_list_row[1], strlen(routine_list_row[1])); + DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i], + name_buff)); + routine_name=quote_name(routine_list_row[1], name_buff, 0); my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s", - routine_type, name_buff); + routine_type[i], routine_name); if (mysql_query_with_error_report(sock, &routine_res, query_buff)) DBUG_RETURN(1); @@ -1249,41 +1245,36 @@ static uint dump_routines_for_db (char *db) while ((row=mysql_fetch_row(routine_res))) { /* - the user can see routine names, but NOT the routine body of other - routines that are not the creator of! + if the user has EXECUTE privilege he see routine names, but NOT the + routine body of other routines that are not the creator of! */ DBUG_PRINT("info",("length of body for %s row[2] '%s' is %d", - name_buff, row[2], strlen(row[2]))); + routine_name, row[2], strlen(row[2]))); if (strlen(row[2])) { - fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/ //\n", - row[1] /* sql_mode */); - if (opt_drop) fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */ //\n", - routine_type, name_buff); + routine_type[i], routine_name); /* - the i==0 is temporary until we can figure out why functions - can't be in comments - */ - /* create proc/func body */; + we need to change sql_mode only for the CREATE PROCEDURE/FUNCTION + otherwise we may need to re-quote routine_name + */; + fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/ //\n", + row[1] /* sql_mode */); fprintf(sql_file, "/*!50003 %s */ //\n", row[2]); + fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ //\n"); } } /* end of routine printing */ } /* end of list of routines */ mysql_free_result(routine_res); - routine_res=NULL; } mysql_free_result(routine_list_res); - routine_list_res=NULL; } /* end of for i (0 .. 1) */ /* set the delimiter back to ';' */ fprintf(sql_file, "DELIMITER ;\n"); - fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;\n"); - /* again, no error report due to permissions */ - if (opt_lock) - mysql_query(sock, "UNLOCK TABLES"); + if (lock_tables) + mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"); DBUG_RETURN(0); } @@ -1739,12 +1730,6 @@ continue_xml: the tables have been dumped in case a trigger depends on the existence of a table - INPUT - char * tablename and db name - RETURNS - 0 Failure - 1 Succes - */ static void dump_triggers_for_table (char *table, char *db) @@ -1752,7 +1737,7 @@ static void dump_triggers_for_table (char *table, char *db) MYSQL_RES *result; MYSQL_ROW row; char *result_table; - char name_buff[NAME_LEN+3], table_buff[NAME_LEN*2+3]; + char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3]; char query_buff[512]; FILE *sql_file = md_result_file; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index f795bda5553..f23f18ae217 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1908,28 +1908,28 @@ a2 DROP TRIGGER testref; DROP TABLE test1; DROP TABLE test2; -CREATE TABLE t1 (id int); -INSERT INTO t1 VALUES(1); -INSERT INTO t1 VALUES(2); -INSERT INTO t1 VALUES(3); -INSERT INTO t1 VALUES(4); -INSERT INTO t1 VALUES(5); +DROP TABLE IF EXISTS t1; DROP FUNCTION IF EXISTS bug9056_func1; -CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) -RETURN a+b // +DROP FUNCTION IF EXISTS bug9056_func2; +DROP PROCEDURE IF EXISTS bug9056_proc1; +DROP PROCEDURE IF EXISTS bug9056_proc2; +CREATE TABLE t1 (id int); +INSERT INTO t1 VALUES(1), (2), (3), (4), (5); +CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) RETURN a+b // CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT) BEGIN SELECT a+b INTO c; end // -DROP FUNCTION IF EXISTS bug9056_func2 // create function bug9056_func2(f1 char binary) returns char binary begin set f1= concat( 'hello', f1 ); return f1; end // -DROP PROCEDURE IF EXISTS bug9056_proc2 // CREATE PROCEDURE bug9056_proc2(OUT a INT) BEGIN select sum(id) from t1 into a; END // +set sql_mode='ansi'; +create procedure `a'b` () select 1; +set sql_mode=''; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1954,32 +1954,38 @@ LOCK TABLES `t1` WRITE; INSERT INTO `t1` VALUES (1),(2),(3),(4),(5); UNLOCK TABLES; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; - -/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/; DELIMITER // +/*!50003 DROP FUNCTION IF EXISTS `bug9056_func1` */ // /*!50003 SET SESSION SQL_MODE=""*/ // -/*!50003 DROP FUNCTION IF EXISTS bug9056_func1 */ // /*!50003 CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) RETURN a+b */ // +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // +/*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */ // /*!50003 SET SESSION SQL_MODE=""*/ // -/*!50003 DROP FUNCTION IF EXISTS bug9056_func2 */ // /*!50003 CREATE FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) begin set f1= concat( 'hello', f1 ); return f1; end */ // +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // +/*!50003 DROP PROCEDURE IF EXISTS `a'b` */ // +/*!50003 SET SESSION SQL_MODE="REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI"*/ // +/*!50003 CREATE PROCEDURE "a'b"() +select 1 */ // +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // +/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc1` */ // /*!50003 SET SESSION SQL_MODE=""*/ // -/*!50003 DROP PROCEDURE IF EXISTS bug9056_proc1 */ // /*!50003 CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT) BEGIN SELECT a+b INTO c; end */ // +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // +/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc2` */ // /*!50003 SET SESSION SQL_MODE=""*/ // -/*!50003 DROP PROCEDURE IF EXISTS bug9056_proc2 */ // /*!50003 CREATE PROCEDURE `bug9056_proc2`(OUT a INT) BEGIN select sum(id) from t1 into a; END */ // +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // DELIMITER ; -/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; @@ -1989,8 +1995,8 @@ DELIMITER ; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -DROP PROCEDURE IF EXISTS bug9056_func1; -DROP PROCEDURE IF EXISTS bug9056_func2; -DROP PROCEDURE IF EXISTS bug9056_proc1; -DROP PROCEDURE IF EXISTS bug9056_proc2; +DROP FUNCTION bug9056_func1; +DROP FUNCTION bug9056_func2; +DROP PROCEDURE bug9056_proc1; +DROP PROCEDURE bug9056_proc2; drop table t1; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index c34840b0725..9fce7ca42cd 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -810,34 +810,32 @@ DROP TRIGGER testref; DROP TABLE test1; DROP TABLE test2; -CREATE TABLE t1 (id int); -INSERT INTO t1 VALUES(1); -INSERT INTO t1 VALUES(2); -INSERT INTO t1 VALUES(3); -INSERT INTO t1 VALUES(4); -INSERT INTO t1 VALUES(5); ---disable_warnings -DROP FUNCTION IF EXISTS bug9056_func1; -DELIMITER //; ---enable_warnings -CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) -RETURN a+b // -CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT) -BEGIN SELECT a+b INTO c; end // +# +# BUG#9056 - mysqldump does not dump routines +# --disable_warnings -DROP FUNCTION IF EXISTS bug9056_func2 // +DROP TABLE IF EXISTS t1; +DROP FUNCTION IF EXISTS bug9056_func1; +DROP FUNCTION IF EXISTS bug9056_func2; +DROP PROCEDURE IF EXISTS bug9056_proc1; +DROP PROCEDURE IF EXISTS bug9056_proc2; --enable_warnings +CREATE TABLE t1 (id int); +INSERT INTO t1 VALUES(1), (2), (3), (4), (5); + +DELIMITER //; +CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) RETURN a+b // +CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT) +BEGIN SELECT a+b INTO c; end // + create function bug9056_func2(f1 char binary) returns char binary begin set f1= concat( 'hello', f1 ); return f1; end // ---disable_warnings -DROP PROCEDURE IF EXISTS bug9056_proc2 // ---enable_warnings CREATE PROCEDURE bug9056_proc2(OUT a INT) BEGIN select sum(id) from t1 into a; @@ -845,14 +843,17 @@ END // DELIMITER ;// +set sql_mode='ansi'; +create procedure `a'b` () select 1; # to fix syntax highlighting :') +set sql_mode=''; + # Dump the DB and ROUTINES --exec $MYSQL_DUMP --skip-comments --routines --databases test # ok, now blow it all away ---disable_warnings -DROP PROCEDURE IF EXISTS bug9056_func1; -DROP PROCEDURE IF EXISTS bug9056_func2; -DROP PROCEDURE IF EXISTS bug9056_proc1; -DROP PROCEDURE IF EXISTS bug9056_proc2; +DROP FUNCTION bug9056_func1; +DROP FUNCTION bug9056_func2; +DROP PROCEDURE bug9056_proc1; +DROP PROCEDURE bug9056_proc2; drop table t1; ---enable-warnings + From f1c4e958cd1b276543710600def1644126f56752 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 11:59:19 -0700 Subject: [PATCH 16/21] Fixed minor error message bug from work for WL#2414 mysql-test/r/federated.result: fixed error message sql/ha_federated.cc: Minor refactoring to fix error message, resulting in big whitespace change --- mysql-test/r/federated.result | 2 +- sql/ha_federated.cc | 194 +++++++++++++++++----------------- 2 files changed, 97 insertions(+), 99 deletions(-) diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index cb58f12bbc0..1ec9857c8a7 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -26,7 +26,7 @@ CREATE TABLE federated.t1 ( ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:@/too/many/items/federated/t1'; -ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1:@/too/many/items/federated/t1ее' is not in the correct format +ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1:@/too/many/items/federated/t1' is not in the correct format CREATE TABLE federated.t1 ( `id` int(20) NOT NULL, `name` varchar(32) NOT NULL default '' diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 02a110811c0..5cc5b7aa32c 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -517,6 +517,25 @@ error: } +static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num) +{ + char buf[table->s->connect_string.length+1]; + DBUG_ENTER("ha_federated parse_url_error"); + if (share->scheme) + { + DBUG_PRINT("info", + ("error: parse_url. Returning error code %d \ + freeing share->scheme %lx", error_num, share->scheme)); + my_free((gptr) share->scheme, MYF(0)); + share->scheme= 0; + } + + strnmov(buf, table->s->connect_string.str, table->s->connect_string.length+1); + buf[table->s->connect_string.length]= '\0'; + my_error(error_num, MYF(0), buf); + DBUG_RETURN(error_num); +} + /* Parse connection info from table->s->connect_string @@ -577,113 +596,92 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, remove addition of null terminator and store length for each string in share */ - if ((share->username= strstr(share->scheme, "://"))) + if (!(share->username= strstr(share->scheme, "://"))) + goto error; + share->scheme[share->username - share->scheme]= '\0'; + + if (strcmp(share->scheme, "mysql") != 0) + goto error; + + share->username+= 3; + + if (!(share->hostname= strchr(share->username, '@'))) + goto error; + + share->username[share->hostname - share->username]= '\0'; + share->hostname++; + + if ((share->password= strchr(share->username, ':'))) { - share->scheme[share->username - share->scheme]= '\0'; - - if (strcmp(share->scheme, "mysql") != 0) - goto error; - - share->username+= 3; - - if ((share->hostname= strchr(share->username, '@'))) - { - share->username[share->hostname - share->username]= '\0'; - share->hostname++; - - if ((share->password= strchr(share->username, ':'))) - { - share->username[share->password - share->username]= '\0'; - share->password++; - share->username= share->username; - /* make sure there isn't an extra / or @ */ - if ((strchr(share->password, '/') || strchr(share->hostname, '@'))) - goto error; - /* - Found that if the string is: - user:@hostname:port/database/table - Then password is a null string, so set to NULL - */ - if ((share->password[0] == '\0')) - share->password= NULL; - } - else - share->username= share->username; - - /* make sure there isn't an extra / or @ */ - if ((strchr(share->username, '/')) || (strchr(share->hostname, '@'))) - goto error; - - if ((share->database= strchr(share->hostname, '/'))) - { - share->hostname[share->database - share->hostname]= '\0'; - share->database++; - - if ((share->sport= strchr(share->hostname, ':'))) - { - share->hostname[share->sport - share->hostname]= '\0'; - share->sport++; - if (share->sport[0] == '\0') - share->sport= NULL; - else - share->port= atoi(share->sport); - } - - if ((share->table_name= strchr(share->database, '/'))) - { - share->database[share->table_name - share->database]= '\0'; - share->table_name++; - } - else - goto error; - - share->table_name_length= strlen(share->table_name); - } - else - goto error; - /* make sure there's not an extra / */ - if ((strchr(share->table_name, '/'))) - goto error; - - if (share->hostname[0] == '\0') - share->hostname= NULL; - - if (!share->port) - { - if (strcmp(share->hostname, my_localhost) == 0) - share->socket= my_strdup(MYSQL_UNIX_ADDR, MYF(0)); - else - share->port= MYSQL_PORT; - } - - DBUG_PRINT("info", - ("scheme %s username %s password %s \ - hostname %s port %d database %s tablename %s\n", - share->scheme, share->username, share->password, - share->hostname, share->port, share->database, - share->table_name)); - } - else + share->username[share->password - share->username]= '\0'; + share->password++; + share->username= share->username; + /* make sure there isn't an extra / or @ */ + if ((strchr(share->password, '/') || strchr(share->hostname, '@'))) goto error; + /* + Found that if the string is: + user:@hostname:port/database/table + Then password is a null string, so set to NULL + */ + if ((share->password[0] == '\0')) + share->password= NULL; } else + share->username= share->username; + + /* make sure there isn't an extra / or @ */ + if ((strchr(share->username, '/')) || (strchr(share->hostname, '@'))) goto error; + if (!(share->database= strchr(share->hostname, '/'))) + goto error; + share->hostname[share->database - share->hostname]= '\0'; + share->database++; + + if ((share->sport= strchr(share->hostname, ':'))) + { + share->hostname[share->sport - share->hostname]= '\0'; + share->sport++; + if (share->sport[0] == '\0') + share->sport= NULL; + else + share->port= atoi(share->sport); + } + + if (!(share->table_name= strchr(share->database, '/'))) + goto error; + share->database[share->table_name - share->database]= '\0'; + share->table_name++; + + share->table_name_length= strlen(share->table_name); + + /* make sure there's not an extra / */ + if ((strchr(share->table_name, '/'))) + goto error; + + if (share->hostname[0] == '\0') + share->hostname= NULL; + + if (!share->port) + { + if (strcmp(share->hostname, my_localhost) == 0) + share->socket= my_strdup(MYSQL_UNIX_ADDR, MYF(0)); + else + share->port= MYSQL_PORT; + } + + DBUG_PRINT("info", + ("scheme %s username %s password %s \ + hostname %s port %d database %s tablename %s\n", + share->scheme, share->username, share->password, + share->hostname, share->port, share->database, + share->table_name)); + DBUG_RETURN(0); error: - if (share->scheme) - { - DBUG_PRINT("info", - ("error: parse_url. Returning error code %d \ - freeing share->scheme %lx", error_num, share->scheme)); - my_free((gptr) share->scheme, MYF(0)); - share->scheme= 0; - } - /* FIXME: table->s->connect_string is NOT null terminated */ - my_error(error_num, MYF(0), "invalid connection string"); - DBUG_RETURN(error_num); - + DBUG_RETURN(parse_url_error(share, table, error_num)); } From c6dfe79beba3a4c03468d6e45aface45dfc38967 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 14:53:19 -0500 Subject: [PATCH 17/21] fixed the service bits of the IM server-tools/instance-manager/IMService.cpp: * setting username and password to NULL so that the IM runs at LocalSystem (this should be changed soon) * implemented stop service by raising a sigterm * implemented start service by loading options and calling manager() server-tools/instance-manager/IMService.h: changed the sig for Run() server-tools/instance-manager/WindowsService.cpp: default debugging to false changed the sig of RuN() server-tools/instance-manager/WindowsService.h: change the sig of run() server-tools/instance-manager/instance.cc: * remove the inclusion of process.h * concat all args into a single buffer to pass to CreateProcess server-tools/instance-manager/instance_options.cc: quoting the binary to handle paths with quotes server-tools/instance-manager/listener.cc: use a timeval for select so that our select will only run for 100 msec before we check to see if we are shutting down server-tools/instance-manager/mysqlmanager.cc: if we are given the stand alone option, then run the manager as standalone server-tools/instance-manager/options.cc: Added stand alone command line arg server-tools/instance-manager/options.h: Added stand alone command line arg --- server-tools/instance-manager/IMService.cpp | 13 ++++++++- server-tools/instance-manager/IMService.h | 2 +- .../instance-manager/WindowsService.cpp | 5 ++-- .../instance-manager/WindowsService.h | 2 +- server-tools/instance-manager/instance.cc | 28 ++++++++----------- .../instance-manager/instance_options.cc | 8 ++++++ server-tools/instance-manager/listener.cc | 13 +++++---- server-tools/instance-manager/mysqlmanager.cc | 10 ++++--- server-tools/instance-manager/options.cc | 5 ++++ server-tools/instance-manager/options.h | 3 +- 10 files changed, 58 insertions(+), 31 deletions(-) diff --git a/server-tools/instance-manager/IMService.cpp b/server-tools/instance-manager/IMService.cpp index e040a5da8c2..b7ea8e7eb81 100644 --- a/server-tools/instance-manager/IMService.cpp +++ b/server-tools/instance-manager/IMService.cpp @@ -1,12 +1,16 @@ #include +#include #include "log.h" #include "options.h" #include "IMService.h" +#include "manager.h" IMService::IMService(void) { serviceName= "MySqlManager"; displayName= "MySQL Manager"; + username= NULL; + password= NULL; } IMService::~IMService(void) @@ -16,18 +20,25 @@ IMService::~IMService(void) void IMService::Stop() { ReportStatus(SERVICE_STOP_PENDING); + // stop the IM work + raise(SIGTERM); } -void IMService::Run() +void IMService::Run(DWORD argc, LPTSTR *argv) { // report to the SCM that we're about to start ReportStatus((DWORD)SERVICE_START_PENDING); + Options o; + o.load(argc, argv); + // init goes here ReportStatus((DWORD)SERVICE_RUNNING); // wait for main loop to terminate + manager(o); + o.cleanup(); } void IMService::Log(const char *msg) diff --git a/server-tools/instance-manager/IMService.h b/server-tools/instance-manager/IMService.h index 60c202fc561..cad38bebdaf 100644 --- a/server-tools/instance-manager/IMService.h +++ b/server-tools/instance-manager/IMService.h @@ -10,5 +10,5 @@ public: protected: void Log(const char *msg); void Stop(); - void Run(); + void Run(DWORD argc, LPTSTR *argv); }; diff --git a/server-tools/instance-manager/WindowsService.cpp b/server-tools/instance-manager/WindowsService.cpp index fb7e00e0d9b..192045b7a4c 100644 --- a/server-tools/instance-manager/WindowsService.cpp +++ b/server-tools/instance-manager/WindowsService.cpp @@ -8,7 +8,8 @@ WindowsService::WindowsService(void) : statusCheckpoint(0), serviceName(NULL), inited(false), - dwAcceptedControls(SERVICE_ACCEPT_STOP) + dwAcceptedControls(SERVICE_ACCEPT_STOP), + debugging(false) { gService= this; status.dwServiceType= SERVICE_WIN32_OWN_PROCESS; @@ -148,7 +149,7 @@ void WindowsService::RegisterAndRun(DWORD argc, LPTSTR *argv) { statusHandle= ::RegisterServiceCtrlHandler(serviceName, ControlHandler); if (statusHandle && ReportStatus(SERVICE_START_PENDING)) - Run(); + Run(argc, argv); ReportStatus(SERVICE_STOPPED); } diff --git a/server-tools/instance-manager/WindowsService.h b/server-tools/instance-manager/WindowsService.h index 612eeda21e9..1a034ce1351 100644 --- a/server-tools/instance-manager/WindowsService.h +++ b/server-tools/instance-manager/WindowsService.h @@ -30,7 +30,7 @@ public: static void WINAPI ControlHandler(DWORD CtrlType); protected: - virtual void Run()= 0; + virtual void Run(DWORD argc, LPTSTR *argv)= 0; virtual void Stop() {} virtual void Shutdown() {} virtual void Pause() {} diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc index 7f705bac1c1..5e1c3d2ea9f 100644 --- a/server-tools/instance-manager/instance.cc +++ b/server-tools/instance-manager/instance.cc @@ -18,9 +18,6 @@ #pragma implementation #endif -#ifdef __WIN__ -#include -#endif #include "instance.h" #include "mysql_manager_error.h" @@ -171,25 +168,24 @@ static int start_process(Instance_options *instance_options, ZeroMemory(pi, sizeof(PROCESS_INFORMATION)); int cmdlen= 0; - for (int i= 1; instance_options->argv[i] != 0; i++) - cmdlen+= strlen(instance_options->argv[i]) + 1; - cmdlen++; /* we have to add a single space for CreateProcess (see docs) */ + for (int i= 0; instance_options->argv[i] != 0; i++) + cmdlen+= strlen(instance_options->argv[i]) + 3; + cmdlen++; /* make room for the null */ - char *cmdline= NULL; - if (cmdlen > 0) + char *cmdline= new char[cmdlen]; + if (cmdline == NULL) + return 1; + + for (int i= 0; instance_options->argv[i] != 0; i++) { - cmdline= new char[cmdlen]; - cmdline[0]= 0; - for (int i= 1; instance_options->argv[i] != 0; i++) - { - strcat(cmdline, " "); - strcat(cmdline, instance_options->argv[i]); - } + strcat(cmdline, "\""); + strcat(cmdline, instance_options->argv[i]); + strcat(cmdline, "\" "); } /* Start the child process */ BOOL result= - CreateProcess(instance_options->mysqld_path, /* File to execute */ + CreateProcess(NULL, /* Put it all in cmdline */ cmdline, /* Command line */ NULL, /* Process handle not inheritable */ NULL, /* Thread handle not inheritable */ diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 124195aad37..70950a91015 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -46,8 +46,16 @@ static inline int create_mysqld_command(Buffer *buf, if (buf->get_size()) /* malloc succeeded */ { +#ifdef __WIN__ + buf->append(position, "\"", 1); + position++; +#endif buf->append(position, mysqld_path_str, mysqld_path_len); position+= mysqld_path_len; +#ifdef __WIN__ + buf->append(position, "\"", 1); + position++; +#endif /* here the '\0' character is copied from the option string */ buf->append(position, option, option_len); diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc index 790770be09e..374946d3b73 100644 --- a/server-tools/instance-manager/listener.cc +++ b/server-tools/instance-manager/listener.cc @@ -121,6 +121,9 @@ void Listener_thread::run() n= max(n, sockets[i]); n++; + timeval tv; + tv.tv_sec= 0; + tv.tv_usec= 100000; while (!thread_registry.is_shutdown()) { fd_set read_fds_arg= read_fds; @@ -130,13 +133,13 @@ void Listener_thread::run() signal during shutdown. This results in failing assert (Thread_registry::~Thread_registry). Valgrind 2.2 works fine. */ - int rc= select(n, &read_fds_arg, 0, 0, 0); + int rc= select(n, &read_fds_arg, 0, 0, &tv); - - if (rc == -1 && errno != EINTR) + if (rc == 0 || rc == -1) { - log_error("Listener_thread::run(): select() failed, %s", - strerror(errno)); + if (rc == -1 && errno != EINTR) + log_error("Listener_thread::run(): select() failed, %s", + strerror(errno)); continue; } diff --git a/server-tools/instance-manager/mysqlmanager.cc b/server-tools/instance-manager/mysqlmanager.cc index a1420a639cb..3d2907f4776 100644 --- a/server-tools/instance-manager/mysqlmanager.cc +++ b/server-tools/instance-manager/mysqlmanager.cc @@ -102,10 +102,12 @@ int main(int argc, char *argv[]) angel(options); } #else -#ifdef NDEBUG - return_value= HandleServiceOptions(options); - goto err; /* this is not always an error but we reuse the label */ -#endif + if (!options.stand_alone) + { + if (HandleServiceOptions(options)) + goto err; + } + else #endif manager(options); diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc index 36fe0a89dda..74ccade3a2c 100644 --- a/server-tools/instance-manager/options.cc +++ b/server-tools/instance-manager/options.cc @@ -33,6 +33,7 @@ #ifdef __WIN__ char Options::install_as_service; char Options::remove_service; +char Options::stand_alone; char windows_config_file[FN_REFLEN]; char default_password_file_name[FN_REFLEN]; char default_log_file_name[FN_REFLEN]; @@ -72,6 +73,7 @@ enum options { #else OPT_INSTALL_SERVICE, OPT_REMOVE_SERVICE, + OPT_STAND_ALONE, #endif OPT_MONITORING_INTERVAL, OPT_PORT, @@ -131,6 +133,9 @@ static struct my_option my_long_options[] = { "remove", OPT_REMOVE_SERVICE, "Remove system service.", (gptr *)&Options::remove_service, (gptr*) &Options::remove_service, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0}, + { "standalone", OPT_STAND_ALONE, "Run the application in stand alone mode.", + (gptr *)&Options::stand_alone, (gptr*) &Options::stand_alone, + 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0}, #else { "run-as-service", OPT_RUN_AS_SERVICE, "Daemonize and start angel process.", (gptr *) &Options::run_as_service, diff --git a/server-tools/instance-manager/options.h b/server-tools/instance-manager/options.h index 5cc14e7ee7f..a5cd049decf 100644 --- a/server-tools/instance-manager/options.h +++ b/server-tools/instance-manager/options.h @@ -31,6 +31,7 @@ struct Options #ifdef __WIN__ static char install_as_service; static char remove_service; + static char stand_alone; #else static char run_as_service; /* handle_options doesn't support bool */ static const char *user; @@ -52,7 +53,7 @@ struct Options int load(int argc, char **argv); void cleanup(); #ifdef __WIN__ - int setup_windows_defaults(const char *progname); + int setup_windows_defaults(); #endif }; From f8f1c01675858dcd30d2f29ed3cbc8284baf189e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Sep 2005 01:41:44 +0300 Subject: [PATCH 18/21] Added option --valgrind-mysqltest to mysql-test-run Added flag to Field::store(longlong) to specify if value is unsigned. This fixes bug #12750: Incorrect storage of 9999999999999999999 in DECIMAL(19, 0) Fixed warning from valgrind in CREATE ... SELECT Fixed double free of mysql.options if reconnect failed mysql-test/mysql-test-run.sh: Added option --valgrind-mysqltest to allow one to run mysqltest with valgrind mysql-test/r/bigint.result: Update results after fix for Field::store(longlong) mysql-test/r/range.result: Update results after fix for Field::store(longlong) mysql-test/r/strict.result: Update results after fix for Field::store(longlong) (This fixes some wrong results when storing things into bigint columns) mysql-test/r/type_ranges.result: Update results after fix for Field::store(longlong) mysql-test/t/bigint.test: Added testing for #12750: Incorrect storage of 9999999999999999999 in DECIMAL(19, 0) mysql-test/t/innodb.test: Removed comments affected by this bug fix mysql-test/t/mysqldump.test: Fixed result to not depend on existing config files mysql-test/t/range.test: 0xff numbers are now unsigned mysql-test/t/strict.test: Added errors for things that previously (wrongly) succeeded sql-common/client.c: Fixed double free of mysql.options if reconnect failed sql/field.cc: Added flag to Field::store(longlong) to specify if value is unsigned sql/field.h: Added flag to Field::store(longlong) to specify if value is unsigned sql/field_conv.cc: Fixed calls to Field::store(longlong,flag) sql/ha_ndbcluster.cc: Fixed calls to Field::store(longlong,flag) sql/handler.cc: Fixed calls to Field::store(longlong,flag) sql/item.cc: Fixed calls to Field::store(longlong,flag) sql/item_sum.cc: Fixed calls to Field::store(longlong,flag) sql/sp.cc: Fixed calls to Field::store(longlong,flag) sql/sql_acl.cc: Fixed calls to Field::store(longlong,flag) sql/sql_help.cc: Fixed calls to Field::store(longlong,flag) sql/sql_show.cc: Fixed calls to Field::store(longlong,flag) sql/sql_table.cc: Fixed varning from valgrind sql/sql_udf.cc: Fixed calls to Field::store(longlong,flag) sql/tztime.cc: Fixed calls to Field::store(longlong,flag) sql/unireg.cc: Fixed calls to Field::store(longlong,flag) --- mysql-test/mysql-test-run.sh | 10 +- mysql-test/r/bigint.result | 192 +++++++++++++++++++++++++++-- mysql-test/r/range.result | 4 +- mysql-test/r/strict.result | 10 +- mysql-test/r/type_ranges.result | 6 +- mysql-test/t/bigint.test | 153 ++++++++++++++++++++++- mysql-test/t/innodb.test | 3 - mysql-test/t/mysqldump.test | 2 +- mysql-test/t/range.test | 4 +- mysql-test/t/strict.test | 4 +- sql-common/client.c | 11 +- sql/field.cc | 211 ++++++++++++++++++++------------ sql/field.h | 55 +++++---- sql/field_conv.cc | 7 +- sql/ha_ndbcluster.cc | 6 +- sql/handler.cc | 2 +- sql/item.cc | 14 +-- sql/item_sum.cc | 4 +- sql/sp.cc | 2 +- sql/sql_acl.cc | 19 +-- sql/sql_help.cc | 4 +- sql/sql_show.cc | 34 ++--- sql/sql_table.cc | 1 + sql/sql_udf.cc | 4 +- sql/tztime.cc | 6 +- sql/unireg.cc | 2 +- 26 files changed, 586 insertions(+), 184 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index d9460dcdd72..aadf9080348 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -235,6 +235,7 @@ DO_GDB="" MANUAL_GDB="" DO_DDD="" DO_CLIENT_GDB="" +DO_VALGRIND_MYSQL_TEST="" SLEEP_TIME_AFTER_RESTART=1 SLEEP_TIME_FOR_DELETE=10 SLEEP_TIME_FOR_FIRST_MASTER=400 # Enough time to create innodb tables @@ -432,6 +433,9 @@ while test $# -gt 0; do TMP=`$ECHO "$1" | $SED -e "s;--valgrind-options=;;"` VALGRIND="$VALGRIND $TMP" ;; + --valgrind-mysqltest) + DO_VALGRIND_MYSQL_TEST=1 + ;; --skip-ndbcluster | --skip-ndb) USE_NDBCLUSTER="" EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-ndbcluster" @@ -666,7 +670,7 @@ else MYSQL_CLIENT_TEST="$CLIENT_BINDIR/mysql_client_test_embedded" fi else - MYSQL_TEST="$CLIENT_BINDIR/mysqltest" + MYSQL_TEST="$VALGRIND_MYSQLTEST $CLIENT_BINDIR/mysqltest" MYSQL_CLIENT_TEST="$CLIENT_BINDIR/mysql_client_test" fi fi @@ -681,6 +685,10 @@ then SLAVE_MYSQLD=$MYSQLD fi +if [ x$DO_VALGRIND_MYSQL_TEST = x1 ] ; then + MYSQL_TEST="$VALGRIND $MYSQL_TEST" +fi + # If we should run all tests cases, we will use a local server for that if [ -z "$1" ] diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 1b5619eb18d..ca9a2662f94 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -46,6 +46,14 @@ a drop table t1; create table t1 ( a int not null default 1, big bigint ); insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807),(18446744073709551615); +Warnings: +Warning 1264 Out of range value adjusted for column 'big' at row 4 +select * from t1; +a big +1 -1 +1 12345678901234567 +1 9223372036854775807 +1 9223372036854775807 select min(big),max(big),max(big)-1 from t1; min(big) max(big) max(big)-1 -1 9223372036854775807 9223372036854775806 @@ -53,26 +61,51 @@ select min(big),max(big),max(big)-1 from t1 group by a; min(big) max(big) max(big)-1 -1 9223372036854775807 9223372036854775806 alter table t1 modify big bigint unsigned not null; +Warnings: +Warning 1264 Out of range value adjusted for column 'big' at row 1 select min(big),max(big),max(big)-1 from t1; min(big) max(big) max(big)-1 -12345678901234567 18446744073709551615 18446744073709551614 +0 9223372036854775807 9223372036854775806 select min(big),max(big),max(big)-1 from t1 group by a; min(big) max(big) max(big)-1 -12345678901234567 18446744073709551615 18446744073709551614 +0 9223372036854775807 9223372036854775806 +insert into t1 (big) values (18446744073709551615); +select * from t1; +a big +1 0 +1 12345678901234567 +1 9223372036854775807 +1 9223372036854775807 +1 18446744073709551615 +select min(big),max(big),max(big)-1 from t1; +min(big) max(big) max(big)-1 +0 18446744073709551615 18446744073709551614 +select min(big),max(big),max(big)-1 from t1 group by a; +min(big) max(big) max(big)-1 +0 18446744073709551615 18446744073709551614 alter table t1 add key (big); select min(big),max(big),max(big)-1 from t1; min(big) max(big) max(big)-1 -12345678901234567 18446744073709551615 18446744073709551614 +0 18446744073709551615 18446744073709551614 select min(big),max(big),max(big)-1 from t1 group by a; min(big) max(big) max(big)-1 -12345678901234567 18446744073709551615 18446744073709551614 +0 18446744073709551615 18446744073709551614 alter table t1 modify big bigint not null; +Warnings: +Warning 1264 Out of range value adjusted for column 'big' at row 5 +select * from t1; +a big +1 0 +1 12345678901234567 +1 9223372036854775807 +1 9223372036854775807 +1 9223372036854775807 select min(big),max(big),max(big)-1 from t1; min(big) max(big) max(big)-1 --1 9223372036854775807 9223372036854775806 +0 9223372036854775807 9223372036854775806 select min(big),max(big),max(big)-1 from t1 group by a; min(big) max(big) max(big)-1 --1 9223372036854775807 9223372036854775806 +0 9223372036854775807 9223372036854775806 drop table t1; create table t1 (id bigint auto_increment primary key, a int) auto_increment=9999999999; insert into t1 values (null,1); @@ -89,7 +122,7 @@ insert into t1 values (10000000000000000000.0); insert into t1 values ('10000000000000000000'); select * from t1; quantity --8446744073709551616 +10000000000000000000 10000000000000000000 10000000000000000000 drop table t1; @@ -154,3 +187,148 @@ select * from t1; a 9223372036854775809 drop table t1; +DROP DATABASE IF EXISTS `scott`; +Warnings: +Note 1008 Can't drop database 'scott'; database doesn't exist +create table t1 (a char(100), b varchar(100), c text, d blob); +insert into t1 values( +18446744073709551615,18446744073709551615, +18446744073709551615, 18446744073709551615 +); +insert into t1 values (-1 | 0,-1 | 0,-1 | 0 ,-1 | 0); +select * from t1; +a b c d +18446744073709551615 18446744073709551615 18446744073709551615 18446744073709551615 +18446744073709551615 18446744073709551615 18446744073709551615 18446744073709551615 +drop table t1; +create table t1 ( quantity decimal(2) unsigned); +insert into t1 values (500), (-500), (~0), (-1); +Warnings: +Warning 1264 Out of range value adjusted for column 'quantity' at row 1 +Warning 1264 Out of range value adjusted for column 'quantity' at row 2 +Warning 1264 Out of range value adjusted for column 'quantity' at row 3 +Warning 1264 Out of range value adjusted for column 'quantity' at row 4 +select * from t1; +quantity +99 +0 +99 +0 +drop table t1; +CREATE TABLE t1 ( +`col1` INT(1) NULL, +`col2` INT(2) NULL, +`col3` INT(3) NULL, +`col4` INT(4) NULL, +`col5` INT(5) NULL, +`col6` INT(6) NULL, +`col7` INT(7) NULL, +`col8` INT(8) NULL, +`col9` INT(9) NULL, +`col10` BIGINT(10) NULL, +`col11` BIGINT(11) NULL, +`col12` BIGINT(12) NULL, +`col13` BIGINT(13) NULL, +`col14` BIGINT(14) NULL, +`col15` BIGINT(15) NULL, +`col16` BIGINT(16) NULL, +`col17` BIGINT(17) NULL, +`col18` BIGINT(18) NULL, +`col19` DECIMAL(19, 0) NULL, +`col20` DECIMAL(20, 0) NULL, +`col21` DECIMAL(21, 0) NULL, +`col22` DECIMAL(22, 0) NULL, +`col23` DECIMAL(23, 0) NULL, +`col24` DECIMAL(24, 0) NULL, +`col25` DECIMAL(25, 0) NULL, +`col26` DECIMAL(26, 0) NULL, +`col27` DECIMAL(27, 0) NULL, +`col28` DECIMAL(28, 0) NULL, +`col29` DECIMAL(29, 0) NULL, +`col30` DECIMAL(30, 0) NULL, +`col31` DECIMAL(31, 0) NULL, +`col32` DECIMAL(32, 0) NULL, +`col33` DECIMAL(33, 0) NULL, +`col34` DECIMAL(34, 0) NULL, +`col35` DECIMAL(35, 0) NULL, +`col36` DECIMAL(36, 0) NULL, +`col37` DECIMAL(37, 0) NULL, +`col38` DECIMAL(38, 0) NULL, +`fix1` DECIMAL(38, 1) NULL, +`fix2` DECIMAL(38, 2) NULL, +`fix3` DECIMAL(38, 3) NULL, +`fix4` DECIMAL(38, 4) NULL, +`fix5` DECIMAL(38, 5) NULL, +`fix6` DECIMAL(38, 6) NULL, +`fix7` DECIMAL(38, 7) NULL, +`fix8` DECIMAL(38, 8) NULL, +`fix9` DECIMAL(38, 9) NULL, +`fix10` DECIMAL(38, 10) NULL, +`fix11` DECIMAL(38, 11) NULL, +`fix12` DECIMAL(38, 12) NULL, +`fix13` DECIMAL(38, 13) NULL, +`fix14` DECIMAL(38, 14) NULL, +`fix15` DECIMAL(38, 15) NULL, +`fix16` DECIMAL(38, 16) NULL, +`fix17` DECIMAL(38, 17) NULL, +`fix18` DECIMAL(38, 18) NULL, +`fix19` DECIMAL(38, 19) NULL, +`fix20` DECIMAL(38, 20) NULL, +`fix21` DECIMAL(38, 21) NULL, +`fix22` DECIMAL(38, 22) NULL, +`fix23` DECIMAL(38, 23) NULL, +`fix24` DECIMAL(38, 24) NULL, +`fix25` DECIMAL(38, 25) NULL, +`fix26` DECIMAL(38, 26) NULL, +`fix27` DECIMAL(38, 27) NULL, +`fix28` DECIMAL(38, 28) NULL, +`fix29` DECIMAL(38, 29) NULL, +`fix30` DECIMAL(38, 30) NULL +); +INSERT INTO t1(`col1`, `col2`, `col3`, `col4`, `col5`, `col6`, `col7`, `col8`, `col9`, `col10`, `col11`, `col12`, `col13`, `col14`, `col15`, `col16`, `col17`, `col18`, `col19`, `col20`, `col21`, `col22`, `col23`, `col24`, `col25`, `col26`, `col27`, `col28`, `col29`, `col30`, `col31`, `col32`, `col33`, `col34`, `col35`, `col36`, `col37`, `col38`, `fix1`, `fix2`, `fix3`, `fix4`, `fix5`, `fix6`, `fix7`, `fix8`, `fix9`, `fix10`, `fix11`, `fix12`, `fix13`, `fix14`, `fix15`, `fix16`, `fix17`, `fix18`, `fix19`, `fix20`, `fix21`, `fix22`, `fix23`, `fix24`, `fix25`, `fix26`, `fix27`, `fix28`, `fix29`, `fix30`) +VALUES (9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, +9999999999, 99999999999, 999999999999, 9999999999999, 99999999999999, +999999999999999, 9999999999999999, 99999999999999999, 999999999999999999, +9999999999999999999, 99999999999999999999, 999999999999999999999, +9999999999999999999999, 99999999999999999999999, 999999999999999999999999, +9999999999999999999999999, 99999999999999999999999999, +999999999999999999999999999, 9999999999999999999999999999, +99999999999999999999999999999, 999999999999999999999999999999, +9999999999999999999999999999999, 99999999999999999999999999999999, +999999999999999999999999999999999, 9999999999999999999999999999999999, +99999999999999999999999999999999999, 999999999999999999999999999999999999, +9999999999999999999999999999999999999, 99999999999999999999999999999999999999, +9999999999999999999999999999999999999.9, +999999999999999999999999999999999999.99, +99999999999999999999999999999999999.999, +9999999999999999999999999999999999.9999, +999999999999999999999999999999999.99999, +99999999999999999999999999999999.999999, +9999999999999999999999999999999.9999999, +999999999999999999999999999999.99999999, +99999999999999999999999999999.999999999, +9999999999999999999999999999.9999999999, +999999999999999999999999999.99999999999, +99999999999999999999999999.999999999999, +9999999999999999999999999.9999999999999, +999999999999999999999999.99999999999999, +99999999999999999999999.999999999999999, +9999999999999999999999.9999999999999999, +999999999999999999999.99999999999999999, +99999999999999999999.999999999999999999, +9999999999999999999.9999999999999999999, +999999999999999999.99999999999999999999, +99999999999999999.999999999999999999999, +9999999999999999.9999999999999999999999, +999999999999999.99999999999999999999999, +99999999999999.999999999999999999999999, +9999999999999.9999999999999999999999999, +999999999999.99999999999999999999999999, +99999999999.999999999999999999999999999, +9999999999.9999999999999999999999999999, +999999999.99999999999999999999999999999, +99999999.999999999999999999999999999999); +SELECT * FROM t1; +col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13 col14 col15 col16 col17 col18 col19 col20 col21 col22 col23 col24 col25 col26 col27 col28 col29 col30 col31 col32 col33 col34 col35 col36 col37 col38 fix1 fix2 fix3 fix4 fix5 fix6 fix7 fix8 fix9 fix10 fix11 fix12 fix13 fix14 fix15 fix16 fix17 fix18 fix19 fix20 fix21 fix22 fix23 fix24 fix25 fix26 fix27 fix28 fix29 fix30 +9 99 999 9999 99999 999999 9999999 99999999 999999999 9999999999 99999999999 999999999999 9999999999999 99999999999999 999999999999999 9999999999999999 99999999999999999 999999999999999999 9999999999999999999 99999999999999999999 999999999999999999999 9999999999999999999999 99999999999999999999999 999999999999999999999999 9999999999999999999999999 99999999999999999999999999 999999999999999999999999999 9999999999999999999999999999 99999999999999999999999999999 999999999999999999999999999999 9999999999999999999999999999999 99999999999999999999999999999999 999999999999999999999999999999999 9999999999999999999999999999999999 99999999999999999999999999999999999 999999999999999999999999999999999999 9999999999999999999999999999999999999 99999999999999999999999999999999999999 9999999999999999999999999999999999999.9 999999999999999999999999999999999999.99 99999999999999999999999999999999999.999 9999999999999999999999999999999999.9999 999999999999999999999999999999999.99999 99999999999999999999999999999999.999999 9999999999999999999999999999999.9999999 999999999999999999999999999999.99999999 99999999999999999999999999999.999999999 9999999999999999999999999999.9999999999 999999999999999999999999999.99999999999 99999999999999999999999999.999999999999 9999999999999999999999999.9999999999999 999999999999999999999999.99999999999999 99999999999999999999999.999999999999999 9999999999999999999999.9999999999999999 999999999999999999999.99999999999999999 99999999999999999999.999999999999999999 9999999999999999999.9999999999999999999 999999999999999999.99999999999999999999 99999999999999999.999999999999999999999 9999999999999999.9999999999999999999999 999999999999999.99999999999999999999999 99999999999999.999999999999999999999999 9999999999999.9999999999999999999999999 999999999999.99999999999999999999999999 99999999999.999999999999999999999999999 9999999999.9999999999999999999999999999 999999999.99999999999999999999999999999 99999999.999999999999999999999999999999 +DROP TABLE t1; diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index e8e30b3653a..f490c2e1383 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -521,8 +521,8 @@ select count(*) from t1 where x = 18446744073709551601; count(*) 1 create table t2 (x bigint not null); -insert into t2(x) values (0xfffffffffffffff0); -insert into t2(x) values (0xfffffffffffffff1); +insert into t2(x) values (cast(0xfffffffffffffff0+0 as signed)); +insert into t2(x) values (cast(0xfffffffffffffff1+0 as signed)); select * from t2; x -16 diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 6299e8dcc88..2b1a47ed337 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -667,7 +667,9 @@ INSERT INTO t1 VALUES(-9223372036854774000.0,0.0),(9223372036854775700.0,1844674 INSERT INTO t1 (col1) VALUES(-9223372036854775809); ERROR 22003: Out of range value adjusted for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(9223372036854775808); +ERROR 22003: Out of range value adjusted for column 'col1' at row 1 INSERT INTO t1 (col2) VALUES(-1); +ERROR 22003: Out of range value adjusted for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(18446744073709551616); ERROR 22003: Out of range value adjusted for column 'col2' at row 1 INSERT INTO t1 (col1) VALUES('-9223372036854775809'); @@ -706,6 +708,8 @@ Error 1365 Division by 0 INSERT IGNORE INTO t1 VALUES(-9223372036854775809,-1),(9223372036854775808,18446744073709551616); Warnings: Warning 1264 Out of range value adjusted for column 'col1' at row 1 +Warning 1264 Out of range value adjusted for column 'col2' at row 1 +Warning 1264 Out of range value adjusted for column 'col1' at row 2 Warning 1264 Out of range value adjusted for column 'col2' at row 2 INSERT IGNORE INTO t1 VALUES('-9223372036854775809','-1'),('9223372036854775808','18446744073709551616'); Warnings: @@ -729,12 +733,10 @@ col1 col2 9223372036854775807 18446744073709551615 -9223372036854774000 0 9223372036854775700 1844674407370954000 --9223372036854775808 NULL -NULL 18446744073709551615 2 NULL NULL NULL --9223372036854775808 18446744073709551615 --9223372036854775808 18446744073709551615 +-9223372036854775808 0 +9223372036854775807 18446744073709551615 -9223372036854775808 0 9223372036854775807 18446744073709551615 -9223372036854775808 0 diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index 1342603f755..ff07dcca106 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -95,6 +95,7 @@ Warning 1264 Out of range value adjusted for column 'utiny' at row 1 Warning 1264 Out of range value adjusted for column 'ushort' at row 1 Warning 1264 Out of range value adjusted for column 'umedium' at row 1 Warning 1264 Out of range value adjusted for column 'ulong' at row 1 +Warning 1264 Out of range value adjusted for column 'ulonglong' at row 1 Warning 1265 Data truncated for column 'options' at row 1 Warning 1265 Data truncated for column 'flags' at row 1 insert into t1 values (0,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,NULL,0,0,0,-4294967295,-4294967295,-4294967295,'-4294967295',0,"one,two,tree"); @@ -108,6 +109,7 @@ Warning 1264 Out of range value adjusted for column 'utiny' at row 1 Warning 1264 Out of range value adjusted for column 'ushort' at row 1 Warning 1264 Out of range value adjusted for column 'umedium' at row 1 Warning 1264 Out of range value adjusted for column 'ulong' at row 1 +Warning 1264 Out of range value adjusted for column 'ulonglong' at row 1 Warning 1265 Data truncated for column 'options' at row 1 insert into t1 values (0,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,NULL,0,0,0,4294967295,4294967295,4294967295,'4294967295',0,0); Warnings: @@ -125,8 +127,8 @@ auto string tiny short medium long_int longlong real_float real_double utiny ush 10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1 11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2 12 0.33333333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3 -13 -1 -1 -1 -1 -1 -1 -1.0 -1.0000 0 00000 0 0 18446744073709551615 0 1997-08-07 08:07:06 1997-04-03 09:08:07 -1 -1 -1 -1 -14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 18446744069414584321 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295 +13 -1 -1 -1 -1 -1 -1 -1.0 -1.0000 0 00000 0 0 0 0 1997-08-07 08:07:06 1997-04-03 09:08:07 -1 -1 -1 -1 +14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 0 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295 15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295 16 hello 1 1 0 0 0 0.0 NULL 0 00000 0 0 0 0 NULL NULL NULL NULL NULL ALTER TABLE t1 diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index 5f21d2b5813..d9c1abd9ba9 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -35,21 +35,27 @@ drop table t1; create table t1 ( a int not null default 1, big bigint ); insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807),(18446744073709551615); +select * from t1; select min(big),max(big),max(big)-1 from t1; select min(big),max(big),max(big)-1 from t1 group by a; alter table t1 modify big bigint unsigned not null; select min(big),max(big),max(big)-1 from t1; select min(big),max(big),max(big)-1 from t1 group by a; +insert into t1 (big) values (18446744073709551615); +select * from t1; +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; alter table t1 add key (big); select min(big),max(big),max(big)-1 from t1; select min(big),max(big),max(big)-1 from t1 group by a; alter table t1 modify big bigint not null; +select * from t1; select min(big),max(big),max(big)-1 from t1; select min(big),max(big),max(big)-1 from t1 group by a; drop table t1; # -# Test problem with big values fir auto_increment +# Test problem with big values for auto_increment # create table t1 (id bigint auto_increment primary key, a int) auto_increment=9999999999; @@ -112,6 +118,7 @@ drop table t1, t2; # # Test of CREATE ... SELECT and unsigned integers # + create table t1 select 1 as 'a'; show create table t1; drop table t1; @@ -119,3 +126,147 @@ create table t1 select 9223372036854775809 as 'a'; show create table t1; select * from t1; drop table t1; +DROP DATABASE IF EXISTS `scott`; + + +# +# Check various conversions from/to unsigned bigint. +# + +create table t1 (a char(100), b varchar(100), c text, d blob); +insert into t1 values( + 18446744073709551615,18446744073709551615, + 18446744073709551615, 18446744073709551615 +); + +insert into t1 values (-1 | 0,-1 | 0,-1 | 0 ,-1 | 0); +select * from t1; +drop table t1; + +create table t1 ( quantity decimal(2) unsigned); +insert into t1 values (500), (-500), (~0), (-1); +select * from t1; +drop table t1; + +# +# Test of storing decimal values in BIGINT range +# (Bug #12750: Incorrect storage of 9999999999999999999 in DECIMAL(19, 0)) +# + +CREATE TABLE t1 ( + `col1` INT(1) NULL, + `col2` INT(2) NULL, + `col3` INT(3) NULL, + `col4` INT(4) NULL, + `col5` INT(5) NULL, + `col6` INT(6) NULL, + `col7` INT(7) NULL, + `col8` INT(8) NULL, + `col9` INT(9) NULL, + `col10` BIGINT(10) NULL, + `col11` BIGINT(11) NULL, + `col12` BIGINT(12) NULL, + `col13` BIGINT(13) NULL, + `col14` BIGINT(14) NULL, + `col15` BIGINT(15) NULL, + `col16` BIGINT(16) NULL, + `col17` BIGINT(17) NULL, + `col18` BIGINT(18) NULL, + `col19` DECIMAL(19, 0) NULL, + `col20` DECIMAL(20, 0) NULL, + `col21` DECIMAL(21, 0) NULL, + `col22` DECIMAL(22, 0) NULL, + `col23` DECIMAL(23, 0) NULL, + `col24` DECIMAL(24, 0) NULL, + `col25` DECIMAL(25, 0) NULL, + `col26` DECIMAL(26, 0) NULL, + `col27` DECIMAL(27, 0) NULL, + `col28` DECIMAL(28, 0) NULL, + `col29` DECIMAL(29, 0) NULL, + `col30` DECIMAL(30, 0) NULL, + `col31` DECIMAL(31, 0) NULL, + `col32` DECIMAL(32, 0) NULL, + `col33` DECIMAL(33, 0) NULL, + `col34` DECIMAL(34, 0) NULL, + `col35` DECIMAL(35, 0) NULL, + `col36` DECIMAL(36, 0) NULL, + `col37` DECIMAL(37, 0) NULL, + `col38` DECIMAL(38, 0) NULL, + `fix1` DECIMAL(38, 1) NULL, + `fix2` DECIMAL(38, 2) NULL, + `fix3` DECIMAL(38, 3) NULL, + `fix4` DECIMAL(38, 4) NULL, + `fix5` DECIMAL(38, 5) NULL, + `fix6` DECIMAL(38, 6) NULL, + `fix7` DECIMAL(38, 7) NULL, + `fix8` DECIMAL(38, 8) NULL, + `fix9` DECIMAL(38, 9) NULL, + `fix10` DECIMAL(38, 10) NULL, + `fix11` DECIMAL(38, 11) NULL, + `fix12` DECIMAL(38, 12) NULL, + `fix13` DECIMAL(38, 13) NULL, + `fix14` DECIMAL(38, 14) NULL, + `fix15` DECIMAL(38, 15) NULL, + `fix16` DECIMAL(38, 16) NULL, + `fix17` DECIMAL(38, 17) NULL, + `fix18` DECIMAL(38, 18) NULL, + `fix19` DECIMAL(38, 19) NULL, + `fix20` DECIMAL(38, 20) NULL, + `fix21` DECIMAL(38, 21) NULL, + `fix22` DECIMAL(38, 22) NULL, + `fix23` DECIMAL(38, 23) NULL, + `fix24` DECIMAL(38, 24) NULL, + `fix25` DECIMAL(38, 25) NULL, + `fix26` DECIMAL(38, 26) NULL, + `fix27` DECIMAL(38, 27) NULL, + `fix28` DECIMAL(38, 28) NULL, + `fix29` DECIMAL(38, 29) NULL, + `fix30` DECIMAL(38, 30) NULL +); + +INSERT INTO t1(`col1`, `col2`, `col3`, `col4`, `col5`, `col6`, `col7`, `col8`, `col9`, `col10`, `col11`, `col12`, `col13`, `col14`, `col15`, `col16`, `col17`, `col18`, `col19`, `col20`, `col21`, `col22`, `col23`, `col24`, `col25`, `col26`, `col27`, `col28`, `col29`, `col30`, `col31`, `col32`, `col33`, `col34`, `col35`, `col36`, `col37`, `col38`, `fix1`, `fix2`, `fix3`, `fix4`, `fix5`, `fix6`, `fix7`, `fix8`, `fix9`, `fix10`, `fix11`, `fix12`, `fix13`, `fix14`, `fix15`, `fix16`, `fix17`, `fix18`, `fix19`, `fix20`, `fix21`, `fix22`, `fix23`, `fix24`, `fix25`, `fix26`, `fix27`, `fix28`, `fix29`, `fix30`) +VALUES (9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, +9999999999, 99999999999, 999999999999, 9999999999999, 99999999999999, +999999999999999, 9999999999999999, 99999999999999999, 999999999999999999, +9999999999999999999, 99999999999999999999, 999999999999999999999, +9999999999999999999999, 99999999999999999999999, 999999999999999999999999, +9999999999999999999999999, 99999999999999999999999999, +999999999999999999999999999, 9999999999999999999999999999, +99999999999999999999999999999, 999999999999999999999999999999, +9999999999999999999999999999999, 99999999999999999999999999999999, +999999999999999999999999999999999, 9999999999999999999999999999999999, +99999999999999999999999999999999999, 999999999999999999999999999999999999, +9999999999999999999999999999999999999, 99999999999999999999999999999999999999, +9999999999999999999999999999999999999.9, +999999999999999999999999999999999999.99, +99999999999999999999999999999999999.999, +9999999999999999999999999999999999.9999, +999999999999999999999999999999999.99999, +99999999999999999999999999999999.999999, +9999999999999999999999999999999.9999999, +999999999999999999999999999999.99999999, +99999999999999999999999999999.999999999, +9999999999999999999999999999.9999999999, +999999999999999999999999999.99999999999, +99999999999999999999999999.999999999999, +9999999999999999999999999.9999999999999, +999999999999999999999999.99999999999999, +99999999999999999999999.999999999999999, +9999999999999999999999.9999999999999999, +999999999999999999999.99999999999999999, +99999999999999999999.999999999999999999, +9999999999999999999.9999999999999999999, +999999999999999999.99999999999999999999, +99999999999999999.999999999999999999999, +9999999999999999.9999999999999999999999, +999999999999999.99999999999999999999999, +99999999999999.999999999999999999999999, +9999999999999.9999999999999999999999999, +999999999999.99999999999999999999999999, +99999999999.999999999999999999999999999, +9999999999.9999999999999999999999999999, +999999999.99999999999999999999999999999, +99999999.999999999999999999999999999999); + +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index ed238f46e0b..beec3b0f8c7 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1274,9 +1274,6 @@ select count(*) from t1 where x<0; select count(*) from t1 where x < -16; select count(*) from t1 where x = -16; explain select count(*) from t1 where x > -16; - -# The following result should be (2). To be fixed when we add 'unsigned flag' to -# Field::store(longlong) select count(*) from t1 where x > -16; select * from t1 where x > -16; select count(*) from t1 where x = 18446744073709551601; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index c34840b0725..89fc206eeec 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -769,7 +769,7 @@ DROP TABLE t1, t2; --exec echo "[client]" > $MYSQL_TEST_DIR/var/tmp/tmp.cnf --exec echo "port=1234" >> $MYSQL_TEST_DIR/var/tmp/tmp.cnf --exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQL_TEST_DIR/var/tmp/tmp.cnf client ---exec $MYSQL_MY_PRINT_DEFAULTS -e $MYSQL_TEST_DIR/var/tmp/tmp.cnf client +--exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQL_TEST_DIR/var/tmp/tmp.cnf -e $MYSQL_TEST_DIR/var/tmp/tmp.cnf client client --exec rm $MYSQL_TEST_DIR/var/tmp/tmp.cnf # diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 12dda022cb9..bbe5798e7e5 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -406,8 +406,8 @@ select count(*) from t1 where x = 18446744073709551601; create table t2 (x bigint not null); -insert into t2(x) values (0xfffffffffffffff0); -insert into t2(x) values (0xfffffffffffffff1); +insert into t2(x) values (cast(0xfffffffffffffff0+0 as signed)); +insert into t2(x) values (cast(0xfffffffffffffff1+0 as signed)); select * from t2; select count(*) from t2 where x>0; select count(*) from t2 where x=0; diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 6af0a10d831..d3b36cbc2a8 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -659,9 +659,11 @@ INSERT INTO t1 VALUES(-9223372036854775808,0),(0,0),(9223372036854775807,1844674 INSERT INTO t1 VALUES('-9223372036854775808','0'),('9223372036854775807','18446744073709551615'); INSERT INTO t1 VALUES(-9223372036854774000.0,0.0),(9223372036854775700.0,1844674407370954000.0); --- error 1264 +--error 1264 INSERT INTO t1 (col1) VALUES(-9223372036854775809); +--error 1264 INSERT INTO t1 (col1) VALUES(9223372036854775808); +--error 1264 INSERT INTO t1 (col2) VALUES(-1); --error 1264 diff --git a/sql-common/client.c b/sql-common/client.c index 43c50f12ae1..08ad906e2b6 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2203,8 +2203,9 @@ my_bool mysql_reconnect(MYSQL *mysql) DBUG_RETURN(1); } mysql_init(&tmp_mysql); - tmp_mysql.options=mysql->options; - tmp_mysql.rpl_pivot = mysql->rpl_pivot; + tmp_mysql.options= mysql->options; + tmp_mysql.rpl_pivot= mysql->rpl_pivot; + if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd, mysql->db, mysql->port, mysql->unix_socket, mysql->client_flag | CLIENT_REMEMBER_OPTIONS)) @@ -2216,6 +2217,8 @@ my_bool mysql_reconnect(MYSQL *mysql) } if (mysql_set_character_set(&tmp_mysql, mysql->charset->csname)) { + DBUG_PRINT("error", ("mysql_set_character_set() failed")); + bzero((char*) &tmp_mysql.options,sizeof(tmp_mysql.options)); mysql_close(&tmp_mysql); mysql->net.last_errno= tmp_mysql.net.last_errno; strmov(mysql->net.last_error, tmp_mysql.net.last_error); @@ -2223,6 +2226,7 @@ my_bool mysql_reconnect(MYSQL *mysql) DBUG_RETURN(1); } + DBUG_PRINT("info", ("reconnect succeded")); tmp_mysql.reconnect= 1; tmp_mysql.free_me= mysql->free_me; @@ -2286,6 +2290,8 @@ mysql_select_db(MYSQL *mysql, const char *db) static void mysql_close_free_options(MYSQL *mysql) { + DBUG_ENTER("mysql_close_free_options"); + my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR)); @@ -2314,6 +2320,7 @@ static void mysql_close_free_options(MYSQL *mysql) my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif /* HAVE_SMEM */ bzero((char*) &mysql->options,sizeof(mysql->options)); + DBUG_VOID_RETURN; } diff --git a/sql/field.cc b/sql/field.cc index 224b6c279f3..e8731cb0ea5 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1199,7 +1199,7 @@ static bool test_if_real(const char *str,int length, CHARSET_INFO *cs) This is used for printing bit_fields as numbers while debugging */ -String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_flag) +String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val) { CHARSET_INFO *cs= &my_charset_bin; uint length= 21; @@ -1208,7 +1208,7 @@ String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_flag) return 0; length= (uint) (*cs->cset->longlong10_to_str)(cs, (char*) val_buffer->ptr(), length, - unsigned_flag ? 10 : -10, + unsigned_val ? 10 : -10, value); val_buffer->length(length); return val_buffer; @@ -1360,7 +1360,7 @@ int Field_num::store_decimal(const my_decimal *val) { int err= 0; longlong i= convert_decimal2longlong(val, unsigned_flag, &err); - return test(err | store(i)); + return test(err | store(i, unsigned_flag)); } @@ -2122,36 +2122,37 @@ int Field_decimal::store(double nr) } -int Field_decimal::store(longlong nr) +int Field_decimal::store(longlong nr, bool unsigned_val) { - if (unsigned_flag && nr < 0) + char buff[22]; + uint length, int_part; + char fyllchar, *to; + + if (nr < 0 && unsigned_flag && !unsigned_val) { overflow(1); return 1; } - char buff[22]; - uint length=(uint) (longlong10_to_str(nr,buff,-10)-buff); - uint int_part=field_length- (dec ? dec+1 : 0); + length= (uint) (longlong10_to_str(nr,buff,unsigned_val ? 10 : -10) - buff); + int_part= field_length- (dec ? dec+1 : 0); if (length > int_part) { - overflow(test(nr < 0L)); /* purecov: inspected */ + overflow(!unsigned_val && nr < 0L); /* purecov: inspected */ return 1; } - else + + fyllchar = zerofill ? (char) '0' : (char) ' '; + to= ptr; + for (uint i=int_part-length ; i-- > 0 ;) + *to++ = fyllchar; + memcpy(to,buff,length); + if (dec) { - char fyllchar = zerofill ? (char) '0' : (char) ' '; - char *to=ptr; - for (uint i=int_part-length ; i-- > 0 ;) - *to++ = fyllchar; - memcpy(to,buff,length); - if (dec) - { - to[length]='.'; - bfill(to+length+1,dec,'0'); - } - return 0; + to[length]='.'; + bfill(to+length+1,dec,'0'); } + return 0; } @@ -2482,13 +2483,13 @@ int Field_new_decimal::store(double nr) } -int Field_new_decimal::store(longlong nr) +int Field_new_decimal::store(longlong nr, bool unsigned_val) { my_decimal decimal_value; int err; if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, - nr, FALSE, &decimal_value))) + nr, unsigned_val, &decimal_value))) { if (check_overflow(err)) set_value_on_overflow(&decimal_value, decimal_value.sign()); @@ -2663,18 +2664,20 @@ int Field_tiny::store(double nr) return error; } -int Field_tiny::store(longlong nr) + +int Field_tiny::store(longlong nr, bool unsigned_val) { int error= 0; + if (unsigned_flag) { - if (nr < 0L) + if (nr < 0 && !unsigned_val) { - *ptr=0; + *ptr= 0; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; } - else if (nr > 255L) + else if ((ulonglong) nr > (ulonglong) 255) { *ptr= (char) 255; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); @@ -2685,13 +2688,15 @@ int Field_tiny::store(longlong nr) } else { - if (nr < -128L) + if (nr < 0 && unsigned_val) + nr= 256; // Generate overflow + if (nr < -128) { *ptr= (char) -128; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; } - else if (nr > 127L) + else if (nr > 127) { *ptr=127; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); @@ -2711,6 +2716,7 @@ double Field_tiny::val_real(void) return (double) tmp; } + longlong Field_tiny::val_int(void) { int tmp= unsigned_flag ? (int) ((uchar*) ptr)[0] : @@ -2718,6 +2724,7 @@ longlong Field_tiny::val_int(void) return (longlong) tmp; } + String *Field_tiny::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { @@ -2877,19 +2884,21 @@ int Field_short::store(double nr) return error; } -int Field_short::store(longlong nr) + +int Field_short::store(longlong nr, bool unsigned_val) { int error= 0; int16 res; + if (unsigned_flag) { - if (nr < 0L) + if (nr < 0L && !unsigned_val) { res=0; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; } - else if (nr > (longlong) UINT_MAX16) + else if ((ulonglong) nr > (ulonglong) UINT_MAX16) { res=(int16) UINT_MAX16; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); @@ -2900,13 +2909,16 @@ int Field_short::store(longlong nr) } else { + if (nr < 0 && unsigned_val) + nr= UINT_MAX16+1; // Generate overflow + if (nr < INT_MIN16) { res=INT_MIN16; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; } - else if (nr > INT_MAX16) + else if (nr > (longlong) INT_MAX16) { res=INT_MAX16; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); @@ -3134,20 +3146,22 @@ int Field_medium::store(double nr) return error; } -int Field_medium::store(longlong nr) + +int Field_medium::store(longlong nr, bool unsigned_val) { int error= 0; + if (unsigned_flag) { - if (nr < 0L) + if (nr < 0 && !unsigned_val) { int3store(ptr,0); set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; } - else if (nr >= (longlong) (long) (1L << 24)) + else if ((ulonglong) nr >= (ulonglong) (long) (1L << 24)) { - long tmp=(long) (1L << 24)-1L;; + long tmp= (long) (1L << 24)-1L; int3store(ptr,tmp); set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; @@ -3157,9 +3171,12 @@ int Field_medium::store(longlong nr) } else { + if (nr < 0 && unsigned_val) + nr= (ulonglong) (long) (1L << 24); // Generate overflow + if (nr < (longlong) INT_MIN24) { - long tmp=(long) INT_MIN24; + long tmp= (long) INT_MIN24; int3store(ptr,tmp); set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; @@ -3397,7 +3414,7 @@ int Field_long::store(double nr) } -int Field_long::store(longlong nr) +int Field_long::store(longlong nr, bool unsigned_val) { int error= 0; int32 res; @@ -3405,12 +3422,12 @@ int Field_long::store(longlong nr) if (unsigned_flag) { - if (nr < 0) + if (nr < 0 && !unsigned_val) { res=0; error= 1; } - else if (nr >= (LL(1) << 32)) + else if ((ulonglong) nr >= (LL(1) << 32)) { res=(int32) (uint32) ~0L; error= 1; @@ -3420,7 +3437,9 @@ int Field_long::store(longlong nr) } else { - if (nr < (longlong) INT_MIN32) + if (nr < 0 && unsigned_val) + nr= INT_MAX32+1; // Generate overflow + if (nr < (longlong) INT_MIN32) { res=(int32) INT_MIN32; error= 1; @@ -3657,8 +3676,24 @@ int Field_longlong::store(double nr) } -int Field_longlong::store(longlong nr) +int Field_longlong::store(longlong nr, bool unsigned_val) { + int error= 0; + + if (nr < 0) // Only possible error + { + /* + if field is unsigned and value is signed (< 0) or + if field is signed and value is unsigned we have an overflow + */ + if (unsigned_flag != unsigned_val) + { + nr= unsigned_flag ? (ulonglong) 0 : (ulonglong) LONGLONG_MAX; + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); + error= 1; + } + } + #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { @@ -3667,7 +3702,7 @@ int Field_longlong::store(longlong nr) else #endif longlongstore(ptr,nr); - return 0; + return error; } @@ -3886,11 +3921,12 @@ int Field_float::store(double nr) } -int Field_float::store(longlong nr) +int Field_float::store(longlong nr, bool unsigned_val) { - return store((double)nr); + return store(unsigned_val ? ulonglong2double((ulonglong) nr) : (double) nr); } + double Field_float::val_real(void) { float j; @@ -4166,11 +4202,12 @@ int Field_double::store(double nr) } -int Field_double::store(longlong nr) +int Field_double::store(longlong nr, bool unsigned_val) { - return store((double)nr); + return store(unsigned_val ? ulonglong2double((ulonglong) nr) : (double) nr); } + int Field_real::store_decimal(const my_decimal *dm) { double dbl; @@ -4529,12 +4566,12 @@ int Field_timestamp::store(double nr) nr= 0; // Avoid overflow on buff error= 1; } - error|= Field_timestamp::store((longlong) rint(nr)); + error|= Field_timestamp::store((longlong) rint(nr), FALSE); return error; } -int Field_timestamp::store(longlong nr) +int Field_timestamp::store(longlong nr, bool unsigned_val) { TIME l_time; my_time_t timestamp= 0; @@ -4829,7 +4866,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) if (ltime.neg) tmp= -tmp; - error |= Field_time::store((longlong) tmp); + error |= Field_time::store((longlong) tmp, FALSE); return error; } @@ -4881,21 +4918,21 @@ int Field_time::store(double nr) } -int Field_time::store(longlong nr) +int Field_time::store(longlong nr, bool unsigned_val) { long tmp; int error= 0; - if (nr > (longlong) 8385959L) + if (nr < (longlong) -8385959L && !unsigned_val) { - tmp=8385959L; + tmp= -8385959L; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME, 1); error= 1; } - else if (nr < (longlong) -8385959L) + else if (nr > (longlong) 8385959 || nr < 0 && unsigned_val) { - tmp= -8385959L; + tmp=8385959L; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME, 1); @@ -5076,18 +5113,18 @@ int Field_year::store(double nr) { if (nr < 0.0 || nr >= 2155.0) { - (void) Field_year::store((longlong) -1); + (void) Field_year::store((longlong) -1, FALSE); return 1; } - else - return Field_year::store((longlong) nr); + return Field_year::store((longlong) nr, FALSE); } -int Field_year::store(longlong nr) + +int Field_year::store(longlong nr, bool unsigned_val) { if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) { - *ptr=0; + *ptr= 0; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); return 1; } @@ -5102,17 +5139,20 @@ int Field_year::store(longlong nr) return 0; } + bool Field_year::send_binary(Protocol *protocol) { ulonglong tmp= Field_year::val_int(); return protocol->store_short(tmp); } + double Field_year::val_real(void) { return (double) Field_year::val_int(); } + longlong Field_year::val_int(void) { int tmp= (int) ((uchar*) ptr)[0]; @@ -5123,6 +5163,7 @@ longlong Field_year::val_int(void) return (longlong) tmp; } + String *Field_year::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { @@ -5133,6 +5174,7 @@ String *Field_year::val_str(String *val_buffer, return val_buffer; } + void Field_year::sql_type(String &res) const { CHARSET_INFO *cs=res.charset(); @@ -5203,7 +5245,7 @@ int Field_date::store(double nr) } -int Field_date::store(longlong nr) +int Field_date::store(longlong nr, bool unsigned_val) { TIME not_used; int error; @@ -5262,6 +5304,7 @@ double Field_date::val_real(void) return (double) (uint32) j; } + longlong Field_date::val_int(void) { int32 j; @@ -5274,6 +5317,7 @@ longlong Field_date::val_int(void) return (longlong) (uint32) j; } + String *Field_date::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { @@ -5382,11 +5426,11 @@ int Field_newdate::store(double nr) WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE); return 1; } - return Field_newdate::store((longlong) rint(nr)); + return Field_newdate::store((longlong) rint(nr), FALSE); } -int Field_newdate::store(longlong nr) +int Field_newdate::store(longlong nr, bool unsigned_val) { TIME l_time; longlong tmp; @@ -5576,12 +5620,12 @@ int Field_datetime::store(double nr) nr= 0.0; error= 1; } - error|= Field_datetime::store((longlong) rint(nr)); + error|= Field_datetime::store((longlong) rint(nr), FALSE); return error; } -int Field_datetime::store(longlong nr) +int Field_datetime::store(longlong nr, bool unsigned_val) { TIME not_used; int error; @@ -5905,12 +5949,13 @@ int Field_str::store(double nr) } -int Field_string::store(longlong nr) +int Field_string::store(longlong nr, bool unsigned_val) { char buff[64]; int l; CHARSET_INFO *cs=charset(); - l= (cs->cset->longlong10_to_str)(cs,buff,sizeof(buff),-10,nr); + l= (cs->cset->longlong10_to_str)(cs,buff,sizeof(buff), + unsigned_val ? 10 : -10, nr); return Field_string::store(buff,(uint)l,cs); } @@ -6234,14 +6279,16 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) } -int Field_varstring::store(longlong nr) +int Field_varstring::store(longlong nr, bool unsigned_val) { char buff[64]; uint length; length= (uint) (field_charset->cset->longlong10_to_str)(field_charset, buff, sizeof(buff), - -10,nr); + (unsigned_val ? 10: + -10), + nr); return Field_varstring::store(buff, length, field_charset); } @@ -6859,13 +6906,17 @@ int Field_blob::store(double nr) } -int Field_blob::store(longlong nr) +int Field_blob::store(longlong nr, bool unsigned_val) { CHARSET_INFO *cs=charset(); - value.set(nr, cs); + if (unsigned_val) + value.set((ulonglong) nr, cs); + else + value.set(nr, cs); return Field_blob::store(value.ptr(), (uint) value.length(), cs); } + double Field_blob::val_real(void) { int not_used; @@ -7330,7 +7381,7 @@ int Field_geom::store(double nr) } -int Field_geom::store(longlong nr) +int Field_geom::store(longlong nr, bool unsigned_val) { my_message(ER_CANT_CREATE_GEOMETRY_OBJECT, ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0)); @@ -7483,14 +7534,14 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) int Field_enum::store(double nr) { - return Field_enum::store((longlong) nr); + return Field_enum::store((longlong) nr, FALSE); } -int Field_enum::store(longlong nr) +int Field_enum::store(longlong nr, bool unsigned_val) { int error= 0; - if ((uint) nr > typelib->count || nr == 0) + if ((ulonglong) nr > typelib->count || nr == 0) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); nr=0; @@ -7661,7 +7712,7 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) } -int Field_set::store(longlong nr) +int Field_set::store(longlong nr, bool unsigned_val) { int error= 0; if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) - @@ -7881,11 +7932,11 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs) int Field_bit::store(double nr) { - return store((longlong) nr); + return store((longlong) nr, FALSE); } -int Field_bit::store(longlong nr) +int Field_bit::store(longlong nr, bool unsigned_val) { char buf[8]; @@ -8466,8 +8517,8 @@ create_field::create_field(Field *old_field,Field *orig_field) else interval=0; def=0; + if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) && - !old_field->is_real_null() && old_field->ptr && orig_field && (sql_type != FIELD_TYPE_TIMESTAMP || /* set def only if */ old_field->table->timestamp_field != old_field || /* timestamp field */ diff --git a/sql/field.h b/sql/field.h index 2b67ed3f599..632169868bc 100644 --- a/sql/field.h +++ b/sql/field.h @@ -97,7 +97,7 @@ public: /* Store functions returns 1 on overflow and -1 on fatal error */ virtual int store(const char *to,uint length,CHARSET_INFO *cs)=0; virtual int store(double nr)=0; - virtual int store(longlong nr)=0; + virtual int store(longlong nr, bool unsigned_val)=0; virtual int store_decimal(const my_decimal *d)=0; virtual int store_time(TIME *ltime, timestamp_type t_type); virtual double val_real(void)=0; @@ -357,7 +357,7 @@ public: Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } int store(double nr); - int store(longlong nr)=0; + int store(longlong nr, bool unsigned_val)=0; int store_decimal(const my_decimal *); int store(const char *to,uint length,CHARSET_INFO *cs)=0; uint size_of() const { return sizeof(*this); } @@ -422,7 +422,7 @@ public: void reset(void); int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -464,7 +464,7 @@ public: void set_value_on_overflow(my_decimal *decimal_value, bool sign); int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); int store_decimal(const my_decimal *); double val_real(void); longlong val_int(void); @@ -497,7 +497,7 @@ public: { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { ptr[0]=0; } double val_real(void); longlong val_int(void); @@ -533,7 +533,7 @@ public: { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;} int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { ptr[0]=ptr[1]=0; } double val_real(void); longlong val_int(void); @@ -564,7 +564,7 @@ public: { return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } double val_real(void); longlong val_int(void); @@ -600,7 +600,7 @@ public: { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } double val_real(void); longlong val_int(void); @@ -638,7 +638,7 @@ public: { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } double val_real(void); longlong val_int(void); @@ -674,7 +674,7 @@ public: enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { bzero(ptr,sizeof(float)); } double val_real(void); longlong val_int(void); @@ -708,7 +708,7 @@ public: enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { bzero(ptr,sizeof(double)); } double val_real(void); longlong val_int(void); @@ -737,7 +737,7 @@ public: int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } int store(double nr) { null[0]=1; return 0; } - int store(longlong nr) { null[0]=1; return 0; } + int store(longlong nr, bool unsigned_val) { null[0]=1; return 0; } int store_decimal(const my_decimal *d) { null[0]=1; return 0; } void reset(void) {} double val_real(void) { return 0.0;} @@ -766,7 +766,7 @@ public: enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } double val_real(void); longlong val_int(void); @@ -818,7 +818,7 @@ public: enum_field_types type() const { return FIELD_TYPE_YEAR;} int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -845,7 +845,7 @@ public: enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } double val_real(void); longlong val_int(void); @@ -873,7 +873,7 @@ public: enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); int store_time(TIME *ltime, timestamp_type type); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } double val_real(void); @@ -909,7 +909,7 @@ public: int store_time(TIME *ltime, timestamp_type type); int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } double val_real(void); longlong val_int(void); @@ -946,7 +946,7 @@ public: uint decimals() const { return DATETIME_DEC; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); int store_time(TIME *ltime, timestamp_type type); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } double val_real(void); @@ -990,7 +990,7 @@ public: bool zero_pack() const { return 0; } void reset(void) { charset()->cset->fill(charset(),ptr,field_length,' '); } int store(const char *to,uint length,CHARSET_INFO *charset); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */ double val_real(void); longlong val_int(void); @@ -1049,7 +1049,7 @@ public: uint32 pack_length() const { return (uint32) field_length+length_bytes; } uint32 key_length() const { return (uint32) field_length; } int store(const char *to,uint length,CHARSET_INFO *charset); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */ double val_real(void); longlong val_int(void); @@ -1106,7 +1106,7 @@ public: { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -1201,7 +1201,7 @@ public: void sql_type(String &str) const; int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); int store_decimal(const my_decimal *); void get_key_image(char *buff,uint length,imagetype type); uint size_of() const { return sizeof(*this); } @@ -1232,7 +1232,7 @@ public: enum ha_base_keytype key_type() const; int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); void reset() { bzero(ptr,packlength); } double val_real(void); longlong val_int(void); @@ -1268,8 +1268,8 @@ public: flags=(flags & ~ENUM_FLAG) | SET_FLAG; } int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr) { return Field_set::store((longlong) nr); } - int store(longlong nr); + int store(double nr) { return Field_set::store((longlong) nr, FALSE); } + int store(longlong nr, bool unsigned_val); virtual bool zero_pack() const { return 1; } String *val_str(String*,String *); void sql_type(String &str) const; @@ -1296,7 +1296,7 @@ public: void reset(void) { bzero(ptr, field_length); } int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); - int store(longlong nr); + int store(longlong nr, bool unsigned_val); int store_decimal(const my_decimal *); double val_real(void); longlong val_int(void); @@ -1342,7 +1342,8 @@ public: uint size_of() const { return sizeof(*this); } int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr) { return Field_bit::store(nr); } - int store(longlong nr) { return Field_bit::store(nr); } + int store(longlong nr, bool unsigned_val) + { return Field_bit::store(nr, unsigned_val); } void sql_type(String &str) const; }; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 40f3ff85c58..bbe2dbe5e9f 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -311,8 +311,9 @@ static void do_field_string(Copy_field *copy) static void do_field_int(Copy_field *copy) { - longlong value=copy->from_field->val_int(); - copy->to_field->store(value); + longlong value= copy->from_field->val_int(); + copy->to_field->store(value, + test(copy->from_field->flags & UNSIGNED_FLAG)); } static void do_field_real(Copy_field *copy) @@ -689,5 +690,5 @@ void field_conv(Field *to,Field *from) to->store_decimal(from->val_decimal(&buff)); } else - to->store(from->val_int()); + to->store(from->val_int(), test(from->flags & UNSIGNED_FLAG)); } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 146fbee93c8..ff631ac9db8 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2332,7 +2332,8 @@ void ha_ndbcluster::unpack_record(byte* buf) DBUG_PRINT("info", ("bit field H'%.8X", (*value).rec->u_32_value())); ((Field_bit *) *field)->store((longlong) - (*value).rec->u_32_value()); + (*value).rec->u_32_value(), + FALSE); } else { @@ -2340,7 +2341,8 @@ void ha_ndbcluster::unpack_record(byte* buf) *(Uint32 *)(*value).rec->aRef(), *((Uint32 *)(*value).rec->aRef()+1))); ((Field_bit *) *field)->store((longlong) - (*value).rec->u_64_value()); } + (*value).rec->u_64_value(), TRUE); + } } } else diff --git a/sql/handler.cc b/sql/handler.cc index 3acca812a13..b3754891d05 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1518,7 +1518,7 @@ bool handler::update_auto_increment() /* Mark that we should clear next_insert_id before next stmt */ thd->clear_next_insert_id= 1; - if (!table->next_number_field->store((longlong) nr)) + if (!table->next_number_field->store((longlong) nr, TRUE)) thd->insert_id((ulonglong) nr); else thd->insert_id(table->next_number_field->val_int()); diff --git a/sql/item.cc b/sql/item.cc index e7da646ae73..2086d8cc161 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2341,7 +2341,7 @@ int Item_param::save_in_field(Field *field, bool no_conversions) switch (state) { case INT_VALUE: - return field->store(value.integer); + return field->store(value.integer, unsigned_flag); case REAL_VALUE: return field->store(value.real); case DECIMAL_VALUE: @@ -3895,7 +3895,7 @@ int Item::save_in_field(Field *field, bool no_conversions) if (null_value) return set_field_to_null_with_conversions(field, no_conversions); field->set_notnull(); - error=field->store(nr); + error=field->store(nr, unsigned_flag); } return error; } @@ -3911,12 +3911,10 @@ int Item_string::save_in_field(Field *field, bool no_conversions) return field->store(result->ptr(),result->length(),collation.collation); } + int Item_uint::save_in_field(Field *field, bool no_conversions) { - /* - TODO: To be fixed when wen have a - field->store(longlong, unsigned_flag) method - */ + /* Item_int::save_in_field handles both signed and unsigned. */ return Item_int::save_in_field(field, no_conversions); } @@ -3927,7 +3925,7 @@ int Item_int::save_in_field(Field *field, bool no_conversions) if (null_value) return set_field_to_null(field); field->set_notnull(); - return field->store(nr); + return field->store(nr, unsigned_flag); } @@ -4134,7 +4132,7 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions) else { longlong nr=val_int(); - error=field->store(nr); + error=field->store(nr, TRUE); // Assume hex numbers are unsigned } return error; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 4f991615bfa..880ab4c8cb1 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1614,7 +1614,7 @@ void Item_sum_hybrid::reset_field() else result_field->set_notnull(); } - result_field->store(nr); + result_field->store(nr, unsigned_flag); break; } case REAL_RESULT: @@ -1930,7 +1930,7 @@ Item_sum_hybrid::min_max_update_int_field() } else if (result_field->is_null(0)) result_field->set_null(); - result_field->store(old_nr); + result_field->store(old_nr, unsigned_flag); } diff --git a/sql/sp.cc b/sql/sp.cc index 016703662a5..271a5d3a4f8 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -223,7 +223,7 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) table->field[0]->store(name->m_db.str, name->m_db.length, &my_charset_bin); table->field[1]->store(name->m_name.str, name->m_name.length, &my_charset_bin); - table->field[2]->store((longlong) type); + table->field[2]->store((longlong) type, TRUE); key_copy(key, table->record[0], table->key_info, table->key_info->key_length); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4127129576b..9cd19b8e8e6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1800,11 +1800,11 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, USER_RESOURCES mqh= lex->mqh; if (mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR) - table->field[next_field]->store((longlong) mqh.questions); + table->field[next_field]->store((longlong) mqh.questions, TRUE); if (mqh.specified_limits & USER_RESOURCES::UPDATES_PER_HOUR) - table->field[next_field+1]->store((longlong) mqh.updates); + table->field[next_field+1]->store((longlong) mqh.updates, TRUE); if (mqh.specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR) - table->field[next_field+2]->store((longlong) mqh.conn_per_hour); + table->field[next_field+2]->store((longlong) mqh.conn_per_hour, TRUE); if (table->s->fields >= 36 && (mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS)) table->field[next_field+3]->store((longlong) mqh.user_conn); @@ -2306,7 +2306,7 @@ static int replace_column_table(GRANT_TABLE *g_t, store_record(table,record[1]); // copy original row } - table->field[6]->store((longlong) get_rights_for_column(privileges)); + table->field[6]->store((longlong) get_rights_for_column(privileges), TRUE); if (old_row_exists) { @@ -2373,7 +2373,7 @@ static int replace_column_table(GRANT_TABLE *g_t, privileges&= ~rights; table->field[6]->store((longlong) - get_rights_for_column(privileges)); + get_rights_for_column(privileges), TRUE); table->field[4]->val_str(&column_name); grant_column = column_hash_search(g_t, column_name.ptr(), @@ -2492,8 +2492,8 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } table->field[4]->store(grantor,(uint) strlen(grantor), system_charset_info); - table->field[6]->store((longlong) store_table_rights); - table->field[7]->store((longlong) store_col_rights); + table->field[6]->store((longlong) store_table_rights, TRUE); + table->field[7]->store((longlong) store_col_rights, TRUE); rights=fix_rights_for_table(store_table_rights); col_rights=fix_rights_for_column(store_col_rights); @@ -2568,7 +2568,8 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, table->field[3]->store(routine_name,(uint) strlen(routine_name), &my_charset_latin1); table->field[4]->store((longlong)(is_proc ? - TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION)); + TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION), + TRUE); store_record(table,record[1]); // store at pos 1 if (table->file->index_read_idx(table->record[0],0, @@ -2609,7 +2610,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, } table->field[5]->store(grantor,(uint) strlen(grantor), &my_charset_latin1); - table->field[6]->store((longlong) store_proc_rights); + table->field[6]->store((longlong) store_proc_rights, TRUE); rights=fix_rights_for_procedure(store_proc_rights); if (old_row_exists) diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 799758f7d1e..f4d835541cf 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -289,7 +289,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, topics->file->ha_index_init(iindex_topic); relations->file->ha_index_init(iindex_relations); - rkey_id->store((longlong) key_id); + rkey_id->store((longlong) key_id, TRUE); rkey_id->get_key_image(buff, rkey_id->pack_length(), Field::itRAW); int key_res= relations->file->index_read(relations->record[0], (byte *)buff, rkey_id->pack_length(), @@ -302,7 +302,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, char topic_id_buff[8]; longlong topic_id= rtopic_id->val_int(); Field *field= find_fields[help_topic_help_topic_id].field; - field->store((longlong) topic_id); + field->store((longlong) topic_id, TRUE); field->get_key_image(topic_id_buff, field->pack_length(), Field::itRAW); if (!topics->file->index_read(topics->record[0], (byte *)topic_id_buff, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 51330a6109b..d657183b8f4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2255,7 +2255,7 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables, } tmp_buff= file->table_type(); table->field[4]->store(tmp_buff, strlen(tmp_buff), cs); - table->field[5]->store((longlong) share->frm_version); + table->field[5]->store((longlong) share->frm_version, TRUE); enum row_type row_type = file->get_row_type(); switch (row_type) { case ROW_TYPE_NOT_USED: @@ -2284,7 +2284,7 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables, table->field[6]->store(tmp_buff, strlen(tmp_buff), cs); if (!tables->schema_table) { - table->field[7]->store((longlong) file->records); + table->field[7]->store((longlong) file->records, TRUE); table->field[7]->set_notnull(); } table->field[8]->store((longlong) file->mean_rec_length); @@ -2297,7 +2297,7 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables, table->field[12]->store((longlong) file->delete_length); if (show_table->found_next_number_field) { - table->field[13]->store((longlong) file->auto_increment_value); + table->field[13]->store((longlong) file->auto_increment_value, TRUE); table->field[13]->set_notnull(); } if (file->create_time) @@ -2325,7 +2325,7 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables, table->field[17]->store(tmp_buff, strlen(tmp_buff), cs); if (file->table_flags() & (ulong) HA_HAS_CHECKSUM) { - table->field[18]->store((longlong) file->checksum()); + table->field[18]->store((longlong) file->checksum(), TRUE); table->field[18]->set_notnull(); } @@ -2476,7 +2476,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, table->field[2]->store(file_name, file_name_length, cs); table->field[3]->store(field->field_name, strlen(field->field_name), cs); - table->field[4]->store((longlong) count); + table->field[4]->store((longlong) count, TRUE); field->sql_type(type); table->field[14]->store(type.ptr(), type.length(), cs); tmp_buff= strchr(type.ptr(), '('); @@ -2520,7 +2520,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, { longlong c_octet_len= is_blob ? (longlong) field->max_length() : (longlong) field->max_length()/field->charset()->mbmaxlen; - table->field[8]->store(c_octet_len); + table->field[8]->store(c_octet_len, TRUE); table->field[8]->set_notnull(); table->field[9]->store((longlong) field->max_length()); table->field[9]->set_notnull(); @@ -2568,7 +2568,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, } if (decimals >= 0) { - table->field[11]->store((longlong) decimals); + table->field[11]->store((longlong) decimals, TRUE); table->field[11]->set_notnull(); } @@ -2624,7 +2624,7 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond) table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs); comment= tmp_cs->comment ? tmp_cs->comment : ""; table->field[2]->store(comment, strlen(comment), scs); - table->field[3]->store((longlong) tmp_cs->mbmaxlen); + table->field[3]->store((longlong) tmp_cs->mbmaxlen, TRUE); if (schema_table_store_record(thd, table)) return 1; } @@ -2659,12 +2659,12 @@ int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond) restore_record(table, s->default_values); table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs); table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs); - table->field[2]->store((longlong) tmp_cl->number); + table->field[2]->store((longlong) tmp_cl->number, TRUE); tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : ""; table->field[3]->store(tmp_buff, strlen(tmp_buff), scs); tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : ""; table->field[4]->store(tmp_buff, strlen(tmp_buff), scs); - table->field[5]->store((longlong) tmp_cl->strxfrm_multiply); + table->field[5]->store((longlong) tmp_cl->strxfrm_multiply, TRUE); if (schema_table_store_record(thd, table)) return 1; } @@ -2865,10 +2865,10 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables, table->field[1]->store(base_name, strlen(base_name), cs); table->field[2]->store(file_name, strlen(file_name), cs); table->field[3]->store((longlong) ((key_info->flags & - HA_NOSAME) ? 0 :1)); + HA_NOSAME) ? 0 : 1), TRUE); table->field[4]->store(base_name, strlen(base_name), cs); table->field[5]->store(key_info->name, strlen(key_info->name), cs); - table->field[6]->store((longlong) (j+1)); + table->field[6]->store((longlong) (j+1), TRUE); str=(key_part->field ? key_part->field->field_name : "?unknown field?"); table->field[7]->store(str, strlen(str), cs); @@ -2884,7 +2884,7 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables, { ha_rows records=(show_table->file->records / key->rec_per_key[j]); - table->field[9]->store((longlong) records); + table->field[9]->store((longlong) records, TRUE); table->field[9]->set_notnull(); } if (!(key_info->flags & HA_FULLTEXT) && @@ -3123,7 +3123,7 @@ void store_key_column_usage(TABLE *table, const char*db, const char *tname, table->field[4]->store(db, strlen(db), cs); table->field[5]->store(tname, strlen(tname), cs); table->field[6]->store(con_type, con_len, cs); - table->field[7]->store((longlong) idx); + table->field[7]->store((longlong) idx, TRUE); } @@ -3195,7 +3195,7 @@ static int get_schema_key_column_usage_record(THD *thd, f_key_info->forein_id->length, f_info->str, f_info->length, (longlong) f_idx); - table->field[8]->store((longlong) f_idx); + table->field[8]->store((longlong) f_idx, TRUE); table->field[8]->set_notnull(); table->field[9]->store(f_key_info->referenced_db->str, f_key_info->referenced_db->length, @@ -3233,8 +3233,8 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) restore_record(table, s->default_values); table->field[0]->store(open_list->db, strlen(open_list->db), cs); table->field[1]->store(open_list->table, strlen(open_list->table), cs); - table->field[2]->store((longlong) open_list->in_use); - table->field[3]->store((longlong) open_list->locked); + table->field[2]->store((longlong) open_list->in_use, TRUE); + table->field[3]->store((longlong) open_list->locked, TRUE); if (schema_table_store_record(thd, table)) DBUG_RETURN(1); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 611ab0f16aa..64437ce26ce 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1712,6 +1712,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, DBUG_ENTER("create_table_from_items"); tmp_table.alias= 0; + tmp_table.timestamp_field= 0; tmp_table.s= &tmp_table.share_not_to_be_used; tmp_table.s->db_create_options=0; tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr; diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index e0c3034a58a..ba3c598a784 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -472,10 +472,10 @@ int mysql_create_function(THD *thd,udf_func *udf) restore_record(table, s->default_values); // Default values for fields table->field[0]->store(u_d->name.str, u_d->name.length, system_charset_info); - table->field[1]->store((longlong) u_d->returns); + table->field[1]->store((longlong) u_d->returns, TRUE); table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl), system_charset_info); if (table->s->fields >= 4) // If not old func format - table->field[3]->store((longlong) u_d->type); + table->field[3]->store((longlong) u_d->type, TRUE); error = table->file->write_row(table->record[0]); close_thread_tables(thd); diff --git a/sql/tztime.cc b/sql/tztime.cc index 5a907f0d170..537050e94db 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1826,7 +1826,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ table= tz_tables->table; tz_tables= tz_tables->next_local; - table->field[0]->store((longlong)tzid); + table->field[0]->store((longlong) tzid, TRUE); (void)table->file->ha_index_init(0); if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, @@ -1853,7 +1853,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ table= tz_tables->table; tz_tables= tz_tables->next_local; - table->field[0]->store((longlong)tzid); + table->field[0]->store((longlong) tzid, TRUE); (void)table->file->ha_index_init(0); // FIXME Is there any better approach than explicitly specifying 4 ??? @@ -1925,7 +1925,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) in ascending order by index scan also satisfies us. */ table= tz_tables->table; - table->field[0]->store((longlong)tzid); + table->field[0]->store((longlong) tzid, TRUE); (void)table->file->ha_index_init(0); // FIXME Is there any better approach than explicitly specifying 4 ??? diff --git a/sql/unireg.cc b/sql/unireg.cc index a89d89426a6..70b0fb400f9 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -754,7 +754,7 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, (field->flags & NOT_NULL_FLAG)) { regfield->set_notnull(); - regfield->store((longlong) 1); + regfield->store((longlong) 1, TRUE); } else if (type == Field::YES) // Old unireg type regfield->store(ER(ER_YES),(uint) strlen(ER(ER_YES)),system_charset_info); From e338cf105f5eb980a1820c76d9f976ac7e7244b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Sep 2005 03:16:25 +0300 Subject: [PATCH 19/21] Fixed wrong merge --- mysql-test/t/mysqldump.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 397a1907681..ca7f5622ae5 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -768,8 +768,8 @@ DROP TABLE t1, t2; --exec echo "[mysqltest1]" > $MYSQL_TEST_DIR/var/tmp/tmp.cnf --exec echo "port=1234" >> $MYSQL_TEST_DIR/var/tmp/tmp.cnf ---exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQL_TEST_DIR/var/tmp/tmp.cnf client ---exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQL_TEST_DIR/var/tmp/tmp.cnf -e $MYSQL_TEST_DIR/var/tmp/tmp.cnf client client +--exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQL_TEST_DIR/var/tmp/tmp.cnf mysqltest1 +--exec $MYSQL_MY_PRINT_DEFAULTS -e $MYSQL_TEST_DIR/var/tmp/tmp.cnf mysqltest1 mysqltest1 --exec rm $MYSQL_TEST_DIR/var/tmp/tmp.cnf # From 4f4ab005af7800dcc25a4f53aa2a6a01ced62811 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Sep 2005 04:40:18 +0300 Subject: [PATCH 20/21] Removed compiler warnings --- client/mysqldump.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 2f7040afb05..be93b48f496 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1193,7 +1193,8 @@ static void print_xml_row(FILE *xml_file, const char *row_name, static uint dump_routines_for_db (char *db) { - char query_buff[512], *routine_type[]={"FUNCTION", "PROCEDURE"}; + char query_buff[512]; + const char *routine_type[]={"FUNCTION", "PROCEDURE"}; char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3], *routine_name; int i; FILE *sql_file = md_result_file; From ab5b9baf53d056b1dd3db1888b0fb32f3da95601 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Sep 2005 23:31:17 -0700 Subject: [PATCH 21/21] Improvement to federated for BUG#12659 Now many direct references to my_error() have been removed. mysql-test/r/federated_archive.result: new results with new error message mysql-test/t/federated_archive.test: corrected error number sql/ha_federated.cc: some minor 80 column formatting corrected some error handling to be more handler print_error friendly moved duplicate code into new "stash_remote_error" function sql/ha_federated.h: added error number, and places to stash error message and number added private method to stash error --- mysql-test/r/federated_archive.result | 4 +- mysql-test/t/federated_archive.test | 6 +- sql/ha_federated.cc | 93 +++++++++++++-------------- sql/ha_federated.h | 12 ++++ 4 files changed, 62 insertions(+), 53 deletions(-) diff --git a/mysql-test/r/federated_archive.result b/mysql-test/r/federated_archive.result index 5fc9bfadeb6..3fd7cb2acd4 100644 --- a/mysql-test/r/federated_archive.result +++ b/mysql-test/r/federated_archive.result @@ -29,13 +29,13 @@ id name 1 foo 2 bar DELETE FROM federated.t1 WHERE id = 1; -ERROR HY000: There was a problem processing the query on the foreign data source. Data source error: ': 1031 : Table storage engine for 'archive_table' doesn't have t' +ERROR HY000: Got error 10000 'Error on remote system: 1031: Table storage engine for 'archive_table' doesn't have this option' from FEDERATED SELECT * FROM federated.t1; id name 1 foo 2 bar UPDATE federated.t1 SET name='baz' WHERE id = 1; -ERROR HY000: There was a problem processing the query on the foreign data source. Data source error: ': 1031 : Table storage engine for 'archive_table' doesn't have t' +ERROR HY000: Got error 10000 'Error on remote system: 1031: Table storage engine for 'archive_table' doesn't have this option' from FEDERATED SELECT * FROM federated.t1; id name 1 foo diff --git a/mysql-test/t/federated_archive.test b/mysql-test/t/federated_archive.test index df0d8c5cca1..6d80664fef7 100644 --- a/mysql-test/t/federated_archive.test +++ b/mysql-test/t/federated_archive.test @@ -32,19 +32,19 @@ INSERT INTO federated.t1 (id, name) VALUES (2, 'bar'); SELECT * FROM federated.t1; ---error 1430 +--error 1296 DELETE FROM federated.t1 WHERE id = 1; SELECT * FROM federated.t1; ---error 1430 +--error 1296 UPDATE federated.t1 SET name='baz' WHERE id = 1; SELECT * FROM federated.t1; -# --error 1430 +# --error 1296 # TRUNCATE federated.t1; # # SELECT * from federated.t1; diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 5cc5b7aa32c..83224649842 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -473,13 +473,15 @@ static int check_foreign_data_source( else { /* - Since we do not support transactions at this version, we can let the client - API silently reconnect. For future versions, we will need more logic to deal - with transactions + Since we do not support transactions at this version, we can let the + client API silently reconnect. For future versions, we will need more + logic to deal with transactions */ mysql->reconnect= 1; /* - Note: I am not using INORMATION_SCHEMA because this needs to work with < 5.0 + Note: I am not using INORMATION_SCHEMA because this needs to work with + versions prior to 5.0 + if we can connect, then make sure the table exists the query will be: SELECT * FROM `tablename` WHERE 1=0 @@ -497,7 +499,8 @@ static int check_foreign_data_source( query.append(FEDERATED_WHERE); query.append(FEDERATED_FALSE); - DBUG_PRINT("info", ("check_foreign_data_source query %s", query.c_ptr_quick())); + DBUG_PRINT("info", ("check_foreign_data_source query %s", + query.c_ptr_quick())); if (mysql_real_query(mysql, query.ptr(), query.length())) { error_code= table_create_flag ? @@ -1449,13 +1452,7 @@ int ha_federated::open(const char *name, int mode, uint test_if_locked) share->port, share->socket, 0)) { - int error_code; - char error_buffer[FEDERATED_QUERY_BUFFER_SIZE]; - error_code= ER_CONNECT_TO_FOREIGN_DATA_SOURCE; - my_sprintf(error_buffer, (error_buffer, ": %d : %s", - mysql_errno(mysql), mysql_error(mysql))); - my_error(error_code, MYF(0), error_buffer); - DBUG_RETURN(error_code); + DBUG_RETURN(stash_remote_error()); } /* Since we do not support transactions at this version, we can let the client @@ -1687,13 +1684,7 @@ int ha_federated::write_row(byte *buf) if (mysql_real_query(mysql, insert_string.ptr(), insert_string.length())) { - int error_code; - char error_buffer[FEDERATED_QUERY_BUFFER_SIZE]; - error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE; - my_sprintf(error_buffer, (error_buffer, ": %d : %s", - mysql_errno(mysql), mysql_error(mysql))); - my_error(error_code, MYF(0), error_buffer); - DBUG_RETURN(error_code); + DBUG_RETURN(stash_remote_error()); } DBUG_RETURN(0); @@ -1717,8 +1708,7 @@ int ha_federated::optimize(THD* thd, HA_CHECK_OPT* check_opt) if (mysql_real_query(mysql, query.ptr(), query.length())) { - my_error(-1, MYF(0), mysql_error(mysql)); - DBUG_RETURN(-1); + DBUG_RETURN(stash_remote_error()); } DBUG_RETURN(0); @@ -1748,8 +1738,7 @@ int ha_federated::repair(THD* thd, HA_CHECK_OPT* check_opt) if (mysql_real_query(mysql, query.ptr(), query.length())) { - my_error(-1, MYF(0), mysql_error(mysql)); - DBUG_RETURN(-1); + DBUG_RETURN(stash_remote_error()); } DBUG_RETURN(0); @@ -1892,12 +1881,7 @@ int ha_federated::update_row(const byte *old_data, byte *new_data) if (mysql_real_query(mysql, update_string.ptr(), update_string.length())) { - int error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE; - char error_buffer[FEDERATED_QUERY_BUFFER_SIZE]; - my_sprintf(error_buffer, (error_buffer, ": %d : %s", - mysql_errno(mysql), mysql_error(mysql))); - my_error(error_code, MYF(0), error_buffer); - DBUG_RETURN(error_code); + DBUG_RETURN(stash_remote_error()); } DBUG_RETURN(0); } @@ -1962,12 +1946,7 @@ int ha_federated::delete_row(const byte *buf) ("Delete sql: %s", delete_string.c_ptr_quick())); if (mysql_real_query(mysql, delete_string.ptr(), delete_string.length())) { - int error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE; - char error_buffer[FEDERATED_QUERY_BUFFER_SIZE]; - my_sprintf(error_buffer, (error_buffer, ": %d : %s", - mysql_errno(mysql), mysql_error(mysql))); - my_error(error_code, MYF(0), error_buffer); - DBUG_RETURN(error_code); + DBUG_RETURN(stash_remote_error()); } deleted+= mysql->affected_rows; DBUG_PRINT("info", @@ -2262,13 +2241,7 @@ int ha_federated::rnd_init(bool scan) DBUG_RETURN(0); error: - retval= ER_QUERY_ON_FOREIGN_DATA_SOURCE; - my_sprintf(error_buffer, (error_buffer, ": %d : %s", - mysql_errno(mysql), mysql_error(mysql))); - my_error(retval, MYF(0), error_buffer); - DBUG_PRINT("info", - ("return error code %d", retval)); - DBUG_RETURN(retval); + DBUG_RETURN(stash_remote_error()); } int ha_federated::rnd_end() @@ -2551,12 +2524,7 @@ int ha_federated::delete_all_rows() deleted+= records; if (mysql_real_query(mysql, query.ptr(), query.length())) { - int error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE; - char error_buffer[FEDERATED_QUERY_BUFFER_SIZE]; - my_sprintf(error_buffer, (error_buffer, ": %d : %s", - mysql_errno(mysql), mysql_error(mysql))); - my_error(error_code, MYF(0), error_buffer); - DBUG_RETURN(error_code); + DBUG_RETURN(stash_remote_error()); } DBUG_RETURN(0); } @@ -2665,4 +2633,33 @@ error: DBUG_RETURN(retval); } + + +int ha_federated::stash_remote_error() +{ + DBUG_ENTER("ha_federated::stash_remote_error()"); + remote_error_number= mysql_errno(mysql); + snprintf(remote_error_buf, FEDERATED_QUERY_BUFFER_SIZE, mysql_error(mysql)); + DBUG_RETURN(HA_FEDERATED_ERROR_WITH_REMOTE_SYSTEM); +} + + +bool ha_federated::get_error_message(int error, String* buf) +{ + DBUG_ENTER("ha_federated::get_error_message"); + DBUG_PRINT("enter", ("error: %d", error)); + if (error == HA_FEDERATED_ERROR_WITH_REMOTE_SYSTEM) + { + buf->append("Error on remote system: "); + buf->qs_append(remote_error_number); + buf->append(": "); + buf->append(remote_error_buf, FEDERATED_QUERY_BUFFER_SIZE); + + remote_error_number= 0; + remote_error_buf[0]= '\0'; + } + DBUG_PRINT("exit", ("message: %s", buf->ptr())); + DBUG_RETURN(FALSE); +} + #endif /* HAVE_FEDERATED_DB */ diff --git a/sql/ha_federated.h b/sql/ha_federated.h index f75fa21b1d6..b25071dda16 100644 --- a/sql/ha_federated.h +++ b/sql/ha_federated.h @@ -27,6 +27,14 @@ #include +/* + handler::print_error has a case statement for error numbers. + This value is (10000) is far out of range and will envoke the + default: case. + (Current error range is 120-159 from include/my_base.h) +*/ +#define HA_FEDERATED_ERROR_WITH_REMOTE_SYSTEM 10000 + #define FEDERATED_QUERY_BUFFER_SIZE STRING_BUFFER_USUAL_SIZE * 5 #define FEDERATED_RECORDS_IN_RANGE 2 @@ -149,6 +157,8 @@ class ha_federated: public handler uint ref_length; uint fetch_num; // stores the fetch num MYSQL_ROW_OFFSET current_position; // Current position used by ::position() + int remote_error_number; + char remote_error_buf[FEDERATED_QUERY_BUFFER_SIZE]; private: /* @@ -160,6 +170,7 @@ private: const key_range *start_key, const key_range *end_key, bool records_in_range); + int stash_remote_error(); public: ha_federated(TABLE *table_arg); @@ -286,6 +297,7 @@ public: THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); //required + virtual bool get_error_message(int error, String *buf); }; bool federated_db_init(void);