Commit 32747b19 authored by unknown's avatar unknown

Fixed bug in error handling of CREATE ... SELECT

More tests cases
After merge fixes


BitKeeper/deleted/.del-ansi-master.opt~4d337eb61642a838:
  Delete: mysql-test/t/ansi-master.opt
mysql-test/r/ansi.result:
  Cleaned up test to be able to remove ansi-master.opt
mysql-test/r/create.result:
  Updated results
mysql-test/r/insert_select.result:
  Updated results
mysql-test/r/rpl000009.result:
  Updated results
mysql-test/t/ansi.test:
  Cleaned up test to be able to remove ansi-master.opt
mysql-test/t/create.test:
  More tests
mysql-test/t/insert_select.test:
  More tests
mysql-test/t/mysqlbinlog.test:
  Fixed test after merge
sql/mysql_priv.h:
  Added character-sets-dir to 'show variables'
sql/set_var.cc:
  Added character-sets-dir to 'show variables'
sql/sql_class.cc:
  Fixed that send_error() is called properly when a SELECT fails
sql/sql_class.h:
  Fixed that send_error() is called properly when a SELECT fails
sql/sql_insert.cc:
  Fixed bug in error handling of CREATE ... SELECT
sql/sql_select.cc:
  Fixed bug in error handling of CREATE ... SELECT
parent 69ea87fe
drop table if exists t1; drop table if exists t1;
set sql_mode="MySQL40";
select @@sql_mode;
@@sql_mode
NO_FIELD_OPTIONS,MYSQL40
set @@sql_mode="ANSI";
select @@sql_mode;
@@sql_mode
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI
SELECT 'A' || 'B'; SELECT 'A' || 'B';
'A' || 'B' 'A' || 'B'
AB AB
...@@ -8,11 +16,4 @@ id NULL 1 1.1 a ...@@ -8,11 +16,4 @@ id NULL 1 1.1 a
SELECT id FROM t1 GROUP BY id2; SELECT id FROM t1 GROUP BY id2;
ERROR 42000: 'test.t1.id' isn't in GROUP BY ERROR 42000: 'test.t1.id' isn't in GROUP BY
drop table t1; drop table t1;
set sql_mode="MySQL40"; SET @@SQL_MODE="";
select @@sql_mode;
@@sql_mode
NO_FIELD_OPTIONS,MYSQL40
set sql_mode="ANSI";
select @@sql_mode;
@@sql_mode
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI
...@@ -129,6 +129,16 @@ ERROR 42S21: Duplicate column name 'b' ...@@ -129,6 +129,16 @@ ERROR 42S21: Duplicate column name 'b'
drop table if exists t1,t2; drop table if exists t1,t2;
Warnings: Warnings:
Note 1051 Unknown table 't2' Note 1051 Unknown table 't2'
CREATE TABLE t1 (a int not null);
INSERT INTO t1 values (1),(2),(1);
CREATE TABLE t2 (primary key(a)) SELECT * FROM t1;
ERROR 23000: Duplicate entry '1' for key 1
SELECT * from t2;
ERROR 42S02: Table 'test.t2' doesn't exist
DROP TABLE t1;
DROP TABLE IF EXISTS t2;
Warnings:
Note 1051 Unknown table 't2'
create table t1 (a int not null, b int, primary key(a), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b)); create table t1 (a int not null, b int, primary key(a), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b), key (b));
show create table t1; show create table t1;
Table Create Table Table Create Table
......
...@@ -74,7 +74,12 @@ insert into t1 select * from t2; ...@@ -74,7 +74,12 @@ insert into t1 select * from t2;
ERROR 23000: Duplicate entry '2' for key 1 ERROR 23000: Duplicate entry '2' for key 1
show binlog events; show binlog events;
Log_name Pos Event_type Server_id Orig_log_pos Info Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.000001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
master-bin.000001 79 Query 1 79 use `test`; insert into t1 select * from t2 master-bin.000001 79 Query 1 79 use `test`; insert into t1 select * from t2
select * from t1;
a
1
2
drop table t1, t2; drop table t1, t2;
create table t1 (a int not null); create table t1 (a int not null);
create table t2 (a int not null); create table t2 (a int not null);
......
...@@ -4,9 +4,13 @@ reset master; ...@@ -4,9 +4,13 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
drop database if exists mysqltest;
drop database if exists mysqltest2; drop database if exists mysqltest2;
create database mysqltest2; drop database if exists mysqltest3;
drop database if exists mysqltest; drop database if exists mysqltest;
drop database if exists mysqltest2;
drop database if exists mysqltest3;
create database mysqltest2;
create database mysqltest; create database mysqltest;
create database mysqltest2; create database mysqltest2;
create table mysqltest2.foo (n int); create table mysqltest2.foo (n int);
...@@ -46,45 +50,43 @@ show databases; ...@@ -46,45 +50,43 @@ show databases;
Database Database
mysql mysql
test test
create database foo; create database mysqltest2;
create table foo.t1(n int, s char(20)); create table mysqltest2.t1(n int, s char(20));
insert into foo.t1 values (1, 'original foo.t1'); insert into mysqltest2.t1 values (1, 'original foo.t1');
create table foo.t3(n int, s char(20)); create table mysqltest2.t3(n int, s char(20));
insert into foo.t3 values (1, 'original foo.t3'); insert into mysqltest2.t3 values (1, 'original foo.t3');
create database foo2; create database mysqltest3;
create table foo2.t1(n int, s char(20)); create table mysqltest3.t1(n int, s char(20));
insert into foo2.t1 values (1, 'original foo2.t1'); insert into mysqltest3.t1 values (1, 'original foo2.t1');
create database bar; create database mysqltest;
create table bar.t1(n int, s char(20)); create table mysqltest.t1(n int, s char(20));
insert into bar.t1 values (1, 'original bar.t1'); insert into mysqltest.t1 values (1, 'original bar.t1');
create table bar.t3(n int, s char(20)); create table mysqltest.t3(n int, s char(20));
insert into bar.t3 values (1, 'original bar.t3'); insert into mysqltest.t3 values (1, 'original bar.t3');
load data from master; load data from master;
Warnings:
Note 1008 Can't drop database 'mysqltest'; database doesn't exist
Note 1008 Can't drop database 'mysqltest2'; database doesn't exist
show databases; show databases;
Database Database
mysql mysql
mysqltest mysqltest
mysqltest2 mysqltest2
mysqltest3
test test
use mysqltest2; use mysqltest2;
show tables; show tables;
Tables_in_mysqltest2 Tables_in_mysqltest2
use mysqltest;
t1 t1
t3 t3
select * from t1; select * from t1;
n s n s
1 original foo.t1 1 original foo.t1
use foo2; use mysqltest3;
show tables; show tables;
Tables_in_foo2 Tables_in_mysqltest3
t1 t1
select * from t1; select * from t1;
n s n s
1 original foo2.t1 1 original foo2.t1
use mysqltest;
show tables; show tables;
Tables_in_mysqltest Tables_in_mysqltest
t1 t1
...@@ -100,6 +102,9 @@ n s ...@@ -100,6 +102,9 @@ n s
11 eleven test 11 eleven test
12 twelve test 12 twelve test
13 thirteen test 13 thirteen test
select * from mysqltest.t3;
n s
1 original bar.t3
insert into mysqltest.t1 values (4, 'four test'); insert into mysqltest.t1 values (4, 'four test');
select * from mysqltest.t1; select * from mysqltest.t1;
n s n s
...@@ -107,5 +112,13 @@ n s ...@@ -107,5 +112,13 @@ n s
2 two test 2 two test
3 three test 3 three test
4 four test 4 four test
load table mysqltest.t1 from master;
ERROR 42S01: Table 't1' already exists
drop table mysqltest.t1;
load table mysqltest.t1 from master;
load table bar.t1 from master;
ERROR HY000: Error from master: 'Table 'bar.t1' doesn't exist'
drop database mysqltest; drop database mysqltest;
drop database mysqltest2; drop database mysqltest2;
drop database mysqltest2;
drop database mysqltest3;
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
set sql_mode="MySQL40";
select @@sql_mode;
set @@sql_mode="ANSI";
select @@sql_mode;
# Test some functions that works different in ansi mode # Test some functions that works different in ansi mode
SELECT 'A' || 'B'; SELECT 'A' || 'B';
...@@ -18,7 +23,4 @@ SELECT id,NULL,1,1.1,'a' FROM t1 GROUP BY id; ...@@ -18,7 +23,4 @@ SELECT id,NULL,1,1.1,'a' FROM t1 GROUP BY id;
SELECT id FROM t1 GROUP BY id2; SELECT id FROM t1 GROUP BY id2;
drop table t1; drop table t1;
set sql_mode="MySQL40"; SET @@SQL_MODE="";
select @@sql_mode;
set sql_mode="ANSI";
select @@sql_mode;
...@@ -110,6 +110,19 @@ drop table if exists t2; ...@@ -110,6 +110,19 @@ drop table if exists t2;
create table t2 (b int) select a as b, a+1 as b from t1; create table t2 (b int) select a as b, a+1 as b from t1;
drop table if exists t1,t2; drop table if exists t1,t2;
#
# Test CREATE ... SELECT when insert fails
#
CREATE TABLE t1 (a int not null);
INSERT INTO t1 values (1),(2),(1);
--error 1062
CREATE TABLE t2 (primary key(a)) SELECT * FROM t1;
--error 1146
SELECT * from t2;
DROP TABLE t1;
DROP TABLE IF EXISTS t2;
# #
# Test of primary key with 32 index # Test of primary key with 32 index
# #
......
...@@ -86,6 +86,7 @@ insert into t1 select * from t2; ...@@ -86,6 +86,7 @@ insert into t1 select * from t2;
let $VERSION=`select version()`; let $VERSION=`select version()`;
--replace_result $VERSION VERSION --replace_result $VERSION VERSION
show binlog events; show binlog events;
select * from t1;
drop table t1, t2; drop table t1, t2;
# #
......
...@@ -83,7 +83,7 @@ select "--- Remote --" as ""; ...@@ -83,7 +83,7 @@ select "--- Remote --" as "";
select "--- Broken LOAD DATA --" as ""; select "--- Broken LOAD DATA --" as "";
--enable_query_log --enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.002 --exec $MYSQL_BINLOG --short-form --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# And this too ! (altough it is documented) # And this too ! (altough it is documented)
--disable_query_log --disable_query_log
...@@ -97,7 +97,7 @@ select "--- --database --" as ""; ...@@ -97,7 +97,7 @@ select "--- --database --" as "";
select "--- --position --" as ""; select "--- --position --" as "";
--enable_query_log --enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form --read-from-remote-server --position=27 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.002 --exec $MYSQL_BINLOG --short-form --read-from-remote-server --position=27 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# clean up # clean up
drop table t1; drop table t1;
...@@ -733,7 +733,7 @@ extern void yyerror(const char*); ...@@ -733,7 +733,7 @@ extern void yyerror(const char*);
extern time_t start_time; extern time_t start_time;
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
mysql_real_data_home[], *opt_mysql_tmpdir; mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[];
#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list)) #define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
extern MY_TMPDIR mysql_tmpdir_list; extern MY_TMPDIR mysql_tmpdir_list;
extern const char *command_name[]; extern const char *command_name[];
......
...@@ -509,8 +509,9 @@ struct show_var_st init_vars[]= { ...@@ -509,8 +509,9 @@ struct show_var_st init_vars[]= {
{sys_character_set_server.name, (char*) &sys_character_set_server,SHOW_SYS}, {sys_character_set_server.name, (char*) &sys_character_set_server,SHOW_SYS},
{sys_charset_system.name, (char*) &sys_charset_system, SHOW_SYS}, {sys_charset_system.name, (char*) &sys_charset_system, SHOW_SYS},
{sys_character_set_database.name, (char*) &sys_character_set_database,SHOW_SYS}, {sys_character_set_database.name, (char*) &sys_character_set_database,SHOW_SYS},
{sys_character_set_client.name,(char*) &sys_character_set_client,SHOW_SYS}, {sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS},
{sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS}, {sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS},
{"character-sets-dir", mysql_charsets_dir, SHOW_CHAR},
{sys_character_set_results.name,(char*) &sys_character_set_results, SHOW_SYS}, {sys_character_set_results.name,(char*) &sys_character_set_results, SHOW_SYS},
{sys_collation_connection.name,(char*) &sys_collation_connection, SHOW_SYS}, {sys_collation_connection.name,(char*) &sys_collation_connection, SHOW_SYS},
{sys_collation_database.name,(char*) &sys_collation_database, SHOW_SYS}, {sys_collation_database.name,(char*) &sys_collation_database, SHOW_SYS},
......
...@@ -576,10 +576,14 @@ select_result::select_result() ...@@ -576,10 +576,14 @@ select_result::select_result()
thd=current_thd; thd=current_thd;
} }
static String void select_result::send_error(uint errcode,const char *err)
default_line_term("\n",default_charset_info), {
default_escaped("\\",default_charset_info), ::send_error(thd, errcode, err);
default_field_term("\t",default_charset_info); }
static String default_line_term("\n",default_charset_info);
static String default_escaped("\\",default_charset_info);
static String default_field_term("\t",default_charset_info);
sql_exchange::sql_exchange(char *name,bool flag) sql_exchange::sql_exchange(char *name,bool flag)
:file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0) :file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0)
...@@ -884,7 +888,7 @@ bool select_export::send_data(List<Item> &items) ...@@ -884,7 +888,7 @@ bool select_export::send_data(List<Item> &items)
void select_export::send_error(uint errcode, const char *err) void select_export::send_error(uint errcode, const char *err)
{ {
my_message(errcode, err, MYF(0));; ::send_error(thd,errcode,err);
(void) end_io_cache(&cache); (void) end_io_cache(&cache);
(void) my_close(file,MYF(0)); (void) my_close(file,MYF(0));
file= -1; file= -1;
...@@ -994,7 +998,7 @@ bool select_dump::send_data(List<Item> &items) ...@@ -994,7 +998,7 @@ bool select_dump::send_data(List<Item> &items)
void select_dump::send_error(uint errcode,const char *err) void select_dump::send_error(uint errcode,const char *err)
{ {
my_message(errcode, err, MYF(0)); ::send_error(thd,errcode,err);
(void) end_io_cache(&cache); (void) end_io_cache(&cache);
(void) my_close(file,MYF(0)); (void) my_close(file,MYF(0));
(void) my_delete(path,MYF(0)); // Delete file on error (void) my_delete(path,MYF(0)); // Delete file on error
......
...@@ -763,10 +763,7 @@ class select_result :public Sql_alloc { ...@@ -763,10 +763,7 @@ class select_result :public Sql_alloc {
virtual bool send_fields(List<Item> &list,uint flag)=0; virtual bool send_fields(List<Item> &list,uint flag)=0;
virtual bool send_data(List<Item> &items)=0; virtual bool send_data(List<Item> &items)=0;
virtual bool initialize_tables (JOIN *join=0) { return 0; } virtual bool initialize_tables (JOIN *join=0) { return 0; }
virtual void send_error(uint errcode,const char *err) virtual void send_error(uint errcode,const char *err);
{
my_message(errcode, err, MYF(0));
}
virtual bool send_eof()=0; virtual bool send_eof()=0;
virtual void abort() {} virtual void abort() {}
}; };
......
...@@ -1440,8 +1440,17 @@ void select_insert::send_error(uint errcode,const char *err) ...@@ -1440,8 +1440,17 @@ void select_insert::send_error(uint errcode,const char *err)
{ {
DBUG_ENTER("select_insert::send_error"); DBUG_ENTER("select_insert::send_error");
//TODO error should be sent at the query processing end /* TODO error should be sent at the query processing end */
::send_error(thd,errcode,err); ::send_error(thd,errcode,err);
if (!table)
{
/*
This can only happen when using CREATE ... SELECT and the table was not
created becasue of an syntax error
*/
DBUG_VOID_RETURN;
}
table->file->extra(HA_EXTRA_NO_CACHE); table->file->extra(HA_EXTRA_NO_CACHE);
table->file->activate_all_index(thd); table->file->activate_all_index(thd);
/* /*
......
...@@ -171,6 +171,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result) ...@@ -171,6 +171,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
{ {
int res; int res;
register SELECT_LEX *select_lex = &lex->select_lex; register SELECT_LEX *select_lex = &lex->select_lex;
DBUG_ENTER("handle_select");
fix_tables_pointers(lex->all_selects_list); fix_tables_pointers(lex->all_selects_list);
if (select_lex->next_select()) if (select_lex->next_select())
res=mysql_union(thd, lex, result, &lex->unit, 0); res=mysql_union(thd, lex, result, &lex->unit, 0);
...@@ -187,16 +189,25 @@ int handle_select(THD *thd, LEX *lex, select_result *result) ...@@ -187,16 +189,25 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
(ORDER*) lex->proc_list.first, (ORDER*) lex->proc_list.first,
select_lex->options | thd->options, select_lex->options | thd->options,
result, &(lex->unit), &(lex->select_lex), 0); result, &(lex->unit), &(lex->select_lex), 0);
if (res && result)
result->abort();
if (res || thd->net.report_error) /* Don't set res if it's -1 as we may want this later */
{ DBUG_PRINT("info",("res: %d report_error: %d", res,
send_error(thd, 0, NullS); thd->net.report_error));
if (thd->net.report_error)
res= 1; res= 1;
if (res)
{
if (result)
{
result->send_error(0, NullS);
result->abort();
}
else
send_error(thd, 0, NullS);
res= 1; // Error sent to client
} }
delete result; delete result;
return res; DBUG_RETURN(res);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment