summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <anozdrin/alik@quad.>2008-02-26 19:34:02 +0300
committerunknown <anozdrin/alik@quad.>2008-02-26 19:34:02 +0300
commit336f2c7e51fbd60a184aca8f7cdc926cf651f7cd (patch)
tree4f6c2940e96b98c7499c2146e93e3ff920aed282
parent977edd0c8424dd2ee3ab743ef5b6ef16b770bb49 (diff)
parentfb3f8bdbb6d0eed44e0868e193d9e4f119cd0ee5 (diff)
downloadmariadb-git-336f2c7e51fbd60a184aca8f7cdc926cf651f7cd.tar.gz
Merge quad.:/mnt/raid/alik/MySQL/devel/5.1
into quad.:/mnt/raid/alik/MySQL/devel/5.1-rt-merged client/mysqltest.c: Auto merged mysql-test/r/view.result: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/ha_ndbcluster_binlog.cc: Auto merged sql/handler.cc: Auto merged sql/log_event.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/set_var.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_connect.cc: Auto merged sql/sql_parse.cc: Auto merged tests/mysql_client_test.c: Auto merged mysql-test/suite/rpl_ndb/t/disabled.def: Manually merged. mysql-test/t/disabled.def: Manually merged.
-rw-r--r--client/mysqltest.c2
-rw-r--r--dbug/dbug.c45
-rw-r--r--dbug/user.r5
-rw-r--r--mysql-test/include/commit.inc742
-rw-r--r--mysql-test/include/ddl_i18n.check_views.inc12
-rw-r--r--mysql-test/include/mix1.inc29
-rw-r--r--mysql-test/r/case.result4
-rw-r--r--mysql-test/r/commit_1innodb.result888
-rw-r--r--mysql-test/r/compress.result2
-rw-r--r--mysql-test/r/create.result44
-rw-r--r--mysql-test/r/ctype_collate.result2
-rw-r--r--mysql-test/r/date_formats.result2
-rw-r--r--mysql-test/r/ddl_i18n_koi8r.result58
-rw-r--r--mysql-test/r/ddl_i18n_utf8.result58
-rw-r--r--mysql-test/r/fulltext.result4
-rw-r--r--mysql-test/r/func_crypt.result2
-rw-r--r--mysql-test/r/func_encrypt.result2
-rw-r--r--mysql-test/r/func_if.result2
-rw-r--r--mysql-test/r/func_in.result2
-rw-r--r--mysql-test/r/func_like.result4
-rw-r--r--mysql-test/r/func_regexp.result2
-rw-r--r--mysql-test/r/func_set.result2
-rw-r--r--mysql-test/r/func_str.result70
-rw-r--r--mysql-test/r/func_time.result4
-rw-r--r--mysql-test/r/gis.result6
-rw-r--r--mysql-test/r/group_min_max.result20
-rw-r--r--mysql-test/r/information_schema.result25
-rw-r--r--mysql-test/r/information_schema_db.result2
-rw-r--r--mysql-test/r/innodb_mysql.result13
-rw-r--r--mysql-test/r/kill.result1
-rw-r--r--mysql-test/r/mysqldump.result38
-rw-r--r--mysql-test/r/named_pipe.result2
-rw-r--r--mysql-test/r/negation_elimination.result2
-rw-r--r--mysql-test/r/not_embedded_server.result7
-rw-r--r--mysql-test/r/null.result4
-rw-r--r--mysql-test/r/ps.result152
-rw-r--r--mysql-test/r/select.result2
-rw-r--r--mysql-test/r/shm.result2
-rw-r--r--mysql-test/r/show_check.result6
-rw-r--r--mysql-test/r/sp-code.result92
-rw-r--r--mysql-test/r/ssl.result2
-rw-r--r--mysql-test/r/ssl_compress.result2
-rw-r--r--mysql-test/r/subselect.result18
-rw-r--r--mysql-test/r/temp_table.result2
-rw-r--r--mysql-test/r/trigger.result38
-rw-r--r--mysql-test/r/type_blob.result2
-rw-r--r--mysql-test/r/variables_debug.result12
-rw-r--r--mysql-test/r/view.result80
-rw-r--r--mysql-test/r/view_grant.result1
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result4
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_blackhole.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_get_lock.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_master_pos_wait.result2
-rw-r--r--mysql-test/suite/rpl_ndb/t/disabled.def3
-rw-r--r--mysql-test/t/change_user.test11
-rw-r--r--mysql-test/t/commit_1innodb.test6
-rw-r--r--mysql-test/t/create.test64
-rw-r--r--mysql-test/t/ddl_i18n_koi8r.test8
-rw-r--r--mysql-test/t/ddl_i18n_utf8.test8
-rw-r--r--mysql-test/t/disabled.def2
-rw-r--r--mysql-test/t/kill.test4
-rw-r--r--mysql-test/t/lock_multi.test3
-rw-r--r--mysql-test/t/mysql_client_test-master.opt2
-rw-r--r--mysql-test/t/mysqldump.test55
-rw-r--r--mysql-test/t/not_embedded_server.test34
-rw-r--r--mysql-test/t/ps.test123
-rw-r--r--mysql-test/t/trigger.test33
-rw-r--r--mysql-test/t/variables_debug.test12
-rw-r--r--mysql-test/t/view.test122
-rw-r--r--mysql-test/t/view_grant.test1
-rw-r--r--mysys/my_thr_init.c1
-rw-r--r--sql-common/client.c10
-rw-r--r--sql/event_queue.cc38
-rw-r--r--sql/events.cc9
-rw-r--r--sql/ha_ndbcluster.cc2
-rw-r--r--sql/ha_ndbcluster_binlog.cc1
-rw-r--r--sql/handler.cc619
-rw-r--r--sql/handler.h122
-rw-r--r--sql/item.cc104
-rw-r--r--sql/item.h178
-rw-r--r--sql/item_cmpfunc.cc56
-rw-r--r--sql/item_cmpfunc.h51
-rw-r--r--sql/item_func.cc65
-rw-r--r--sql/item_func.h54
-rw-r--r--sql/item_geofunc.h9
-rw-r--r--sql/item_row.cc4
-rw-r--r--sql/item_row.h2
-rw-r--r--sql/item_strfunc.cc32
-rw-r--r--sql/item_strfunc.h12
-rw-r--r--sql/item_subselect.cc49
-rw-r--r--sql/item_subselect.h20
-rw-r--r--sql/item_sum.cc14
-rw-r--r--sql/item_sum.h6
-rw-r--r--sql/item_timefunc.cc32
-rw-r--r--sql/item_timefunc.h14
-rw-r--r--sql/log.cc10
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/mysql_priv.h15
-rw-r--r--sql/mysqld.cc14
-rw-r--r--sql/protocol.cc8
-rw-r--r--sql/repl_failsafe.cc6
-rw-r--r--sql/rpl_injector.cc20
-rw-r--r--sql/set_var.cc6
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sp.cc22
-rw-r--r--sql/sp_head.cc17
-rw-r--r--sql/sql_acl.cc8
-rw-r--r--sql/sql_base.cc58
-rw-r--r--sql/sql_binlog.cc2
-rw-r--r--sql/sql_class.cc14
-rw-r--r--sql/sql_class.h42
-rw-r--r--sql/sql_connect.cc4
-rw-r--r--sql/sql_cursor.cc103
-rw-r--r--sql/sql_db.cc10
-rw-r--r--sql/sql_delete.cc50
-rw-r--r--sql/sql_do.cc14
-rw-r--r--sql/sql_error.cc2
-rw-r--r--sql/sql_handler.cc6
-rw-r--r--sql/sql_help.cc2
-rw-r--r--sql/sql_insert.cc48
-rw-r--r--sql/sql_lex.cc27
-rw-r--r--sql/sql_lex.h18
-rw-r--r--sql/sql_load.cc12
-rw-r--r--sql/sql_parse.cc146
-rw-r--r--sql/sql_partition.cc40
-rw-r--r--sql/sql_prepare.cc53
-rw-r--r--sql/sql_profile.cc2
-rw-r--r--sql/sql_rename.cc2
-rw-r--r--sql/sql_repl.cc20
-rw-r--r--sql/sql_select.cc81
-rw-r--r--sql/sql_show.cc20
-rw-r--r--sql/sql_table.cc66
-rw-r--r--sql/sql_test.cc6
-rw-r--r--sql/sql_trigger.cc2
-rw-r--r--sql/sql_udf.cc9
-rw-r--r--sql/sql_update.cc71
-rw-r--r--sql/sql_view.cc303
-rw-r--r--sql/sql_view.h3
-rw-r--r--sql/sql_yacc.yy73
-rw-r--r--sql/table.h2
-rw-r--r--tests/mysql_client_test.c292
142 files changed, 5081 insertions, 1181 deletions
diff --git a/client/mysqltest.c b/client/mysqltest.c
index c7819129c06..52e02789579 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -6333,6 +6333,8 @@ int util_query(MYSQL* org_mysql, const char* query){
if (!(mysql= mysql_init(mysql)))
die("Failed in mysql_init()");
+ /* enable local infile, in non-binary builds often disabled by default */
+ mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0);
safe_connect(mysql, "util", org_mysql->host, org_mysql->user,
org_mysql->passwd, org_mysql->db, org_mysql->port,
org_mysql->unix_socket);
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 7f4292d18b1..666ab2b3e3c 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -412,15 +412,11 @@ void _db_process_(const char *name)
cs->process= name;
}
+
/*
* FUNCTION
*
- * _db_set_ set current debugger settings
- *
- * SYNOPSIS
- *
- * VOID _db_set_(control)
- * char *control;
+ * DbugParse parse control string and set current debugger setting
*
* DESCRIPTION
*
@@ -444,7 +440,7 @@ void _db_process_(const char *name)
*
*/
-void _db_set_(CODE_STATE *cs, const char *control)
+static void DbugParse(CODE_STATE *cs, const char *control)
{
const char *end;
int rel=0;
@@ -674,6 +670,35 @@ void _db_set_(CODE_STATE *cs, const char *control)
/*
* FUNCTION
*
+ * _db_set_ set current debugger settings
+ *
+ * SYNOPSIS
+ *
+ * VOID _db_set_(control)
+ * char *control;
+ *
+ * DESCRIPTION
+ *
+ * Given pointer to a debug control string in "control",
+ * parses the control string, and sets up a current debug
+ * settings. Pushes a new debug settings if the current is
+ * set to the initial debugger settings.
+ */
+
+void _db_set_(CODE_STATE *cs, const char *control)
+{
+ get_code_state_or_return;
+
+ if (cs->stack == &init_settings)
+ PushState(cs);
+
+ DbugParse(cs, control);
+}
+
+
+/*
+ * FUNCTION
+ *
* _db_push_ push current debugger settings and set up new one
*
* SYNOPSIS
@@ -685,7 +710,7 @@ void _db_set_(CODE_STATE *cs, const char *control)
*
* Given pointer to a debug control string in "control", pushes
* the current debug settings, parses the control string, and sets
- * up a new debug settings with _db_set_()
+ * up a new debug settings with DbugParse()
*
*/
@@ -694,7 +719,7 @@ void _db_push_(const char *control)
CODE_STATE *cs=0;
get_code_state_or_return;
PushState(cs);
- _db_set_(cs, control);
+ DbugParse(cs, control);
}
/*
@@ -717,7 +742,7 @@ void _db_set_init_(const char *control)
CODE_STATE tmp_cs;
bzero((uchar*) &tmp_cs, sizeof(tmp_cs));
tmp_cs.stack= &init_settings;
- _db_set_(&tmp_cs, control);
+ DbugParse(&tmp_cs, control);
}
/*
diff --git a/dbug/user.r b/dbug/user.r
index e41367de321..19de840d0ad 100644
--- a/dbug/user.r
+++ b/dbug/user.r
@@ -730,8 +730,9 @@ warning will be given. The DBUG_POP macro has no arguments.
EX:\ \fCDBUG_POP\ ();\fR
.SP 1
.LI DBUG_SET\
-Modifies the current debugger state on top of the stack using the
-debug control string passed as the macro argument. Unless
+Modifies the current debugger state on top of the stack or pushes
+a new state if the current is set to the initial settings, using
+the debug control string passed as the macro argument. Unless
.I incremental
control string is used (see below), it's equivalent to a combination of
DBUG_POP and DBUG_PUSH.
diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc
new file mode 100644
index 00000000000..770871fbcca
--- /dev/null
+++ b/mysql-test/include/commit.inc
@@ -0,0 +1,742 @@
+## Bug#12713 (Error in a stored function called from a SELECT doesn't cause
+## ROLLBACK of statem)
+
+##
+## Pre-Requisites :
+## - $engine_type should be set
+##
+
+set sql_mode=no_engine_substitution;
+eval set storage_engine = $engine_type;
+set autocommit=1;
+
+--disable_warnings
+drop table if exists t1;
+drop table if exists t2;
+drop table if exists t3;
+drop function if exists f2;
+drop procedure if exists bug12713_call;
+drop procedure if exists bug12713_dump_spvars;
+drop procedure if exists dummy;
+--enable_warnings
+
+create table t1 (a int);
+create table t2 (a int unique);
+create table t3 (a int);
+
+# a workaround for Bug#32633: Can not create any routine if
+# SQL_MODE=no_engine_substitution
+
+set sql_mode=default;
+
+insert into t1 (a) values (1), (2);
+insert into t3 (a) values (1), (2);
+
+delimiter |;
+
+## Cause a failure every time
+create function f2(x int) returns int
+begin
+ insert into t2 (a) values (x);
+ insert into t2 (a) values (x);
+ return x;
+end|
+
+delimiter ;|
+
+set autocommit=0;
+
+flush status;
+##============================================================================
+## Design notes
+##
+## In each case, statement rollback is expected.
+## for transactional engines, the rollback should be properly executed
+## for non transactional engines, the rollback may cause warnings.
+##
+## The test pattern is as follows
+## - insert 1000+N
+## - statement with a side effect, that fails to insert N twice
+## - a statement rollback is expected (expecting 1 row 1000+N only) in t2
+## - a rollback is performed
+## - expecting a clean table t2.
+##============================================================================
+
+insert into t2 (a) values (1001);
+--error ER_DUP_ENTRY
+insert into t1 (a) values (f2(1));
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1002);
+--error ER_DUP_ENTRY
+insert into t3 (a) select f2(2) from t1;
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1003);
+--error ER_DUP_ENTRY
+update t1 set a= a + f2(3);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1004);
+--error ER_DUP_ENTRY
+update t1, t3 set t1.a = 0, t3.a = 0 where (f2(4) = 4) and (t1.a = t3.a);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1005);
+--error ER_DUP_ENTRY
+delete from t1 where (a = f2(5));
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1006);
+--error ER_DUP_ENTRY
+delete from t1, t3 using t1, t3 where (f2(6) = 6) ;
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1007);
+--error ER_DUP_ENTRY
+replace t1 values (f2(7));
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1008);
+--error ER_DUP_ENTRY
+replace into t3 (a) select f2(8) from t1;
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1009);
+--error ER_DUP_ENTRY
+select f2(9) from t1 ;
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1010);
+--error ER_DUP_ENTRY
+show databases where (f2(10) = 10);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1011);
+--error ER_DUP_ENTRY
+show tables where (f2(11) = 11);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1012);
+--error ER_DUP_ENTRY
+show triggers where (f2(12) = 12);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1013);
+--error ER_DUP_ENTRY
+show table status where (f2(13) = 13);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1014);
+--error ER_DUP_ENTRY
+show open tables where (f2(14) = 14);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1015);
+--error ER_DUP_ENTRY
+show columns in mysql.proc where (f2(15) = 15);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1016);
+--error ER_DUP_ENTRY
+show status where (f2(16) = 16);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1017);
+--error ER_DUP_ENTRY
+show variables where (f2(17) = 17);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1018);
+--error ER_DUP_ENTRY
+show charset where (f2(18) = 18);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1019);
+--error ER_DUP_ENTRY
+show collation where (f2(19) = 19);
+select * from t2;
+rollback;
+select * from t2;
+
+--echo # We need at least one procedure to make sure the WHERE clause is
+--echo # evaluated
+create procedure dummy() begin end;
+insert into t2 (a) values (1020);
+--error ER_DUP_ENTRY
+show procedure status where (f2(20) = 20);
+select * from t2;
+rollback;
+select * from t2;
+drop procedure dummy;
+
+insert into t2 (a) values (1021);
+--error ER_DUP_ENTRY
+show function status where (f2(21) = 21);
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1022);
+prepare stmt from "insert into t1 (a) values (f2(22))";
+--error ER_DUP_ENTRY
+execute stmt;
+select * from t2;
+rollback;
+select * from t2;
+
+insert into t2 (a) values (1023);
+do (f2(23));
+select * from t2;
+rollback;
+select * from t2;
+
+## Please note :
+## This will insert a record 1024 in t1 (statement commit)
+## This will insert a record 24 in t1 (statement commit)
+## then will rollback the second insert only (24) (statement rollback)
+## then will rollback the complete transaction (transaction rollback)
+
+delimiter |;
+
+create procedure bug12713_call ()
+begin
+ insert into t2 (a) values (24);
+ insert into t2 (a) values (24);
+end|
+
+delimiter ;|
+
+insert into t2 (a) values (1024);
+--error ER_DUP_ENTRY
+call bug12713_call();
+select * from t2;
+rollback;
+select * from t2;
+
+--echo =======================================================================
+--echo Testing select_to_file
+--echo =======================================================================
+
+insert into t2 (a) values (1025);
+
+--replace_result $MYSQLTEST_VARDIR ..
+--error ER_DUP_ENTRY
+eval select f2(25) into outfile "$MYSQLTEST_VARDIR/tmp/dml.out" from t1;
+select * from t2;
+rollback;
+select * from t2;
+--remove_file $MYSQLTEST_VARDIR/tmp/dml.out
+
+insert into t2 (a) values (1026);
+--replace_result $MYSQLTEST_VARDIR ..
+--error ER_DUP_ENTRY
+eval load data infile "../std_data_ln/words.dat" into table t1 (a) set a:=f2(26);
+
+select * from t2;
+rollback;
+select * from t2;
+
+--echo =======================================================================
+--echo Testing select_dumpvar
+--echo =======================================================================
+
+insert into t2 (a) values (1027);
+--error ER_DUP_ENTRY
+select f2(27) into @foo;
+select * from t2;
+rollback;
+select * from t2;
+
+--echo =======================================================================
+--echo Testing Select_fetch_into_spvars
+--echo =======================================================================
+
+delimiter |;
+
+create procedure bug12713_dump_spvars ()
+begin
+ declare foo int;
+
+ declare continue handler for sqlexception
+ begin
+ select "Exception trapped";
+ end;
+
+ select f2(28) into foo;
+ select * from t2;
+end|
+
+delimiter ;|
+
+insert into t2 (a) values (1028);
+call bug12713_dump_spvars ();
+rollback;
+select * from t2;
+
+--echo =======================================================================
+--echo Cleanup
+--echo =======================================================================
+
+set autocommit=default;
+
+drop table t1;
+drop table t2;
+drop table t3;
+drop function f2;
+drop procedure bug12713_call;
+drop procedure bug12713_dump_spvars;
+--echo #
+--echo # Bug#12713 Error in a stored function called from a SELECT doesn't
+--echo # cause ROLLBACK of statem
+--echo #
+--echo # Verify that two-phase commit is not issued for read-only
+--echo # transactions.
+--echo #
+--echo # Verify that two-phase commit is issued for read-write transactions,
+--echo # even if the change is done inside a stored function called from
+--echo # SELECT or SHOW statement.
+--echo #
+set autocommit=0;
+--disable_warnings
+drop table if exists t1;
+drop table if exists t2;
+drop function if exists f1;
+drop procedure if exists p_verify_status_increment;
+--enable_warnings
+
+set sql_mode=no_engine_substitution;
+create table t1 (a int unique);
+create table t2 (a int) engine=myisam;
+set sql_mode=default;
+--echo #
+--echo # An auxiliary procedure to track Handler_prepare and Handler_commit
+--echo # statistics.
+--echo #
+delimiter |;
+create procedure
+p_verify_status_increment(commit_inc_mixed int, prepare_inc_mixed int,
+ commit_inc_row int, prepare_inc_row int)
+begin
+ declare commit_inc int;
+ declare prepare_inc int;
+ declare old_commit_count int default ifnull(@commit_count, 0);
+ declare old_prepare_count int default ifnull(@prepare_count, 0);
+ declare c_res int;
+# Use a cursor to have just one access to I_S instead of 2, it is very slow
+# and amounts for over 90% of test CPU time
+ declare c cursor for
+ select variable_value
+ from information_schema.session_status
+ where variable_name='Handler_commit' or variable_name='Handler_prepare'
+ order by variable_name;
+
+ if @@global.binlog_format = 'ROW' then
+ set commit_inc= commit_inc_row;
+ set prepare_inc= prepare_inc_row;
+ else
+ set commit_inc= commit_inc_mixed;
+ set prepare_inc= prepare_inc_mixed;
+ end if;
+
+ open c;
+ fetch c into c_res;
+ set @commit_count=c_res;
+ fetch c into c_res;
+ set @prepare_count=c_res;
+ close c;
+
+ if old_commit_count + commit_inc <> @commit_count then
+ select concat("Expected commit increment: ", commit_inc,
+ " actual: ", @commit_count - old_commit_count)
+ as 'ERROR';
+ elseif old_prepare_count + prepare_inc <> @prepare_count then
+ select concat("Expected prepare increment: ", prepare_inc,
+ " actual: ", @prepare_count - old_prepare_count)
+ as 'ERROR';
+ else
+ select '' as 'SUCCESS';
+ end if;
+end|
+delimiter ;|
+--echo # Reset Handler_commit and Handler_prepare counters
+flush status;
+--echo #
+--echo # 1. Read-only statement: SELECT
+--echo #
+select * from t1;
+call p_verify_status_increment(1, 0, 1, 0);
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+
+--echo # 2. Read-write statement: INSERT, insert 1 row.
+--echo #
+insert into t1 (a) values (1);
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+
+--echo # 3. Read-write statement: UPDATE, update 1 row.
+--echo #
+update t1 set a=2;
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+
+--echo # 4. Read-write statement: UPDATE, update 0 rows, 1 row matches WHERE
+--echo #
+--echo # Note the wrong Handler_prepare/Handler_commit count is due to
+--echo # Bug#29157 "UPDATE, changed rows incorrect" and
+--echo # Bug#Bug #33846 UPDATE word:Wrong 'Changed rows' if InnoDB, unique
+--echo # key and no rows qualify WHERE
+--echo #
+update t1 set a=2;
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+
+--echo # 5. Read-write statement: UPDATE, update 0 rows, 0 rows match WHERE
+--echo #
+--echo # In mixed replication mode, there is a read-only transaction
+--echo # in InnoDB and also the statement is written to the binary log.
+--echo # So we have two commits but no 2pc, since the first engine's
+--echo # transaction is read-only.
+--echo # In the row level replication mode, we only have the read-only
+--echo # transaction in InnoDB and nothing is written to the binary log.
+--echo #
+update t1 set a=3 where a=1;
+call p_verify_status_increment(2, 0, 1, 0);
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+
+--echo # 6. Read-write statement: DELETE, delete 0 rows.
+--echo #
+delete from t1 where a=1;
+call p_verify_status_increment(2, 0, 1, 0);
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+
+--echo # 7. Read-write statement: DELETE, delete 1 row.
+--echo #
+delete from t1 where a=2;
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+
+--echo # 8. Read-write statement: unqualified DELETE
+--echo #
+--echo # In statement or mixed replication mode, we call
+--echo # handler::ha_delete_all_rows() and write statement text
+--echo # to the binary log. This results in two read-write transactions.
+--echo # In row level replication mode, we do not call
+--echo # handler::ha_delete_all_rows(), but delete rows one by one.
+--echo # Since there are no rows, nothing is written to the binary log.
+--echo # Thus we have just one read-only transaction in InnoDB.
+delete from t1;
+call p_verify_status_increment(2, 2, 1, 0);
+commit;
+call p_verify_status_increment(2, 2, 1, 0);
+
+--echo # 9. Read-write statement: REPLACE, change 1 row.
+--echo #
+replace t1 set a=1;
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+
+--echo # 10. Read-write statement: REPLACE, change 0 rows.
+--echo #
+replace t1 set a=1;
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+
+--echo # 11. Read-write statement: IODKU, change 1 row.
+--echo #
+insert t1 set a=1 on duplicate key update a=a+1;
+call p_verify_status_increment(2, 2, 2, 2);
+select * from t1;
+call p_verify_status_increment(1, 0, 1, 0);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+
+--echo # 12. Read-write statement: IODKU, change 0 rows.
+--echo #
+insert t1 set a=2 on duplicate key update a=2;
+call p_verify_status_increment(1, 0, 1, 0);
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+
+--echo # 13. Read-write statement: INSERT IGNORE, change 0 rows.
+--echo #
+insert ignore t1 set a=2;
+call p_verify_status_increment(1, 0, 1, 0);
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+
+--echo # 14. Read-write statement: INSERT IGNORE, change 1 row.
+--echo #
+insert ignore t1 set a=1;
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+--echo # 15. Read-write statement: UPDATE IGNORE, change 0 rows.
+--echo #
+update ignore t1 set a=2 where a=1;
+call p_verify_status_increment(2, 2, 1, 0);
+commit;
+call p_verify_status_increment(2, 2, 1, 0);
+--echo #
+--echo # Create a stored function that modifies a
+--echo # non-transactional table. Demonstrate that changes in
+--echo # non-transactional tables do not affect the two phase commit
+--echo # algorithm.
+--echo #
+delimiter |;
+create function f1() returns int
+begin
+ insert t2 set a=2;
+ return 2;
+end|
+delimiter ;|
+call p_verify_status_increment(0, 0, 0, 0);
+
+--echo # 16. A function changes non-trans-table.
+--echo #
+select f1();
+call p_verify_status_increment(0, 0, 0, 0);
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+
+--echo # 17. Read-only statement, a function changes non-trans-table.
+--echo #
+select f1() from t1;
+call p_verify_status_increment(1, 0, 1, 0);
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+
+--echo # 18. Read-write statement: UPDATE, change 0 (transactional) rows.
+--echo #
+select count(*) from t2;
+update t1 set a=2 where a=f1()+10;
+select count(*) from t2;
+call p_verify_status_increment(2, 0, 2, 0);
+commit;
+call p_verify_status_increment(2, 0, 2, 0);
+--echo #
+--echo # Replace the non-transactional table with a temporary
+--echo # transactional table. Demonstrate that a change to a temporary
+--echo # transactional table does not provoke 2-phase commit, although
+--echo # does trigger a commit and a binlog write (in statement mode).
+--echo #
+drop table t2;
+set sql_mode=no_engine_substitution;
+create temporary table t2 (a int);
+call p_verify_status_increment(0, 0, 0, 0);
+set sql_mode=default;
+--echo # 19. A function changes temp-trans-table.
+--echo #
+select f1();
+--echo # Two commits because a binary log record is written
+call p_verify_status_increment(2, 0, 1, 0);
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+
+--echo # 20. Read-only statement, a function changes non-trans-table.
+--echo #
+select f1() from t1;
+--echo # Two commits because a binary log record is written
+call p_verify_status_increment(2, 0, 1, 0);
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+
+--echo # 21. Read-write statement: UPDATE, change 0 (transactional) rows.
+--echo #
+update t1 set a=2 where a=f1()+10;
+call p_verify_status_increment(2, 0, 1, 0);
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+
+--echo # 22. DDL: ALTER TEMPORARY TABLE, should not cause a 2pc
+--echo #
+alter table t2 add column b int default 5;
+--echo # A commit is done internally by ALTER.
+call p_verify_status_increment(2, 0, 2, 0);
+commit;
+--echo # There is nothing left to commit
+call p_verify_status_increment(0, 0, 0, 0);
+
+--echo # 23. DDL: RENAME TEMPORARY TABLE, does not start a transaction
+--echo
+--echo # No test because of Bug#8729 "rename table fails on temporary table"
+
+--echo # 24. DDL: TRUNCATE TEMPORARY TABLE, does not start a transaction
+--echo
+truncate table t2;
+call p_verify_status_increment(2, 0, 2, 0);
+commit;
+--echo # There is nothing left to commit
+call p_verify_status_increment(0, 0, 0, 0);
+
+--echo # 25. Read-write statement: unqualified DELETE
+--echo
+delete from t2;
+call p_verify_status_increment(2, 0, 1, 0);
+commit;
+--echo # There is nothing left to commit
+call p_verify_status_increment(2, 0, 1, 0);
+
+--echo # 25. DDL: DROP TEMPORARY TABLE, does not start a transaction
+--echo #
+drop temporary table t2;
+call p_verify_status_increment(0, 0, 0, 0);
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+
+--echo # 26. Verify that SET AUTOCOMMIT issues an implicit commit
+--echo #
+insert t1 set a=3;
+call p_verify_status_increment(2, 2, 2, 2);
+set autocommit=1;
+call p_verify_status_increment(2, 2, 2, 2);
+rollback;
+select a from t1 where a=3;
+call p_verify_status_increment(1, 0, 1, 0);
+delete from t1 where a=3;
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+set autocommit=0;
+call p_verify_status_increment(0, 0, 0, 0);
+insert t1 set a=3;
+call p_verify_status_increment(2, 2, 2, 2);
+--echo # Sic: not actually changing the value of autocommit
+set autocommit=0;
+call p_verify_status_increment(0, 0, 0, 0);
+rollback;
+select a from t1 where a=3;
+call p_verify_status_increment(1, 0, 1, 0);
+
+--echo # 27. Savepoint management
+--echo #
+insert t1 set a=3;
+call p_verify_status_increment(2, 2, 2, 2);
+savepoint a;
+call p_verify_status_increment(0, 0, 0, 0);
+insert t1 set a=4;
+--echo # Sic: a bug. Binlog did not register itself this time.
+call p_verify_status_increment(1, 0, 1, 0);
+release savepoint a;
+rollback;
+call p_verify_status_increment(0, 0, 0, 0);
+select a from t1 where a=3;
+call p_verify_status_increment(1, 0, 1, 0);
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+
+--echo # 28. Read-write statement: DO
+--echo #
+create table t2 (a int);
+call p_verify_status_increment(0, 0, 0, 0);
+do (select f1() from t1 where a=2);
+call p_verify_status_increment(2, 2, 2, 2);
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+
+--echo # 29. Read-write statement: MULTI-DELETE
+--echo #
+delete t1, t2 from t1 join t2 on (t1.a=t2.a) where t1.a=2;
+commit;
+call p_verify_status_increment(4, 4, 4, 4);
+
+--echo # 30. Read-write statement: INSERT-SELECT, MULTI-UPDATE, REPLACE-SELECT
+--echo #
+insert into t2 select a from t1;
+commit;
+replace into t2 select a from t1;
+commit;
+call p_verify_status_increment(8, 8, 8, 8);
+#
+# Multi-update is one of the few remaining statements that still
+# locks the tables at prepare step (and hence starts the transaction.
+# Disable the PS protocol, since in this protocol we get a different
+# number of commmits (there is an extra commit after prepare
+#
+--disable_ps_protocol
+update t1, t2 set t1.a=4, t2.a=8 where t1.a=t2.a and t1.a=1;
+--enable_ps_protocol
+commit;
+call p_verify_status_increment(4, 4, 4, 4);
+
+--echo # 31. DDL: various DDL with transactional tables
+--echo #
+--echo # Sic: no table is created.
+create table if not exists t2 (a int) select 6 union select 7;
+--echo # Sic: first commits the statement, and then the transaction.
+call p_verify_status_increment(4, 4, 4, 4);
+create table t3 select a from t2;
+call p_verify_status_increment(4, 4, 4, 4);
+alter table t3 add column (b int);
+call p_verify_status_increment(2, 0, 2, 0);
+alter table t3 rename t4;
+call p_verify_status_increment(1, 0, 1, 0);
+rename table t4 to t3;
+call p_verify_status_increment(1, 0, 1, 0);
+truncate table t3;
+call p_verify_status_increment(2, 2, 2, 2);
+create view v1 as select * from t2;
+call p_verify_status_increment(1, 0, 1, 0);
+check table t1;
+call p_verify_status_increment(3, 0, 3, 0);
+--echo # Sic: after this bug is fixed, CHECK leaves no pending transaction
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+check table t1, t2, t3;
+call p_verify_status_increment(6, 0, 6, 0);
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+drop view v1;
+call p_verify_status_increment(0, 0, 0, 0);
+
+--echo #
+--echo # Cleanup
+--echo #
+drop table t1;
+drop procedure p_verify_status_increment;
+drop function f1;
diff --git a/mysql-test/include/ddl_i18n.check_views.inc b/mysql-test/include/ddl_i18n.check_views.inc
index 727f3506e4a..db3ad02f459 100644
--- a/mysql-test/include/ddl_i18n.check_views.inc
+++ b/mysql-test/include/ddl_i18n.check_views.inc
@@ -9,6 +9,10 @@ SHOW CREATE VIEW v1|
SHOW CREATE VIEW v2|
+--echo
+
+SHOW CREATE VIEW v3|
+
# - Check INFORMATION_SCHEMA;
--echo
@@ -20,6 +24,10 @@ SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v1'|
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v2'|
+--echo
+
+SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v3'|
+
# - Execute the views;
--echo
@@ -30,3 +38,7 @@ SELECT COLLATION(c1), COLLATION(c2) FROM v1|
--echo
SELECT COLLATION(c1) FROM v2|
+
+--echo
+
+SELECT * FROM v3|
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 703dfa44df0..c1fd5cac10c 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -1410,4 +1410,33 @@ SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC;
DROP TABLE t1;
+#
+# Bug#21704: Renaming column does not update FK definition.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1(id INT PRIMARY KEY)
+ ENGINE=innodb;
+
+CREATE TABLE t2(
+ t1_id INT PRIMARY KEY,
+ CONSTRAINT fk1 FOREIGN KEY (t1_id) REFERENCES t1(id))
+ ENGINE=innodb;
+
+--echo
+
+--disable_result_log
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t1 CHANGE id id2 INT;
+--enable_result_log
+
+--echo
+
+DROP TABLE t2;
+DROP TABLE t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index d408a0b6153..0c0e2d623c8 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -27,7 +27,7 @@ explain extended select CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" E
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select (case 1 when 1 then _latin1'one' when 2 then _latin1'two' else _latin1'more' end) AS `CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END`
+Note 1003 select (case 1 when 1 then 'one' when 2 then 'two' else 'more' end) AS `CASE 1 when 1 then "one" WHEN 2 then "two" ELSE "more" END`
select CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END;
CASE 2.0 when 1 then "one" WHEN 2.0 then "two" ELSE "more" END
two
@@ -147,7 +147,7 @@ COALESCE('a' COLLATE latin1_bin,'b');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select coalesce(1) AS `COALESCE(1)`,coalesce(1.0) AS `COALESCE(1.0)`,coalesce(_latin1'a') AS `COALESCE('a')`,coalesce(1,1.0) AS `COALESCE(1,1.0)`,coalesce(1,_latin1'1') AS `COALESCE(1,'1')`,coalesce(1.1,_latin1'1') AS `COALESCE(1.1,'1')`,coalesce((_latin1'a' collate latin1_bin),_latin1'b') AS `COALESCE('a' COLLATE latin1_bin,'b')`
+Note 1003 select coalesce(1) AS `COALESCE(1)`,coalesce(1.0) AS `COALESCE(1.0)`,coalesce('a') AS `COALESCE('a')`,coalesce(1,1.0) AS `COALESCE(1,1.0)`,coalesce(1,'1') AS `COALESCE(1,'1')`,coalesce(1.1,'1') AS `COALESCE(1.1,'1')`,coalesce(('a' collate latin1_bin),'b') AS `COALESCE('a' COLLATE latin1_bin,'b')`
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result
new file mode 100644
index 00000000000..87f4fc32bc8
--- /dev/null
+++ b/mysql-test/r/commit_1innodb.result
@@ -0,0 +1,888 @@
+set sql_mode=no_engine_substitution;
+set storage_engine = InnoDB;
+set autocommit=1;
+drop table if exists t1;
+drop table if exists t2;
+drop table if exists t3;
+drop function if exists f2;
+drop procedure if exists bug12713_call;
+drop procedure if exists bug12713_dump_spvars;
+drop procedure if exists dummy;
+create table t1 (a int);
+create table t2 (a int unique);
+create table t3 (a int);
+set sql_mode=default;
+insert into t1 (a) values (1), (2);
+insert into t3 (a) values (1), (2);
+create function f2(x int) returns int
+begin
+insert into t2 (a) values (x);
+insert into t2 (a) values (x);
+return x;
+end|
+set autocommit=0;
+flush status;
+insert into t2 (a) values (1001);
+insert into t1 (a) values (f2(1));
+ERROR 23000: Duplicate entry '1' for key 'a'
+select * from t2;
+a
+1001
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1002);
+insert into t3 (a) select f2(2) from t1;
+ERROR 23000: Duplicate entry '2' for key 'a'
+select * from t2;
+a
+1002
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1003);
+update t1 set a= a + f2(3);
+ERROR 23000: Duplicate entry '3' for key 'a'
+select * from t2;
+a
+1003
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1004);
+update t1, t3 set t1.a = 0, t3.a = 0 where (f2(4) = 4) and (t1.a = t3.a);
+ERROR 23000: Duplicate entry '4' for key 'a'
+select * from t2;
+a
+1004
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1005);
+delete from t1 where (a = f2(5));
+ERROR 23000: Duplicate entry '5' for key 'a'
+select * from t2;
+a
+1005
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1006);
+delete from t1, t3 using t1, t3 where (f2(6) = 6) ;
+ERROR 23000: Duplicate entry '6' for key 'a'
+select * from t2;
+a
+1006
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1007);
+replace t1 values (f2(7));
+ERROR 23000: Duplicate entry '7' for key 'a'
+select * from t2;
+a
+1007
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1008);
+replace into t3 (a) select f2(8) from t1;
+ERROR 23000: Duplicate entry '8' for key 'a'
+select * from t2;
+a
+1008
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1009);
+select f2(9) from t1 ;
+ERROR 23000: Duplicate entry '9' for key 'a'
+select * from t2;
+a
+1009
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1010);
+show databases where (f2(10) = 10);
+ERROR 23000: Duplicate entry '10' for key 'a'
+select * from t2;
+a
+1010
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1011);
+show tables where (f2(11) = 11);
+ERROR 23000: Duplicate entry '11' for key 'a'
+select * from t2;
+a
+1011
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1012);
+show triggers where (f2(12) = 12);
+ERROR 23000: Duplicate entry '12' for key 'a'
+select * from t2;
+a
+1012
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1013);
+show table status where (f2(13) = 13);
+ERROR 23000: Duplicate entry '13' for key 'a'
+select * from t2;
+a
+1013
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1014);
+show open tables where (f2(14) = 14);
+ERROR 23000: Duplicate entry '14' for key 'a'
+select * from t2;
+a
+1014
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1015);
+show columns in mysql.proc where (f2(15) = 15);
+ERROR 23000: Duplicate entry '15' for key 'a'
+select * from t2;
+a
+1015
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1016);
+show status where (f2(16) = 16);
+ERROR 23000: Duplicate entry '16' for key 'a'
+select * from t2;
+a
+1016
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1017);
+show variables where (f2(17) = 17);
+ERROR 23000: Duplicate entry '17' for key 'a'
+select * from t2;
+a
+1017
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1018);
+show charset where (f2(18) = 18);
+ERROR 23000: Duplicate entry '18' for key 'a'
+select * from t2;
+a
+1018
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1019);
+show collation where (f2(19) = 19);
+ERROR 23000: Duplicate entry '19' for key 'a'
+select * from t2;
+a
+1019
+rollback;
+select * from t2;
+a
+# We need at least one procedure to make sure the WHERE clause is
+# evaluated
+create procedure dummy() begin end;
+insert into t2 (a) values (1020);
+show procedure status where (f2(20) = 20);
+ERROR 23000: Duplicate entry '20' for key 'a'
+select * from t2;
+a
+1020
+rollback;
+select * from t2;
+a
+drop procedure dummy;
+insert into t2 (a) values (1021);
+show function status where (f2(21) = 21);
+ERROR 23000: Duplicate entry '21' for key 'a'
+select * from t2;
+a
+1021
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1022);
+prepare stmt from "insert into t1 (a) values (f2(22))";
+execute stmt;
+ERROR 23000: Duplicate entry '22' for key 'a'
+select * from t2;
+a
+1022
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1023);
+do (f2(23));
+Warnings:
+Error 1062 Duplicate entry '23' for key 'a'
+select * from t2;
+a
+1023
+rollback;
+select * from t2;
+a
+create procedure bug12713_call ()
+begin
+insert into t2 (a) values (24);
+insert into t2 (a) values (24);
+end|
+insert into t2 (a) values (1024);
+call bug12713_call();
+ERROR 23000: Duplicate entry '24' for key 'a'
+select * from t2;
+a
+24
+1024
+rollback;
+select * from t2;
+a
+=======================================================================
+Testing select_to_file
+=======================================================================
+insert into t2 (a) values (1025);
+select f2(25) into outfile "../tmp/dml.out" from t1;
+ERROR 23000: Duplicate entry '25' for key 'a'
+select * from t2;
+a
+1025
+rollback;
+select * from t2;
+a
+insert into t2 (a) values (1026);
+load data infile "../std_data_ln/words.dat" into table t1 (a) set a:=f2(26);
+ERROR 23000: Duplicate entry '26' for key 'a'
+select * from t2;
+a
+1026
+rollback;
+select * from t2;
+a
+=======================================================================
+Testing select_dumpvar
+=======================================================================
+insert into t2 (a) values (1027);
+select f2(27) into @foo;
+ERROR 23000: Duplicate entry '27' for key 'a'
+select * from t2;
+a
+1027
+rollback;
+select * from t2;
+a
+=======================================================================
+Testing Select_fetch_into_spvars
+=======================================================================
+create procedure bug12713_dump_spvars ()
+begin
+declare foo int;
+declare continue handler for sqlexception
+begin
+select "Exception trapped";
+end;
+select f2(28) into foo;
+select * from t2;
+end|
+insert into t2 (a) values (1028);
+call bug12713_dump_spvars ();
+Exception trapped
+Exception trapped
+a
+1028
+rollback;
+select * from t2;
+a
+=======================================================================
+Cleanup
+=======================================================================
+set autocommit=default;
+drop table t1;
+drop table t2;
+drop table t3;
+drop function f2;
+drop procedure bug12713_call;
+drop procedure bug12713_dump_spvars;
+#
+# Bug#12713 Error in a stored function called from a SELECT doesn't
+# cause ROLLBACK of statem
+#
+# Verify that two-phase commit is not issued for read-only
+# transactions.
+#
+# Verify that two-phase commit is issued for read-write transactions,
+# even if the change is done inside a stored function called from
+# SELECT or SHOW statement.
+#
+set autocommit=0;
+drop table if exists t1;
+drop table if exists t2;
+drop function if exists f1;
+drop procedure if exists p_verify_status_increment;
+set sql_mode=no_engine_substitution;
+create table t1 (a int unique);
+create table t2 (a int) engine=myisam;
+set sql_mode=default;
+#
+# An auxiliary procedure to track Handler_prepare and Handler_commit
+# statistics.
+#
+create procedure
+p_verify_status_increment(commit_inc_mixed int, prepare_inc_mixed int,
+commit_inc_row int, prepare_inc_row int)
+begin
+declare commit_inc int;
+declare prepare_inc int;
+declare old_commit_count int default ifnull(@commit_count, 0);
+declare old_prepare_count int default ifnull(@prepare_count, 0);
+declare c_res int;
+# Use a cursor to have just one access to I_S instead of 2, it is very slow
+# and amounts for over 90% of test CPU time
+declare c cursor for
+select variable_value
+from information_schema.session_status
+where variable_name='Handler_commit' or variable_name='Handler_prepare'
+ order by variable_name;
+if @@global.binlog_format = 'ROW' then
+set commit_inc= commit_inc_row;
+set prepare_inc= prepare_inc_row;
+else
+set commit_inc= commit_inc_mixed;
+set prepare_inc= prepare_inc_mixed;
+end if;
+open c;
+fetch c into c_res;
+set @commit_count=c_res;
+fetch c into c_res;
+set @prepare_count=c_res;
+close c;
+if old_commit_count + commit_inc <> @commit_count then
+select concat("Expected commit increment: ", commit_inc,
+" actual: ", @commit_count - old_commit_count)
+as 'ERROR';
+elseif old_prepare_count + prepare_inc <> @prepare_count then
+select concat("Expected prepare increment: ", prepare_inc,
+" actual: ", @prepare_count - old_prepare_count)
+as 'ERROR';
+else
+select '' as 'SUCCESS';
+end if;
+end|
+# Reset Handler_commit and Handler_prepare counters
+flush status;
+#
+# 1. Read-only statement: SELECT
+#
+select * from t1;
+a
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+# 2. Read-write statement: INSERT, insert 1 row.
+#
+insert into t1 (a) values (1);
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 3. Read-write statement: UPDATE, update 1 row.
+#
+update t1 set a=2;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 4. Read-write statement: UPDATE, update 0 rows, 1 row matches WHERE
+#
+# Note the wrong Handler_prepare/Handler_commit count is due to
+# Bug#29157 "UPDATE, changed rows incorrect" and
+# Bug#Bug #33846 UPDATE word:Wrong 'Changed rows' if InnoDB, unique
+# key and no rows qualify WHERE
+#
+update t1 set a=2;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 5. Read-write statement: UPDATE, update 0 rows, 0 rows match WHERE
+#
+# In mixed replication mode, there is a read-only transaction
+# in InnoDB and also the statement is written to the binary log.
+# So we have two commits but no 2pc, since the first engine's
+# transaction is read-only.
+# In the row level replication mode, we only have the read-only
+# transaction in InnoDB and nothing is written to the binary log.
+#
+update t1 set a=3 where a=1;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+# 6. Read-write statement: DELETE, delete 0 rows.
+#
+delete from t1 where a=1;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+# 7. Read-write statement: DELETE, delete 1 row.
+#
+delete from t1 where a=2;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 8. Read-write statement: unqualified DELETE
+#
+# In statement or mixed replication mode, we call
+# handler::ha_delete_all_rows() and write statement text
+# to the binary log. This results in two read-write transactions.
+# In row level replication mode, we do not call
+# handler::ha_delete_all_rows(), but delete rows one by one.
+# Since there are no rows, nothing is written to the binary log.
+# Thus we have just one read-only transaction in InnoDB.
+delete from t1;
+call p_verify_status_increment(2, 2, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 1, 0);
+SUCCESS
+
+# 9. Read-write statement: REPLACE, change 1 row.
+#
+replace t1 set a=1;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 10. Read-write statement: REPLACE, change 0 rows.
+#
+replace t1 set a=1;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 11. Read-write statement: IODKU, change 1 row.
+#
+insert t1 set a=1 on duplicate key update a=a+1;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+select * from t1;
+a
+2
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 12. Read-write statement: IODKU, change 0 rows.
+#
+insert t1 set a=2 on duplicate key update a=2;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+# 13. Read-write statement: INSERT IGNORE, change 0 rows.
+#
+insert ignore t1 set a=2;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+# 14. Read-write statement: INSERT IGNORE, change 1 row.
+#
+insert ignore t1 set a=1;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 15. Read-write statement: UPDATE IGNORE, change 0 rows.
+#
+update ignore t1 set a=2 where a=1;
+call p_verify_status_increment(2, 2, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 1, 0);
+SUCCESS
+
+#
+# Create a stored function that modifies a
+# non-transactional table. Demonstrate that changes in
+# non-transactional tables do not affect the two phase commit
+# algorithm.
+#
+create function f1() returns int
+begin
+insert t2 set a=2;
+return 2;
+end|
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+# 16. A function changes non-trans-table.
+#
+select f1();
+f1()
+2
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+# 17. Read-only statement, a function changes non-trans-table.
+#
+select f1() from t1;
+f1()
+2
+2
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+# 18. Read-write statement: UPDATE, change 0 (transactional) rows.
+#
+select count(*) from t2;
+count(*)
+3
+update t1 set a=2 where a=f1()+10;
+select count(*) from t2;
+count(*)
+5
+call p_verify_status_increment(2, 0, 2, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 0, 2, 0);
+SUCCESS
+
+#
+# Replace the non-transactional table with a temporary
+# transactional table. Demonstrate that a change to a temporary
+# transactional table does not provoke 2-phase commit, although
+# does trigger a commit and a binlog write (in statement mode).
+#
+drop table t2;
+set sql_mode=no_engine_substitution;
+create temporary table t2 (a int);
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+set sql_mode=default;
+# 19. A function changes temp-trans-table.
+#
+select f1();
+f1()
+2
+# Two commits because a binary log record is written
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+# 20. Read-only statement, a function changes non-trans-table.
+#
+select f1() from t1;
+f1()
+2
+2
+# Two commits because a binary log record is written
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+# 21. Read-write statement: UPDATE, change 0 (transactional) rows.
+#
+update t1 set a=2 where a=f1()+10;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+# 22. DDL: ALTER TEMPORARY TABLE, should not cause a 2pc
+#
+alter table t2 add column b int default 5;
+# A commit is done internally by ALTER.
+call p_verify_status_increment(2, 0, 2, 0);
+SUCCESS
+
+commit;
+# There is nothing left to commit
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+# 23. DDL: RENAME TEMPORARY TABLE, does not start a transaction
+
+# No test because of Bug#8729 "rename table fails on temporary table"
+# 24. DDL: TRUNCATE TEMPORARY TABLE, does not start a transaction
+
+truncate table t2;
+call p_verify_status_increment(2, 0, 2, 0);
+SUCCESS
+
+commit;
+# There is nothing left to commit
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+# 25. Read-write statement: unqualified DELETE
+
+delete from t2;
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+commit;
+# There is nothing left to commit
+call p_verify_status_increment(2, 0, 1, 0);
+SUCCESS
+
+# 25. DDL: DROP TEMPORARY TABLE, does not start a transaction
+#
+drop temporary table t2;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+# 26. Verify that SET AUTOCOMMIT issues an implicit commit
+#
+insert t1 set a=3;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+set autocommit=1;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+rollback;
+select a from t1 where a=3;
+a
+3
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+delete from t1 where a=3;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+set autocommit=0;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+insert t1 set a=3;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# Sic: not actually changing the value of autocommit
+set autocommit=0;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+rollback;
+select a from t1 where a=3;
+a
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+# 27. Savepoint management
+#
+insert t1 set a=3;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+savepoint a;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+insert t1 set a=4;
+# Sic: a bug. Binlog did not register itself this time.
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+release savepoint a;
+rollback;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+select a from t1 where a=3;
+a
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+# 28. Read-write statement: DO
+#
+create table t2 (a int);
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+do (select f1() from t1 where a=2);
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+commit;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+# 29. Read-write statement: MULTI-DELETE
+#
+delete t1, t2 from t1 join t2 on (t1.a=t2.a) where t1.a=2;
+commit;
+call p_verify_status_increment(4, 4, 4, 4);
+SUCCESS
+
+# 30. Read-write statement: INSERT-SELECT, MULTI-UPDATE, REPLACE-SELECT
+#
+insert into t2 select a from t1;
+commit;
+replace into t2 select a from t1;
+commit;
+call p_verify_status_increment(8, 8, 8, 8);
+SUCCESS
+
+update t1, t2 set t1.a=4, t2.a=8 where t1.a=t2.a and t1.a=1;
+commit;
+call p_verify_status_increment(4, 4, 4, 4);
+SUCCESS
+
+# 31. DDL: various DDL with transactional tables
+#
+# Sic: no table is created.
+create table if not exists t2 (a int) select 6 union select 7;
+Warnings:
+Note 1050 Table 't2' already exists
+# Sic: first commits the statement, and then the transaction.
+call p_verify_status_increment(4, 4, 4, 4);
+SUCCESS
+
+create table t3 select a from t2;
+call p_verify_status_increment(4, 4, 4, 4);
+SUCCESS
+
+alter table t3 add column (b int);
+call p_verify_status_increment(2, 0, 2, 0);
+SUCCESS
+
+alter table t3 rename t4;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+rename table t4 to t3;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+truncate table t3;
+call p_verify_status_increment(2, 2, 2, 2);
+SUCCESS
+
+create view v1 as select * from t2;
+call p_verify_status_increment(1, 0, 1, 0);
+SUCCESS
+
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+call p_verify_status_increment(3, 0, 3, 0);
+SUCCESS
+
+# Sic: after this bug is fixed, CHECK leaves no pending transaction
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+check table t1, t2, t3;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+test.t2 check status OK
+test.t3 check status OK
+call p_verify_status_increment(6, 0, 6, 0);
+SUCCESS
+
+commit;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+drop view v1;
+call p_verify_status_increment(0, 0, 0, 0);
+SUCCESS
+
+#
+# Cleanup
+#
+drop table t1;
+drop procedure p_verify_status_increment;
+drop function f1;
diff --git a/mysql-test/r/compress.result b/mysql-test/r/compress.result
index a71d840d229..1d3752f09e7 100644
--- a/mysql-test/r/compress.result
+++ b/mysql-test/r/compress.result
@@ -1511,7 +1511,7 @@ explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
Warnings:
-Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> _latin1''))
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 4bdcca81b74..0dfc9c1e761 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1789,4 +1789,48 @@ DROP TABLE t2;
# -- End of test case for Bug#21380.
+# --
+# -- Bug#18834: ALTER TABLE ADD INDEX on table with two timestamp fields
+# --
+
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+
+CREATE TABLE t1(c1 TIMESTAMP, c2 TIMESTAMP);
+
+SET sql_mode = NO_ZERO_DATE;
+
+CREATE TABLE t2(c1 TIMESTAMP, c2 TIMESTAMP DEFAULT 0);
+ERROR 42000: Invalid default value for 'c2'
+
+CREATE TABLE t2(c1 TIMESTAMP, c2 TIMESTAMP);
+ERROR 42000: Invalid default value for 'c2'
+
+# -- Check that NULL column still can be created.
+CREATE TABLE t2(c1 TIMESTAMP NULL);
+
+# -- Check ALTER TABLE.
+ALTER TABLE t1 ADD INDEX(c1);
+ERROR 42000: Invalid default value for 'c2'
+
+# -- Check DATETIME.
+SET sql_mode = '';
+
+CREATE TABLE t3(c1 DATETIME NOT NULL);
+INSERT INTO t3 VALUES (0);
+
+SET sql_mode = TRADITIONAL;
+
+ALTER TABLE t3 ADD INDEX(c1);
+ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'c1' at row 1
+
+# -- Cleanup.
+SET sql_mode = '';
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+# -- End of Bug#18834.
+
End of 5.1 tests
diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result
index 026c0ebdcf2..69b48ee2952 100644
--- a/mysql-test/r/ctype_collate.result
+++ b/mysql-test/r/ctype_collate.result
@@ -519,7 +519,7 @@ explain extended SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select charset(_latin1'a') AS `charset('a')`,collation(_latin1'a') AS `collation('a')`,coercibility(_latin1'a') AS `coercibility('a')`,(_latin1'a' = _latin1'A') AS `'a'='A'`
+Note 1003 select charset('a') AS `charset('a')`,collation('a') AS `collation('a')`,coercibility('a') AS `coercibility('a')`,('a' = 'A') AS `'a'='A'`
SET CHARACTER SET koi8r;
SHOW VARIABLES LIKE 'collation_client';
Variable_name Value
diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result
index fbe46e9fa21..dfd8244ef77 100644
--- a/mysql-test/r/date_formats.result
+++ b/mysql-test/r/date_formats.result
@@ -445,7 +445,7 @@ explain extended select makedate(1997,1), addtime("31.12.97 11.59.59.999999 PM",
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select makedate(1997,1) AS `makedate(1997,1)`,addtime(_latin1'31.12.97 11.59.59.999999 PM',_latin1'1 1.1.1.000002') AS `addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")`,subtime(_latin1'31.12.97 11.59.59.999999 PM',_latin1'1 1.1.1.000002') AS `subtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")`,timediff(_latin1'01.01.97 11:59:59.000001 PM',_latin1'31.12.95 11:59:59.000002 PM') AS `timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM")`,cast(str_to_date(_latin1'15-01-2001 12:59:59',_latin1'%d-%m-%Y %H:%i:%S') as time) AS `cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME)`,maketime(23,11,12) AS `maketime(23,11,12)`,microsecond(_latin1'1997-12-31 23:59:59.000001') AS `microsecond("1997-12-31 23:59:59.000001")`
+Note 1003 select makedate(1997,1) AS `makedate(1997,1)`,addtime('31.12.97 11.59.59.999999 PM','1 1.1.1.000002') AS `addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")`,subtime('31.12.97 11.59.59.999999 PM','1 1.1.1.000002') AS `subtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")`,timediff('01.01.97 11:59:59.000001 PM','31.12.95 11:59:59.000002 PM') AS `timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM")`,cast(str_to_date('15-01-2001 12:59:59','%d-%m-%Y %H:%i:%S') as time) AS `cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME)`,maketime(23,11,12) AS `maketime(23,11,12)`,microsecond('1997-12-31 23:59:59.000001') AS `microsecond("1997-12-31 23:59:59.000001")`
create table t1 (d date);
insert into t1 values ('2004-07-14'),('2005-07-14');
select date_format(d,"%d") from t1 order by 1;
diff --git a/mysql-test/r/ddl_i18n_koi8r.result b/mysql-test/r/ddl_i18n_koi8r.result
index fbaf2f2fd4a..34cea2a5a7d 100644
--- a/mysql-test/r/ddl_i18n_koi8r.result
+++ b/mysql-test/r/ddl_i18n_koi8r.result
@@ -16,25 +16,34 @@ FROM t1|
CREATE VIEW v2 AS SELECT _utf8'теÑÑ‚' as c1|
+CREATE VIEW v3 AS SELECT _utf8'теÑÑ‚'|
+
SHOW CREATE VIEW v1|
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _koi8r'ÔÅÓÔ' AS `c1`,`t1`.`ËÏÌ` AS `c2` from `t1` koi8r koi8r_general_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'ÔÅÓÔ' AS `c1`,`t1`.`ËÏÌ` AS `c2` from `t1` koi8r koi8r_general_ci
SHOW CREATE VIEW v2|
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select _utf8'теÑÑ‚' AS `c1` koi8r koi8r_general_ci
+SHOW CREATE VIEW v3|
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select _utf8'теÑÑ‚' AS `ÔÅÓÔ` koi8r koi8r_general_ci
+
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v1'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v1 SELECT 'ÔÅÓÔ' AS c1, ËÏÌ AS c2
-FROM t1 NONE YES root@localhost DEFINER koi8r koi8r_general_ci
+NULL mysqltest1 v1 select 'ÔÅÓÔ' AS `c1`,`mysqltest1`.`t1`.`ËÏÌ` AS `c2` from `mysqltest1`.`t1` NONE YES root@localhost DEFINER koi8r koi8r_general_ci
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v2'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v2 SELECT 'ÔÅÓÔ' as c1 NONE NO root@localhost DEFINER koi8r koi8r_general_ci
+NULL mysqltest1 v2 select 'ÔÅÓÔ' AS `c1` NONE NO root@localhost DEFINER koi8r koi8r_general_ci
+
+SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v3'|
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
+NULL mysqltest1 v3 select 'ÔÅÓÔ' AS `ÔÅÓÔ` NONE NO root@localhost DEFINER koi8r koi8r_general_ci
SELECT COLLATION(c1), COLLATION(c2) FROM v1|
@@ -45,6 +54,10 @@ SELECT COLLATION(c1) FROM v2|
COLLATION(c1)
utf8_general_ci
+SELECT * FROM v3|
+ÔÅÓÔ
+ÔÅÓÔ
+
ALTER DATABASE mysqltest1 COLLATE cp866_general_ci|
@@ -54,27 +67,35 @@ SET @@character_set_results= cp1251|
SET @@collation_connection= cp1251_general_ci|
SELECT * FROM mysqltest1.v1|
SELECT * FROM mysqltest1.v2|
+SELECT * FROM mysqltest1.v3|
use mysqltest1|
set names koi8r|
SHOW CREATE VIEW v1|
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _koi8r'ÔÅÓÔ' AS `c1`,`t1`.`ËÏÌ` AS `c2` from `t1` koi8r koi8r_general_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'ÔÅÓÔ' AS `c1`,`t1`.`ËÏÌ` AS `c2` from `t1` koi8r koi8r_general_ci
SHOW CREATE VIEW v2|
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select _utf8'теÑÑ‚' AS `c1` koi8r koi8r_general_ci
+SHOW CREATE VIEW v3|
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select _utf8'теÑÑ‚' AS `ÔÅÓÔ` koi8r koi8r_general_ci
+
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v1'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v1 SELECT 'ÔÅÓÔ' AS c1, ËÏÌ AS c2
-FROM t1 NONE YES root@localhost DEFINER koi8r koi8r_general_ci
+NULL mysqltest1 v1 select 'ÔÅÓÔ' AS `c1`,`mysqltest1`.`t1`.`ËÏÌ` AS `c2` from `mysqltest1`.`t1` NONE YES root@localhost DEFINER koi8r koi8r_general_ci
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v2'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v2 SELECT 'ÔÅÓÔ' as c1 NONE NO root@localhost DEFINER koi8r koi8r_general_ci
+NULL mysqltest1 v2 select 'ÔÅÓÔ' AS `c1` NONE NO root@localhost DEFINER koi8r koi8r_general_ci
+
+SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v3'|
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
+NULL mysqltest1 v3 select 'ÔÅÓÔ' AS `ÔÅÓÔ` NONE NO root@localhost DEFINER koi8r koi8r_general_ci
SELECT COLLATION(c1), COLLATION(c2) FROM v1|
@@ -85,6 +106,10 @@ SELECT COLLATION(c1) FROM v2|
COLLATION(c1)
utf8_general_ci
+SELECT * FROM v3|
+ÔÅÓÔ
+ÔÅÓÔ
+
---> Dumping mysqltest1 to ddl_i18n_koi8r.views.mysqltest1.sql
@@ -99,27 +124,36 @@ SET @@character_set_results= cp1251|
SET @@collation_connection= cp1251_general_ci|
SELECT * FROM mysqltest1.v1|
SELECT * FROM mysqltest1.v2|
+SELECT * FROM mysqltest1.v3|
use mysqltest1|
set names koi8r|
SHOW CREATE VIEW v1|
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _koi8r'ÔÅÓÔ' AS `c1`,`t1`.`ËÏÌ` AS `c2` from `t1` koi8r koi8r_general_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'ÔÅÓÔ' AS `c1`,`t1`.`ËÏÌ` AS `c2` from `t1` koi8r koi8r_general_ci
SHOW CREATE VIEW v2|
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select _utf8'теÑÑ‚' AS `c1` koi8r koi8r_general_ci
+SHOW CREATE VIEW v3|
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select _utf8'теÑÑ‚' AS `ÔÅÓÔ` koi8r koi8r_general_ci
+
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v1'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v1 select 'ÔÅÓÔ' AS `c1`,`t1`.`ËÏÌ` AS `c2` from `t1` NONE YES root@localhost DEFINER koi8r koi8r_general_ci
+NULL mysqltest1 v1 select 'ÔÅÓÔ' AS `c1`,`mysqltest1`.`t1`.`ËÏÌ` AS `c2` from `mysqltest1`.`t1` NONE YES root@localhost DEFINER koi8r koi8r_general_ci
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v2'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
NULL mysqltest1 v2 select 'ÔÅÓÔ' AS `c1` NONE NO root@localhost DEFINER koi8r koi8r_general_ci
+SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v3'|
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
+NULL mysqltest1 v3 select 'ÔÅÓÔ' AS `ÔÅÓÔ` NONE NO root@localhost DEFINER koi8r koi8r_general_ci
+
SELECT COLLATION(c1), COLLATION(c2) FROM v1|
COLLATION(c1) COLLATION(c2)
@@ -129,6 +163,10 @@ SELECT COLLATION(c1) FROM v2|
COLLATION(c1)
utf8_general_ci
+SELECT * FROM v3|
+ÔÅÓÔ
+ÔÅÓÔ
+
---> connection: default
use test|
DROP DATABASE mysqltest1|
diff --git a/mysql-test/r/ddl_i18n_utf8.result b/mysql-test/r/ddl_i18n_utf8.result
index d0f176c1985..cf5dac3dc7c 100644
--- a/mysql-test/r/ddl_i18n_utf8.result
+++ b/mysql-test/r/ddl_i18n_utf8.result
@@ -16,25 +16,34 @@ FROM t1|
CREATE VIEW v2 AS SELECT _koi8r'ÔÅÓÔ' as c1|
+CREATE VIEW v3 AS SELECT _koi8r'ÔÅÓÔ'|
+
SHOW CREATE VIEW v1|
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _utf8'теÑÑ‚' AS `c1`,`t1`.`кол` AS `c2` from `t1` utf8 utf8_general_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'теÑÑ‚' AS `c1`,`t1`.`кол` AS `c2` from `t1` utf8 utf8_general_ci
SHOW CREATE VIEW v2|
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select _koi8r'ÔÅÓÔ' AS `c1` utf8 utf8_general_ci
+SHOW CREATE VIEW v3|
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select _koi8r'ÔÅÓÔ' AS `теÑÑ‚` utf8 utf8_general_ci
+
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v1'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v1 SELECT 'теÑÑ‚' AS c1, кол AS c2
-FROM t1 NONE YES root@localhost DEFINER utf8 utf8_general_ci
+NULL mysqltest1 v1 select 'теÑÑ‚' AS `c1`,`mysqltest1`.`t1`.`кол` AS `c2` from `mysqltest1`.`t1` NONE YES root@localhost DEFINER utf8 utf8_general_ci
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v2'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v2 SELECT 'теÑÑ‚' as c1 NONE NO root@localhost DEFINER utf8 utf8_general_ci
+NULL mysqltest1 v2 select 'теÑÑ‚' AS `c1` NONE NO root@localhost DEFINER utf8 utf8_general_ci
+
+SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v3'|
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
+NULL mysqltest1 v3 select 'теÑÑ‚' AS `теÑÑ‚` NONE NO root@localhost DEFINER utf8 utf8_general_ci
SELECT COLLATION(c1), COLLATION(c2) FROM v1|
@@ -45,6 +54,10 @@ SELECT COLLATION(c1) FROM v2|
COLLATION(c1)
koi8r_general_ci
+SELECT * FROM v3|
+теÑÑ‚
+теÑÑ‚
+
ALTER DATABASE mysqltest1 COLLATE cp866_general_ci|
@@ -54,27 +67,35 @@ SET @@character_set_results= cp1251|
SET @@collation_connection= cp1251_general_ci|
SELECT * FROM mysqltest1.v1|
SELECT * FROM mysqltest1.v2|
+SELECT * FROM mysqltest1.v3|
use mysqltest1|
set names utf8|
SHOW CREATE VIEW v1|
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _utf8'теÑÑ‚' AS `c1`,`t1`.`кол` AS `c2` from `t1` utf8 utf8_general_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'теÑÑ‚' AS `c1`,`t1`.`кол` AS `c2` from `t1` utf8 utf8_general_ci
SHOW CREATE VIEW v2|
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select _koi8r'ÔÅÓÔ' AS `c1` utf8 utf8_general_ci
+SHOW CREATE VIEW v3|
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select _koi8r'ÔÅÓÔ' AS `теÑÑ‚` utf8 utf8_general_ci
+
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v1'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v1 SELECT 'теÑÑ‚' AS c1, кол AS c2
-FROM t1 NONE YES root@localhost DEFINER utf8 utf8_general_ci
+NULL mysqltest1 v1 select 'теÑÑ‚' AS `c1`,`mysqltest1`.`t1`.`кол` AS `c2` from `mysqltest1`.`t1` NONE YES root@localhost DEFINER utf8 utf8_general_ci
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v2'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v2 SELECT 'теÑÑ‚' as c1 NONE NO root@localhost DEFINER utf8 utf8_general_ci
+NULL mysqltest1 v2 select 'теÑÑ‚' AS `c1` NONE NO root@localhost DEFINER utf8 utf8_general_ci
+
+SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v3'|
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
+NULL mysqltest1 v3 select 'теÑÑ‚' AS `теÑÑ‚` NONE NO root@localhost DEFINER utf8 utf8_general_ci
SELECT COLLATION(c1), COLLATION(c2) FROM v1|
@@ -85,6 +106,10 @@ SELECT COLLATION(c1) FROM v2|
COLLATION(c1)
koi8r_general_ci
+SELECT * FROM v3|
+теÑÑ‚
+теÑÑ‚
+
---> Dumping mysqltest1 to ddl_i18n_utf8views.mysqltest1.sql
@@ -99,27 +124,36 @@ SET @@character_set_results= cp1251|
SET @@collation_connection= cp1251_general_ci|
SELECT * FROM mysqltest1.v1|
SELECT * FROM mysqltest1.v2|
+SELECT * FROM mysqltest1.v3|
use mysqltest1|
set names utf8|
SHOW CREATE VIEW v1|
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _utf8'теÑÑ‚' AS `c1`,`t1`.`кол` AS `c2` from `t1` utf8 utf8_general_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'теÑÑ‚' AS `c1`,`t1`.`кол` AS `c2` from `t1` utf8 utf8_general_ci
SHOW CREATE VIEW v2|
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select _koi8r'ÔÅÓÔ' AS `c1` utf8 utf8_general_ci
+SHOW CREATE VIEW v3|
+View Create View character_set_client collation_connection
+v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select _koi8r'ÔÅÓÔ' AS `теÑÑ‚` utf8 utf8_general_ci
+
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v1'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL mysqltest1 v1 select 'теÑÑ‚' AS `c1`,`t1`.`кол` AS `c2` from `t1` NONE YES root@localhost DEFINER utf8 utf8_general_ci
+NULL mysqltest1 v1 select 'теÑÑ‚' AS `c1`,`mysqltest1`.`t1`.`кол` AS `c2` from `mysqltest1`.`t1` NONE YES root@localhost DEFINER utf8 utf8_general_ci
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v2'|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
NULL mysqltest1 v2 select 'теÑÑ‚' AS `c1` NONE NO root@localhost DEFINER utf8 utf8_general_ci
+SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v3'|
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
+NULL mysqltest1 v3 select 'теÑÑ‚' AS `теÑÑ‚` NONE NO root@localhost DEFINER utf8 utf8_general_ci
+
SELECT COLLATION(c1), COLLATION(c2) FROM v1|
COLLATION(c1) COLLATION(c2)
@@ -129,6 +163,10 @@ SELECT COLLATION(c1) FROM v2|
COLLATION(c1)
koi8r_general_ci
+SELECT * FROM v3|
+теÑÑ‚
+теÑÑ‚
+
---> connection: default
use test|
DROP DATABASE mysqltest1|
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index c3fa427127b..2fc00073448 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -17,7 +17,7 @@ explain extended select * from t1 where MATCH(a,b) AGAINST ("collections");
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 fulltext a a 0 1 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (match `test`.`t1`.`a`,`test`.`t1`.`b` against (_latin1'collections'))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (match `test`.`t1`.`a`,`test`.`t1`.`b` against ('collections'))
select * from t1 where MATCH(a,b) AGAINST ("indexes");
a b
Full-text indexes are called collections
@@ -87,7 +87,7 @@ explain extended select * from t1 where MATCH(a,b) AGAINST("support -collections
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 fulltext a a 0 1 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (match `test`.`t1`.`a`,`test`.`t1`.`b` against (_latin1'support -collections' in boolean mode))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (match `test`.`t1`.`a`,`test`.`t1`.`b` against ('support -collections' in boolean mode))
select * from t1 where MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE);
a b
MySQL has now support for full-text search
diff --git a/mysql-test/r/func_crypt.result b/mysql-test/r/func_crypt.result
index 32377c9ba63..25b921681c5 100644
--- a/mysql-test/r/func_crypt.result
+++ b/mysql-test/r/func_crypt.result
@@ -91,7 +91,7 @@ explain extended select password('idkfa '), old_password('idkfa');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select password(_latin1'idkfa ') AS `password('idkfa ')`,old_password(_latin1'idkfa') AS `old_password('idkfa')`
+Note 1003 select password('idkfa ') AS `password('idkfa ')`,old_password('idkfa') AS `old_password('idkfa')`
select encrypt('1234','_.');
encrypt('1234','_.')
#
diff --git a/mysql-test/r/func_encrypt.result b/mysql-test/r/func_encrypt.result
index dc2b5498b2a..04af76429f8 100644
--- a/mysql-test/r/func_encrypt.result
+++ b/mysql-test/r/func_encrypt.result
@@ -182,4 +182,4 @@ explain extended select des_decrypt(des_encrypt("hello",4),'password2'), des_dec
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select des_decrypt(des_encrypt(_latin1'hello',4),_latin1'password2') AS `des_decrypt(des_encrypt("hello",4),'password2')`,des_decrypt(des_encrypt(_latin1'hello',_latin1'hidden')) AS `des_decrypt(des_encrypt("hello","hidden"))`
+Note 1003 select des_decrypt(des_encrypt('hello',4),'password2') AS `des_decrypt(des_encrypt("hello",4),'password2')`,des_decrypt(des_encrypt('hello','hidden')) AS `des_decrypt(des_encrypt("hello","hidden"))`
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index e9a17324397..42a2aa840ea 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -43,7 +43,7 @@ explain extended select if(u=1,st,binary st) s from t1 where st like "%a%" order
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 7 100.00 Using where; Using filesort
Warnings:
-Note 1003 select if((`test`.`t1`.`u` = 1),`test`.`t1`.`st`,cast(`test`.`t1`.`st` as char charset binary)) AS `s` from `test`.`t1` where (`test`.`t1`.`st` like _latin1'%a%') order by if((`test`.`t1`.`u` = 1),`test`.`t1`.`st`,cast(`test`.`t1`.`st` as char charset binary))
+Note 1003 select if((`test`.`t1`.`u` = 1),`test`.`t1`.`st`,cast(`test`.`t1`.`st` as char charset binary)) AS `s` from `test`.`t1` where (`test`.`t1`.`st` like '%a%') order by if((`test`.`t1`.`u` = 1),`test`.`t1`.`st`,cast(`test`.`t1`.`st` as char charset binary))
select nullif(u, 1) from t1;
nullif(u, 1)
NULL
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 80fa8f17a2a..6e1f9bd8188 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -146,7 +146,7 @@ explain extended select * from t1 where 'a' in (a,b,c collate latin1_bin);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (_latin1'a' in (`test`.`t1`.`a`,`test`.`t1`.`b`,(`test`.`t1`.`c` collate latin1_bin)))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ('a' in (`test`.`t1`.`a`,`test`.`t1`.`b`,(`test`.`t1`.`c` collate latin1_bin)))
drop table t1;
set names utf8;
create table t1 (a char(10) character set utf8 not null);
diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result
index 5de5962efeb..9338a76e320 100644
--- a/mysql-test/r/func_like.result
+++ b/mysql-test/r/func_like.result
@@ -5,12 +5,12 @@ explain extended select * from t1 where a like 'abc%';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index a a 13 NULL 5 20.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` like _latin1'abc%')
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` like 'abc%')
explain extended select * from t1 where a like concat('abc','%');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index a a 13 NULL 5 20.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` like concat(_latin1'abc',_latin1'%'))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` like concat('abc','%'))
select * from t1 where a like "abc%";
a
abc
diff --git a/mysql-test/r/func_regexp.result b/mysql-test/r/func_regexp.result
index 9d85b1d3e7f..794ae79973a 100644
--- a/mysql-test/r/func_regexp.result
+++ b/mysql-test/r/func_regexp.result
@@ -52,7 +52,7 @@ explain extended select * from t1 where xxx regexp('is a test of some long text
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
Warnings:
-Note 1003 select 'this is a test of some long text to see what happens' AS `xxx` from `test`.`t1` where ('this is a test of some long text to see what happens' regexp _latin1'is a test of some long text to')
+Note 1003 select 'this is a test of some long text to see what happens' AS `xxx` from `test`.`t1` where ('this is a test of some long text to see what happens' regexp 'is a test of some long text to')
select * from t1 where xxx regexp('is a test of some long text to ');
xxx
this is a test of some long text to see what happens
diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result
index 4dd11cafdcd..3f9f7b85731 100644
--- a/mysql-test/r/func_set.result
+++ b/mysql-test/r/func_set.result
@@ -5,7 +5,7 @@ explain extended select INTERVAL(55,10,20,30,40,50,60,70,80,90,100),interval(3,1
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select interval((55,10,20,30,40,50,60,70,80,90,100)) AS `INTERVAL(55,10,20,30,40,50,60,70,80,90,100)`,interval((3,1,(1 + 1),(((1 + 1) + 1) + 1))) AS `interval(3,1,1+1,1+1+1+1)`,field(_latin1'IBM',_latin1'NCA',_latin1'ICL',_latin1'SUN',_latin1'IBM',_latin1'DIGITAL') AS `field("IBM","NCA","ICL","SUN","IBM","DIGITAL")`,field(_latin1'A',_latin1'B',_latin1'C') AS `field("A","B","C")`,elt(2,_latin1'ONE',_latin1'TWO',_latin1'THREE') AS `elt(2,"ONE","TWO","THREE")`,interval((0,1,2,3,4)) AS `interval(0,1,2,3,4)`,(elt(1,1,2,3) | 0) AS `elt(1,1,2,3)|0`,(elt(1,1.1,1.2,1.3) + 0) AS `elt(1,1.1,1.2,1.3)+0`
+Note 1003 select interval((55,10,20,30,40,50,60,70,80,90,100)) AS `INTERVAL(55,10,20,30,40,50,60,70,80,90,100)`,interval((3,1,(1 + 1),(((1 + 1) + 1) + 1))) AS `interval(3,1,1+1,1+1+1+1)`,field('IBM','NCA','ICL','SUN','IBM','DIGITAL') AS `field("IBM","NCA","ICL","SUN","IBM","DIGITAL")`,field('A','B','C') AS `field("A","B","C")`,elt(2,'ONE','TWO','THREE') AS `elt(2,"ONE","TWO","THREE")`,interval((0,1,2,3,4)) AS `interval(0,1,2,3,4)`,(elt(1,1,2,3) | 0) AS `elt(1,1,2,3)|0`,(elt(1,1.1,1.2,1.3) + 0) AS `elt(1,1.1,1.2,1.3)+0`
SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56)
1
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 6f6edd5112b..ea79eefb316 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -817,57 +817,57 @@ explain extended select md5('hello');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select md5(_latin1'hello') AS `md5('hello')`
+Note 1003 select md5('hello') AS `md5('hello')`
explain extended select sha('abc');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select sha(_latin1'abc') AS `sha('abc')`
+Note 1003 select sha('abc') AS `sha('abc')`
explain extended select sha1('abc');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select sha(_latin1'abc') AS `sha1('abc')`
+Note 1003 select sha('abc') AS `sha1('abc')`
explain extended select soundex('');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select soundex(_latin1'') AS `soundex('')`
+Note 1003 select soundex('') AS `soundex('')`
explain extended select 'mood' sounds like 'mud';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select (soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`
+Note 1003 select (soundex('mood') = soundex('mud')) AS `'mood' sounds like 'mud'`
explain extended select aes_decrypt(aes_encrypt('abc','1'),'1');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`
+Note 1003 select aes_decrypt(aes_encrypt('abc','1'),'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`
explain extended select concat('*',space(5),'*');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`
+Note 1003 select concat('*',repeat(' ',5),'*') AS `concat('*',space(5),'*')`
explain extended select reverse('abc');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select reverse(_latin1'abc') AS `reverse('abc')`
+Note 1003 select reverse('abc') AS `reverse('abc')`
explain extended select rpad('a',4,'1');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`
+Note 1003 select rpad('a',4,'1') AS `rpad('a',4,'1')`
explain extended select lpad('a',4,'1');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`
+Note 1003 select lpad('a',4,'1') AS `lpad('a',4,'1')`
explain extended select concat_ws(',','',NULL,'a');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`
+Note 1003 select concat_ws(',','',NULL,'a') AS `concat_ws(',','',NULL,'a')`
explain extended select make_set(255,_latin2'a', _latin2'b', _latin2'c');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -882,7 +882,7 @@ explain extended select locate("a","b",2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`
+Note 1003 select locate('a','b',2) AS `locate("a","b",2)`
explain extended select format(130,10);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -907,7 +907,7 @@ explain extended select binary 'HE';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select cast(_latin1'HE' as char charset binary) AS `binary 'HE'`
+Note 1003 select cast('HE' as char charset binary) AS `binary 'HE'`
explain extended select export_set(255,_latin2'y', _latin2'n', _latin2' ');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -917,7 +917,7 @@ explain extended select FIELD('b' COLLATE latin1_bin,'A','B');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select field((_latin1'b' collate latin1_bin),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`
+Note 1003 select field(('b' collate latin1_bin),'A','B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`
explain extended select FIND_IN_SET(_latin1'B', _latin1'a,b,c,d');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -937,37 +937,37 @@ explain extended select length('\n\t\r\b\0\_\%\\');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`
+Note 1003 select length('\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`
explain extended select bit_length('\n\t\r\b\0\_\%\\');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`
+Note 1003 select bit_length('\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`
explain extended select bit_length('\n\t\r\b\0\_\%\\');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`
+Note 1003 select bit_length('\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`
explain extended select concat('monty',' was here ','again');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`
+Note 1003 select concat('monty',' was here ','again') AS `concat('monty',' was here ','again')`
explain extended select length('hello');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select length(_latin1'hello') AS `length('hello')`
+Note 1003 select length('hello') AS `length('hello')`
explain extended select char(ascii('h'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select char(ascii(_latin1'h')) AS `char(ascii('h'))`
+Note 1003 select char(ascii('h')) AS `char(ascii('h'))`
explain extended select ord('h');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select ord(_latin1'h') AS `ord('h')`
+Note 1003 select ord('h') AS `ord('h')`
explain extended select quote(1/0);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -977,17 +977,17 @@ explain extended select crc32("123");
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select crc32(_latin1'123') AS `crc32("123")`
+Note 1003 select crc32('123') AS `crc32("123")`
explain extended select replace('aaaa','a','b');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`
+Note 1003 select replace('aaaa','a','b') AS `replace('aaaa','a','b')`
explain extended select insert('txs',2,1,'hi');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`
+Note 1003 select insert('txs',2,1,'hi') AS `insert('txs',2,1,'hi')`
explain extended select left(_latin2'a',1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -1012,12 +1012,12 @@ explain extended select SUBSTR('abcdefg',3,2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`
+Note 1003 select substr('abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`
explain extended select substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select substring_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`
+Note 1003 select substring_index('1abcd;2abcd;3abcd;4abcd',';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`
explain extended select trim(_latin2' a ');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -1037,7 +1037,7 @@ explain extended select decode(encode(repeat("a",100000),"monty"),"monty");
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select decode(encode(repeat(_latin1'a',100000),_latin1'monty'),_latin1'monty') AS `decode(encode(repeat("a",100000),"monty"),"monty")`
+Note 1003 select decode(encode(repeat('a',100000),'monty'),'monty') AS `decode(encode(repeat("a",100000),"monty"),"monty")`
SELECT lpad(12345, 5, "#");
lpad(12345, 5, "#")
12345
@@ -1282,39 +1282,39 @@ EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(s) > 'ab';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(`test`.`t1`.`s`) > _latin1'ab')
+Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(`test`.`t1`.`s`) > 'ab')
EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM('y' FROM s) > 'ab';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(both _latin1'y' from `test`.`t1`.`s`) > _latin1'ab')
+Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(both 'y' from `test`.`t1`.`s`) > 'ab')
EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(LEADING 'y' FROM s) > 'ab';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(leading _latin1'y' from `test`.`t1`.`s`) > _latin1'ab')
+Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(leading 'y' from `test`.`t1`.`s`) > 'ab')
EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(TRAILING 'y' FROM s) > 'ab';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(trailing _latin1'y' from `test`.`t1`.`s`) > _latin1'ab')
+Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(trailing 'y' from `test`.`t1`.`s`) > 'ab')
EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(BOTH 'y' FROM s) > 'ab';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(both _latin1'y' from `test`.`t1`.`s`) > _latin1'ab')
+Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(both 'y' from `test`.`t1`.`s`) > 'ab')
DROP TABLE t1;
create table t1(f1 varchar(4));
explain extended select encode(f1,'zxcv') as 'enc' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select encode('',_latin1'zxcv') AS `enc` from `test`.`t1`
+Note 1003 select encode('','zxcv') AS `enc` from `test`.`t1`
explain extended select decode(f1,'zxcv') as 'enc' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select decode('',_latin1'zxcv') AS `enc` from `test`.`t1`
+Note 1003 select decode('','zxcv') AS `enc` from `test`.`t1`
drop table t1;
create table t1 (a bigint not null)engine=myisam;
insert into t1 set a = 1024*1024*1024*4;
@@ -1390,7 +1390,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 const PRIMARY PRIMARY 12 const 1 100.00 Using index
1 SIMPLE t1 ref code code 13 const 3 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`code` AS `code`,'a12' AS `id` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`code` = _latin1'a12') and (length(`test`.`t1`.`code`) = 5))
+Note 1003 select `test`.`t1`.`code` AS `code`,'a12' AS `id` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`code` = 'a12') and (length(`test`.`t1`.`code`) = 5))
DROP TABLE t1,t2;
select encode(NULL, NULL);
encode(NULL, NULL)
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 4dd8fb1531d..9cdf8a3cf50 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -839,7 +839,7 @@ explain extended select period_add("9602",-12),period_diff(199505,"9404"),from_d
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select period_add(_latin1'9602',-(12)) AS `period_add("9602",-12)`,period_diff(199505,_latin1'9404') AS `period_diff(199505,"9404")`,from_days(to_days(_latin1'960101')) AS `from_days(to_days("960101"))`,dayofmonth(_latin1'1997-01-02') AS `dayofmonth("1997-01-02")`,month(_latin1'1997-01-02') AS `month("1997-01-02")`,monthname(_latin1'1972-03-04') AS `monthname("1972-03-04")`,dayofyear(_latin1'0000-00-00') AS `dayofyear("0000-00-00")`,hour(_latin1'1997-03-03 23:03:22') AS `HOUR("1997-03-03 23:03:22")`,minute(_latin1'23:03:22') AS `MINUTE("23:03:22")`,second(230322) AS `SECOND(230322)`,quarter(980303) AS `QUARTER(980303)`,week(_latin1'1998-03-03',0) AS `WEEK("1998-03-03")`,yearweek(_latin1'2000-01-01',1) AS `yearweek("2000-01-01",1)`,week(19950101,1) AS `week(19950101,1)`,year(_latin1'98-02-03') AS `year("98-02-03")`,(weekday(curdate()) - weekday(now())) AS `weekday(curdate())-weekday(now())`,dayname(_latin1'1962-03-03') AS `dayname("1962-03-03")`,unix_timestamp() AS `unix_timestamp()`,sec_to_time((time_to_sec(_latin1'0:30:47') / 6.21)) AS `sec_to_time(time_to_sec("0:30:47")/6.21)`,curtime() AS `curtime()`,utc_time() AS `utc_time()`,curdate() AS `curdate()`,utc_date() AS `utc_date()`,utc_timestamp() AS `utc_timestamp()`,date_format(_latin1'1997-01-02 03:04:05',_latin1'%M %W %D %Y %y %m %d %h %i %s %w') AS `date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")`,from_unixtime(unix_timestamp(_latin1'1994-03-02 10:11:12')) AS `from_unixtime(unix_timestamp("1994-03-02 10:11:12"))`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `"1997-12-31 23:59:59" + INTERVAL 1 SECOND`,(_latin1'1998-01-01 00:00:00' - interval 1 second) AS `"1998-01-01 00:00:00" - INTERVAL 1 SECOND`,(_latin1'1997-12-31' + interval 1 day) AS `INTERVAL 1 DAY + "1997-12-31"`,extract(year from _latin1'1999-01-02 10:11:12') AS `extract(YEAR FROM "1999-01-02 10:11:12")`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)`
+Note 1003 select period_add('9602',-(12)) AS `period_add("9602",-12)`,period_diff(199505,'9404') AS `period_diff(199505,"9404")`,from_days(to_days('960101')) AS `from_days(to_days("960101"))`,dayofmonth('1997-01-02') AS `dayofmonth("1997-01-02")`,month('1997-01-02') AS `month("1997-01-02")`,monthname('1972-03-04') AS `monthname("1972-03-04")`,dayofyear('0000-00-00') AS `dayofyear("0000-00-00")`,hour('1997-03-03 23:03:22') AS `HOUR("1997-03-03 23:03:22")`,minute('23:03:22') AS `MINUTE("23:03:22")`,second(230322) AS `SECOND(230322)`,quarter(980303) AS `QUARTER(980303)`,week('1998-03-03',0) AS `WEEK("1998-03-03")`,yearweek('2000-01-01',1) AS `yearweek("2000-01-01",1)`,week(19950101,1) AS `week(19950101,1)`,year('98-02-03') AS `year("98-02-03")`,(weekday(curdate()) - weekday(now())) AS `weekday(curdate())-weekday(now())`,dayname('1962-03-03') AS `dayname("1962-03-03")`,unix_timestamp() AS `unix_timestamp()`,sec_to_time((time_to_sec('0:30:47') / 6.21)) AS `sec_to_time(time_to_sec("0:30:47")/6.21)`,curtime() AS `curtime()`,utc_time() AS `utc_time()`,curdate() AS `curdate()`,utc_date() AS `utc_date()`,utc_timestamp() AS `utc_timestamp()`,date_format('1997-01-02 03:04:05','%M %W %D %Y %y %m %d %h %i %s %w') AS `date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")`,from_unixtime(unix_timestamp('1994-03-02 10:11:12')) AS `from_unixtime(unix_timestamp("1994-03-02 10:11:12"))`,('1997-12-31 23:59:59' + interval 1 second) AS `"1997-12-31 23:59:59" + INTERVAL 1 SECOND`,('1998-01-01 00:00:00' - interval 1 second) AS `"1998-01-01 00:00:00" - INTERVAL 1 SECOND`,('1997-12-31' + interval 1 day) AS `INTERVAL 1 DAY + "1997-12-31"`,extract(year from '1999-01-02 10:11:12') AS `extract(YEAR FROM "1999-01-02 10:11:12")`,('1997-12-31 23:59:59' + interval 1 second) AS `date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)`
SET @TMP='2007-08-01 12:22:49';
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES ('2007-08-01 12:22:59');
@@ -1069,7 +1069,7 @@ timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select timestampdiff(WEEK,_latin1'2001-02-01',_latin1'2001-05-01') AS `a1`,timestampdiff(SECOND_FRAC,_latin1'2001-02-01 12:59:59.120000',_latin1'2001-05-01 12:58:58.119999') AS `a2`
+Note 1003 select timestampdiff(WEEK,'2001-02-01','2001-05-01') AS `a1`,timestampdiff(SECOND_FRAC,'2001-02-01 12:59:59.120000','2001-05-01 12:58:58.119999') AS `a2`
select time_format('100:00:00', '%H %k %h %I %l');
time_format('100:00:00', '%H %k %h %I %l')
100 100 04 04 4
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 73fb9cc69e0..d91e21e9399 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -439,12 +439,12 @@ explain extended SELECT AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select astext(geometryfromwkb(aswkb(geometryfromtext(_latin1'POINT(1 4)')))) AS `AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)'))))`
+Note 1003 select astext(geometryfromwkb(aswkb(geometryfromtext('POINT(1 4)')))) AS `AsText(GeometryFromWKB(AsWKB(GeometryFromText('POINT(1 4)'))))`
explain extended SELECT AsText(GeometryFromWKB(AsWKB(PointFromText('POINT(1 4)'))));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select astext(geometryfromwkb(aswkb(geometryfromtext(_latin1'POINT(1 4)')))) AS `AsText(GeometryFromWKB(AsWKB(PointFromText('POINT(1 4)'))))`
+Note 1003 select astext(geometryfromwkb(aswkb(geometryfromtext('POINT(1 4)')))) AS `AsText(GeometryFromWKB(AsWKB(PointFromText('POINT(1 4)'))))`
SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
SRID(GeomFromText('LineString(1 1,2 2)',101))
101
@@ -452,7 +452,7 @@ explain extended SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select srid(geometryfromtext(_latin1'LineString(1 1,2 2)',101)) AS `SRID(GeomFromText('LineString(1 1,2 2)',101))`
+Note 1003 select srid(geometryfromtext('LineString(1 1,2 2)',101)) AS `SRID(GeomFromText('LineString(1 1,2 2)',101))`
explain extended select issimple(MultiPoint(Point(3, 6), Point(4, 10))), issimple(Point(3, 6));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index 103a7f5515a..bdc8d586f4e 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -1562,7 +1562,7 @@ explain extended select distinct a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL idx_t1_1 163 NULL 128 50.78 Using where; Using index
Warnings:
-Note 1003 select distinct `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`c` = _latin1'i121') and (`test`.`t1`.`b` = _latin1'a') and (`test`.`t1`.`a2` >= _latin1'b'))
+Note 1003 select distinct `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`c` = 'i121') and (`test`.`t1`.`b` = 'a') and (`test`.`t1`.`a2` >= 'b'))
explain select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 Using where; Using index for group-by
@@ -1579,7 +1579,7 @@ explain extended select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 index NULL idx_t2_1 163 NULL 164 50.61 Using where; Using index
Warnings:
-Note 1003 select distinct `test`.`t2`.`a1` AS `a1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where ((`test`.`t2`.`c` = _latin1'i121') and (`test`.`t2`.`b` = _latin1'a') and (`test`.`t2`.`a2` >= _latin1'b'))
+Note 1003 select distinct `test`.`t2`.`a1` AS `a1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where ((`test`.`t2`.`c` = 'i121') and (`test`.`t2`.`b` = 'a') and (`test`.`t2`.`a2` >= 'b'))
explain select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 146 NULL # Using where; Using index for group-by
@@ -1808,7 +1808,7 @@ explain extended select count(distinct a1,a2,b) from t1 where (a1 > 'a') and (a2
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index
Warnings:
-Note 1003 select count(distinct `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`) AS `count(distinct a1,a2,b)` from `test`.`t1` where ((`test`.`t1`.`b` = _latin1'c') and (`test`.`t1`.`a1` > _latin1'a') and (`test`.`t1`.`a2` > _latin1'a'))
+Note 1003 select count(distinct `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`) AS `count(distinct a1,a2,b)` from `test`.`t1` where ((`test`.`t1`.`b` = 'c') and (`test`.`t1`.`a1` > 'a') and (`test`.`t1`.`a2` > 'a'))
explain select count(distinct b) from t1 where (a2 >= 'b') and (b = 'a');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx_t1_2 147 NULL 128 Using where; Using index
@@ -1816,7 +1816,7 @@ explain extended select ord(a1) + count(distinct a1,a2,b) from t1 where (a1 > 'a
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index
Warnings:
-Note 1003 select (ord(`test`.`t1`.`a1`) + count(distinct `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`)) AS `ord(a1) + count(distinct a1,a2,b)` from `test`.`t1` where ((`test`.`t1`.`a1` > _latin1'a') and (`test`.`t1`.`a2` > _latin1'a'))
+Note 1003 select (ord(`test`.`t1`.`a1`) + count(distinct `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`)) AS `ord(a1) + count(distinct a1,a2,b)` from `test`.`t1` where ((`test`.`t1`.`a1` > 'a') and (`test`.`t1`.`a2` > 'a'))
select count(distinct a1,a2,b) from t1 where (a2 >= 'b') and (b = 'a');
count(distinct a1,a2,b)
4
@@ -1924,19 +1924,19 @@ where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (c > 'a1
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 76 85.53 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,min(`test`.`t1`.`b`) AS `min(b)`,max(`test`.`t1`.`b`) AS `max(b)` from `test`.`t1` where (((`test`.`t1`.`a1` = _latin1'b') or (`test`.`t1`.`a1` = _latin1'd') or (`test`.`t1`.`a1` = _latin1'a') or (`test`.`t1`.`a1` = _latin1'c')) and (`test`.`t1`.`a2` > _latin1'a') and (`test`.`t1`.`c` > _latin1'a111')) group by `test`.`t1`.`a1`,`test`.`t1`.`a2`
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,min(`test`.`t1`.`b`) AS `min(b)`,max(`test`.`t1`.`b`) AS `max(b)` from `test`.`t1` where (((`test`.`t1`.`a1` = 'b') or (`test`.`t1`.`a1` = 'd') or (`test`.`t1`.`a1` = 'a') or (`test`.`t1`.`a1` = 'c')) and (`test`.`t1`.`a2` > 'a') and (`test`.`t1`.`c` > 'a111')) group by `test`.`t1`.`a1`,`test`.`t1`.`a2`
explain extended select a1,a2,b,min(c),max(c) from t1
where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (d > 'xy2') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL idx_t1_0,idx_t1_1,idx_t1_2 NULL NULL NULL 128 50.78 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,min(`test`.`t1`.`c`) AS `min(c)`,max(`test`.`t1`.`c`) AS `max(c)` from `test`.`t1` where (((`test`.`t1`.`a1` = _latin1'b') or (`test`.`t1`.`a1` = _latin1'd') or (`test`.`t1`.`a1` = _latin1'a') or (`test`.`t1`.`a1` = _latin1'c')) and (`test`.`t1`.`a2` > _latin1'a') and (`test`.`t1`.`d` > _latin1'xy2')) group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,min(`test`.`t1`.`c`) AS `min(c)`,max(`test`.`t1`.`c`) AS `max(c)` from `test`.`t1` where (((`test`.`t1`.`a1` = 'b') or (`test`.`t1`.`a1` = 'd') or (`test`.`t1`.`a1` = 'a') or (`test`.`t1`.`a1` = 'c')) and (`test`.`t1`.`a2` > 'a') and (`test`.`t1`.`d` > 'xy2')) group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`
explain extended select a1,a2,b,c from t1
where (a1 = 'b' or a1 = 'd' or a1 = 'a' or a1 = 'c') and (a2 > 'a') and (d > 'xy2') group by a1,a2,b,c;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL idx_t1_0,idx_t1_1,idx_t1_2 NULL NULL NULL 128 50.78 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (((`test`.`t1`.`a1` = _latin1'b') or (`test`.`t1`.`a1` = _latin1'd') or (`test`.`t1`.`a1` = _latin1'a') or (`test`.`t1`.`a1` = _latin1'c')) and (`test`.`t1`.`a2` > _latin1'a') and (`test`.`t1`.`d` > _latin1'xy2')) group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`,`test`.`t1`.`c`
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where (((`test`.`t1`.`a1` = 'b') or (`test`.`t1`.`a1` = 'd') or (`test`.`t1`.`a1` = 'a') or (`test`.`t1`.`a1` = 'c')) and (`test`.`t1`.`a2` > 'a') and (`test`.`t1`.`d` > 'xy2')) group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`,`test`.`t1`.`c`
explain select a1,a2,b,max(c),min(c) from t2 where (a2 = 'a') and (b = 'b') or (b < 'b') group by a1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
@@ -1944,7 +1944,7 @@ explain extended select a1,a2,b from t1 where (a1 = 'b' or a1 = 'd' or a1 = 'a'
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 130 NULL 76 85.53 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (((`test`.`t1`.`a1` = _latin1'b') or (`test`.`t1`.`a1` = _latin1'd') or (`test`.`t1`.`a1` = _latin1'a') or (`test`.`t1`.`a1` = _latin1'c')) and (`test`.`t1`.`a2` > _latin1'a') and (`test`.`t1`.`c` > _latin1'a111')) group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (((`test`.`t1`.`a1` = 'b') or (`test`.`t1`.`a1` = 'd') or (`test`.`t1`.`a1` = 'a') or (`test`.`t1`.`a1` = 'c')) and (`test`.`t1`.`a2` > 'a') and (`test`.`t1`.`c` > 'a111')) group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`
explain select a1,a2,min(b),c from t2 where (a2 = 'a') and (c = 'a111') group by a1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
@@ -1968,12 +1968,12 @@ explain extended select a1,a2,count(a2) from t1 where (a1 > 'a') group by a1,a2,
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,count(`test`.`t1`.`a2`) AS `count(a2)` from `test`.`t1` where (`test`.`t1`.`a1` > _latin1'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,count(`test`.`t1`.`a2`) AS `count(a2)` from `test`.`t1` where (`test`.`t1`.`a1` > 'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`
explain extended select sum(ord(a1)) from t1 where (a1 > 'a') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_2 147 NULL 128 75.00 Using where; Using index
Warnings:
-Note 1003 select sum(ord(`test`.`t1`.`a1`)) AS `sum(ord(a1))` from `test`.`t1` where (`test`.`t1`.`a1` > _latin1'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`
+Note 1003 select sum(ord(`test`.`t1`.`a1`)) AS `sum(ord(a1))` from `test`.`t1` where (`test`.`t1`.`a1` > 'a') group by `test`.`t1`.`a1`,`test`.`t1`.`a2`,`test`.`t1`.`b`
explain select distinct(a1) from t1 where ord(a2) = 98;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx_t1_2 147 NULL 128 Using where; Using index
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 708d8ab027d..7f4efa32dc2 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -387,15 +387,11 @@ show keys from v4;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
select * from information_schema.views where TABLE_NAME like "v%";
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL test v0 select schema_name from information_schema.schemata NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
-NULL test v1 select table_name from information_schema.tables
-where table_name="v1" NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
-NULL test v2 select column_name from information_schema.columns
-where table_name="v2" NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
-NULL test v3 select CHARACTER_SET_NAME from information_schema.character_sets
-where CHARACTER_SET_NAME like "latin1%" NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
-NULL test v4 select COLLATION_NAME from information_schema.collations
-where COLLATION_NAME like "latin1%" NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v0 select `schemata`.`SCHEMA_NAME` AS `c` from `information_schema`.`schemata` NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v1 select `tables`.`TABLE_NAME` AS `c` from `information_schema`.`tables` where (`tables`.`TABLE_NAME` = 'v1') NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v2 select `columns`.`COLUMN_NAME` AS `c` from `information_schema`.`columns` where (`columns`.`TABLE_NAME` = 'v2') NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v3 select `character_sets`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`character_sets` where (`character_sets`.`CHARACTER_SET_NAME` like 'latin1%') NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v4 select `collations`.`COLLATION_NAME` AS `c` from `information_schema`.`collations` where (`collations`.`COLLATION_NAME` like 'latin1%') NONE NO root@localhost DEFINER latin1 latin1_swedish_ci
drop view v0, v1, v2, v3, v4;
create table t1 (a int);
grant select,update,insert on t1 to mysqltest_1@localhost;
@@ -488,9 +484,9 @@ create view v2 (c) as select a from t1 WITH LOCAL CHECK OPTION;
create view v3 (c) as select a from t1 WITH CASCADED CHECK OPTION;
select * from information_schema.views;
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL test v1 select a from t1 with check option CASCADED YES root@localhost DEFINER latin1 latin1_swedish_ci
-NULL test v2 select a from t1 WITH LOCAL CHECK OPTION LOCAL YES root@localhost DEFINER latin1 latin1_swedish_ci
-NULL test v3 select a from t1 WITH CASCADED CHECK OPTION CASCADED YES root@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v1 select `test`.`t1`.`a` AS `c` from `test`.`t1` CASCADED YES root@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v2 select `test`.`t1`.`a` AS `c` from `test`.`t1` LOCAL YES root@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v3 select `test`.`t1`.`a` AS `c` from `test`.`t1` CASCADED YES root@localhost DEFINER latin1 latin1_swedish_ci
grant select (a) on test.t1 to joe@localhost with grant option;
select * from INFORMATION_SCHEMA.COLUMN_PRIVILEGES;
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE
@@ -1175,7 +1171,7 @@ select * from information_schema.views
where table_name='v1' or table_name='v2';
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
NULL test v1 NONE YES root@localhost DEFINER latin1 latin1_swedish_ci
-NULL test v2 select 1 NONE NO mysqltest_1@localhost DEFINER latin1 latin1_swedish_ci
+NULL test v2 select 1 AS `1` NONE NO mysqltest_1@localhost DEFINER latin1 latin1_swedish_ci
drop view v1, v2;
drop table t1;
drop user mysqltest_1@localhost;
@@ -1559,8 +1555,7 @@ AS SELECT *
FROM INFORMATION_SCHEMA.TABLES;
SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS where TABLE_NAME = 'v1';
VIEW_DEFINITION
-SELECT *
-FROM INFORMATION_SCHEMA.TABLES
+select `TABLES`.`TABLE_CATALOG` AS `TABLE_CATALOG`,`TABLES`.`TABLE_SCHEMA` AS `TABLE_SCHEMA`,`TABLES`.`TABLE_NAME` AS `TABLE_NAME`,`TABLES`.`TABLE_TYPE` AS `TABLE_TYPE`,`TABLES`.`ENGINE` AS `ENGINE`,`TABLES`.`VERSION` AS `VERSION`,`TABLES`.`ROW_FORMAT` AS `ROW_FORMAT`,`TABLES`.`TABLE_ROWS` AS `TABLE_ROWS`,`TABLES`.`AVG_ROW_LENGTH` AS `AVG_ROW_LENGTH`,`TABLES`.`DATA_LENGTH` AS `DATA_LENGTH`,`TABLES`.`MAX_DATA_LENGTH` AS `MAX_DATA_LENGTH`,`TABLES`.`INDEX_LENGTH` AS `INDEX_LENGTH`,`TABLES`.`DATA_FREE` AS `DATA_FREE`,`TABLES`.`AUTO_INCREMENT` AS `AUTO_INCREMENT`,`TABLES`.`CREATE_TIME` AS `CREATE_TIME`,`TABLES`.`UPDATE_TIME` AS `UPDATE_TIME`,`TABLES`.`CHECK_TIME` AS `CHECK_TIME`,`TABLES`.`TABLE_COLLATION` AS `TABLE_COLLATION`,`TABLES`.`CHECKSUM` AS `CHECKSUM`,`TABLES`.`CREATE_OPTIONS` AS `CREATE_OPTIONS`,`TABLES`.`TABLE_COMMENT` AS `TABLE_COMMENT` from `INFORMATION_SCHEMA`.`TABLES`
DROP VIEW v1;
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME ='information_schema';
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index cb56fb3d5cc..3044a11fb39 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -210,7 +210,7 @@ v2
select view_definition from information_schema.views a
where a.table_name = 'v2';
view_definition
-select f1 from testdb_1.v1
+select `v1`.`f1` AS `f1` from `testdb_1`.`v1`
select view_definition from information_schema.views a
where a.table_name = 'testdb_1.v1';
view_definition
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index e9f00a667c0..ffc3ca25a99 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1634,4 +1634,17 @@ vid tid idx name type
3 1 2 c1 NULL
3 1 1 pk NULL
DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1(id INT PRIMARY KEY)
+ENGINE=innodb;
+CREATE TABLE t2(
+t1_id INT PRIMARY KEY,
+CONSTRAINT fk1 FOREIGN KEY (t1_id) REFERENCES t1(id))
+ENGINE=innodb;
+
+ALTER TABLE t1 CHANGE id id2 INT;
+
+DROP TABLE t2;
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index 3ea5bbd20bc..a522d18f36b 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -1,3 +1,4 @@
+set @@global.concurrent_insert= 0;
drop table if exists t1, t2, t3;
create table t1 (kill_id int);
insert into t1 values(connection_id());
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index d07aed5317a..a1b8eaa52f8 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -2011,7 +2011,7 @@ SET character_set_client = @saved_cs_client;
/*!50001 SET collation_connection = latin1_swedish_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
-/*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') */
+/*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like 'a%') */
/*!50002 WITH CASCADED CHECK OPTION */;
/*!50001 SET character_set_client = @saved_cs_client */;
/*!50001 SET character_set_results = @saved_cs_results */;
@@ -2182,7 +2182,7 @@ SET character_set_client = @saved_cs_client;
/*!50001 SET collation_connection = latin1_swedish_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
-/*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') */
+/*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like 'a%') */
/*!50002 WITH CASCADED CHECK OPTION */;
/*!50001 SET character_set_client = @saved_cs_client */;
/*!50001 SET character_set_results = @saved_cs_results */;
@@ -4230,6 +4230,40 @@ LOCK TABLES `test` WRITE;
UNLOCK TABLES;
drop database `test-database`;
use test;
+
+# -----------------------------------------------------------------
+# -- Bug#30217: Views: changes in metadata behaviour between 5.0 and 5.1.
+# -----------------------------------------------------------------
+
+DROP DATABASE IF EXISTS mysqldump_test_db;
+CREATE DATABASE mysqldump_test_db;
+use mysqldump_test_db;
+
+CREATE VIEW v1(x, y) AS SELECT 'a', 'a';
+
+SELECT view_definition
+FROM INFORMATION_SCHEMA.VIEWS
+WHERE table_schema = 'mysqldump_test_db' AND table_name = 'v1';
+view_definition
+select 'a' AS `x`,'a' AS `y`
+
+---> Dumping mysqldump_test_db to bug30217.sql
+
+DROP DATABASE mysqldump_test_db;
+use test;
+
+---> Restoring mysqldump_test_db...
+
+SELECT view_definition
+FROM INFORMATION_SCHEMA.VIEWS
+WHERE table_schema = 'mysqldump_test_db' AND table_name = 'v1';
+view_definition
+select 'a' AS `x`,'a' AS `y`
+
+DROP DATABASE mysqldump_test_db;
+
+# -- End of test case for Bug#32538.
+
#
# End of 5.1 tests
#
diff --git a/mysql-test/r/named_pipe.result b/mysql-test/r/named_pipe.result
index eb93c5f6344..32e96fa27b7 100644
--- a/mysql-test/r/named_pipe.result
+++ b/mysql-test/r/named_pipe.result
@@ -1505,7 +1505,7 @@ explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
Warnings:
-Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> _latin1''))
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
diff --git a/mysql-test/r/negation_elimination.result b/mysql-test/r/negation_elimination.result
index ccb8e87b714..91a4c273832 100644
--- a/mysql-test/r/negation_elimination.result
+++ b/mysql-test/r/negation_elimination.result
@@ -387,5 +387,5 @@ explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL a 5 NULL 5 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like _latin1'1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where `test`.`t1`.`a` having `test`.`t1`.`a`
+Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where `test`.`t1`.`a` having `test`.`t1`.`a`
drop table t1;
diff --git a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result
index f2ffe28895d..1b734136e6c 100644
--- a/mysql-test/r/not_embedded_server.result
+++ b/mysql-test/r/not_embedded_server.result
@@ -3,3 +3,10 @@ execute stmt1;
ID USER HOST DB COMMAND TIME STATE INFO
number root localhost test Query time executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND!='Daemon'
deallocate prepare stmt1;
+FLUSH STATUS;
+SHOW GLOBAL STATUS LIKE 'com_select';
+Variable_name Value
+Com_select 102
+SHOW GLOBAL STATUS LIKE 'com_select';
+Variable_name Value
+Com_select 102
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index 5a2ebc37cc8..64b8aa74af3 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -6,7 +6,7 @@ explain extended select null,\N,isnull(null),isnull(1/0),isnull(1/0 = null),ifnu
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select NULL AS `NULL`,NULL AS `NULL`,isnull(NULL) AS `isnull(null)`,isnull((1 / 0)) AS `isnull(1/0)`,isnull(((1 / 0) = NULL)) AS `isnull(1/0 = null)`,ifnull(NULL,1) AS `ifnull(null,1)`,ifnull(NULL,_latin1'TRUE') AS `ifnull(null,"TRUE")`,ifnull(_latin1'TRUE',_latin1'ERROR') AS `ifnull("TRUE","ERROR")`,isnull((1 / 0)) AS `1/0 is null`,(1 is not null) AS `1 is not null`
+Note 1003 select NULL AS `NULL`,NULL AS `NULL`,isnull(NULL) AS `isnull(null)`,isnull((1 / 0)) AS `isnull(1/0)`,isnull(((1 / 0) = NULL)) AS `isnull(1/0 = null)`,ifnull(NULL,1) AS `ifnull(null,1)`,ifnull(NULL,'TRUE') AS `ifnull(null,"TRUE")`,ifnull('TRUE','ERROR') AS `ifnull("TRUE","ERROR")`,isnull((1 / 0)) AS `1/0 is null`,(1 is not null) AS `1 is not null`
select 1 | NULL,1 & NULL,1+NULL,1-NULL;
1 | NULL 1 & NULL 1+NULL 1-NULL
NULL NULL NULL NULL
@@ -49,7 +49,7 @@ explain extended select inet_ntoa(null),inet_aton(null),inet_aton("122.256"),ine
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select inet_ntoa(NULL) AS `inet_ntoa(null)`,inet_aton(NULL) AS `inet_aton(null)`,inet_aton(_latin1'122.256') AS `inet_aton("122.256")`,inet_aton(_latin1'122.226.') AS `inet_aton("122.226.")`,inet_aton(_latin1'') AS `inet_aton("")`
+Note 1003 select inet_ntoa(NULL) AS `inet_ntoa(null)`,inet_aton(NULL) AS `inet_aton(null)`,inet_aton('122.256') AS `inet_aton("122.256")`,inet_aton('122.226.') AS `inet_aton("122.226.")`,inet_aton('') AS `inet_aton("")`
create table t1 (x int);
insert into t1 values (null);
select * from t1 where x != 0;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 75d3f79f4b0..f2c1d5da3b5 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1733,6 +1733,158 @@ a b
9999999999999999 14632475938453979136
deallocate prepare stmt;
drop table t1;
+drop view if exists v1;
+drop table if exists t1;
+create table t1 (a int, b int);
+insert into t1 values (1,1), (2,2), (3,3);
+insert into t1 values (3,1), (1,2), (2,3);
+prepare stmt from "create view v1 as select * from t1";
+execute stmt;
+drop table t1;
+create table t1 (a int, b int);
+drop view v1;
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` latin1 latin1_swedish_ci
+drop view v1;
+prepare stmt from "create view v1 (c,d) as select a,b from t1";
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d` from `t1` latin1 latin1_swedish_ci
+select * from v1;
+c d
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d` from `t1` latin1 latin1_swedish_ci
+select * from v1;
+c d
+drop view v1;
+prepare stmt from "create view v1 (c) as select b+1 from t1";
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1` latin1 latin1_swedish_ci
+select * from v1;
+c
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1` latin1 latin1_swedish_ci
+select * from v1;
+c
+drop view v1;
+prepare stmt from "create view v1 (c,d,e,f) as select a,b,a in (select a+2 from t1), a = all (select a from t1) from t1";
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d`,`t1`.`a` in (select (`t1`.`a` + 2) AS `a+2` from `t1`) AS `e`,`t1`.`a` = all (select `t1`.`a` AS `a` from `t1`) AS `f` from `t1` latin1 latin1_swedish_ci
+select * from v1;
+c d e f
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d`,`t1`.`a` in (select (`t1`.`a` + 2) AS `a+2` from `t1`) AS `e`,`t1`.`a` = all (select `t1`.`a` AS `a` from `t1`) AS `f` from `t1` latin1 latin1_swedish_ci
+select * from v1;
+c d e f
+drop view v1;
+prepare stmt from "create or replace view v1 as select 1";
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1` latin1 latin1_swedish_ci
+select * from v1;
+1
+1
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1` latin1 latin1_swedish_ci
+deallocate prepare stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1` latin1 latin1_swedish_ci
+select * from v1;
+1
+1
+drop view v1;
+prepare stmt from "create view v1 as select 1, 1";
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`,1 AS `My_exp_1` latin1 latin1_swedish_ci
+select * from v1;
+1 My_exp_1
+1 1
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`,1 AS `My_exp_1` latin1 latin1_swedish_ci
+select * from v1;
+1 My_exp_1
+1 1
+drop view v1;
+prepare stmt from "create view v1 (x) as select a from t1 where a > 1";
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `x` from `t1` where (`t1`.`a` > 1) latin1 latin1_swedish_ci
+select * from v1;
+x
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `x` from `t1` where (`t1`.`a` > 1) latin1 latin1_swedish_ci
+select * from v1;
+x
+drop view v1;
+prepare stmt from "create view v1 as select * from `t1` `b`";
+execute stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `b`.`a` AS `a`,`b`.`b` AS `b` from `t1` `b` latin1 latin1_swedish_ci
+select * from v1;
+a b
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `b`.`a` AS `a`,`b`.`b` AS `b` from `t1` `b` latin1 latin1_swedish_ci
+select * from v1;
+a b
+drop view v1;
+prepare stmt from "create view v1 (a,b,c) as select * from t1";
+execute stmt;
+ERROR HY000: View's SELECT and view's field list have different column counts
+execute stmt;
+ERROR HY000: View's SELECT and view's field list have different column counts
+deallocate prepare stmt;
+drop table t1;
+create temporary table t1 (a int, b int);
+prepare stmt from "create view v1 as select * from t1";
+execute stmt;
+ERROR HY000: View's SELECT refers to a temporary table 't1'
+execute stmt;
+ERROR HY000: View's SELECT refers to a temporary table 't1'
+deallocate prepare stmt;
+drop table t1;
+prepare stmt from "create view v1 as select * from t1";
+ERROR 42S02: Table 'test.t1' doesn't exist
+prepare stmt from "create view v1 as select * from `t1` `b`";
+ERROR 42S02: Table 'test.t1' doesn't exist
End of 5.0 tests.
create procedure proc_1() reset query cache;
call proc_1();
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 2f305f6ec5d..d3dca16fe4f 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -1507,7 +1507,7 @@ explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
Warnings:
-Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> _latin1''))
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
diff --git a/mysql-test/r/shm.result b/mysql-test/r/shm.result
index b42de1e0f70..36ab17c1e4d 100644
--- a/mysql-test/r/shm.result
+++ b/mysql-test/r/shm.result
@@ -1505,7 +1505,7 @@ explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
Warnings:
-Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> _latin1''))
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index c5fcb833933..103b3c9a289 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -1075,7 +1075,7 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is
def VIEWS TABLE_CATALOG TABLE_CATALOG 253 1536 0 Y 0 0 33
def VIEWS TABLE_SCHEMA TABLE_SCHEMA 253 192 4 N 1 0 33
def VIEWS TABLE_NAME TABLE_NAME 253 192 2 N 1 0 33
-def VIEWS VIEW_DEFINITION VIEW_DEFINITION 252 589815 8 N 17 0 33
+def VIEWS VIEW_DEFINITION VIEW_DEFINITION 252 589815 15 N 17 0 33
def VIEWS CHECK_OPTION CHECK_OPTION 253 24 4 N 1 0 33
def VIEWS IS_UPDATABLE IS_UPDATABLE 253 9 2 N 1 0 33
def VIEWS DEFINER DEFINER 253 231 14 N 1 0 33
@@ -1083,7 +1083,7 @@ def VIEWS SECURITY_TYPE SECURITY_TYPE 253 21 7 N 1 0 33
def VIEWS CHARACTER_SET_CLIENT CHARACTER_SET_CLIENT 253 96 6 N 1 0 33
def VIEWS COLLATION_CONNECTION COLLATION_CONNECTION 253 96 6 N 1 0 33
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION
-NULL test v1 SELECT 1 NONE NO root@localhost DEFINER binary binary
+NULL test v1 select 1 AS `1` NONE NO root@localhost DEFINER binary binary
----------------------------------------------------------------
SHOW CREATE PROCEDURE p1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
@@ -1404,7 +1404,7 @@ CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT 'ÔÅÓÔ' AS test;
set names utf8;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _koi8r'теÑÑ‚' AS `test` koi8r koi8r_general_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'теÑÑ‚' AS `test` koi8r koi8r_general_ci
SHOW CREATE PROCEDURE p1;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
diff --git a/mysql-test/r/sp-code.result b/mysql-test/r/sp-code.result
index ca5c5b42102..f9c6914468c 100644
--- a/mysql-test/r/sp-code.result
+++ b/mysql-test/r/sp-code.result
@@ -324,29 +324,29 @@ Pos Instruction
0 set str@1 NULL
1 set_case_expr (12) 0 i@0
2 jump_if_not 5(12) (case_expr@0 = 1)
-3 set str@1 _latin1'1'
+3 set str@1 '1'
4 jump 12
5 jump_if_not 8(12) (case_expr@0 = 2)
-6 set str@1 _latin1'2'
+6 set str@1 '2'
7 jump 12
8 jump_if_not 11(12) (case_expr@0 = 3)
-9 set str@1 _latin1'3'
+9 set str@1 '3'
10 jump 12
-11 set str@1 _latin1'unknown'
+11 set str@1 'unknown'
12 stmt 0 "SELECT str"
SHOW PROCEDURE CODE proc_19194_searched;
Pos Instruction
0 set str@1 NULL
1 jump_if_not 4(11) (i@0 = 1)
-2 set str@1 _latin1'1'
+2 set str@1 '1'
3 jump 11
4 jump_if_not 7(11) (i@0 = 2)
-5 set str@1 _latin1'2'
+5 set str@1 '2'
6 jump 11
7 jump_if_not 10(11) (i@0 = 3)
-8 set str@1 _latin1'3'
+8 set str@1 '3'
9 jump 11
-10 set str@1 _latin1'unknown'
+10 set str@1 'unknown'
11 stmt 0 "SELECT str"
SHOW PROCEDURE CODE proc_19194_nested_1;
Pos Instruction
@@ -354,59 +354,59 @@ Pos Instruction
1 set str_j@3 NULL
2 set_case_expr (27) 0 i@0
3 jump_if_not 6(27) (case_expr@0 = 10)
-4 set str_i@2 _latin1'10'
+4 set str_i@2 '10'
5 jump 27
6 jump_if_not 20(27) (case_expr@0 = 20)
-7 set str_i@2 _latin1'20'
+7 set str_i@2 '20'
8 jump_if_not 11(18) (j@1 = 1)
-9 set str_j@3 _latin1'1'
+9 set str_j@3 '1'
10 jump 18
11 jump_if_not 14(18) (j@1 = 2)
-12 set str_j@3 _latin1'2'
+12 set str_j@3 '2'
13 jump 18
14 jump_if_not 17(18) (j@1 = 3)
-15 set str_j@3 _latin1'3'
+15 set str_j@3 '3'
16 jump 18
-17 set str_j@3 _latin1'unknown'
+17 set str_j@3 'unknown'
18 stmt 0 "select "i was 20""
19 jump 27
20 jump_if_not 23(27) (case_expr@0 = 30)
-21 set str_i@2 _latin1'30'
+21 set str_i@2 '30'
22 jump 27
23 jump_if_not 26(27) (case_expr@0 = 40)
-24 set str_i@2 _latin1'40'
+24 set str_i@2 '40'
25 jump 27
-26 set str_i@2 _latin1'unknown'
+26 set str_i@2 'unknown'
27 stmt 0 "SELECT str_i, str_j"
SHOW PROCEDURE CODE proc_19194_nested_2;
Pos Instruction
0 set str_i@2 NULL
1 set str_j@3 NULL
2 jump_if_not 5(27) (i@0 = 10)
-3 set str_i@2 _latin1'10'
+3 set str_i@2 '10'
4 jump 27
5 jump_if_not 20(27) (i@0 = 20)
-6 set str_i@2 _latin1'20'
+6 set str_i@2 '20'
7 set_case_expr (18) 0 j@1
8 jump_if_not 11(18) (case_expr@0 = 1)
-9 set str_j@3 _latin1'1'
+9 set str_j@3 '1'
10 jump 18
11 jump_if_not 14(18) (case_expr@0 = 2)
-12 set str_j@3 _latin1'2'
+12 set str_j@3 '2'
13 jump 18
14 jump_if_not 17(18) (case_expr@0 = 3)
-15 set str_j@3 _latin1'3'
+15 set str_j@3 '3'
16 jump 18
-17 set str_j@3 _latin1'unknown'
+17 set str_j@3 'unknown'
18 stmt 0 "select "i was 20""
19 jump 27
20 jump_if_not 23(27) (i@0 = 30)
-21 set str_i@2 _latin1'30'
+21 set str_i@2 '30'
22 jump 27
23 jump_if_not 26(27) (i@0 = 40)
-24 set str_i@2 _latin1'40'
+24 set str_i@2 '40'
25 jump 27
-26 set str_i@2 _latin1'unknown'
+26 set str_i@2 'unknown'
27 stmt 0 "SELECT str_i, str_j"
SHOW PROCEDURE CODE proc_19194_nested_3;
Pos Instruction
@@ -414,59 +414,59 @@ Pos Instruction
1 set str_j@3 NULL
2 set_case_expr (28) 0 i@0
3 jump_if_not 6(28) (case_expr@0 = 10)
-4 set str_i@2 _latin1'10'
+4 set str_i@2 '10'
5 jump 28
6 jump_if_not 21(28) (case_expr@0 = 20)
-7 set str_i@2 _latin1'20'
+7 set str_i@2 '20'
8 set_case_expr (19) 1 j@1
9 jump_if_not 12(19) (case_expr@1 = 1)
-10 set str_j@3 _latin1'1'
+10 set str_j@3 '1'
11 jump 19
12 jump_if_not 15(19) (case_expr@1 = 2)
-13 set str_j@3 _latin1'2'
+13 set str_j@3 '2'
14 jump 19
15 jump_if_not 18(19) (case_expr@1 = 3)
-16 set str_j@3 _latin1'3'
+16 set str_j@3 '3'
17 jump 19
-18 set str_j@3 _latin1'unknown'
+18 set str_j@3 'unknown'
19 stmt 0 "select "i was 20""
20 jump 28
21 jump_if_not 24(28) (case_expr@0 = 30)
-22 set str_i@2 _latin1'30'
+22 set str_i@2 '30'
23 jump 28
24 jump_if_not 27(28) (case_expr@0 = 40)
-25 set str_i@2 _latin1'40'
+25 set str_i@2 '40'
26 jump 28
-27 set str_i@2 _latin1'unknown'
+27 set str_i@2 'unknown'
28 stmt 0 "SELECT str_i, str_j"
SHOW PROCEDURE CODE proc_19194_nested_4;
Pos Instruction
0 set str_i@2 NULL
1 set str_j@3 NULL
2 jump_if_not 5(26) (i@0 = 10)
-3 set str_i@2 _latin1'10'
+3 set str_i@2 '10'
4 jump 26
5 jump_if_not 19(26) (i@0 = 20)
-6 set str_i@2 _latin1'20'
+6 set str_i@2 '20'
7 jump_if_not 10(17) (j@1 = 1)
-8 set str_j@3 _latin1'1'
+8 set str_j@3 '1'
9 jump 17
10 jump_if_not 13(17) (j@1 = 2)
-11 set str_j@3 _latin1'2'
+11 set str_j@3 '2'
12 jump 17
13 jump_if_not 16(17) (j@1 = 3)
-14 set str_j@3 _latin1'3'
+14 set str_j@3 '3'
15 jump 17
-16 set str_j@3 _latin1'unknown'
+16 set str_j@3 'unknown'
17 stmt 0 "select "i was 20""
18 jump 26
19 jump_if_not 22(26) (i@0 = 30)
-20 set str_i@2 _latin1'30'
+20 set str_i@2 '30'
21 jump 26
22 jump_if_not 25(26) (i@0 = 40)
-23 set str_i@2 _latin1'40'
+23 set str_i@2 '40'
24 jump 26
-25 set str_i@2 _latin1'unknown'
+25 set str_i@2 'unknown'
26 stmt 0 "SELECT str_i, str_j"
CALL proc_19194_nested_1(10, 1);
str_i str_j
@@ -793,7 +793,7 @@ end while;
end//
show procedure code proc_33618_h;
Pos Instruction
-0 set count1@1 _latin1'0'
+0 set count1@1 '0'
1 set vb@2 NULL
2 set last_row@3 NULL
3 jump_if_not 24(24) (num@0 >= 1)
@@ -818,7 +818,7 @@ Pos Instruction
22 jump 3
show procedure code proc_33618_c;
Pos Instruction
-0 set count1@1 _latin1'0'
+0 set count1@1 '0'
1 set vb@2 NULL
2 set last_row@3 NULL
3 jump_if_not 23(23) (num@0 >= 1)
diff --git a/mysql-test/r/ssl.result b/mysql-test/r/ssl.result
index 3622fb51c99..9ad515a53a3 100644
--- a/mysql-test/r/ssl.result
+++ b/mysql-test/r/ssl.result
@@ -1508,7 +1508,7 @@ explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
Warnings:
-Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> _latin1''))
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
diff --git a/mysql-test/r/ssl_compress.result b/mysql-test/r/ssl_compress.result
index 3018fce5cad..1bd427a65e2 100644
--- a/mysql-test/r/ssl_compress.result
+++ b/mysql-test/r/ssl_compress.result
@@ -1511,7 +1511,7 @@ explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 100.00 Using where
Warnings:
-Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> _latin1''))
+Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> ''))
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 20d44933128..1ef250aae99 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -393,13 +393,13 @@ EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
Warnings:
-Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = _latin1'2002-08-03')
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
Warnings:
-Note 1003 select (select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = _latin1'2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+Note 1003 select (select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
date
2002-08-03
@@ -540,13 +540,13 @@ EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = _latin1'1')
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select '3' AS `numreponse` from `test`.`t1` where (('1' = _latin1'1'))
+Note 1003 select '3' AS `numreponse` from `test`.`t1` where (('1' = '1'))
drop table t1;
CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
@@ -1024,7 +1024,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select (select encrypt(_latin1'test') AS `ENCRYPT('test')` from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+Note 1003 select (select encrypt('test') AS `ENCRYPT('test')` from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
@@ -1481,7 +1481,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
Warnings:
-Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < _latin1'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
drop table t1,t2;
create table t2 (a int, b int);
create table t3 (a int);
@@ -2820,19 +2820,19 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = _latin1'0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 Using where
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = _latin1'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`))))
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = 'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`))))
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary; Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where (`test`.`t2`.`flag` = _latin1'0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
DROP TABLE t1,t2;
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index 46724de4281..1c846700346 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -112,7 +112,7 @@ v1 CREATE TEMPORARY TABLE `v1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show create view v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'This is view' AS `A` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'This is view' AS `A` latin1 latin1_swedish_ci
drop view v1;
select * from v1;
A
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 8b384dfdc4e..e7f5c41513b 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2016,4 +2016,42 @@ i j
10 10
unlock tables;
drop table t1;
+drop table if exists t1, t2;
+drop trigger if exists trg1;
+drop trigger if exists trg2;
+create table t1 (a int);
+create table t2 (b int);
+create trigger trg1 after update on t1 for each row set @a= @a+1;
+create trigger trg2 after update on t2 for each row set @b= @b+1;
+insert into t1 values (1), (2), (3);
+insert into t2 values (1), (2), (3);
+set @a= 0;
+set @b= 0;
+update t1, t2 set t1.a= t1.a, t2.b= t2.b;
+select @a, @b;
+@a @b
+3 3
+update t1, t2 set t1.a= t2.b, t2.b= t1.a;
+select @a, @b;
+@a @b
+6 6
+update t1 set a= a;
+select @a, @b;
+@a @b
+9 6
+update t2 set b= b;
+select @a, @b;
+@a @b
+9 9
+update t1 set a= 1;
+select @a, @b;
+@a @b
+12 9
+update t2 set b= 1;
+select @a, @b;
+@a @b
+12 12
+drop trigger trg1;
+drop trigger trg2;
+drop table t1, t2;
End of 5.1 tests.
diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result
index c98c8c5b68c..7cf85b9b315 100644
--- a/mysql-test/r/type_blob.result
+++ b/mysql-test/r/type_blob.result
@@ -519,7 +519,7 @@ coercibility(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select charset(load_file(_latin1'MYSQLTEST_VARDIR/std_data_ln/words.dat')) AS `charset(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat'))`,collation(load_file(_latin1'MYSQLTEST_VARDIR/std_data_ln/words.dat')) AS `collation(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat'))`,coercibility(load_file(_latin1'MYSQLTEST_VARDIR/std_data_ln/words.dat')) AS `coercibility(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat'))`
+Note 1003 select charset(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat')) AS `charset(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat'))`,collation(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat')) AS `collation(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat'))`,coercibility(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat')) AS `coercibility(load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat'))`
update t1 set imagem=load_file('MYSQLTEST_VARDIR/std_data_ln/words.dat') where id=1;
select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1;
if(imagem is null, "ERROR", "OK") length(imagem)
diff --git a/mysql-test/r/variables_debug.result b/mysql-test/r/variables_debug.result
new file mode 100644
index 00000000000..9cd133dddb1
--- /dev/null
+++ b/mysql-test/r/variables_debug.result
@@ -0,0 +1,12 @@
+set debug= 'T';
+select @@debug;
+@@debug
+T
+set debug= '+P';
+select @@debug;
+@@debug
+P:T
+set debug= '-P';
+select @@debug;
+@@debug
+T
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 09b997797b4..0e89210cb60 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -3061,7 +3061,7 @@ TheEnd
TheEnd
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 'The\ZEnd' AS `TheEnd` latin1 latin1_swedish_ci
DROP VIEW v1;
CREATE TABLE t1 (mydate DATETIME);
INSERT INTO t1 VALUES
@@ -3613,7 +3613,26 @@ ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default val
set @@sql_mode=@old_mode;
drop view v1;
drop table t1;
-End of 5.0 tests.
+# -----------------------------------------------------------------
+# -- Bug#34337: Server crash when Altering a view using a table name.
+# -----------------------------------------------------------------
+
+DROP TABLE IF EXISTS t1;
+
+CREATE TABLE t1(c1 INT);
+
+SELECT * FROM t1;
+c1
+ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1);
+ERROR HY000: 'test.t1' is not VIEW
+
+DROP TABLE t1;
+
+# -- End of test case for Bug#34337.
+
+# -----------------------------------------------------------------
+# -- End of 5.0 tests.
+# -----------------------------------------------------------------
DROP DATABASE IF EXISTS `d-1`;
CREATE DATABASE `d-1`;
USE `d-1`;
@@ -3676,4 +3695,59 @@ DROP TABLE t1;
# End of test case for Bug#26676.
-End of 5.1 tests.
+# -----------------------------------------------------------------
+# -- Bug#32538: View definition picks up character set, but not collation
+# -----------------------------------------------------------------
+
+DROP VIEW IF EXISTS v1;
+
+SET collation_connection = latin1_general_ci;
+CREATE VIEW v1 AS SELECT _latin1 'text1' AS c1, 'text2' AS c2;
+
+SELECT COLLATION(c1), COLLATION(c2) FROM v1;
+COLLATION(c1) COLLATION(c2)
+latin1_swedish_ci latin1_general_ci
+
+SHOW CREATE VIEW v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'text1' AS `c1`,'text2' AS `c2` latin1 latin1_general_ci
+
+SELECT * FROM v1 WHERE c1 = 'text1';
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin1_general_ci,COERCIBLE) for operation '='
+
+SELECT * FROM v1 WHERE c2 = 'text2';
+c1 c2
+text1 text2
+
+use test;
+SET names latin1;
+
+SELECT COLLATION(c1), COLLATION(c2) FROM v1;
+COLLATION(c1) COLLATION(c2)
+latin1_swedish_ci latin1_general_ci
+
+SELECT * FROM v1 WHERE c1 = 'text1';
+c1 c2
+text1 text2
+
+SELECT * FROM v1 WHERE c2 = 'text2';
+ERROR HY000: Illegal mix of collations (latin1_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '='
+
+DROP VIEW v1;
+
+# -- End of test case for Bug#32538.
+
+drop view if exists a;
+drop procedure if exists p;
+create procedure p()
+begin
+declare continue handler for sqlexception begin end;
+create view a as select 1;
+end|
+call p();
+call p();
+drop view a;
+drop procedure p;
+# -----------------------------------------------------------------
+# -- End of 5.1 tests.
+# -----------------------------------------------------------------
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index c301953f508..133fb5600bf 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -469,6 +469,7 @@ use test;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
drop database mysqltest;
drop view if exists v1;
+drop table if exists t1;
create table t1 as select * from mysql.user where user='';
delete from mysql.user where user='';
flush privileges;
diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
index 63bab2c1169..fa979dd7ac1 100644
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
@@ -379,7 +379,7 @@ master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t2)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; DROP TABLE t2
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
@@ -391,7 +391,7 @@ master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE table t2
-master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
diff --git a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result
index 20e9bf6283e..a96d2fd1bab 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result
@@ -73,7 +73,7 @@ explain extended select * from t1 where MATCH(a,b) AGAINST ("collections");
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 fulltext a a 0 1 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (match `test`.`t1`.`a`,`test`.`t1`.`b` against (_latin1'collections'))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (match `test`.`t1`.`a`,`test`.`t1`.`b` against ('collections'))
select * from t1 where MATCH(a,b) AGAINST ("indexes");
a b
Full-text indexes are called collections
diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
index 39927a8d866..50849e0887b 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
@@ -251,7 +251,7 @@ master-bin.000001 # Query # # use `test`; drop table t1,t2
master-bin.000001 # Query # # use `test`; create temporary table ti (a int) engine=innodb
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; insert into ti values(1)
-master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; create temporary table t1 (a int) engine=myisam
master-bin.000001 # Query # # use `test`; insert t1 values (1)
master-bin.000001 # Query # # use `test`; create table t0 (n int)
@@ -358,11 +358,11 @@ master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (8,8)
master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (9,9)
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE table t2
-master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (10,10)
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t2 values (100,100)
-master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; DROP TABLE t1,t2
reset master;
create table t1 (a int) engine=innodb;
diff --git a/mysql-test/suite/rpl/r/rpl_get_lock.result b/mysql-test/suite/rpl/r/rpl_get_lock.result
index 235640acad0..f7c9541bd9f 100644
--- a/mysql-test/suite/rpl/r/rpl_get_lock.result
+++ b/mysql-test/suite/rpl/r/rpl_get_lock.result
@@ -25,7 +25,7 @@ explain extended select is_free_lock("lock"), is_used_lock("lock");
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select is_free_lock(_latin1'lock') AS `is_free_lock("lock")`,is_used_lock(_latin1'lock') AS `is_used_lock("lock")`
+Note 1003 select is_free_lock('lock') AS `is_free_lock("lock")`,is_used_lock('lock') AS `is_used_lock("lock")`
select is_free_lock("lock2");
is_free_lock("lock2")
1
diff --git a/mysql-test/suite/rpl/r/rpl_master_pos_wait.result b/mysql-test/suite/rpl/r/rpl_master_pos_wait.result
index 951e944fddc..ab9b8cdad9d 100644
--- a/mysql-test/suite/rpl/r/rpl_master_pos_wait.result
+++ b/mysql-test/suite/rpl/r/rpl_master_pos_wait.result
@@ -11,7 +11,7 @@ explain extended select master_pos_wait('master-bin.999999',0,2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select master_pos_wait(_latin1'master-bin.999999',0,2) AS `master_pos_wait('master-bin.999999',0,2)`
+Note 1003 select master_pos_wait('master-bin.999999',0,2) AS `master_pos_wait('master-bin.999999',0,2)`
select master_pos_wait('master-bin.999999',0);
stop slave sql_thread;
master_pos_wait('master-bin.999999',0)
diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def
index 9fd63d2e72e..ebc99feeac6 100644
--- a/mysql-test/suite/rpl_ndb/t/disabled.def
+++ b/mysql-test/suite/rpl_ndb/t/disabled.def
@@ -10,6 +10,7 @@
#
##############################################################################
-
+rpl_ndb_circular : Bug#33849 COMMIT event missing in cluster circular replication.
+rpl_ndb_circular_simplex : Bug#33849 COMMIT event missing in cluster circular replication.
# the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
diff --git a/mysql-test/t/change_user.test b/mysql-test/t/change_user.test
index d0cdfc8a741..82aeb4da4af 100644
--- a/mysql-test/t/change_user.test
+++ b/mysql-test/t/change_user.test
@@ -33,3 +33,14 @@ SELECT IS_USED_LOCK('bug31418') = CONNECTION_ID();
--change_user
SELECT IS_FREE_LOCK('bug31418');
SELECT IS_USED_LOCK('bug31418');
+
+#
+# Bug#31222: com_% global status counters behave randomly with
+# mysql_change_user.
+#
+# Moved to not_embedded_server.test due to Bug#34517: SHOW GLOBAL STATUS does
+# not work properly in embedded server.
+#
+# TODO: move it back when Bug#34517 is fixed (don't forget to add
+# --force-restart into change_user-master.opt).
+#
diff --git a/mysql-test/t/commit_1innodb.test b/mysql-test/t/commit_1innodb.test
new file mode 100644
index 00000000000..c4a29acdddd
--- /dev/null
+++ b/mysql-test/t/commit_1innodb.test
@@ -0,0 +1,6 @@
+-- source include/have_log_bin.inc
+-- source include/have_innodb.inc
+
+let $engine_type = InnoDB;
+
+-- source include/commit.inc
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 09170cbc4f5..8912fd46b42 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1385,4 +1385,68 @@ DROP TABLE t2;
--echo # -- End of test case for Bug#21380.
--echo
+--echo # --
+--echo # -- Bug#18834: ALTER TABLE ADD INDEX on table with two timestamp fields
+--echo # --
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+--enable_warnings
+
+--echo
+
+CREATE TABLE t1(c1 TIMESTAMP, c2 TIMESTAMP);
+
+--echo
+
+SET sql_mode = NO_ZERO_DATE;
+
+--echo
+--error ER_INVALID_DEFAULT
+CREATE TABLE t2(c1 TIMESTAMP, c2 TIMESTAMP DEFAULT 0);
+
+--echo
+--error ER_INVALID_DEFAULT
+CREATE TABLE t2(c1 TIMESTAMP, c2 TIMESTAMP);
+
+--echo
+--echo # -- Check that NULL column still can be created.
+CREATE TABLE t2(c1 TIMESTAMP NULL);
+
+--echo
+--echo # -- Check ALTER TABLE.
+--error ER_INVALID_DEFAULT
+ALTER TABLE t1 ADD INDEX(c1);
+
+--echo
+--echo # -- Check DATETIME.
+SET sql_mode = '';
+
+--echo
+
+CREATE TABLE t3(c1 DATETIME NOT NULL);
+INSERT INTO t3 VALUES (0);
+
+--echo
+SET sql_mode = TRADITIONAL;
+
+--echo
+--error ER_TRUNCATED_WRONG_VALUE
+ALTER TABLE t3 ADD INDEX(c1);
+
+--echo
+--echo # -- Cleanup.
+
+SET sql_mode = '';
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+--echo
+--echo # -- End of Bug#18834.
+--echo
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/ddl_i18n_koi8r.test b/mysql-test/t/ddl_i18n_koi8r.test
index 1d16adbad55..e3bed098126 100644
--- a/mysql-test/t/ddl_i18n_koi8r.test
+++ b/mysql-test/t/ddl_i18n_koi8r.test
@@ -85,6 +85,10 @@ CREATE VIEW v2 AS SELECT _utf8'теÑÑ‚' as c1|
--echo
+CREATE VIEW v3 AS SELECT _utf8'теÑÑ‚'|
+
+--echo
+
#
# First-round checks.
#
@@ -120,6 +124,7 @@ SET @@collation_connection= cp1251_general_ci|
--disable_result_log
SELECT * FROM mysqltest1.v1|
SELECT * FROM mysqltest1.v2|
+SELECT * FROM mysqltest1.v3|
--enable_result_log
use mysqltest1|
@@ -168,7 +173,7 @@ DROP DATABASE mysqltest1|
--echo
--echo ---> connection: con3
-# - Switch environment variables and trigger loading stored procedures;
+# - Switch environment variables and trigger loading views;
SET @@character_set_client= cp1251|
SET @@character_set_results= cp1251|
@@ -177,6 +182,7 @@ SET @@collation_connection= cp1251_general_ci|
--disable_result_log
SELECT * FROM mysqltest1.v1|
SELECT * FROM mysqltest1.v2|
+SELECT * FROM mysqltest1.v3|
--enable_result_log
use mysqltest1|
diff --git a/mysql-test/t/ddl_i18n_utf8.test b/mysql-test/t/ddl_i18n_utf8.test
index c80137a58b5..d76debcba5b 100644
--- a/mysql-test/t/ddl_i18n_utf8.test
+++ b/mysql-test/t/ddl_i18n_utf8.test
@@ -85,6 +85,10 @@ CREATE VIEW v2 AS SELECT _koi8r'ÔÅÓÔ' as c1|
--echo
+CREATE VIEW v3 AS SELECT _koi8r'ÔÅÓÔ'|
+
+--echo
+
#
# First-round checks.
#
@@ -120,6 +124,7 @@ SET @@collation_connection= cp1251_general_ci|
--disable_result_log
SELECT * FROM mysqltest1.v1|
SELECT * FROM mysqltest1.v2|
+SELECT * FROM mysqltest1.v3|
--enable_result_log
use mysqltest1|
@@ -168,7 +173,7 @@ DROP DATABASE mysqltest1|
--echo
--echo ---> connection: con3
-# - Switch environment variables and trigger loading stored procedures;
+# - Switch environment variables and trigger loading views;
SET @@character_set_client= cp1251|
SET @@character_set_results= cp1251|
@@ -177,6 +182,7 @@ SET @@collation_connection= cp1251_general_ci|
--disable_result_log
SELECT * FROM mysqltest1.v1|
SELECT * FROM mysqltest1.v2|
+SELECT * FROM mysqltest1.v3|
--enable_result_log
use mysqltest1|
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index ac8fc5041de..8ec9cf36751 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -16,11 +16,9 @@ ctype_big5 : BUG#26711 2007-06-21 Lars Test has never worked on Do
federated_transactions : Bug#29523 Transactions do not work
lowercase_table3 : Bug#32667 lowercase_table3.test reports to error log
-kill : Bug#29149: Test "kill" fails on Windows
innodb_mysql : Bug#32724: innodb_mysql.test fails randomly
wait_timeout : Bug#32801 wait_timeout.test fails randomly
ctype_create : Bug#32965 main.ctype_create fails
status : Bug#32966 main.status fails
ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166
csv_alter_table : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL columns in CSV tables
-query_cache_debug : Bug#34424: query_cache_debug.test leads to valgrind warnings
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index 3da4232502d..b7e1e82fe5d 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -6,6 +6,10 @@
#
-- source include/not_embedded.inc
+# Disable concurrent inserts to avoid test failures when reading the
+# connection id which was inserted into a table by another thread.
+set @@global.concurrent_insert= 0;
+
connect (con1, localhost, root,,);
connect (con2, localhost, root,,);
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 06488abb1ae..54c2e4e76ee 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -396,6 +396,9 @@ unlock tables;
connection insert;
--reap
connection default;
+let $wait_condition=
+ select count(*) = 1 from t1;
+--source include/wait_condition.inc
select * from t1;
drop table t1;
disconnect flush;
diff --git a/mysql-test/t/mysql_client_test-master.opt b/mysql-test/t/mysql_client_test-master.opt
index 2dfcc4a2fb9..4c683f7f0a2 100644
--- a/mysql-test/t/mysql_client_test-master.opt
+++ b/mysql-test/t/mysql_client_test-master.opt
@@ -1 +1 @@
---log=$MYSQLTEST_VARDIR/log/master.log --log-output=FILE
+--log=$MYSQLTEST_VARDIR/log/master.log --log-output=FILE,TABLE
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 0e4e9989ffa..6cbe345bc8a 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1799,6 +1799,61 @@ create table test (a int);
drop database `test-database`;
use test;
+###########################################################################
+
+--echo
+--echo # -----------------------------------------------------------------
+--echo # -- Bug#30217: Views: changes in metadata behaviour between 5.0 and 5.1.
+--echo # -----------------------------------------------------------------
+--echo
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqldump_test_db;
+--enable_warnings
+
+CREATE DATABASE mysqldump_test_db;
+use mysqldump_test_db;
+
+--echo
+
+CREATE VIEW v1(x, y) AS SELECT 'a', 'a';
+
+--echo
+
+SELECT view_definition
+FROM INFORMATION_SCHEMA.VIEWS
+WHERE table_schema = 'mysqldump_test_db' AND table_name = 'v1';
+
+--echo
+
+--echo ---> Dumping mysqldump_test_db to bug30217.sql
+--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --databases mysqldump_test_db > $MYSQLTEST_VARDIR/tmp/bug30217.sql
+
+--echo
+
+DROP DATABASE mysqldump_test_db;
+use test;
+
+--echo
+
+--echo ---> Restoring mysqldump_test_db...
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug30217.sql
+
+--echo
+
+SELECT view_definition
+FROM INFORMATION_SCHEMA.VIEWS
+WHERE table_schema = 'mysqldump_test_db' AND table_name = 'v1';
+
+--echo
+
+DROP DATABASE mysqldump_test_db;
+
+--echo
+--echo # -- End of test case for Bug#32538.
+--echo
+
+###########################################################################
--echo #
--echo # End of 5.1 tests
diff --git a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test
index 5beee5967a3..ffc13cf80f7 100644
--- a/mysql-test/t/not_embedded_server.test
+++ b/mysql-test/t/not_embedded_server.test
@@ -20,4 +20,38 @@ prepare stmt1 from ' SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND!
execute stmt1;
deallocate prepare stmt1;
+
+#
+# Bug#31222: com_% global status counters behave randomly with
+# mysql_change_user.
+#
+# Moved from change_user.test due to Bug#34517: SHOW GLOBAL STATUS does not
+# work properly in embedded server.
+#
+# TODO: move it back when Bug#34517 is fixed.
+#
+
+FLUSH STATUS;
+
+--disable_result_log
+--disable_query_log
+
+let $i = 100;
+
+while ($i)
+{
+ dec $i;
+
+ SELECT 1;
+}
+
+--enable_query_log
+--enable_result_log
+
+SHOW GLOBAL STATUS LIKE 'com_select';
+
+--change_user
+
+SHOW GLOBAL STATUS LIKE 'com_select';
+
# End of 5.1 tests
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index a34d41a6dfb..bc784412392 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -1838,6 +1838,129 @@ select * from t1 where a = @a and b = @b;
deallocate prepare stmt;
drop table t1;
+#
+# Bug#32890 Crash after repeated create and drop of tables and views
+#
+
+--disable_warnings
+drop view if exists v1;
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (a int, b int);
+insert into t1 values (1,1), (2,2), (3,3);
+insert into t1 values (3,1), (1,2), (2,3);
+
+prepare stmt from "create view v1 as select * from t1";
+execute stmt;
+drop table t1;
+create table t1 (a int, b int);
+drop view v1;
+execute stmt;
+show create view v1;
+drop view v1;
+
+prepare stmt from "create view v1 (c,d) as select a,b from t1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 (c) as select b+1 from t1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 (c,d,e,f) as select a,b,a in (select a+2 from t1), a = all (select a from t1) from t1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create or replace view v1 as select 1";
+execute stmt;
+show create view v1;
+select * from v1;
+execute stmt;
+show create view v1;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 as select 1, 1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 (x) as select a from t1 where a > 1";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 as select * from `t1` `b`";
+execute stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+execute stmt;
+deallocate prepare stmt;
+show create view v1;
+select * from v1;
+drop view v1;
+
+prepare stmt from "create view v1 (a,b,c) as select * from t1";
+--error ER_VIEW_WRONG_LIST
+execute stmt;
+--error ER_VIEW_WRONG_LIST
+execute stmt;
+deallocate prepare stmt;
+
+drop table t1;
+create temporary table t1 (a int, b int);
+
+prepare stmt from "create view v1 as select * from t1";
+--error ER_VIEW_SELECT_TMPTABLE
+execute stmt;
+--error ER_VIEW_SELECT_TMPTABLE
+execute stmt;
+deallocate prepare stmt;
+
+drop table t1;
+
+--error ER_NO_SUCH_TABLE
+prepare stmt from "create view v1 as select * from t1";
+--error ER_NO_SUCH_TABLE
+prepare stmt from "create view v1 as select * from `t1` `b`";
+
--echo End of 5.0 tests.
#
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 1aeac91e5ad..921c9579bfb 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2304,4 +2304,37 @@ unlock tables;
drop table t1;
+#
+# Bug#23771 AFTER UPDATE trigger not invoked when there are no changes of the data
+#
+
+--disable_warnings
+drop table if exists t1, t2;
+drop trigger if exists trg1;
+drop trigger if exists trg2;
+--enable_warnings
+create table t1 (a int);
+create table t2 (b int);
+create trigger trg1 after update on t1 for each row set @a= @a+1;
+create trigger trg2 after update on t2 for each row set @b= @b+1;
+insert into t1 values (1), (2), (3);
+insert into t2 values (1), (2), (3);
+set @a= 0;
+set @b= 0;
+update t1, t2 set t1.a= t1.a, t2.b= t2.b;
+select @a, @b;
+update t1, t2 set t1.a= t2.b, t2.b= t1.a;
+select @a, @b;
+update t1 set a= a;
+select @a, @b;
+update t2 set b= b;
+select @a, @b;
+update t1 set a= 1;
+select @a, @b;
+update t2 set b= 1;
+select @a, @b;
+drop trigger trg1;
+drop trigger trg2;
+drop table t1, t2;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/variables_debug.test b/mysql-test/t/variables_debug.test
new file mode 100644
index 00000000000..7dcaf246803
--- /dev/null
+++ b/mysql-test/t/variables_debug.test
@@ -0,0 +1,12 @@
+--source include/have_debug.inc
+
+#
+# Bug#34678 @@debug variable's incremental mode
+#
+
+set debug= 'T';
+select @@debug;
+set debug= '+P';
+select @@debug;
+set debug= '-P';
+select @@debug;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 58ef9c1eff1..f337bcdaf89 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -3468,7 +3468,41 @@ set @@sql_mode=@old_mode;
drop view v1;
drop table t1;
---echo End of 5.0 tests.
+###########################################################################
+
+--echo # -----------------------------------------------------------------
+--echo # -- Bug#34337: Server crash when Altering a view using a table name.
+--echo # -----------------------------------------------------------------
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo
+
+CREATE TABLE t1(c1 INT);
+
+--echo
+
+SELECT * FROM t1;
+
+--error ER_WRONG_OBJECT
+ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1);
+
+--echo
+
+DROP TABLE t1;
+
+--echo
+--echo # -- End of test case for Bug#34337.
+--echo
+
+###########################################################################
+
+--echo # -----------------------------------------------------------------
+--echo # -- End of 5.0 tests.
+--echo # -----------------------------------------------------------------
#
# Bug#21370 View renaming lacks tablename_to_filename encoding
@@ -3540,4 +3574,88 @@ DROP TABLE t1;
--echo # End of test case for Bug#26676.
--echo
---echo End of 5.1 tests.
+###########################################################################
+
+--echo # -----------------------------------------------------------------
+--echo # -- Bug#32538: View definition picks up character set, but not collation
+--echo # -----------------------------------------------------------------
+--echo
+
+--disable_warnings
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+--echo
+
+SET collation_connection = latin1_general_ci;
+CREATE VIEW v1 AS SELECT _latin1 'text1' AS c1, 'text2' AS c2;
+
+--echo
+
+SELECT COLLATION(c1), COLLATION(c2) FROM v1;
+
+--echo
+
+SHOW CREATE VIEW v1;
+
+--echo
+
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM v1 WHERE c1 = 'text1';
+
+--echo
+
+SELECT * FROM v1 WHERE c2 = 'text2';
+
+--echo
+
+use test;
+SET names latin1;
+
+--echo
+
+SELECT COLLATION(c1), COLLATION(c2) FROM v1;
+
+--echo
+
+SELECT * FROM v1 WHERE c1 = 'text1';
+
+--echo
+
+--error ER_CANT_AGGREGATE_2COLLATIONS
+SELECT * FROM v1 WHERE c2 = 'text2';
+
+--echo
+
+DROP VIEW v1;
+
+--echo
+--echo # -- End of test case for Bug#32538.
+--echo
+
+#
+# Bug#34587 Creating a view inside a stored procedure leads to a server crash
+#
+
+--disable_warnings
+drop view if exists a;
+drop procedure if exists p;
+--enable_warnings
+
+delimiter |;
+create procedure p()
+begin
+ declare continue handler for sqlexception begin end;
+ create view a as select 1;
+end|
+delimiter ;|
+call p();
+call p();
+drop view a;
+drop procedure p;
+
+###########################################################################
+
+--echo # -----------------------------------------------------------------
+--echo # -- End of 5.1 tests.
+--echo # -----------------------------------------------------------------
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 3be0148f765..cbc66300173 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -614,6 +614,7 @@ drop database mysqltest;
#
--disable_warnings
drop view if exists v1;
+drop table if exists t1;
--enable_warnings
# Backup anonymous users and remove them. (They get in the way of
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 1ba6e5ac92d..933674fa007 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -332,6 +332,7 @@ void my_thread_end(void)
/* tmp->dbug is allocated inside DBUG library */
if (tmp->dbug)
{
+ DBUG_POP();
free(tmp->dbug);
tmp->dbug=0;
}
diff --git a/sql-common/client.c b/sql-common/client.c
index a26207038cf..f4d587d4df3 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -2736,7 +2736,15 @@ get_info:
#ifdef MYSQL_CLIENT
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
{
- int error=handle_local_infile(mysql,(char*) pos);
+ int error;
+
+ if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES))
+ {
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ DBUG_RETURN(1);
+ }
+
+ error= handle_local_infile(mysql,(char*) pos);
if ((length= cli_safe_read(mysql)) == packet_error || error)
DBUG_RETURN(1);
goto get_info; /* Get info packet */
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index 898fc206c34..719a837cbfb 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -60,8 +60,16 @@ extern "C" int event_queue_element_compare_q(void *, uchar *, uchar *);
int event_queue_element_compare_q(void *vptr, uchar* a, uchar *b)
{
- my_time_t lhs = ((Event_queue_element *)a)->execute_at;
- my_time_t rhs = ((Event_queue_element *)b)->execute_at;
+ Event_queue_element *left = (Event_queue_element *)a;
+ Event_queue_element *right = (Event_queue_element *)b;
+ my_time_t lhs = left->execute_at;
+ my_time_t rhs = right->execute_at;
+
+ if (left->status == Event_queue_element::DISABLED)
+ return right->status != Event_queue_element::DISABLED;
+
+ if (right->status == Event_queue_element::DISABLED)
+ return 1;
return (lhs < rhs ? -1 : (lhs > rhs ? 1 : 0));
}
@@ -434,8 +442,34 @@ Event_queue::recalculate_activation_times(THD *thd)
((Event_queue_element*)queue_element(&queue, i))->update_timing_fields(thd);
}
queue_fix(&queue);
+ /*
+ The disabled elements are moved to the end during the `fix`.
+ Start from the end and remove all of the elements which are
+ disabled. When we find the first non-disabled one we break, as we
+ have removed all. The queue has been ordered in a way the disabled
+ events are at the end.
+ */
+ for (i= queue.elements; i > 0; i--)
+ {
+ Event_queue_element *element = (Event_queue_element*)queue_element(&queue, i - 1);
+ if (element->status != Event_queue_element::DISABLED)
+ break;
+ /*
+ This won't cause queue re-order, because we remove
+ always the last element.
+ */
+ queue_remove(&queue, i - 1);
+ delete element;
+ }
UNLOCK_QUEUE_DATA();
+ /*
+ XXX: The events are dropped only from memory and not from disk
+ even if `drop_list[j]->dropped` is TRUE. There will be still on the
+ disk till next server restart.
+ Please add code here to do it.
+ */
+
DBUG_VOID_RETURN;
}
diff --git a/sql/events.cc b/sql/events.cc
index 87385082a82..4225ca055de 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -737,7 +737,7 @@ send_show_create_event(THD *thd, Event_timed *et, Protocol *protocol)
if (protocol->write())
DBUG_RETURN(TRUE);
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -1185,7 +1185,12 @@ Events::load_events_from_db(THD *thd)
{
/*
If not created, a stale event - drop if immediately if
- ON COMPLETION NOT PRESERVE
+ ON COMPLETION NOT PRESERVE.
+ XXX: This won't be replicated, thus the drop won't appear in
+ in the slave. When the slave is restarted it will drop events.
+ However, as the slave will be "out of sync", it might happen that
+ an event created on the master, after master restart, won't be
+ replicated to the slave correctly, as the create will fail there.
*/
int rc= table->file->ha_delete_row(table->record[0]);
if (rc)
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index fdee8f92331..1cfe403407e 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -9454,7 +9454,7 @@ ha_ndbcluster::cond_push(const COND *cond)
my_errno= HA_ERR_OUT_OF_MEM;
DBUG_RETURN(NULL);
}
- DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname););
+ DBUG_EXECUTE("where",print_where((COND *)cond, m_tabname, QT_ORDINARY););
DBUG_RETURN(m_cond->cond_push(cond, table, (NDBTAB *)m_table));
}
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index fc1568a5ea6..4fd5ee1b402 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -283,6 +283,7 @@ static void run_query(THD *thd, char *buf, char *end,
thd_ndb->m_error_code,
(int) thd->is_error(), thd->is_slave_error);
}
+ close_thread_tables(thd);
/*
XXX: this code is broken. mysql_parse()/mysql_reset_thd_for_next_command()
can not be called from within a statement, and
diff --git a/sql/handler.cc b/sql/handler.cc
index eba9b0dc5ea..0fb61895a61 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -576,6 +576,295 @@ void ha_close_connection(THD* thd)
======================= TRANSACTIONS ===================================*/
/**
+ Transaction handling in the server
+ ==================================
+
+ In each client connection, MySQL maintains two transactional
+ states:
+ - a statement transaction,
+ - a standard, also called normal transaction.
+
+ Historical note
+ ---------------
+ "Statement transaction" is a non-standard term that comes
+ from the times when MySQL supported BerkeleyDB storage engine.
+
+ First of all, it should be said that in BerkeleyDB auto-commit
+ mode auto-commits operations that are atomic to the storage
+ engine itself, such as a write of a record, and are too
+ high-granular to be atomic from the application perspective
+ (MySQL). One SQL statement could involve many BerkeleyDB
+ auto-committed operations and thus BerkeleyDB auto-commit was of
+ little use to MySQL.
+
+ Secondly, instead of SQL standard savepoints, BerkeleyDB
+ provided the concept of "nested transactions". In a nutshell,
+ transactions could be arbitrarily nested, but when the parent
+ transaction was committed or aborted, all its child (nested)
+ transactions were handled committed or aborted as well.
+ Commit of a nested transaction, in turn, made its changes
+ visible, but not durable: it destroyed the nested transaction,
+ all its changes would become available to the parent and
+ currently active nested transactions of this parent.
+
+ So the mechanism of nested transactions was employed to
+ provide "all or nothing" guarantee of SQL statements
+ required by the standard.
+ A nested transaction would be created at start of each SQL
+ statement, and destroyed (committed or aborted) at statement
+ end. Such nested transaction was internally referred to as
+ a "statement transaction" and gave birth to the term.
+
+ <Historical note ends>
+
+ Since then a statement transaction is started for each statement
+ that accesses transactional tables or uses the binary log. If
+ the statement succeeds, the statement transaction is committed.
+ If the statement fails, the transaction is rolled back. Commits
+ of statement transactions are not durable -- each such
+ transaction is nested in the normal transaction, and if the
+ normal transaction is rolled back, the effects of all enclosed
+ statement transactions are undone as well. Technically,
+ a statement transaction can be viewed as a savepoint which is
+ maintained automatically in order to make effects of one
+ statement atomic.
+
+ The normal transaction is started by the user and is ended
+ usually upon a user request as well. The normal transaction
+ encloses transactions of all statements issued between
+ its beginning and its end.
+ In autocommit mode, the normal transaction is equivalent
+ to the statement transaction.
+
+ Since MySQL supports PSEA (pluggable storage engine
+ architecture), more than one transactional engine can be
+ active at a time. Hence transactions, from the server
+ point of view, are always distributed. In particular,
+ transactional state is maintained independently for each
+ engine. In order to commit a transaction the two phase
+ commit protocol is employed.
+
+ Not all statements are executed in context of a transaction.
+ Administrative and status information statements do not modify
+ engine data, and thus do not start a statement transaction and
+ also have no effect on the normal transaction. Examples of such
+ statements are SHOW STATUS and RESET SLAVE.
+
+ Similarly DDL statements are not transactional,
+ and therefore a transaction is [almost] never started for a DDL
+ statement. The difference between a DDL statement and a purely
+ administrative statement though is that a DDL statement always
+ commits the current transaction before proceeding, if there is
+ any.
+
+ At last, SQL statements that work with non-transactional
+ engines also have no effect on the transaction state of the
+ connection. Even though they are written to the binary log,
+ and the binary log is, overall, transactional, the writes
+ are done in "write-through" mode, directly to the binlog
+ file, followed with a OS cache sync, in other words,
+ bypassing the binlog undo log (translog).
+ They do not commit the current normal transaction.
+ A failure of a statement that uses non-transactional tables
+ would cause a rollback of the statement transaction, but
+ in case there no non-transactional tables are used,
+ no statement transaction is started.
+
+ Data layout
+ -----------
+
+ The server stores its transaction-related data in
+ thd->transaction. This structure has two members of type
+ THD_TRANS. These members correspond to the statement and
+ normal transactions respectively:
+
+ - thd->transaction.stmt contains a list of engines
+ that are participating in the given statement
+ - thd->transaction.all contains a list of engines that
+ have participated in any of the statement transactions started
+ within the context of the normal transaction.
+ Each element of the list contains a pointer to the storage
+ engine, engine-specific transactional data, and engine-specific
+ transaction flags.
+
+ In autocommit mode thd->transaction.all is empty.
+ Instead, data of thd->transaction.stmt is
+ used to commit/rollback the normal transaction.
+
+ The list of registered engines has a few important properties:
+ - no engine is registered in the list twice
+ - engines are present in the list a reverse temporal order --
+ new participants are always added to the beginning of the list.
+
+ Transaction life cycle
+ ----------------------
+
+ When a new connection is established, thd->transaction
+ members are initialized to an empty state.
+ If a statement uses any tables, all affected engines
+ are registered in the statement engine list. In
+ non-autocommit mode, the same engines are registered in
+ the normal transaction list.
+ At the end of the statement, the server issues a commit
+ or a roll back for all engines in the statement list.
+ At this point transaction flags of an engine, if any, are
+ propagated from the statement list to the list of the normal
+ transaction.
+ When commit/rollback is finished, the statement list is
+ cleared. It will be filled in again by the next statement,
+ and emptied again at the next statement's end.
+
+ The normal transaction is committed in a similar way
+ (by going over all engines in thd->transaction.all list)
+ but at different times:
+ - upon COMMIT SQL statement is issued by the user
+ - implicitly, by the server, at the beginning of a DDL statement
+ or SET AUTOCOMMIT={0|1} statement.
+
+ The normal transaction can be rolled back as well:
+ - if the user has requested so, by issuing ROLLBACK SQL
+ statement
+ - if one of the storage engines requested a rollback
+ by setting thd->transaction_rollback_request. This may
+ happen in case, e.g., when the transaction in the engine was
+ chosen a victim of the internal deadlock resolution algorithm
+ and rolled back internally. When such a situation happens, there
+ is little the server can do and the only option is to rollback
+ transactions in all other participating engines. In this case
+ the rollback is accompanied by an error sent to the user.
+
+ As follows from the use cases above, the normal transaction
+ is never committed when there is an outstanding statement
+ transaction. In most cases there is no conflict, since
+ commits of the normal transaction are issued by a stand-alone
+ administrative or DDL statement, thus no outstanding statement
+ transaction of the previous statement exists. Besides,
+ all statements that manipulate with the normal transaction
+ are prohibited in stored functions and triggers, therefore
+ no conflicting situation can occur in a sub-statement either.
+ The remaining rare cases when the server explicitly has
+ to commit the statement transaction prior to committing the normal
+ one cover error-handling scenarios (see for example
+ SQLCOM_LOCK_TABLES).
+
+ When committing a statement or a normal transaction, the server
+ either uses the two-phase commit protocol, or issues a commit
+ in each engine independently. The two-phase commit protocol
+ is used only if:
+ - all participating engines support two-phase commit (provide
+ handlerton::prepare PSEA API call) and
+ - transactions in at least two engines modify data (i.e. are
+ not read-only).
+
+ Note that the two phase commit is used for
+ statement transactions, even though they are not durable anyway.
+ This is done to ensure logical consistency of data in a multiple-
+ engine transaction.
+ For example, imagine that some day MySQL supports unique
+ constraint checks deferred till the end of statement. In such
+ case a commit in one of the engines may yield ER_DUP_KEY,
+ and MySQL should be able to gracefully abort statement
+ transactions of other participants.
+
+ After the normal transaction has been committed,
+ thd->transaction.all list is cleared.
+
+ When a connection is closed, the current normal transaction, if
+ any, is rolled back.
+
+ Roles and responsibilities
+ --------------------------
+
+ The server has no way to know that an engine participates in
+ the statement and a transaction has been started
+ in it unless the engine says so. Thus, in order to be
+ a part of a transaction, the engine must "register" itself.
+ This is done by invoking trans_register_ha() server call.
+ Normally the engine registers itself whenever handler::external_lock()
+ is called. trans_register_ha() can be invoked many times: if
+ an engine is already registered, the call does nothing.
+ In case autocommit is not set, the engine must register itself
+ twice -- both in the statement list and in the normal transaction
+ list.
+ In which list to register is a parameter of trans_register_ha().
+
+ Note, that although the registration interface in itself is
+ fairly clear, the current usage practice often leads to undesired
+ effects. E.g. since a call to trans_register_ha() in most engines
+ is embedded into implementation of handler::external_lock(), some
+ DDL statements start a transaction (at least from the server
+ point of view) even though they are not expected to. E.g.
+ CREATE TABLE does not start a transaction, since
+ handler::external_lock() is never called during CREATE TABLE. But
+ CREATE TABLE ... SELECT does, since handler::external_lock() is
+ called for the table that is being selected from. This has no
+ practical effects currently, but must be kept in mind
+ nevertheless.
+
+ Once an engine is registered, the server will do the rest
+ of the work.
+
+ During statement execution, whenever any of data-modifying
+ PSEA API methods is used, e.g. handler::write_row() or
+ handler::update_row(), the read-write flag is raised in the
+ statement transaction for the involved engine.
+ Currently All PSEA calls are "traced", and the data can not be
+ changed in a way other than issuing a PSEA call. Important:
+ unless this invariant is preserved the server will not know that
+ a transaction in a given engine is read-write and will not
+ involve the two-phase commit protocol!
+
+ At the end of a statement, server call
+ ha_autocommit_or_rollback() is invoked. This call in turn
+ invokes handlerton::prepare() for every involved engine.
+ Prepare is followed by a call to handlerton::commit_one_phase()
+ If a one-phase commit will suffice, handlerton::prepare() is not
+ invoked and the server only calls handlerton::commit_one_phase().
+ At statement commit, the statement-related read-write engine
+ flag is propagated to the corresponding flag in the normal
+ transaction. When the commit is complete, the list of registered
+ engines is cleared.
+
+ Rollback is handled in a similar fashion.
+
+ Additional notes on DDL and the normal transaction.
+ ---------------------------------------------------
+
+ DDLs and operations with non-transactional engines
+ do not "register" in thd->transaction lists, and thus do not
+ modify the transaction state. Besides, each DDL in
+ MySQL is prefixed with an implicit normal transaction commit
+ (a call to end_active_trans()), and thus leaves nothing
+ to modify.
+ However, as it has been pointed out with CREATE TABLE .. SELECT,
+ some DDL statements can start a *new* transaction.
+
+ Behaviour of the server in this case is currently badly
+ defined.
+ DDL statements use a form of "semantic" logging
+ to maintain atomicity: if CREATE TABLE .. SELECT failed,
+ the newly created table is deleted.
+ In addition, some DDL statements issue interim transaction
+ commits: e.g. ALTER TABLE issues a commit after data is copied
+ from the original table to the internal temporary table. Other
+ statements, e.g. CREATE TABLE ... SELECT do not always commit
+ after itself.
+ And finally there is a group of DDL statements such as
+ RENAME/DROP TABLE that doesn't start a new transaction
+ and doesn't commit.
+
+ This diversity makes it hard to say what will happen if
+ by chance a stored function is invoked during a DDL --
+ whether any modifications it makes will be committed or not
+ is not clear. Fortunately, SQL grammar of few DDLs allows
+ invocation of a stored function.
+
+ A consistent behaviour is perhaps to always commit the normal
+ transaction after all DDLs, just like the statement transaction
+ is always committed at the end of all statements.
+*/
+
+/**
Register a storage engine for a transaction.
Every storage engine MUST call this function when it starts
@@ -592,7 +881,7 @@ void ha_close_connection(THD* thd)
void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
{
THD_TRANS *trans;
- handlerton **ht;
+ Ha_trx_info *ha_info;
DBUG_ENTER("trans_register_ha");
DBUG_PRINT("enter",("%s", all ? "all" : "stmt"));
@@ -604,12 +893,13 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
else
trans= &thd->transaction.stmt;
- for (ht=trans->ht; *ht; ht++)
- if (*ht == ht_arg)
- DBUG_VOID_RETURN; /* already registered, return */
+ ha_info= thd->ha_data[ht_arg->slot].ha_info + static_cast<unsigned>(all);
+
+ if (ha_info->is_started())
+ DBUG_VOID_RETURN; /* already registered, return */
+
+ ha_info->register_ha(trans, ht_arg);
- trans->ht[trans->nht++]=ht_arg;
- DBUG_ASSERT(*ht == ht_arg);
trans->no_2pc|=(ht_arg->prepare==0);
if (thd->transaction.xid_state.xid.is_null())
thd->transaction.xid_state.xid.set(thd->query_id);
@@ -626,18 +916,19 @@ int ha_prepare(THD *thd)
{
int error=0, all=1;
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
- handlerton **ht=trans->ht;
+ Ha_trx_info *ha_info= trans->ha_list;
DBUG_ENTER("ha_prepare");
#ifdef USING_TRANSACTIONS
- if (trans->nht)
+ if (ha_info)
{
- for (; *ht; ht++)
+ for (; ha_info; ha_info= ha_info->next())
{
int err;
+ handlerton *ht= ha_info->ht();
status_var_increment(thd->status_var.ha_prepare_count);
- if ((*ht)->prepare)
+ if (ht->prepare)
{
- if ((err= (*(*ht)->prepare)(*ht, thd, all)))
+ if ((err= ht->prepare(ht, thd, all)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
ha_rollback_trans(thd, all);
@@ -649,7 +940,7 @@ int ha_prepare(THD *thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
- ha_resolve_storage_engine_name(*ht));
+ ha_resolve_storage_engine_name(ht));
}
}
}
@@ -658,6 +949,62 @@ int ha_prepare(THD *thd)
}
/**
+ Check if we can skip the two-phase commit.
+
+ A helper function to evaluate if two-phase commit is mandatory.
+ As a side effect, propagates the read-only/read-write flags
+ of the statement transaction to its enclosing normal transaction.
+
+ @retval TRUE we must run a two-phase commit. Returned
+ if we have at least two engines with read-write changes.
+ @retval FALSE Don't need two-phase commit. Even if we have two
+ transactional engines, we can run two independent
+ commits if changes in one of the engines are read-only.
+*/
+
+static
+bool
+ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list,
+ bool all)
+{
+ /* The number of storage engines that have actual changes. */
+ unsigned rw_ha_count= 0;
+ Ha_trx_info *ha_info;
+
+ for (ha_info= ha_list; ha_info; ha_info= ha_info->next())
+ {
+ if (ha_info->is_trx_read_write())
+ ++rw_ha_count;
+
+ if (! all)
+ {
+ Ha_trx_info *ha_info_all= &thd->ha_data[ha_info->ht()->slot].ha_info[1];
+ DBUG_ASSERT(ha_info != ha_info_all);
+ /*
+ Merge read-only/read-write information about statement
+ transaction to its enclosing normal transaction. Do this
+ only if in a real transaction -- that is, if we know
+ that ha_info_all is registered in thd->transaction.all.
+ Since otherwise we only clutter the normal transaction flags.
+ */
+ if (ha_info_all->is_started()) /* FALSE if autocommit. */
+ ha_info_all->coalesce_trx_with(ha_info);
+ }
+ else if (rw_ha_count > 1)
+ {
+ /*
+ It is a normal transaction, so we don't need to merge read/write
+ information up, and the need for two-phase commit has been
+ already established. Break the loop prematurely.
+ */
+ break;
+ }
+ }
+ return rw_ha_count > 1;
+}
+
+
+/**
@retval
0 ok
@retval
@@ -674,12 +1021,25 @@ int ha_prepare(THD *thd)
int ha_commit_trans(THD *thd, bool all)
{
int error= 0, cookie= 0;
+ /*
+ 'all' means that this is either an explicit commit issued by
+ user, or an implicit commit issued by a DDL.
+ */
THD_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt;
- bool is_real_trans= all || thd->transaction.all.nht == 0;
- handlerton **ht= trans->ht;
+ bool is_real_trans= all || thd->transaction.all.ha_list == 0;
+ Ha_trx_info *ha_info= trans->ha_list;
my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
DBUG_ENTER("ha_commit_trans");
+ /*
+ We must not commit the normal transaction if a statement
+ transaction is pending. Otherwise statement transaction
+ flags will not get propagated to its normal transaction's
+ counterpart.
+ */
+ DBUG_ASSERT(thd->transaction.stmt.ha_list == NULL ||
+ trans == &thd->transaction.stmt);
+
if (thd->in_sub_stmt)
{
/*
@@ -701,8 +1061,10 @@ int ha_commit_trans(THD *thd, bool all)
DBUG_RETURN(2);
}
#ifdef USING_TRANSACTIONS
- if (trans->nht)
+ if (ha_info)
{
+ bool must_2pc;
+
if (is_real_trans && wait_if_global_read_lock(thd, 0, 0))
{
ha_rollback_trans(thd, all);
@@ -727,12 +1089,26 @@ int ha_commit_trans(THD *thd, bool all)
if (is_real_trans) /* not a statement commit */
thd->stmt_map.close_transient_cursors();
- if (!trans->no_2pc && trans->nht > 1)
+ must_2pc= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
+
+ if (!trans->no_2pc && must_2pc)
{
- for (; *ht && !error; ht++)
+ for (; ha_info && !error; ha_info= ha_info->next())
{
int err;
- if ((err= (*(*ht)->prepare)(*ht, thd, all)))
+ handlerton *ht= ha_info->ht();
+ /*
+ Do not call two-phase commit if this particular
+ transaction is read-only. This allows for simpler
+ implementation in engines that are always read-only.
+ */
+ if (! ha_info->is_trx_read_write())
+ continue;
+ /*
+ Sic: we know that prepare() is not NULL since otherwise
+ trans->no_2pc would have been set.
+ */
+ if ((err= ht->prepare(ht, thd, all)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
error= 1;
@@ -770,24 +1146,26 @@ int ha_commit_one_phase(THD *thd, bool all)
{
int error=0;
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
- bool is_real_trans=all || thd->transaction.all.nht == 0;
- handlerton **ht=trans->ht;
+ bool is_real_trans=all || thd->transaction.all.ha_list == 0;
+ Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
DBUG_ENTER("ha_commit_one_phase");
#ifdef USING_TRANSACTIONS
- if (trans->nht)
+ if (ha_info)
{
- for (ht=trans->ht; *ht; ht++)
+ for (; ha_info; ha_info= ha_info_next)
{
int err;
- if ((err= (*(*ht)->commit)(*ht, thd, all)))
+ handlerton *ht= ha_info->ht();
+ if ((err= ht->commit(ht, thd, all)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
error=1;
}
status_var_increment(thd->status_var.ha_commit_count);
- *ht= 0;
+ ha_info_next= ha_info->next();
+ ha_info->reset(); /* keep it conveniently zero-filled */
}
- trans->nht=0;
+ trans->ha_list= 0;
trans->no_2pc=0;
if (is_real_trans)
thd->transaction.xid_state.xid.null();
@@ -810,8 +1188,17 @@ int ha_rollback_trans(THD *thd, bool all)
{
int error=0;
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
- bool is_real_trans=all || thd->transaction.all.nht == 0;
+ Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
+ bool is_real_trans=all || thd->transaction.all.ha_list == 0;
DBUG_ENTER("ha_rollback_trans");
+
+ /*
+ We must not rollback the normal transaction if a statement
+ transaction is pending.
+ */
+ DBUG_ASSERT(thd->transaction.stmt.ha_list == NULL ||
+ trans == &thd->transaction.stmt);
+
if (thd->in_sub_stmt)
{
/*
@@ -826,24 +1213,26 @@ int ha_rollback_trans(THD *thd, bool all)
DBUG_RETURN(1);
}
#ifdef USING_TRANSACTIONS
- if (trans->nht)
+ if (ha_info)
{
/* Close all cursors that can not survive ROLLBACK */
if (is_real_trans) /* not a statement commit */
thd->stmt_map.close_transient_cursors();
- for (handlerton **ht=trans->ht; *ht; ht++)
+ for (; ha_info; ha_info= ha_info_next)
{
int err;
- if ((err= (*(*ht)->rollback)(*ht, thd, all)))
+ handlerton *ht= ha_info->ht();
+ if ((err= ht->rollback(ht, thd, all)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
}
status_var_increment(thd->status_var.ha_rollback_count);
- *ht= 0;
+ ha_info_next= ha_info->next();
+ ha_info->reset(); /* keep it conveniently zero-filled */
}
- trans->nht=0;
+ trans->ha_list= 0;
trans->no_2pc=0;
if (is_real_trans)
thd->transaction.xid_state.xid.null();
@@ -889,17 +1278,19 @@ int ha_autocommit_or_rollback(THD *thd, int error)
{
DBUG_ENTER("ha_autocommit_or_rollback");
#ifdef USING_TRANSACTIONS
- if (thd->transaction.stmt.nht)
+ if (thd->transaction.stmt.ha_list)
{
if (!error)
{
- if (ha_commit_stmt(thd))
+ if (ha_commit_trans(thd, 0))
error=1;
}
- else if (thd->transaction_rollback_request && !thd->in_sub_stmt)
- (void) ha_rollback(thd);
- else
- (void) ha_rollback_stmt(thd);
+ else
+ {
+ (void) ha_rollback_trans(thd, 0);
+ if (thd->transaction_rollback_request && !thd->in_sub_stmt)
+ (void) ha_rollback(thd);
+ }
thd->variables.tx_isolation=thd->session_tx_isolation;
}
@@ -1199,7 +1590,7 @@ bool mysql_xa_recover(THD *thd)
}
pthread_mutex_unlock(&LOCK_xid_cache);
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(0);
}
@@ -1246,43 +1637,49 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
int error=0;
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
&thd->transaction.all);
- handlerton **ht=trans->ht, **end_ht;
+ Ha_trx_info *ha_info, *ha_info_next;
+
DBUG_ENTER("ha_rollback_to_savepoint");
- trans->nht=sv->nht;
trans->no_2pc=0;
- end_ht=ht+sv->nht;
/*
rolling back to savepoint in all storage engines that were part of the
transaction when the savepoint was set
*/
- for (; ht < end_ht; ht++)
+ for (ha_info= sv->ha_list; ha_info; ha_info= ha_info->next())
{
int err;
- DBUG_ASSERT((*ht)->savepoint_set != 0);
- if ((err= (*(*ht)->savepoint_rollback)(*ht, thd, (uchar *)(sv+1)+(*ht)->savepoint_offset)))
+ handlerton *ht= ha_info->ht();
+ DBUG_ASSERT(ht);
+ DBUG_ASSERT(ht->savepoint_set != 0);
+ if ((err= ht->savepoint_rollback(ht, thd,
+ (uchar *)(sv+1)+ht->savepoint_offset)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
}
status_var_increment(thd->status_var.ha_savepoint_rollback_count);
- trans->no_2pc|=(*ht)->prepare == 0;
+ trans->no_2pc|= ht->prepare == 0;
}
/*
rolling back the transaction in all storage engines that were not part of
the transaction when the savepoint was set
*/
- for (; *ht ; ht++)
+ for (ha_info= trans->ha_list; ha_info != sv->ha_list;
+ ha_info= ha_info_next)
{
int err;
- if ((err= (*(*ht)->rollback)(*ht, thd, !thd->in_sub_stmt)))
+ handlerton *ht= ha_info->ht();
+ if ((err= ht->rollback(ht, thd, !thd->in_sub_stmt)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
}
status_var_increment(thd->status_var.ha_rollback_count);
- *ht=0; // keep it conveniently zero-filled
+ ha_info_next= ha_info->next();
+ ha_info->reset(); /* keep it conveniently zero-filled */
}
+ trans->ha_list= sv->ha_list;
DBUG_RETURN(error);
}
@@ -1297,26 +1694,32 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv)
int error=0;
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
&thd->transaction.all);
- handlerton **ht=trans->ht;
+ Ha_trx_info *ha_info= trans->ha_list;
DBUG_ENTER("ha_savepoint");
#ifdef USING_TRANSACTIONS
- for (; *ht; ht++)
+ for (; ha_info; ha_info= ha_info->next())
{
int err;
- if (! (*ht)->savepoint_set)
+ handlerton *ht= ha_info->ht();
+ DBUG_ASSERT(ht);
+ if (! ht->savepoint_set)
{
my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "SAVEPOINT");
error=1;
break;
}
- if ((err= (*(*ht)->savepoint_set)(*ht, thd, (uchar *)(sv+1)+(*ht)->savepoint_offset)))
+ if ((err= ht->savepoint_set(ht, thd, (uchar *)(sv+1)+ht->savepoint_offset)))
{ // cannot happen
my_error(ER_GET_ERRNO, MYF(0), err);
error=1;
}
status_var_increment(thd->status_var.ha_savepoint_count);
}
- sv->nht=trans->nht;
+ /*
+ Remember the list of registered storage engines. All new
+ engines are prepended to the beginning of the list.
+ */
+ sv->ha_list= trans->ha_list;
#endif /* USING_TRANSACTIONS */
DBUG_RETURN(error);
}
@@ -1324,20 +1727,19 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv)
int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
- THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
- &thd->transaction.all);
- handlerton **ht=trans->ht, **end_ht;
+ Ha_trx_info *ha_info= sv->ha_list;
DBUG_ENTER("ha_release_savepoint");
- end_ht=ht+sv->nht;
- for (; ht < end_ht; ht++)
+ for (; ha_info; ha_info= ha_info->next())
{
int err;
- if (!(*ht)->savepoint_release)
+ handlerton *ht= ha_info->ht();
+ /* Savepoint life time is enclosed into transaction life time. */
+ DBUG_ASSERT(ht);
+ if (!ht->savepoint_release)
continue;
- if ((err= (*(*ht)->savepoint_release)(*ht, thd,
- (uchar *)(sv+1)+
- (*ht)->savepoint_offset)))
+ if ((err= ht->savepoint_release(ht, thd,
+ (uchar *)(sv+1) + ht->savepoint_offset)))
{ // cannot happen
my_error(ER_GET_ERRNO, MYF(0), err);
error=1;
@@ -2506,6 +2908,36 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
return update_frm_version(table);
}
+/**
+ A helper function to mark a transaction read-write,
+ if it is started.
+*/
+
+inline
+void
+handler::mark_trx_read_write()
+{
+ Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0];
+ /*
+ When a storage engine method is called, the transaction must
+ have been started, unless it's a DDL call, for which the
+ storage engine starts the transaction internally, and commits
+ it internally, without registering in the ha_list.
+ Unfortunately here we can't know know for sure if the engine
+ has registered the transaction or not, so we must check.
+ */
+ if (ha_info->is_started())
+ {
+ DBUG_ASSERT(has_transactions());
+ /*
+ table_share can be NULL in ha_delete_table(). See implementation
+ of standalone function ha_delete_table() in sql_base.cc.
+ */
+ if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE)
+ ha_info->set_trx_read_write();
+ }
+}
+
/**
Repair table: public interface.
@@ -2516,6 +2948,9 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
{
int result;
+
+ mark_trx_read_write();
+
if ((result= repair(thd, check_opt)))
return result;
return update_frm_version(table);
@@ -2532,6 +2967,8 @@ int
handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data,
uint *dup_key_found)
{
+ mark_trx_read_write();
+
return bulk_update_row(old_data, new_data, dup_key_found);
}
@@ -2545,6 +2982,8 @@ handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data,
int
handler::ha_delete_all_rows()
{
+ mark_trx_read_write();
+
return delete_all_rows();
}
@@ -2558,6 +2997,8 @@ handler::ha_delete_all_rows()
int
handler::ha_reset_auto_increment(ulonglong value)
{
+ mark_trx_read_write();
+
return reset_auto_increment(value);
}
@@ -2571,6 +3012,8 @@ handler::ha_reset_auto_increment(ulonglong value)
int
handler::ha_backup(THD* thd, HA_CHECK_OPT* check_opt)
{
+ mark_trx_read_write();
+
return backup(thd, check_opt);
}
@@ -2584,6 +3027,8 @@ handler::ha_backup(THD* thd, HA_CHECK_OPT* check_opt)
int
handler::ha_restore(THD* thd, HA_CHECK_OPT* check_opt)
{
+ mark_trx_read_write();
+
return restore(thd, check_opt);
}
@@ -2597,6 +3042,8 @@ handler::ha_restore(THD* thd, HA_CHECK_OPT* check_opt)
int
handler::ha_optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
+ mark_trx_read_write();
+
return optimize(thd, check_opt);
}
@@ -2610,6 +3057,8 @@ handler::ha_optimize(THD* thd, HA_CHECK_OPT* check_opt)
int
handler::ha_analyze(THD* thd, HA_CHECK_OPT* check_opt)
{
+ mark_trx_read_write();
+
return analyze(thd, check_opt);
}
@@ -2623,6 +3072,8 @@ handler::ha_analyze(THD* thd, HA_CHECK_OPT* check_opt)
bool
handler::ha_check_and_repair(THD *thd)
{
+ mark_trx_read_write();
+
return check_and_repair(thd);
}
@@ -2636,6 +3087,8 @@ handler::ha_check_and_repair(THD *thd)
int
handler::ha_disable_indexes(uint mode)
{
+ mark_trx_read_write();
+
return disable_indexes(mode);
}
@@ -2649,6 +3102,8 @@ handler::ha_disable_indexes(uint mode)
int
handler::ha_enable_indexes(uint mode)
{
+ mark_trx_read_write();
+
return enable_indexes(mode);
}
@@ -2662,6 +3117,8 @@ handler::ha_enable_indexes(uint mode)
int
handler::ha_discard_or_import_tablespace(my_bool discard)
{
+ mark_trx_read_write();
+
return discard_or_import_tablespace(discard);
}
@@ -2677,6 +3134,8 @@ handler::ha_discard_or_import_tablespace(my_bool discard)
void
handler::ha_prepare_for_alter()
{
+ mark_trx_read_write();
+
prepare_for_alter();
}
@@ -2690,6 +3149,8 @@ handler::ha_prepare_for_alter()
int
handler::ha_rename_table(const char *from, const char *to)
{
+ mark_trx_read_write();
+
return rename_table(from, to);
}
@@ -2703,6 +3164,8 @@ handler::ha_rename_table(const char *from, const char *to)
int
handler::ha_delete_table(const char *name)
{
+ mark_trx_read_write();
+
return delete_table(name);
}
@@ -2716,6 +3179,8 @@ handler::ha_delete_table(const char *name)
void
handler::ha_drop_table(const char *name)
{
+ mark_trx_read_write();
+
return drop_table(name);
}
@@ -2729,6 +3194,8 @@ handler::ha_drop_table(const char *name)
int
handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info)
{
+ mark_trx_read_write();
+
return create(name, form, info);
}
@@ -2743,6 +3210,8 @@ int
handler::ha_create_handler_files(const char *name, const char *old_name,
int action_flag, HA_CREATE_INFO *info)
{
+ mark_trx_read_write();
+
return create_handler_files(name, old_name, action_flag, info);
}
@@ -2761,6 +3230,8 @@ handler::ha_change_partitions(HA_CREATE_INFO *create_info,
const uchar *pack_frm_data,
size_t pack_frm_len)
{
+ mark_trx_read_write();
+
return change_partitions(create_info, path, copied, deleted,
pack_frm_data, pack_frm_len);
}
@@ -2775,6 +3246,8 @@ handler::ha_change_partitions(HA_CREATE_INFO *create_info,
int
handler::ha_drop_partitions(const char *path)
{
+ mark_trx_read_write();
+
return drop_partitions(path);
}
@@ -2788,6 +3261,8 @@ handler::ha_drop_partitions(const char *path)
int
handler::ha_rename_partitions(const char *path)
{
+ mark_trx_read_write();
+
return rename_partitions(path);
}
@@ -2801,6 +3276,8 @@ handler::ha_rename_partitions(const char *path)
int
handler::ha_optimize_partitions(THD *thd)
{
+ mark_trx_read_write();
+
return optimize_partitions(thd);
}
@@ -2814,6 +3291,8 @@ handler::ha_optimize_partitions(THD *thd)
int
handler::ha_analyze_partitions(THD *thd)
{
+ mark_trx_read_write();
+
return analyze_partitions(thd);
}
@@ -2827,6 +3306,8 @@ handler::ha_analyze_partitions(THD *thd)
int
handler::ha_check_partitions(THD *thd)
{
+ mark_trx_read_write();
+
return check_partitions(thd);
}
@@ -2840,6 +3321,8 @@ handler::ha_check_partitions(THD *thd)
int
handler::ha_repair_partitions(THD *thd)
{
+ mark_trx_read_write();
+
return repair_partitions(thd);
}
@@ -2866,7 +3349,7 @@ int ha_enable_transaction(THD *thd, bool on)
is an optimization hint that storage engine is free to ignore.
So, let's commit an open transaction (if any) now.
*/
- if (!(error= ha_commit_stmt(thd)))
+ if (!(error= ha_commit_trans(thd, 0)))
error= end_trans(thd, COMMIT);
}
DBUG_RETURN(error);
@@ -3826,7 +4309,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
}
if (!result)
- send_eof(thd);
+ my_eof(thd);
return result;
}
@@ -4044,6 +4527,9 @@ int handler::ha_write_row(uchar *buf)
{
int error;
DBUG_ENTER("handler::ha_write_row");
+
+ mark_trx_read_write();
+
if (unlikely(error= write_row(buf)))
DBUG_RETURN(error);
if (unlikely(error= binlog_log_row<Write_rows_log_event>(table, 0, buf)))
@@ -4062,6 +4548,8 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data)
*/
DBUG_ASSERT(new_data == table->record[0]);
+ mark_trx_read_write();
+
if (unlikely(error= update_row(old_data, new_data)))
return error;
if (unlikely(error= binlog_log_row<Update_rows_log_event>(table, old_data, new_data)))
@@ -4072,6 +4560,9 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data)
int handler::ha_delete_row(const uchar *buf)
{
int error;
+
+ mark_trx_read_write();
+
if (unlikely(error= delete_row(buf)))
return error;
if (unlikely(error= binlog_log_row<Delete_rows_log_event>(table, buf, 0)))
diff --git a/sql/handler.h b/sql/handler.h
index b3a4b408589..9800f4974c3 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -721,14 +721,14 @@ struct handlerton
#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
#define HTON_NO_PARTITION (1 << 8) //You can not partition these tables
-typedef struct st_thd_trans
+class Ha_trx_info;
+
+struct THD_TRANS
{
- /* number of entries in the ht[] */
- uint nht;
/* true is not all entries in the ht[] support 2pc */
bool no_2pc;
- /* storage engines that registered themselves for this transaction */
- handlerton *ht[MAX_HA];
+ /* storage engines that registered in this transaction */
+ Ha_trx_info *ha_list;
/*
The purpose of this flag is to keep track of non-transactional
tables that were modified in scope of:
@@ -758,7 +758,106 @@ typedef struct st_thd_trans
saved value.
*/
bool modified_non_trans_table;
-} THD_TRANS;
+
+ void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
+};
+
+
+/**
+ Either statement transaction or normal transaction - related
+ thread-specific storage engine data.
+
+ If a storage engine participates in a statement/transaction,
+ an instance of this class is present in
+ thd->transaction.{stmt|all}.ha_list. The addition to
+ {stmt|all}.ha_list is made by trans_register_ha().
+
+ When it's time to commit or rollback, each element of ha_list
+ is used to access storage engine's prepare()/commit()/rollback()
+ methods, and also to evaluate if a full two phase commit is
+ necessary.
+
+ @sa General description of transaction handling in handler.cc.
+*/
+
+class Ha_trx_info
+{
+public:
+ /** Register this storage engine in the given transaction context. */
+ void register_ha(THD_TRANS *trans, handlerton *ht_arg)
+ {
+ DBUG_ASSERT(m_flags == 0);
+ DBUG_ASSERT(m_ht == NULL);
+ DBUG_ASSERT(m_next == NULL);
+
+ m_ht= ht_arg;
+ m_flags= (int) TRX_READ_ONLY; /* Assume read-only at start. */
+
+ m_next= trans->ha_list;
+ trans->ha_list= this;
+ }
+
+ /** Clear, prepare for reuse. */
+ void reset()
+ {
+ m_next= NULL;
+ m_ht= NULL;
+ m_flags= 0;
+ }
+
+ Ha_trx_info() { reset(); }
+
+ void set_trx_read_write()
+ {
+ DBUG_ASSERT(is_started());
+ m_flags|= (int) TRX_READ_WRITE;
+ }
+ bool is_trx_read_write() const
+ {
+ DBUG_ASSERT(is_started());
+ return m_flags & (int) TRX_READ_WRITE;
+ }
+ bool is_started() const { return m_ht != NULL; }
+ /** Mark this transaction read-write if the argument is read-write. */
+ void coalesce_trx_with(const Ha_trx_info *stmt_trx)
+ {
+ /*
+ Must be called only after the transaction has been started.
+ Can be called many times, e.g. when we have many
+ read-write statements in a transaction.
+ */
+ DBUG_ASSERT(is_started());
+ if (stmt_trx->is_trx_read_write())
+ set_trx_read_write();
+ }
+ Ha_trx_info *next() const
+ {
+ DBUG_ASSERT(is_started());
+ return m_next;
+ }
+ handlerton *ht() const
+ {
+ DBUG_ASSERT(is_started());
+ return m_ht;
+ }
+private:
+ enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 };
+ /** Auxiliary, used for ha_list management */
+ Ha_trx_info *m_next;
+ /**
+ Although a given Ha_trx_info instance is currently always used
+ for the same storage engine, 'ht' is not-NULL only when the
+ corresponding storage is a part of a transaction.
+ */
+ handlerton *m_ht;
+ /**
+ Transaction flags related to this engine.
+ Not-null only if this instance is a part of transaction.
+ May assume a combination of enum values above.
+ */
+ uchar m_flags;
+};
+
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
@@ -1640,8 +1739,15 @@ protected:
provide useful functionality.
*/
virtual int rename_table(const char *from, const char *to);
+ /**
+ Delete a table in the engine. Called for base as well as temporary
+ tables.
+ */
virtual int delete_table(const char *name);
private:
+ /* Private helpers */
+ inline void mark_trx_read_write();
+private:
/*
Low-level primitives for storage engines. These should be
overridden by the storage engine class. To call these methods, use
@@ -1821,9 +1927,7 @@ extern TYPELIB tx_isolation_typelib;
extern TYPELIB myisam_stats_method_typelib;
extern ulong total_ha, total_ha_2pc;
- /* Wrapper functions */
-#define ha_commit_stmt(thd) (ha_commit_trans((thd), FALSE))
-#define ha_rollback_stmt(thd) (ha_rollback_trans((thd), FALSE))
+ /* Wrapper functions */
#define ha_commit(thd) (ha_commit_trans((thd), TRUE))
#define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
diff --git a/sql/item.cc b/sql/item.cc
index ab9243fcaf5..f997518ac07 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -442,9 +442,10 @@ uint Item::decimal_precision() const
}
-void Item::print_item_w_name(String *str)
+void Item::print_item_w_name(String *str, enum_query_type query_type)
{
- print(str);
+ print(str, query_type);
+
if (name)
{
THD *thd= current_thd;
@@ -1128,7 +1129,7 @@ Item_splocal::this_item_addr(THD *thd, Item **)
}
-void Item_splocal::print(String *str)
+void Item_splocal::print(String *str, enum_query_type)
{
str->reserve(m_name.length+8);
str->append(m_name.str, m_name.length);
@@ -1182,7 +1183,7 @@ Item_case_expr::this_item_addr(THD *thd, Item **)
}
-void Item_case_expr::print(String *str)
+void Item_case_expr::print(String *str, enum_query_type)
{
if (str->reserve(MAX_INT_WIDTH + sizeof("case_expr@")))
return; /* purecov: inspected */
@@ -1276,12 +1277,12 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
}
-void Item_name_const::print(String *str)
+void Item_name_const::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("NAME_CONST("));
- name_item->print(str);
+ name_item->print(str, query_type);
str->append(',');
- value_item->print(str);
+ value_item->print(str, query_type);
str->append(')');
}
@@ -1298,12 +1299,12 @@ public:
const char *table_name_arg, const char *field_name_arg)
:Item_ref(context_arg, item, table_name_arg, field_name_arg) {}
- void print (String *str)
+ virtual inline void print (String *str, enum_query_type query_type)
{
if (ref)
- (*ref)->print(str);
+ (*ref)->print(str, query_type);
else
- Item_ident::print(str);
+ Item_ident::print(str, query_type);
}
};
@@ -1455,7 +1456,9 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
set(dt);
}
else
- ; // Do nothing
+ {
+ // Do nothing
+ }
}
else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
left_is_superset(this, &dt))
@@ -1872,7 +1875,7 @@ const char *Item_ident::full_name() const
return tmp;
}
-void Item_ident::print(String *str)
+void Item_ident::print(String *str, enum_query_type query_type)
{
THD *thd= current_thd;
char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME];
@@ -2134,7 +2137,7 @@ String *Item_int::val_str(String *str)
return str;
}
-void Item_int::print(String *str)
+void Item_int::print(String *str, enum_query_type query_type)
{
// my_charset_bin is good enough for numbers
str_value.set(value, &my_charset_bin);
@@ -2165,7 +2168,7 @@ String *Item_uint::val_str(String *str)
}
-void Item_uint::print(String *str)
+void Item_uint::print(String *str, enum_query_type query_type)
{
// latin1 is good enough for numbers
str_value.set((ulonglong) value, default_charset());
@@ -2257,7 +2260,7 @@ String *Item_decimal::val_str(String *result)
return result;
}
-void Item_decimal::print(String *str)
+void Item_decimal::print(String *str, enum_query_type query_type)
{
my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, &str_value);
str->append(str_value);
@@ -2310,12 +2313,39 @@ my_decimal *Item_float::val_decimal(my_decimal *decimal_value)
}
-void Item_string::print(String *str)
+void Item_string::print(String *str, enum_query_type query_type)
{
- str->append('_');
- str->append(collation.collation->csname);
+ if (query_type == QT_ORDINARY && is_cs_specified())
+ {
+ str->append('_');
+ str->append(collation.collation->csname);
+ }
+
str->append('\'');
- str_value.print(str);
+
+ if (query_type == QT_ORDINARY ||
+ my_charset_same(str_value.charset(), system_charset_info))
+ {
+ str_value.print(str);
+ }
+ else
+ {
+ THD *thd= current_thd;
+ LEX_STRING utf8_lex_str;
+
+ thd->convert_string(&utf8_lex_str,
+ system_charset_info,
+ str_value.c_ptr_safe(),
+ str_value.length(),
+ str_value.charset());
+
+ String utf8_str(utf8_lex_str.str,
+ utf8_lex_str.length,
+ system_charset_info);
+
+ utf8_str.print(str);
+ }
+
str->append('\'');
}
@@ -3082,7 +3112,7 @@ Item_param::eq(const Item *arg, bool binary_cmp) const
/* End of Item_param related */
-void Item_param::print(String *str)
+void Item_param::print(String *str, enum_query_type query_type)
{
if (state == NO_VALUE)
{
@@ -4795,7 +4825,7 @@ int Item_float::save_in_field(Field *field, bool no_conversions)
}
-void Item_float::print(String *str)
+void Item_float::print(String *str, enum_query_type query_type)
{
if (presentation)
{
@@ -4913,7 +4943,7 @@ warn:
}
-void Item_hex_string::print(String *str)
+void Item_hex_string::print(String *str, enum_query_type query_type)
{
char *end= (char*) str_value.ptr() + str_value.length(),
*ptr= end - min(str_value.length(), sizeof(longlong));
@@ -5175,7 +5205,7 @@ Item *Item_field::update_value_transformer(uchar *select_arg)
}
-void Item_field::print(String *str)
+void Item_field::print(String *str, enum_query_type query_type)
{
if (field && field->table->const_table)
{
@@ -5187,7 +5217,7 @@ void Item_field::print(String *str)
str->append('\'');
return;
}
- Item_ident::print(str);
+ Item_ident::print(str, query_type);
}
@@ -5527,7 +5557,7 @@ void Item_ref::cleanup()
}
-void Item_ref::print(String *str)
+void Item_ref::print(String *str, enum_query_type query_type)
{
if (ref)
{
@@ -5538,10 +5568,10 @@ void Item_ref::print(String *str)
append_identifier(thd, str, name, (uint) strlen(name));
}
else
- (*ref)->print(str);
+ (*ref)->print(str, query_type);
}
else
- Item_ident::print(str);
+ Item_ident::print(str, query_type);
}
@@ -5731,11 +5761,11 @@ Item *Item_ref::get_tmp_table_item(THD *thd)
}
-void Item_ref_null_helper::print(String *str)
+void Item_ref_null_helper::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("<ref_null_helper>("));
if (ref)
- (*ref)->print(str);
+ (*ref)->print(str, query_type);
else
str->append('?');
str->append(')');
@@ -5927,7 +5957,7 @@ error:
}
-void Item_default_value::print(String *str)
+void Item_default_value::print(String *str, enum_query_type query_type)
{
if (!arg)
{
@@ -5935,7 +5965,7 @@ void Item_default_value::print(String *str)
return;
}
str->append(STRING_WITH_LEN("default("));
- arg->print(str);
+ arg->print(str, query_type);
str->append(')');
}
@@ -6071,10 +6101,10 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items)
return FALSE;
}
-void Item_insert_value::print(String *str)
+void Item_insert_value::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("values("));
- arg->print(str);
+ arg->print(str, query_type);
str->append(')');
}
@@ -6195,7 +6225,7 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items)
}
-void Item_trigger_field::print(String *str)
+void Item_trigger_field::print(String *str, enum_query_type query_type)
{
str->append((row_version == NEW_ROW) ? "NEW" : "OLD", 3);
str->append('.');
@@ -6385,13 +6415,13 @@ Item_cache* Item_cache::get_cache(const Item *item)
}
-void Item_cache::print(String *str)
+void Item_cache::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("<cache>("));
if (example)
- example->print(str);
+ example->print(str, query_type);
else
- Item::print(str);
+ Item::print(str, query_type);
str->append(')');
}
diff --git a/sql/item.h b/sql/item.h
index b98389bc8d4..64894866504 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -113,7 +113,6 @@ public:
}
};
-
/*************************************************************************/
/*
A framework to easily handle different return types for hybrid items
@@ -769,20 +768,24 @@ public:
*/
virtual bool const_during_execution() const
{ return (used_tables() & ~PARAM_TABLE_BIT) == 0; }
- /*
- This is an essential method for correct functioning of VIEWS.
- To save a view in an .frm file we need its unequivocal
- definition in SQL that takes into account sql_mode and
- environmental settings. Currently such definition is restored
- by traversing through the parsed tree of a view and
- print()'ing SQL syntax of every node to a String buffer. This
- method is used to print the SQL definition of an item. The
- second use of this method is for EXPLAIN EXTENDED, to print
- the SQL of a query after all optimizations of the parsed tree
- have been done.
- */
- virtual void print(String *str_arg) { str_arg->append(full_name()); }
- void print_item_w_name(String *);
+
+ /**
+ This method is used for to:
+ - to generate a view definition query (SELECT-statement);
+ - to generate a SQL-query for EXPLAIN EXTENDED;
+ - to generate a SQL-query to be shown in INFORMATION_SCHEMA;
+ - debug.
+
+ For more information about view definition query, INFORMATION_SCHEMA
+ query and why they should be generated from the Item-tree, @see
+ mysql_register_view().
+ */
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ str->append(full_name());
+ }
+
+ void print_item_w_name(String *, enum_query_type query_type);
virtual void update_used_tables() {}
virtual void split_sum_func(THD *thd, Item **ref_pointer_array,
List<Item> &fields) {}
@@ -1010,6 +1013,23 @@ public:
class sp_head;
+class Item_basic_constant :public Item
+{
+public:
+ /* to prevent drop fixed flag (no need parent cleanup call) */
+ void cleanup()
+ {
+ /*
+ Restore the original field name as it might not have been allocated
+ in the statement memory. If the name is auto generated, it must be
+ done again between subsequent executions of a prepared statement.
+ */
+ if (orig_name)
+ name= orig_name;
+ }
+};
+
+
/*****************************************************************************
The class is a base class for representation of stored routine variables in
the Item-hierarchy. There are the following kinds of SP-vars:
@@ -1134,7 +1154,7 @@ public:
const Item *this_item() const;
Item **this_item_addr(THD *thd, Item **);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
public:
inline const LEX_STRING *my_name() const;
@@ -1203,7 +1223,7 @@ public:
Item_case_expr can not occur in views, so here it is only for debug
purposes.
*/
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
private:
uint m_case_expr_id;
@@ -1261,7 +1281,7 @@ public:
String *val_str(String *sp);
my_decimal *val_decimal(my_decimal *);
bool is_null();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_result result_type() const
{
@@ -1292,7 +1312,7 @@ bool agg_item_charsets(DTCollation &c, const char *name,
Item **items, uint nitems, uint flags, int item_sep);
-class Item_num: public Item
+class Item_num: public Item_basic_constant
{
public:
Item_num() {} /* Remove gcc warning */
@@ -1343,7 +1363,7 @@ public:
const char *full_name() const;
void cleanup();
bool remove_dependence_processor(uchar * arg);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
virtual bool change_context_processor(uchar *cntx)
{ context= (Name_resolution_context *)cntx; return FALSE; }
friend bool insert_fields(THD *thd, Name_resolution_context *context,
@@ -1473,7 +1493,7 @@ public:
Item *safe_charset_converter(CHARSET_INFO *tocs);
int fix_outer_field(THD *thd, Field **field, Item **reference);
virtual Item *update_value_transformer(uchar *select_arg);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Field::geometry_type get_geometry_type() const
{
DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
@@ -1484,7 +1504,7 @@ public:
friend class st_select_lex_unit;
};
-class Item_null :public Item
+class Item_null :public Item_basic_constant
{
public:
Item_null(char *name_par=0)
@@ -1506,12 +1526,15 @@ public:
bool send(Protocol *protocol, String *str);
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NULL; }
- /* to prevent drop fixed flag (no need parent cleanup call) */
- void cleanup() {}
bool basic_const_item() const { return 1; }
Item *clone_item() { return new Item_null(name); }
bool is_null() { return 1; }
- void print(String *str) { str->append(STRING_WITH_LEN("NULL")); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ str->append(STRING_WITH_LEN("NULL"));
+ }
+
Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
};
@@ -1645,7 +1668,7 @@ public:
*/
virtual table_map used_tables() const
{ return state != NO_VALUE ? (table_map)0 : PARAM_TABLE_BIT; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool is_null()
{ DBUG_ASSERT(state != NO_VALUE); return state == NULL_VALUE; }
bool basic_const_item() const;
@@ -1701,9 +1724,7 @@ public:
int save_in_field(Field *field, bool no_conversions);
bool basic_const_item() const { return 1; }
Item *clone_item() { return new Item_int(name,value,max_length); }
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_num *neg() { value= -value; return this; }
uint decimal_precision() const
{ return (uint)(max_length - test(value < 0)); }
@@ -1723,7 +1744,7 @@ public:
String *val_str(String*);
Item *clone_item() { return new Item_uint(name, value, max_length); }
int save_in_field(Field *field, bool no_conversions);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_num *neg ();
uint decimal_precision() const { return max_length; }
bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
@@ -1757,9 +1778,7 @@ public:
{
return new Item_decimal(name, &decimal_value, decimals, max_length);
}
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_num *neg()
{
my_decimal_neg(&decimal_value);
@@ -1813,12 +1832,10 @@ public:
String *val_str(String*);
my_decimal *val_decimal(my_decimal *);
bool basic_const_item() const { return 1; }
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
Item *clone_item()
{ return new Item_float(name, value, decimals, max_length); }
Item_num *neg() { value= -value; return this; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool eq(const Item *, bool binary_cmp) const;
};
@@ -1831,17 +1848,23 @@ public:
uint length)
:Item_float(NullS, val_arg, decimal_par, length), func_name(str)
{}
- void print(String *str) { str->append(func_name); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ str->append(func_name);
+ }
+
Item *safe_charset_converter(CHARSET_INFO *tocs);
};
-class Item_string :public Item
+class Item_string :public Item_basic_constant
{
public:
Item_string(const char *str,uint length,
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE,
uint repertoire= MY_REPERTOIRE_UNICODE30)
+ : m_cs_specified(FALSE)
{
str_value.set_or_copy_aligned(str, length, cs);
collation.set(cs, dv, repertoire);
@@ -1860,6 +1883,7 @@ public:
}
/* Just create an item and do not fill string representation */
Item_string(CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
+ : m_cs_specified(FALSE)
{
collation.set(cs, dv);
max_length= 0;
@@ -1870,6 +1894,7 @@ public:
Item_string(const char *name_par, const char *str, uint length,
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE,
uint repertoire= MY_REPERTOIRE_UNICODE30)
+ : m_cs_specified(FALSE)
{
str_value.set_or_copy_aligned(str, length, cs);
collation.set(cs, dv, repertoire);
@@ -1919,10 +1944,50 @@ public:
str_value.append(str, length);
max_length= str_value.numchars() * collation.collation->mbmaxlen;
}
- void print(String *str);
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
+ virtual void print(String *str, enum_query_type query_type);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+
+ /**
+ Return TRUE if character-set-introducer was explicitly specified in the
+ original query for this item (text literal).
+
+ This operation is to be called from Item_string::print(). The idea is
+ that when a query is generated (re-constructed) from the Item-tree,
+ character-set-introducers should appear only for those literals, where
+ they were explicitly specified by the user. Otherwise, that may lead to
+ loss collation information (character set introducers implies default
+ collation for the literal).
+
+ Basically, that makes sense only for views and hopefully will be gone
+ one day when we start using original query as a view definition.
+
+ @return This operation returns the value of m_cs_specified attribute.
+ @retval TRUE if character set introducer was explicitly specified in
+ the original query.
+ @retval FALSE otherwise.
+ */
+ inline bool is_cs_specified() const
+ {
+ return m_cs_specified;
+ }
+
+ /**
+ Set the value of m_cs_specified attribute.
+
+ m_cs_specified attribute shows whether character-set-introducer was
+ explicitly specified in the original query for this text literal or
+ not. The attribute makes sense (is used) only for views.
+
+ This operation is to be called from the parser during parsing an input
+ query.
+ */
+ inline void set_cs_specified(bool cs_specified)
+ {
+ m_cs_specified= cs_specified;
+ }
+
+private:
+ bool m_cs_specified;
};
@@ -1936,7 +2001,12 @@ public:
:Item_string(NullS, str, length, cs, dv), func_name(name_par)
{}
Item *safe_charset_converter(CHARSET_INFO *tocs);
- void print(String *str) { str->append(func_name); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ str->append(func_name);
+ }
+
bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
};
@@ -2005,10 +2075,10 @@ public:
};
-class Item_hex_string: public Item
+class Item_hex_string: public Item_basic_constant
{
public:
- Item_hex_string(): Item() {}
+ Item_hex_string() {}
Item_hex_string(const char *str,uint str_length);
enum Type type() const { return VARBIN_ITEM; }
double val_real()
@@ -2024,9 +2094,7 @@ public:
enum Item_result result_type () const { return STRING_RESULT; }
enum Item_result cast_to_int_type() const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool eq(const Item *item, bool binary_cmp) const;
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
@@ -2147,7 +2215,7 @@ public:
}
bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
{ return (*ref)->walk(processor, walk_subquery, arg); }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool result_as_longlong()
{
return (*ref)->result_as_longlong();
@@ -2294,7 +2362,7 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
/*
we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
*/
@@ -2469,7 +2537,7 @@ public:
enum Type type() const { return DEFAULT_VALUE_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, Item **);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
int save_in_field(Field *field_arg, bool no_conversions);
table_map used_tables() const { return (table_map)0L; }
@@ -2502,7 +2570,7 @@ public:
arg(a) {}
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, Item **);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
int save_in_field(Field *field_arg, bool no_conversions)
{
return Item_field::save_in_field(field_arg, no_conversions);
@@ -2573,7 +2641,7 @@ public:
enum Type type() const { return TRIGGER_FIELD_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, Item **);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
table_map used_tables() const { return (table_map)0L; }
Field *get_tmp_table_field() { return 0; }
Item *copy_or_same(THD *thd) { return this; }
@@ -2617,7 +2685,7 @@ private:
};
-class Item_cache: public Item
+class Item_cache: public Item_basic_constant
{
protected:
Item *example;
@@ -2664,9 +2732,7 @@ public:
static Item_cache* get_cache(const Item *item);
table_map used_tables() const { return used_table_map; }
virtual void keep_array() {}
- // to prevent drop fixed flag (no need parent cleanup call)
- void cleanup() {}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool eq_def(Field *field)
{
return cached_field ? cached_field->eq_def (field) : FALSE;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index dc868376796..ae7ea95707c 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -286,10 +286,10 @@ longlong Item_func_not::val_int()
higher than the precedence of NOT.
*/
-void Item_func_not::print(String *str)
+void Item_func_not::print(String *str, enum_query_type query_type)
{
str->append('(');
- Item_func::print(str);
+ Item_func::print(str, query_type);
str->append(')');
}
@@ -321,12 +321,12 @@ bool Item_func_not_all::empty_underlying_subquery()
(test_sub_item && !test_sub_item->any_value()));
}
-void Item_func_not_all::print(String *str)
+void Item_func_not_all::print(String *str, enum_query_type query_type)
{
if (show)
- Item_func::print(str);
+ Item_func::print(str, query_type);
else
- args[0]->print(str);
+ args[0]->print(str, query_type);
}
@@ -1422,10 +1422,10 @@ void Item_func_truth::fix_length_and_dec()
}
-void Item_func_truth::print(String *str)
+void Item_func_truth::print(String *str, enum_query_type query_type)
{
str->append('(');
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" is "));
if (! affirmative)
str->append(STRING_WITH_LEN("not "));
@@ -2109,16 +2109,16 @@ longlong Item_func_between::val_int()
}
-void Item_func_between::print(String *str)
+void Item_func_between::print(String *str, enum_query_type query_type)
{
str->append('(');
- args[0]->print(str);
+ args[0]->print(str, query_type);
if (negated)
str->append(STRING_WITH_LEN(" not"));
str->append(STRING_WITH_LEN(" between "));
- args[1]->print(str);
+ args[1]->print(str, query_type);
str->append(STRING_WITH_LEN(" and "));
- args[2]->print(str);
+ args[2]->print(str, query_type);
str->append(')');
}
@@ -2763,26 +2763,26 @@ uint Item_func_case::decimal_precision() const
Fix this so that it prints the whole CASE expression
*/
-void Item_func_case::print(String *str)
+void Item_func_case::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("(case "));
if (first_expr_num != -1)
{
- args[first_expr_num]->print(str);
+ args[first_expr_num]->print(str, query_type);
str->append(' ');
}
for (uint i=0 ; i < ncases ; i+=2)
{
str->append(STRING_WITH_LEN("when "));
- args[i]->print(str);
+ args[i]->print(str, query_type);
str->append(STRING_WITH_LEN(" then "));
- args[i+1]->print(str);
+ args[i+1]->print(str, query_type);
str->append(' ');
}
if (else_expr_num != -1)
{
str->append(STRING_WITH_LEN("else "));
- args[else_expr_num]->print(str);
+ args[else_expr_num]->print(str, query_type);
str->append(' ');
}
str->append(STRING_WITH_LEN("end)"));
@@ -3706,14 +3706,14 @@ void Item_func_in::fix_length_and_dec()
}
-void Item_func_in::print(String *str)
+void Item_func_in::print(String *str, enum_query_type query_type)
{
str->append('(');
- args[0]->print(str);
+ args[0]->print(str, query_type);
if (negated)
str->append(STRING_WITH_LEN(" not"));
str->append(STRING_WITH_LEN(" in ("));
- print_args(str, 1);
+ print_args(str, 1, query_type);
str->append(STRING_WITH_LEN("))"));
}
@@ -4084,19 +4084,19 @@ void Item_cond::update_used_tables()
}
-void Item_cond::print(String *str)
+void Item_cond::print(String *str, enum_query_type query_type)
{
str->append('(');
List_iterator_fast<Item> li(list);
Item *item;
if ((item=li++))
- item->print(str);
+ item->print(str, query_type);
while ((item=li++))
{
str->append(' ');
str->append(func_name());
str->append(' ');
- item->print(str);
+ item->print(str, query_type);
}
str->append(')');
}
@@ -4279,10 +4279,10 @@ longlong Item_func_isnotnull::val_int()
}
-void Item_func_isnotnull::print(String *str)
+void Item_func_isnotnull::print(String *str, enum_query_type query_type)
{
str->append('(');
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" is not null)"));
}
@@ -5276,24 +5276,24 @@ Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
return Item_func::transform(transformer, arg);
}
-void Item_equal::print(String *str)
+void Item_equal::print(String *str, enum_query_type query_type)
{
str->append(func_name());
str->append('(');
List_iterator_fast<Item_field> it(fields);
Item *item;
if (const_item)
- const_item->print(str);
+ const_item->print(str, query_type);
else
{
item= it++;
- item->print(str);
+ item->print(str, query_type);
}
while ((item= it++))
{
str->append(',');
str->append(' ');
- item->print(str);
+ item->print(str, query_type);
}
str->append(')');
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 188d87a69ca..0166a18029d 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -123,7 +123,7 @@ public:
virtual bool val_bool();
virtual longlong val_int();
virtual void fix_length_and_dec();
- virtual void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
protected:
Item_func_truth(Item *a, bool a_value, bool a_affirmative)
@@ -338,7 +338,12 @@ public:
optimize_type select_optimize() const { return OPTIMIZE_OP; }
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
- void print(String *str) { Item_func::print_op(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ Item_func::print_op(str, query_type);
+ }
+
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
@@ -368,7 +373,7 @@ public:
enum Functype functype() const { return NOT_FUNC; }
const char *func_name() const { return "not"; }
Item *neg_transformer(THD *thd);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
class Item_maxmin_subselect;
@@ -433,7 +438,7 @@ public:
longlong val_int();
enum Functype functype() const { return NOT_ALL_FUNC; }
const char *func_name() const { return "<not>"; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
bool empty_underlying_subquery();
@@ -594,7 +599,7 @@ public:
const char *func_name() const { return "between"; }
bool fix_fields(THD *, Item **);
void fix_length_and_dec();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
uint decimal_precision() const { return 1; }
@@ -608,7 +613,11 @@ public:
longlong val_int();
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
const char *func_name() const { return "strcmp"; }
- void print(String *str) { Item_func::print(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ Item_func::print(str, query_type);
+ }
};
@@ -711,7 +720,12 @@ public:
void fix_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); }
const char *func_name() const { return "nullif"; }
- void print(String *str) { Item_func::print(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ Item_func::print(str, query_type);
+ }
+
table_map not_null_tables() const { return 0; }
bool is_null();
};
@@ -1141,7 +1155,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
enum_field_types field_type() const { return cached_field_type; }
const char *func_name() const { return "case"; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item *find_item(String *str);
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
void cleanup();
@@ -1208,7 +1222,7 @@ public:
}
optimize_type select_optimize() const
{ return OPTIMIZE_KEY; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
enum Functype functype() const { return IN_FUNC; }
const char *func_name() const { return " IN "; }
bool nulls_in_row();
@@ -1330,7 +1344,7 @@ public:
table_map not_null_tables() const
{ return abort_on_null ? not_null_tables_cache : 0; }
Item *neg_transformer(THD *thd);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
void top_level_item() { abort_on_null=1; }
};
@@ -1395,7 +1409,12 @@ public:
longlong val_int();
bool fix_fields(THD *thd, Item **ref);
const char *func_name() const { return "regexp"; }
- void print(String *str) { print_op(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ print_op(str, query_type);
+ }
+
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
};
@@ -1407,7 +1426,11 @@ public:
Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b) {}
longlong val_int() { return 0;}
const char *func_name() const { return "regex"; }
- void print(String *str) { print_op(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ print_op(str, query_type);
+ }
};
#endif /* USE_REGEX */
@@ -1444,7 +1467,7 @@ public:
List<Item>* argument_list() { return &list; }
table_map used_tables() const;
void update_used_tables();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
COND **conds);
@@ -1568,7 +1591,7 @@ public:
void update_used_tables();
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(Item_transformer transformer, uchar *arg);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
CHARSET_INFO *compare_collation()
{ return fields.head()->collation.collation; }
};
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 6e9371de9dc..a7b562d3407 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -374,37 +374,37 @@ table_map Item_func::not_null_tables() const
}
-void Item_func::print(String *str)
+void Item_func::print(String *str, enum_query_type query_type)
{
str->append(func_name());
str->append('(');
- print_args(str, 0);
+ print_args(str, 0, query_type);
str->append(')');
}
-void Item_func::print_args(String *str, uint from)
+void Item_func::print_args(String *str, uint from, enum_query_type query_type)
{
for (uint i=from ; i < arg_count ; i++)
{
if (i != from)
str->append(',');
- args[i]->print(str);
+ args[i]->print(str, query_type);
}
}
-void Item_func::print_op(String *str)
+void Item_func::print_op(String *str, enum_query_type query_type)
{
str->append('(');
for (uint i=0 ; i < arg_count-1 ; i++)
{
- args[i]->print(str);
+ args[i]->print(str, query_type);
str->append(' ');
str->append(func_name());
str->append(' ');
}
- args[arg_count-1]->print(str);
+ args[arg_count-1]->print(str, query_type);
str->append(')');
}
@@ -884,10 +884,10 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
}
-void Item_func_signed::print(String *str)
+void Item_func_signed::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("cast("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as signed)"));
}
@@ -955,10 +955,10 @@ longlong Item_func_signed::val_int()
}
-void Item_func_unsigned::print(String *str)
+void Item_func_unsigned::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("cast("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as unsigned)"));
}
@@ -1064,7 +1064,7 @@ err:
}
-void Item_decimal_typecast::print(String *str)
+void Item_decimal_typecast::print(String *str, enum_query_type query_type)
{
char len_buf[20*3 + 1];
char *end;
@@ -1072,7 +1072,7 @@ void Item_decimal_typecast::print(String *str)
uint precision= my_decimal_length_to_precision(max_length, decimals,
unsigned_flag);
str->append(STRING_WITH_LEN("cast("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as decimal("));
end=int10_to_str(precision, len_buf,10);
@@ -2537,16 +2537,16 @@ longlong Item_func_locate::val_int()
}
-void Item_func_locate::print(String *str)
+void Item_func_locate::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("locate("));
- args[1]->print(str);
+ args[1]->print(str, query_type);
str->append(',');
- args[0]->print(str);
+ args[0]->print(str, query_type);
if (arg_count == 3)
{
str->append(',');
- args[2]->print(str);
+ args[2]->print(str, query_type);
}
str->append(')');
}
@@ -3095,7 +3095,7 @@ void Item_udf_func::cleanup()
}
-void Item_udf_func::print(String *str)
+void Item_udf_func::print(String *str, enum_query_type query_type)
{
str->append(func_name());
str->append('(');
@@ -3103,7 +3103,7 @@ void Item_udf_func::print(String *str)
{
if (i != 0)
str->append(',');
- args[i]->print_item_w_name(str);
+ args[i]->print_item_w_name(str, query_type);
}
str->append(')');
}
@@ -3683,12 +3683,12 @@ longlong Item_func_benchmark::val_int()
}
-void Item_func_benchmark::print(String *str)
+void Item_func_benchmark::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("benchmark("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(',');
- args[1]->print(str);
+ args[1]->print(str, query_type);
str->append(')');
}
@@ -4264,22 +4264,23 @@ my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
}
-void Item_func_set_user_var::print(String *str)
+void Item_func_set_user_var::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("(@"));
str->append(name.str, name.length);
str->append(STRING_WITH_LEN(":="));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(')');
}
-void Item_func_set_user_var::print_as_stmt(String *str)
+void Item_func_set_user_var::print_as_stmt(String *str,
+ enum_query_type query_type)
{
str->append(STRING_WITH_LEN("set @"));
str->append(name.str, name.length);
str->append(STRING_WITH_LEN(":="));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(')');
}
@@ -4652,7 +4653,7 @@ enum Item_result Item_func_get_user_var::result_type() const
}
-void Item_func_get_user_var::print(String *str)
+void Item_func_get_user_var::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("(@"));
str->append(name.str,name.length);
@@ -4750,7 +4751,7 @@ my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer)
}
-void Item_user_var_as_out_param::print(String *str)
+void Item_user_var_as_out_param::print(String *str, enum_query_type query_type)
{
str->append('@');
str->append(name.str,name.length);
@@ -5089,12 +5090,12 @@ double Item_func_match::val_real()
table->record[0], 0));
}
-void Item_func_match::print(String *str)
+void Item_func_match::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("(match "));
- print_args(str, 1);
+ print_args(str, 1, query_type);
str->append(STRING_WITH_LEN(" against ("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
if (flags & FT_BOOL)
str->append(STRING_WITH_LEN(" in boolean mode"));
else if (flags & FT_EXPAND)
@@ -5505,7 +5506,7 @@ Item_result
Item_func_sp::result_type() const
{
DBUG_ENTER("Item_func_sp::result_type");
- DBUG_PRINT("info", ("m_sp = %p", m_sp));
+ DBUG_PRINT("info", ("m_sp = %p", (void *) m_sp));
DBUG_ASSERT(sp_result_field);
DBUG_RETURN(sp_result_field->result_type());
}
diff --git a/sql/item_func.h b/sql/item_func.h
index e09b584de95..f8eb7ff6200 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -140,9 +140,9 @@ public:
inline uint argument_count() const { return arg_count; }
inline void remove_arguments() { arg_count=0; }
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
- void print(String *str);
- void print_op(String *str);
- void print_args(String *str, uint from);
+ virtual void print(String *str, enum_query_type query_type);
+ void print_op(String *str, enum_query_type query_type);
+ void print_args(String *str, uint from, enum_query_type query_type);
virtual void fix_num_length_and_dec();
void count_only_length();
void count_real_length();
@@ -293,7 +293,12 @@ class Item_num_op :public Item_func_numhybrid
public:
Item_num_op(Item *a,Item *b) :Item_func_numhybrid(a, b) {}
virtual void result_precision()= 0;
- void print(String *str) { print_op(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ print_op(str, query_type);
+ }
+
void find_num_type();
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
@@ -339,7 +344,7 @@ public:
longlong val_int_from_str(int *error);
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=0; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
uint decimal_precision() const { return args[0]->decimal_precision(); }
};
@@ -352,7 +357,7 @@ public:
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=1; }
longlong val_int();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -373,7 +378,7 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
void fix_length_and_dec() {};
const char *func_name() const { return "decimal_typecast"; }
- void print(String *);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -441,7 +446,12 @@ public:
longlong val_int();
const char *func_name() const { return "DIV"; }
void fix_length_and_dec();
- void print(String *str) { print_op(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ print_op(str, query_type);
+ }
+
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
};
@@ -843,7 +853,7 @@ public:
const char *func_name() const { return "locate"; }
longlong val_int();
void fix_length_and_dec();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -900,7 +910,11 @@ public:
Item_func_bit(Item *a, Item *b) :Item_int_func(a, b) {}
Item_func_bit(Item *a) :Item_int_func(a) {}
void fix_length_and_dec() { unsigned_flag= 1; }
- void print(String *str) { print_op(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ print_op(str, query_type);
+ }
};
class Item_func_bit_or :public Item_func_bit
@@ -950,7 +964,11 @@ public:
Item_func_bit_neg(Item *a) :Item_func_bit(a) {}
longlong val_int();
const char *func_name() const { return "~"; }
- void print(String *str) { Item_func::print(str); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ Item_func::print(str, query_type);
+ }
};
@@ -979,7 +997,7 @@ public:
longlong val_int();
const char *func_name() const { return "benchmark"; }
void fix_length_and_dec() { max_length=1; maybe_null=0; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -1076,7 +1094,7 @@ public:
Item_result result_type () const { return udf.result_type(); }
table_map not_null_tables() const { return 0; }
bool is_expensive() { return 1; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -1313,8 +1331,8 @@ public:
enum Item_result result_type () const { return cached_result_type; }
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
- void print(String *str);
- void print_as_stmt(String *str);
+ virtual void print(String *str, enum_query_type query_type);
+ void print_as_stmt(String *str, enum_query_type query_type);
const char *func_name() const { return "set_user_var"; }
int save_in_field(Field *field, bool no_conversions,
bool can_use_result_field);
@@ -1344,7 +1362,7 @@ public:
my_decimal *val_decimal(my_decimal*);
String *val_str(String* str);
void fix_length_and_dec();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
enum Item_result result_type() const;
/*
We must always return variables as strings to guard against selects of type
@@ -1389,7 +1407,7 @@ public:
my_decimal *val_decimal(my_decimal *decimal_buffer);
/* fix_fields() binds variable name with its entry structure */
bool fix_fields(THD *thd, Item **ref);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
void set_null_value(CHARSET_INFO* cs);
void set_value(const char *str, uint length, CHARSET_INFO* cs);
};
@@ -1467,7 +1485,7 @@ public:
/* The following should be safe, even if we compare doubles */
longlong val_int() { DBUG_ASSERT(fixed == 1); return val_real() != 0.0; }
double val_real();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool fix_index();
void init_search(bool no_order);
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 62be78eee9e..edbe104e307 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -224,8 +224,13 @@ public:
DBUG_ASSERT(0); // Should never happened
return "sp_unknown";
}
- }
- void print(String *str) { Item_func::print(str); }
+ }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ Item_func::print(str, query_type);
+ }
+
void fix_length_and_dec() { maybe_null= 1; }
bool is_null() { (void) val_int(); return null_value; }
};
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 369aa04930e..28de03bf049 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -134,14 +134,14 @@ bool Item_row::check_cols(uint c)
return 0;
}
-void Item_row::print(String *str)
+void Item_row::print(String *str, enum_query_type query_type)
{
str->append('(');
for (uint i= 0; i < arg_count; i++)
{
if (i)
str->append(',');
- items[i]->print(str);
+ items[i]->print(str, query_type);
}
str->append(')');
}
diff --git a/sql/item_row.h b/sql/item_row.h
index dd7436888f0..67441f49603 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -65,7 +65,7 @@ public:
bool const_item() const { return const_item_cache; };
enum Item_result result_type() const { return ROW_RESULT; }
void update_used_tables();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(Item_transformer transformer, uchar *arg);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 42314872997..fe805d7672a 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1594,20 +1594,20 @@ void Item_func_trim::fix_length_and_dec()
}
}
-void Item_func_trim::print(String *str)
+void Item_func_trim::print(String *str, enum_query_type query_type)
{
if (arg_count == 1)
{
- Item_func::print(str);
+ Item_func::print(str, query_type);
return;
}
str->append(Item_func_trim::func_name());
str->append('(');
str->append(mode_name());
str->append(' ');
- args[1]->print(str);
+ args[1]->print(str, query_type);
str->append(STRING_WITH_LEN(" from "));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(')');
}
@@ -2116,12 +2116,12 @@ String *Item_func_format::val_str(String *str)
}
-void Item_func_format::print(String *str)
+void Item_func_format::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("format("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(',');
- args[1]->print(str);
+ args[1]->print(str, query_type);
str->append(')');
}
@@ -2292,14 +2292,14 @@ Item *Item_func_make_set::transform(Item_transformer transformer, uchar *arg)
}
-void Item_func_make_set::print(String *str)
+void Item_func_make_set::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("make_set("));
- item->print(str);
+ item->print(str, query_type);
if (arg_count)
{
str->append(',');
- print_args(str, 0);
+ print_args(str, 0, query_type);
}
str->append(')');
}
@@ -2710,10 +2710,10 @@ void Item_func_conv_charset::fix_length_and_dec()
max_length = args[0]->max_length*conv_charset->mbmaxlen;
}
-void Item_func_conv_charset::print(String *str)
+void Item_func_conv_charset::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("convert("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" using "));
str->append(conv_charset->csname);
str->append(')');
@@ -2781,10 +2781,10 @@ bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const
}
-void Item_func_set_collation::print(String *str)
+void Item_func_set_collation::print(String *str, enum_query_type query_type)
{
str->append('(');
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" collate "));
DBUG_ASSERT(args[1]->basic_const_item() &&
args[1]->type() == Item::STRING_ITEM);
@@ -2903,10 +2903,10 @@ String *Item_func_unhex::val_str(String *str)
}
-void Item_func_binary::print(String *str)
+void Item_func_binary::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("cast("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as binary)"));
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 0d7cd66acff..81baf9a4c5f 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -225,7 +225,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "trim"; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
virtual const char *mode_name() const { return "both"; }
};
@@ -482,7 +482,7 @@ public:
Item_str_func::walk(processor, walk_subquery, arg);
}
Item *transform(Item_transformer transformer, uchar *arg);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -494,7 +494,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "format"; }
- void print(String *);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -617,7 +617,7 @@ public:
collation.set(&my_charset_bin);
max_length=args[0]->max_length;
}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
const char *func_name() const { return "cast_as_binary"; }
};
@@ -719,7 +719,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "convert"; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
class Item_func_set_collation :public Item_str_func
@@ -731,7 +731,7 @@ public:
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "collate"; }
enum Functype functype() const { return COLLATE_FUNC; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_field *filed_for_view_update()
{
/* this function is transparent for view updating */
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 46b8d2e46cc..7b68d258d29 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -306,10 +306,10 @@ void Item_subselect::update_used_tables()
}
-void Item_subselect::print(String *str)
+void Item_subselect::print(String *str, enum_query_type query_type)
{
str->append('(');
- engine->print(str);
+ engine->print(str, query_type);
str->append(')');
}
@@ -391,10 +391,10 @@ void Item_maxmin_subselect::cleanup()
}
-void Item_maxmin_subselect::print(String *str)
+void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
{
str->append(max?"<max>":"<min>", 5);
- Item_singlerow_subselect::print(str);
+ Item_singlerow_subselect::print(str, query_type);
}
@@ -630,10 +630,10 @@ Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
}
-void Item_exists_subselect::print(String *str)
+void Item_exists_subselect::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("exists"));
- Item_subselect::print(str);
+ Item_subselect::print(str, query_type);
}
@@ -1553,16 +1553,16 @@ err:
}
-void Item_in_subselect::print(String *str)
+void Item_in_subselect::print(String *str, enum_query_type query_type)
{
if (transformed)
str->append(STRING_WITH_LEN("<exists>"));
else
{
- left_expr->print(str);
+ left_expr->print(str, query_type);
str->append(STRING_WITH_LEN(" in "));
}
- Item_subselect::print(str);
+ Item_subselect::print(str, query_type);
}
@@ -1587,18 +1587,18 @@ Item_allany_subselect::select_transformer(JOIN *join)
}
-void Item_allany_subselect::print(String *str)
+void Item_allany_subselect::print(String *str, enum_query_type query_type)
{
if (transformed)
str->append(STRING_WITH_LEN("<exists>"));
else
{
- left_expr->print(str);
+ left_expr->print(str, query_type);
str->append(' ');
str->append(func->symbol(all));
str->append(all ? " all " : " any ", 5);
}
- Item_subselect::print(str);
+ Item_subselect::print(str, query_type);
}
@@ -2384,22 +2384,24 @@ table_map subselect_union_engine::upper_select_const_tables()
}
-void subselect_single_select_engine::print(String *str)
+void subselect_single_select_engine::print(String *str,
+ enum_query_type query_type)
{
- select_lex->print(thd, str);
+ select_lex->print(thd, str, query_type);
}
-void subselect_union_engine::print(String *str)
+void subselect_union_engine::print(String *str, enum_query_type query_type)
{
- unit->print(str);
+ unit->print(str, query_type);
}
-void subselect_uniquesubquery_engine::print(String *str)
+void subselect_uniquesubquery_engine::print(String *str,
+ enum_query_type query_type)
{
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
- tab->ref.items[0]->print(str);
+ tab->ref.items[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" in "));
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
KEY *key_info= tab->table->key_info+ tab->ref.key;
@@ -2408,16 +2410,17 @@ void subselect_uniquesubquery_engine::print(String *str)
if (cond)
{
str->append(STRING_WITH_LEN(" where "));
- cond->print(str);
+ cond->print(str, query_type);
}
str->append(')');
}
-void subselect_indexsubquery_engine::print(String *str)
+void subselect_indexsubquery_engine::print(String *str,
+ enum_query_type query_type)
{
str->append(STRING_WITH_LEN("<index_lookup>("));
- tab->ref.items[0]->print(str);
+ tab->ref.items[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" in "));
str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
KEY *key_info= tab->table->key_info+ tab->ref.key;
@@ -2428,12 +2431,12 @@ void subselect_indexsubquery_engine::print(String *str)
if (cond)
{
str->append(STRING_WITH_LEN(" where "));
- cond->print(str);
+ cond->print(str, query_type);
}
if (having)
{
str->append(STRING_WITH_LEN(" having "));
- having->print(str);
+ having->print(str, query_type);
}
str->append(')');
}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index de4b1cbdc06..d4aa621c083 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -103,7 +103,7 @@ public:
inline bool get_const_item_cache() { return const_item_cache; }
Item *get_tmp_table_item(THD *thd);
void update_used_tables();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
virtual bool have_guarded_conds() { return FALSE; }
bool change_engine(subselect_engine *eng)
{
@@ -203,7 +203,7 @@ protected:
public:
Item_maxmin_subselect(THD *thd, Item_subselect *parent,
st_select_lex *select_lex, bool max);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
void cleanup();
bool any_value() { return was_values; }
void register_value() { was_values= TRUE; }
@@ -234,7 +234,7 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
void fix_length_and_dec();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
friend class select_exists_subselect;
friend class subselect_uniquesubquery_engine;
@@ -312,7 +312,7 @@ public:
void top_level_item() { abort_on_null=1; }
inline bool is_top_level_item() { return abort_on_null; }
bool test_limit(st_select_lex_unit *unit);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool fix_fields(THD *thd, Item **ref);
friend class Item_ref_null_helper;
@@ -335,7 +335,7 @@ public:
// only ALL subquery has upper not
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
trans_res select_transformer(JOIN *join);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -399,7 +399,7 @@ public:
virtual bool may_be_null() { return maybe_null; };
virtual table_map upper_select_const_tables()= 0;
static table_map calc_const_tables(TABLE_LIST *);
- virtual void print(String *str)= 0;
+ virtual void print(String *str, enum_query_type query_type)= 0;
virtual bool change_result(Item_subselect *si, select_subselect *result)= 0;
virtual bool no_tables()= 0;
virtual bool is_executed() const { return FALSE; }
@@ -430,7 +430,7 @@ public:
uint8 uncacheable();
void exclude();
table_map upper_select_const_tables();
- void print (String *str);
+ virtual void print (String *str, enum_query_type query_type);
bool change_result(Item_subselect *si, select_subselect *result);
bool no_tables();
bool may_be_null();
@@ -454,7 +454,7 @@ public:
uint8 uncacheable();
void exclude();
table_map upper_select_const_tables();
- void print (String *str);
+ virtual void print (String *str, enum_query_type query_type);
bool change_result(Item_subselect *si, select_subselect *result);
bool no_tables();
bool is_executed() const;
@@ -511,7 +511,7 @@ public:
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
void exclude();
table_map upper_select_const_tables() { return 0; }
- void print (String *str);
+ virtual void print (String *str, enum_query_type query_type);
bool change_result(Item_subselect *si, select_subselect *result);
bool no_tables();
int scan_table();
@@ -565,7 +565,7 @@ public:
having(having_arg)
{}
int exec();
- void print (String *str);
+ virtual void print (String *str, enum_query_type query_type);
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 27b964a9e15..f5a3956c1e4 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -359,14 +359,14 @@ void Item_sum::make_field(Send_field *tmp_field)
}
-void Item_sum::print(String *str)
+void Item_sum::print(String *str, enum_query_type query_type)
{
str->append(func_name());
for (uint i=0 ; i < arg_count ; i++)
{
if (i)
str->append(',');
- args[i]->print(str);
+ args[i]->print(str, query_type);
}
str->append(')');
}
@@ -2716,7 +2716,7 @@ void Item_udf_sum::cleanup()
}
-void Item_udf_sum::print(String *str)
+void Item_udf_sum::print(String *str, enum_query_type query_type)
{
str->append(func_name());
str->append('(');
@@ -2724,7 +2724,7 @@ void Item_udf_sum::print(String *str)
{
if (i)
str->append(',');
- args[i]->print(str);
+ args[i]->print(str, query_type);
}
str->append(')');
}
@@ -3460,7 +3460,7 @@ String* Item_func_group_concat::val_str(String* str)
}
-void Item_func_group_concat::print(String *str)
+void Item_func_group_concat::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("group_concat("));
if (distinct)
@@ -3469,7 +3469,7 @@ void Item_func_group_concat::print(String *str)
{
if (i)
str->append(',');
- args[i]->print(str);
+ args[i]->print(str, query_type);
}
if (arg_count_order)
{
@@ -3478,7 +3478,7 @@ void Item_func_group_concat::print(String *str)
{
if (i)
str->append(',');
- (*order[i]->item)->print(str);
+ (*order[i]->item)->print(str, query_type);
if (order[i]->asc)
str->append(STRING_WITH_LEN(" ASC"));
else
diff --git a/sql/item_sum.h b/sql/item_sum.h
index a3582967736..d1e6a74e85e 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -343,7 +343,7 @@ public:
}
virtual bool const_item() const { return forced_const; }
void make_field(Send_field *field);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
void fix_num_length_and_dec();
/*
@@ -984,7 +984,7 @@ public:
void reset_field() {};
void update_field() {};
void cleanup();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -1257,7 +1257,7 @@ public:
String* val_str(String* str);
Item *copy_or_same(THD* thd);
void no_rows_in_result() {}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
virtual bool change_context_processor(uchar *cntx)
{ context= (Name_resolution_context *)cntx; return FALSE; }
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index a0beadcd481..390f94945aa 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2217,23 +2217,23 @@ static const char *interval_names[]=
"second_microsecond"
};
-void Item_date_add_interval::print(String *str)
+void Item_date_add_interval::print(String *str, enum_query_type query_type)
{
str->append('(');
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(date_sub_interval?" - interval ":" + interval ");
- args[1]->print(str);
+ args[1]->print(str, query_type);
str->append(' ');
str->append(interval_names[int_type]);
str->append(')');
}
-void Item_extract::print(String *str)
+void Item_extract::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("extract("));
str->append(interval_names[int_type]);
str->append(STRING_WITH_LEN(" from "));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(')');
}
@@ -2374,20 +2374,20 @@ bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
return 1;
}
-void Item_typecast::print(String *str)
+void Item_typecast::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("cast("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as "));
str->append(cast_type());
str->append(')');
}
-void Item_char_typecast::print(String *str)
+void Item_char_typecast::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("cast("));
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(STRING_WITH_LEN(" as char"));
if (cast_length >= 0)
{
@@ -2822,7 +2822,7 @@ null_date:
}
-void Item_func_add_time::print(String *str)
+void Item_func_add_time::print(String *str, enum_query_type query_type)
{
if (is_date)
{
@@ -2836,9 +2836,9 @@ void Item_func_add_time::print(String *str)
else
str->append(STRING_WITH_LEN("subtime("));
}
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(',');
- args[1]->print(str);
+ args[1]->print(str, query_type);
str->append(')');
}
@@ -3083,7 +3083,7 @@ null_date:
}
-void Item_func_timestamp_diff::print(String *str)
+void Item_func_timestamp_diff::print(String *str, enum_query_type query_type)
{
str->append(func_name());
str->append('(');
@@ -3123,7 +3123,7 @@ void Item_func_timestamp_diff::print(String *str)
for (uint i=0 ; i < 2 ; i++)
{
str->append(',');
- args[i]->print(str);
+ args[i]->print(str, query_type);
}
str->append(')');
}
@@ -3163,7 +3163,7 @@ String *Item_func_get_format::val_str(String *str)
}
-void Item_func_get_format::print(String *str)
+void Item_func_get_format::print(String *str, enum_query_type query_type)
{
str->append(func_name());
str->append('(');
@@ -3181,7 +3181,7 @@ void Item_func_get_format::print(String *str)
default:
DBUG_ASSERT(0);
}
- args[0]->print(str);
+ args[0]->print(str, query_type);
str->append(')');
}
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 9be7e97db49..cfcf5fab080 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -694,7 +694,7 @@ public:
longlong val_int();
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -711,7 +711,7 @@ class Item_extract :public Item_int_func
const char *func_name() const { return "extract"; }
void fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
};
@@ -735,7 +735,7 @@ public:
max_length=args[0]->max_length;
}
virtual const char* cast_type() const= 0;
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -767,7 +767,7 @@ public:
const char* cast_type() const { return "char"; };
String *val_str(String *a);
void fix_length_and_dec();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -901,7 +901,7 @@ public:
{
return tmp_table_field_from_field_type(table, 0);
}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
const char *func_name() const { return "add_time"; }
double val_real() { return val_real_from_decimal(); }
my_decimal *val_decimal(my_decimal *decimal_value)
@@ -977,7 +977,7 @@ public:
decimals=0;
maybe_null=1;
}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
@@ -1001,7 +1001,7 @@ public:
decimals=0;
max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
};
diff --git a/sql/log.cc b/sql/log.cc
index 9b5b2ae5a6c..efa8e8fa649 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -3383,6 +3383,16 @@ THD::binlog_start_trans_and_stmt()
if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
trans_register_ha(this, TRUE, binlog_hton);
trans_register_ha(this, FALSE, binlog_hton);
+ /*
+ Mark statement transaction as read/write. We never start
+ a binary log transaction and keep it read-only,
+ therefore it's best to mark the transaction read/write just
+ at the same time we start it.
+ Not necessary to mark the normal transaction read/write
+ since the statement-level flag will be propagated automatically
+ inside ha_commit_trans.
+ */
+ ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
}
DBUG_VOID_RETURN;
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 0d2f3e7e708..7c98ccaff28 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -3116,7 +3116,7 @@ int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
original place when it comes to us; we'll know this by checking
log_pos ("artificial" events have log_pos == 0).
*/
- if (!artificial_event && created && thd->transaction.all.nht)
+ if (!artificial_event && created && thd->transaction.all.ha_list)
{
/* This is not an error (XA is safe), just an information */
rli->report(INFORMATION_LEVEL, 0,
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 2c43959815e..b52e5aa745c 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -44,6 +44,19 @@
#include "sql_plugin.h"
#include "scheduler.h"
+/**
+ Query type constants.
+
+ QT_ORDINARY -- ordinary SQL query.
+ QT_IS -- SQL query to be shown in INFORMATION_SCHEMA (in utf8 and without
+ character set introducers).
+*/
+enum enum_query_type
+{
+ QT_ORDINARY,
+ QT_IS
+};
+
/* TODO convert all these three maps to Bitmap classes */
typedef ulonglong table_map; /* Used for table bits in join */
#if MAX_INDEXES <= 64
@@ -1711,7 +1724,7 @@ bool mysql_manager_submit(void (*action)());
/* sql_test.cc */
#ifndef DBUG_OFF
-void print_where(COND *cond,const char *info);
+void print_where(COND *cond,const char *info, enum_query_type query_type);
void print_cached_tables(void);
void TEST_filesort(SORT_FIELD *sortorder,uint s_length);
void print_plan(JOIN* join,uint idx, double record_count, double read_time,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 8cb98573103..cdd08be6573 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2734,8 +2734,18 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
(TABLE_LIST*) 0, &not_used); // Flush logs
}
/* reenable logs after the options were reloaded */
- logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_TABLE:LOG_NONE,
- opt_log ? LOG_TABLE:LOG_NONE);
+ if (log_output_options & LOG_NONE)
+ {
+ logger.set_handlers(LOG_FILE,
+ opt_slow_log ? LOG_TABLE : LOG_NONE,
+ opt_log ? LOG_TABLE : LOG_NONE);
+ }
+ else
+ {
+ logger.set_handlers(LOG_FILE,
+ opt_slow_log ? log_output_options : LOG_NONE,
+ opt_log ? log_output_options : LOG_NONE);
+ }
break;
#ifdef USE_ONE_SIGNAL_HAND
case THR_SERVER_ALARM:
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 9e1b3c65538..5fe56724d08 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -112,8 +112,6 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
- message : Stored as packed length (1-9 bytes) + message.
Is not stored if no message.
- If net->no_send_ok return without sending packet.
-
@param thd Thread handler
@param affected_rows Number of rows changed by statement
@param id Auto_increment id for first row (if used)
@@ -128,7 +126,7 @@ net_send_ok(THD *thd,
{
NET *net= &thd->net;
uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
- DBUG_ENTER("send_ok");
+ DBUG_ENTER("my_ok");
if (! net->vio) // hack for re-parsing queries
{
@@ -425,8 +423,8 @@ void net_end_statement(THD *thd)
/****************************************************************************
- Functions used by the protocol functions (like send_ok) to store strings
- and numbers in the header result packet.
+ Functions used by the protocol functions (like net_send_ok) to store
+ strings and numbers in the header result packet.
****************************************************************************/
/* The following will only be used for short strings < 65K */
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 589ee8b2605..f8f01d2cad1 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -475,7 +475,7 @@ bool show_new_master(THD* thd)
protocol->store((ulonglong) lex_mi->pos);
if (protocol->write())
DBUG_RETURN(TRUE);
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
}
@@ -688,7 +688,7 @@ bool show_slave_hosts(THD* thd)
}
}
pthread_mutex_unlock(&LOCK_slave_list);
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -1011,7 +1011,7 @@ err:
mysql_close(&mysql); // safe to call since we always do mysql_init()
if (!error)
- send_ok(thd);
+ my_ok(thd);
return error;
}
diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc
index aa3020c42be..684655d1c3b 100644
--- a/sql/rpl_injector.cc
+++ b/sql/rpl_injector.cc
@@ -62,6 +62,26 @@ int injector::transaction::commit()
{
DBUG_ENTER("injector::transaction::commit()");
m_thd->binlog_flush_pending_rows_event(true);
+ /*
+ Cluster replication does not preserve statement or
+ transaction boundaries of the master. Instead, a new
+ transaction on replication slave is started when a new GCI
+ (global checkpoint identifier) is issued, and is committed
+ when the last event of the check point has been received and
+ processed. This ensures consistency of each cluster in
+ cluster replication, and there is no requirement for stronger
+ consistency: MySQL replication is asynchronous with other
+ engines as well.
+
+ A practical consequence of that is that row level replication
+ stream passed through the injector thread never contains
+ COMMIT events.
+ Here we should preserve the server invariant that there is no
+ outstanding statement transaction when the normal transaction
+ is committed by committing the statement transaction
+ explicitly.
+ */
+ ha_autocommit_or_rollback(m_thd, 0);
end_trans(m_thd, COMMIT);
DBUG_RETURN(0);
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 972b92e0b33..8b38ffede41 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -3926,10 +3926,8 @@ bool sys_var_thd_dbug::update(THD *thd, set_var *var)
if (var->type == OPT_GLOBAL)
DBUG_SET_INITIAL(var ? var->value->str_value.c_ptr() : "");
else
- {
- DBUG_POP();
- DBUG_PUSH(var ? var->value->str_value.c_ptr() : "");
- }
+ DBUG_SET(var ? var->value->str_value.c_ptr() : "");
+
return 0;
}
diff --git a/sql/slave.cc b/sql/slave.cc
index ea0dde942da..d9dc014b025 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1451,7 +1451,7 @@ bool show_master_info(THD* thd, Master_info* mi)
if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(), packet->length()))
DBUG_RETURN(TRUE);
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sp.cc b/sql/sp.cc
index 83995e9b753..b486e58883a 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -697,8 +697,16 @@ sp_returns_type(THD *thd, String &result, sp_head *sp)
(TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION).
@param sp Stored routine object to store.
- @return Error code. SP_OK is returned on success. Other SP_ constants are
- used to indicate about errors.
+ @note Opens and closes the thread tables. Therefore assumes
+ that there are no locked tables in this thread at the time of
+ invocation.
+ Unlike some other DDL statements, *does* close the tables
+ in the end, since the call to this function is normally
+ followed by an implicit grant (sp_grant_privileges())
+ and this subsequent call opens and closes mysql.procs_priv.
+
+ @return Error code. SP_OK is returned on success. Other
+ SP_ constants are used to indicate about errors.
*/
int
@@ -1251,7 +1259,7 @@ sp_show_status_routine(THD *thd, int type, const char *name_pattern)
}
err_case1:
- send_eof(thd);
+ my_eof(thd);
err_case:
table->file->ha_index_end();
close_thread_tables(thd);
@@ -1260,7 +1268,13 @@ done:
}
-/* Drop all routines in database 'db' */
+/**
+ Drop all routines in database 'db'
+
+ @note Close the thread tables, the calling code might want to
+ delete from other system tables afterwards.
+*/
+
int
sp_drop_db_routines(THD *thd, char *db)
{
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 8e6f5a96640..8bd10e00f15 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -2419,7 +2419,7 @@ sp_head::show_create_routine(THD *thd, int type)
err_status= protocol->write();
if (!err_status)
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(err_status);
}
@@ -2611,7 +2611,7 @@ sp_head::show_routine_code(THD *thd)
}
if (!res)
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(res);
}
@@ -2700,6 +2700,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
m_lex->unit.cleanup();
thd_proc_info(thd, "closing tables");
+ /* Here we also commit or rollback the current statement. */
close_thread_tables(thd);
thd_proc_info(thd, 0);
@@ -2932,7 +2933,7 @@ sp_instr_set::print(String *str)
}
str->qs_append(m_offset);
str->qs_append(' ');
- m_value->print(str);
+ m_value->print(str, QT_ORDINARY);
}
@@ -2960,9 +2961,9 @@ void
sp_instr_set_trigger_field::print(String *str)
{
str->append(STRING_WITH_LEN("set_trigger_field "));
- trigger_field->print(str);
+ trigger_field->print(str, QT_ORDINARY);
str->append(STRING_WITH_LEN(":="));
- value->print(str);
+ value->print(str, QT_ORDINARY);
}
/*
@@ -3088,7 +3089,7 @@ sp_instr_jump_if_not::print(String *str)
str->qs_append('(');
str->qs_append(m_cont_dest);
str->qs_append(STRING_WITH_LEN(") "));
- m_expr->print(str);
+ m_expr->print(str, QT_ORDINARY);
}
@@ -3176,7 +3177,7 @@ sp_instr_freturn::print(String *str)
str->qs_append(STRING_WITH_LEN("freturn "));
str->qs_append((uint)m_type);
str->qs_append(' ');
- m_value->print(str);
+ m_value->print(str, QT_ORDINARY);
}
/*
@@ -3664,7 +3665,7 @@ sp_instr_set_case_expr::print(String *str)
str->qs_append(STRING_WITH_LEN(") "));
str->qs_append(m_case_expr_id);
str->qs_append(' ');
- m_case_expr->print(str);
+ m_case_expr->print(str, QT_ORDINARY);
}
uint
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index b04f624f746..3805d9fa8b6 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3176,7 +3176,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
rw_unlock(&LOCK_grant);
if (!result) /* success */
- send_ok(thd);
+ my_ok(thd);
/* Tables are automatically closed */
thd->lex->restore_backup_query_tables_list(&backup);
@@ -3344,7 +3344,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
rw_unlock(&LOCK_grant);
if (!result && !no_error)
- send_ok(thd);
+ my_ok(thd);
/* Tables are automatically closed */
DBUG_RETURN(result);
@@ -3460,7 +3460,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
close_thread_tables(thd);
if (!result)
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(result);
}
@@ -4815,7 +4815,7 @@ end:
VOID(pthread_mutex_unlock(&acl_cache->lock));
rw_unlock(&LOCK_grant);
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(error);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index e5a5b51fcf6..4a417dc05b1 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1324,29 +1324,45 @@ void close_thread_tables(THD *thd)
Mark all temporary tables used by this statement as free for reuse.
*/
mark_temp_tables_as_free_for_reuse(thd);
-
- if (thd->locked_tables || prelocked_mode)
+ /*
+ Let us commit transaction for statement. Since in 5.0 we only have
+ one statement transaction and don't allow several nested statement
+ transactions this call will do nothing if we are inside of stored
+ function or trigger (i.e. statement transaction is already active and
+ does not belong to statement for which we do close_thread_tables()).
+ TODO: This should be fixed in later releases.
+ */
+ if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL))
{
+ thd->main_da.can_overwrite_status= TRUE;
+ ha_autocommit_or_rollback(thd, thd->is_error());
+ thd->main_da.can_overwrite_status= FALSE;
+
/*
- Let us commit transaction for statement. Since in 5.0 we only have
- one statement transaction and don't allow several nested statement
- transactions this call will do nothing if we are inside of stored
- function or trigger (i.e. statement transaction is already active and
- does not belong to statement for which we do close_thread_tables()).
- TODO: This should be fixed in later releases.
+ Reset transaction state, but only if we're not inside a
+ sub-statement of a prelocked statement.
*/
- ha_commit_stmt(thd);
+ if (! prelocked_mode || thd->lex->requires_prelocking())
+ thd->transaction.stmt.reset();
+ }
+
+ if (thd->locked_tables || prelocked_mode)
+ {
/* Ensure we are calling ha_reset() for all used tables */
mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
- /* We are under simple LOCK TABLES so should not do anything else. */
+ /*
+ We are under simple LOCK TABLES or we're inside a sub-statement
+ of a prelocked statement, so should not do anything else.
+ */
if (!prelocked_mode || !thd->lex->requires_prelocking())
DBUG_VOID_RETURN;
/*
- We are in prelocked mode, so we have to leave it now with doing
- implicit UNLOCK TABLES if need.
+ We are in the top-level statement of a prelocked statement,
+ so we have to leave the prelocked mode now with doing implicit
+ UNLOCK TABLES if needed.
*/
DBUG_PRINT("info",("thd->prelocked_mode= NON_PRELOCKED"));
thd->prelocked_mode= NON_PRELOCKED;
@@ -1375,19 +1391,6 @@ void close_thread_tables(THD *thd)
thd->lock=0;
}
/*
- assume handlers auto-commit (if some doesn't - transaction handling
- in MySQL should be redesigned to support it; it's a big change,
- and it's not worth it - better to commit explicitly only writing
- transactions, read-only ones should better take care of themselves.
- saves some work in 2pc too)
- see also sql_parse.cc - dispatch_command()
- */
- if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL))
- bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt));
- if (!thd->active_transaction())
- thd->transaction.xid_state.xid.null();
-
- /*
Note that we need to hold LOCK_open while changing the
open_tables list. Another thread may work on it.
(See: remove_table_from_cache(), mysql_wait_completed_table())
@@ -5059,10 +5062,7 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
DBUG_PRINT("info", ("error: %d", error));
if (error)
- {
- ha_rollback_stmt(thd);
return -1;
- }
/*
We switch to row-based format if we are in mixed mode and one of
@@ -5216,7 +5216,6 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
table->table->query_id= thd->query_id;
if (check_lock_and_start_stmt(thd, table->table, table->lock_type))
{
- ha_rollback_stmt(thd);
mysql_unlock_tables(thd, thd->locked_tables);
thd->locked_tables= 0;
thd->options&= ~(OPTION_TABLE_LOCK);
@@ -5251,7 +5250,6 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
if (!table->placeholder() &&
check_lock_and_start_stmt(thd, table->table, table->lock_type))
{
- ha_rollback_stmt(thd);
DBUG_RETURN(-1);
}
}
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 462806ab10d..a6d0c8c9e9b 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -231,7 +231,7 @@ void mysql_client_binlog_statement(THD* thd)
DBUG_PRINT("info",("binlog base64 execution finished successfully"));
- send_ok(thd);
+ my_ok(thd);
end:
thd->rli_fake->clear_tables_to_lock();
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 461a59425d4..376102c8bf9 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -264,7 +264,7 @@ const char *set_thd_proc_info(THD *thd, const char *info,
extern "C"
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
{
- return (void **) thd->ha_data + hton->slot;
+ return (void **) &thd->ha_data[hton->slot].ha_ptr;
}
extern "C"
@@ -770,6 +770,10 @@ void THD::init_for_queries()
void THD::change_user(void)
{
+ pthread_mutex_lock(&LOCK_status);
+ add_to_status(&global_status_var, &status_var);
+ pthread_mutex_unlock(&LOCK_status);
+
cleanup();
killed= NOT_KILLED;
cleanup_done= 0;
@@ -1545,7 +1549,7 @@ bool select_send::send_eof()
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
- ::send_eof(thd);
+ ::my_eof(thd);
is_result_set_started= 0;
return FALSE;
}
@@ -1580,7 +1584,7 @@ bool select_to_file::send_eof()
function, SELECT INTO has to have an own SQLCOM.
TODO: split from SQLCOM_SELECT
*/
- ::send_ok(thd,row_count);
+ ::my_ok(thd,row_count);
}
file= -1;
return error;
@@ -2517,7 +2521,7 @@ bool select_dumpvar::send_data(List<Item> &items)
suv->update();
}
}
- DBUG_RETURN(0);
+ DBUG_RETURN(thd->is_error());
}
bool select_dumpvar::send_eof()
@@ -2530,7 +2534,7 @@ bool select_dumpvar::send_eof()
function, SELECT INTO has to have an own SQLCOM.
TODO: split from SQLCOM_SELECT
*/
- ::send_ok(thd,row_count);
+ ::my_ok(thd,row_count);
return 0;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 5f2b50f48b8..2f225834545 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -689,7 +689,8 @@ private:
struct st_savepoint {
struct st_savepoint *prev;
char *name;
- uint length, nht;
+ uint length;
+ Ha_trx_info *ha_list;
};
enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED};
@@ -992,9 +993,9 @@ public:
{
/** The area is cleared at start of a statement. */
DA_EMPTY= 0,
- /** Set whenever one calls send_ok(). */
+ /** Set whenever one calls my_ok(). */
DA_OK,
- /** Set whenever one calls send_eof(). */
+ /** Set whenever one calls my_eof(). */
DA_EOF,
/** Set whenever one calls my_error() or my_message(). */
DA_ERROR,
@@ -1062,7 +1063,7 @@ private:
Copied from thd->server_status when the diagnostics area is assigned.
We need this member as some places in the code use the following pattern:
thd->server_status|= ...
- send_eof(thd);
+ my_eof(thd);
thd->server_status&= ~...
Assigned by OK, EOF or ERROR.
*/
@@ -1096,6 +1097,33 @@ private:
/**
+ Storage engine specific thread local data.
+*/
+
+struct Ha_data
+{
+ /**
+ Storage engine specific thread local data.
+ Lifetime: one user connection.
+ */
+ void *ha_ptr;
+ /**
+ 0: Life time: one statement within a transaction. If @@autocommit is
+ on, also represents the entire transaction.
+ @sa trans_register_ha()
+
+ 1: Life time: one transaction within a connection.
+ If the storage engine does not participate in a transaction,
+ this should not be used.
+ @sa trans_register_ha()
+ */
+ Ha_trx_info ha_info[2];
+
+ Ha_data() :ha_ptr(NULL) {}
+};
+
+
+/**
@class THD
For each client connection we create a separate thread with THD serving as
a thread/connection descriptor
@@ -1234,7 +1262,7 @@ public:
uint in_sub_stmt;
/* container for handler's private per-connection data */
- void *ha_data[MAX_HA];
+ Ha_data ha_data[MAX_HA];
#ifndef MYSQL_CLIENT
int binlog_setup_trx_data();
@@ -2113,7 +2141,7 @@ private:
/** A short cut for thd->main_da.set_ok_status(). */
inline void
-send_ok(THD *thd, ha_rows affected_rows= 0, ulonglong id= 0,
+my_ok(THD *thd, ha_rows affected_rows= 0, ulonglong id= 0,
const char *message= NULL)
{
thd->main_da.set_ok_status(thd, affected_rows, id, message);
@@ -2123,7 +2151,7 @@ send_ok(THD *thd, ha_rows affected_rows= 0, ulonglong id= 0,
/** A short cut for thd->main_da.set_eof_status(). */
inline void
-send_eof(THD *thd)
+my_eof(THD *thd)
{
thd->main_da.set_eof_status(thd);
}
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index c3541cb4eb4..b22a33e3e92 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -319,7 +319,7 @@ check_user(THD *thd, enum enum_server_command command,
if (mysql_change_db(thd, &db_str, FALSE))
DBUG_RETURN(1);
}
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(0);
#else
@@ -468,7 +468,7 @@ check_user(THD *thd, enum enum_server_command command,
DBUG_RETURN(1);
}
}
- send_ok(thd);
+ my_ok(thd);
thd->password= test(passwd_len); // remember for error messages
/* Ready to handle queries */
DBUG_RETURN(0);
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 2301b561797..5c4e93d4c74 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -88,6 +88,7 @@ class Materialized_cursor: public Server_side_cursor
public:
Materialized_cursor(select_result *result, TABLE *table);
+ int fill_item_list(THD *thd, List<Item> &send_fields);
virtual bool is_open() const { return table != 0; }
virtual int open(JOIN *join __attribute__((unused)));
virtual void fetch(ulong num_rows);
@@ -109,6 +110,7 @@ class Select_materialize: public select_union
{
select_result *result; /**< the result object of the caller (PS or SP) */
public:
+ Materialized_cursor *materialized_cursor;
Select_materialize(select_result *result_arg) :result(result_arg) {}
virtual bool send_fields(List<Item> &list, uint flags);
};
@@ -151,7 +153,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
if (! (sensitive_cursor= new (thd->mem_root) Sensitive_cursor(thd, result)))
{
- delete result;
+ delete result_materialize;
return 1;
}
@@ -173,13 +175,13 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
/*
Possible options here:
- a sensitive cursor is open. In this case rc is 0 and
- result_materialize->table is NULL, or
+ result_materialize->materialized_cursor is NULL, or
- a materialized cursor is open. In this case rc is 0 and
- result_materialize->table is not NULL
- - an error occured during materializaton.
- result_materialize->table is not NULL, but rc != 0
+ result_materialize->materialized is not NULL
+ - an error occurred during materialization.
+ result_materialize->materialized_cursor is not NULL, but rc != 0
- successful completion of mysql_execute_command without
- a cursor: rc is 0, result_materialize->table is NULL,
+ a cursor: rc is 0, result_materialize->materialized_cursor is NULL,
sensitive_cursor is not open.
This is possible if some command writes directly to the
network, bypassing select_result mechanism. An example of
@@ -190,7 +192,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
if (sensitive_cursor->is_open())
{
- DBUG_ASSERT(!result_materialize->table);
+ DBUG_ASSERT(!result_materialize->materialized_cursor);
/*
It's safer if we grab THD state after mysql_execute_command
is finished and not in Sensitive_cursor::open(), because
@@ -201,18 +203,10 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
*pcursor= sensitive_cursor;
goto end;
}
- else if (result_materialize->table)
+ else if (result_materialize->materialized_cursor)
{
- Materialized_cursor *materialized_cursor;
- TABLE *table= result_materialize->table;
- MEM_ROOT *mem_root= &table->mem_root;
-
- if (!(materialized_cursor= new (mem_root)
- Materialized_cursor(result, table)))
- {
- rc= 1;
- goto err_open;
- }
+ Materialized_cursor *materialized_cursor=
+ result_materialize->materialized_cursor;
if ((rc= materialized_cursor->open(0)))
{
@@ -228,8 +222,6 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result,
err_open:
DBUG_ASSERT(! (sensitive_cursor && sensitive_cursor->is_open()));
delete sensitive_cursor;
- if (result_materialize->table)
- free_tmp_table(thd, result_materialize->table);
end:
delete result_materialize;
return rc;
@@ -322,9 +314,10 @@ Sensitive_cursor::post_open(THD *thd)
close_at_commit= FALSE; /* reset in case we're reusing the cursor */
info= &ht_info[0];
- for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++)
+ for (Ha_trx_info *ha_trx_info= thd->transaction.stmt.ha_list;
+ ha_trx_info; ha_trx_info= ha_trx_info->next())
{
- handlerton *ht= *pht;
+ handlerton *ht= ha_trx_info->ht();
close_at_commit|= test(ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT);
if (ht->create_cursor_read_view)
{
@@ -553,6 +546,51 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg,
}
+/**
+ Preserve the original metadata that would be sent to the client.
+
+ @param thd Thread identifier.
+ @param send_fields List of fields that would be sent.
+*/
+
+int Materialized_cursor::fill_item_list(THD *thd, List<Item> &send_fields)
+{
+ Query_arena backup_arena;
+ int rc;
+ List_iterator_fast<Item> it_org(send_fields);
+ List_iterator_fast<Item> it_dst(item_list);
+ Item *item_org;
+ Item *item_dst;
+
+ thd->set_n_backup_active_arena(this, &backup_arena);
+
+ if ((rc= table->fill_item_list(&item_list)))
+ goto end;
+
+ DBUG_ASSERT(send_fields.elements == item_list.elements);
+
+ /*
+ Unless we preserve the original metadata, it will be lost,
+ since new fields describe columns of the temporary table.
+ Allocate a copy of the name for safety only. Currently
+ items with original names are always kept in memory,
+ but in case this changes a memory leak may be hard to notice.
+ */
+ while ((item_dst= it_dst++, item_org= it_org++))
+ {
+ Send_field send_field;
+ Item_ident *ident= static_cast<Item_ident *>(item_dst);
+ item_org->make_field(&send_field);
+
+ ident->db_name= thd->strdup(send_field.db_name);
+ ident->table_name= thd->strdup(send_field.table_name);
+ }
+end:
+ thd->restore_active_arena(this, &backup_arena);
+ /* Check for thd->is_error() in case of OOM */
+ return rc || thd->is_error();
+}
+
int Materialized_cursor::open(JOIN *join __attribute__((unused)))
{
THD *thd= fake_unit.thd;
@@ -561,8 +599,7 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
thd->set_n_backup_active_arena(this, &backup_arena);
/* Create a list of fields and start sequential scan */
- rc= (table->fill_item_list(&item_list) ||
- result->prepare(item_list, &fake_unit) ||
+ rc= (result->prepare(item_list, &fake_unit) ||
table->file->ha_rnd_init(TRUE));
thd->restore_active_arena(this, &backup_arena);
if (rc == 0)
@@ -668,6 +705,24 @@ bool Select_materialize::send_fields(List<Item> &list, uint flags)
if (create_result_table(unit->thd, unit->get_unit_column_types(),
FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
return TRUE;
+
+ materialized_cursor= new (&table->mem_root)
+ Materialized_cursor(result, table);
+
+ if (! materialized_cursor)
+ {
+ free_tmp_table(table->in_use, table);
+ table= 0;
+ return TRUE;
+ }
+ if (materialized_cursor->fill_item_list(unit->thd, list))
+ {
+ delete materialized_cursor;
+ table= 0;
+ materialized_cursor= 0;
+ return TRUE;
+ }
+
return FALSE;
}
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index b5f49b97ec9..d03ac7921ac 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -595,7 +595,7 @@ CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
In this case the entry should not be logged.
SIDE-EFFECTS
- 1. Report back to client that command succeeded (send_ok)
+ 1. Report back to client that command succeeded (my_ok)
2. Report errors to client
3. Log event to binary log
(The 'silent' flags turns off 1 and 3.)
@@ -660,7 +660,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
if (!silent)
- send_ok(thd);
+ my_ok(thd);
error= 0;
goto exit;
}
@@ -749,7 +749,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
/* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
}
- send_ok(thd, result);
+ my_ok(thd, result);
}
exit:
@@ -826,7 +826,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
/* These DDL methods and logging protected with LOCK_mysql_create_db */
mysql_bin_log.write(&qinfo);
}
- send_ok(thd, result);
+ my_ok(thd, result);
exit:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
@@ -960,7 +960,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
}
thd->clear_error();
thd->server_status|= SERVER_STATUS_DB_DROPPED;
- send_ok(thd, (ulong) deleted);
+ my_ok(thd, (ulong) deleted);
thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
}
else if (mysql_bin_log.is_open())
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index c6435387f44..990f7713561 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -24,6 +24,14 @@
#include "sp_head.h"
#include "sql_trigger.h"
+/**
+ Implement DELETE SQL word.
+
+ @note Like implementations of other DDL/DML in MySQL, this function
+ relies on the caller to close the thread tables. This is done in the
+ end of dispatch_command().
+*/
+
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
SQL_LIST *order, ha_rows limit, ulonglong options,
bool reset_auto_increment)
@@ -150,7 +158,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
{
free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0;
- send_ok(thd, (ha_rows) thd->row_count_func); // No matching records
+ my_ok(thd, (ha_rows) thd->row_count_func); // No matching records
DBUG_RETURN(0);
}
#endif
@@ -167,7 +175,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
delete select;
free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0;
- send_ok(thd, (ha_rows) thd->row_count_func);
+ my_ok(thd, (ha_rows) thd->row_count_func);
/*
We don't need to call reset_auto_increment in this case, because
mysql_truncate always gives a NULL conds argument, hence we never
@@ -380,21 +388,10 @@ cleanup:
}
DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
free_underlaid_joins(thd, select_lex);
- if (transactional_table)
- {
- if (ha_autocommit_or_rollback(thd,error >= 0))
- error=1;
- }
-
- if (thd->lock)
- {
- mysql_unlock_tables(thd, thd->lock);
- thd->lock=0;
- }
if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
{
thd->row_count_func= deleted;
- send_ok(thd, (ha_rows) thd->row_count_func);
+ my_ok(thd, (ha_rows) thd->row_count_func);
DBUG_PRINT("info",("%ld records deleted",(long) deleted));
}
DBUG_RETURN(error >= 0 || thd->is_error());
@@ -751,11 +748,9 @@ void multi_delete::abort()
The same if all tables are transactional, regardless of where we are.
In all other cases do attempt deletes ...
*/
- if ((table_being_deleted == delete_tables &&
- table_being_deleted->table->file->has_transactions()) ||
- !normal_tables)
- ha_rollback_stmt(thd);
- else if (do_delete)
+ if (do_delete && normal_tables &&
+ (table_being_deleted != delete_tables ||
+ !table_being_deleted->table->file->has_transactions()))
{
/*
We have to execute the recorded do_deletes() and write info into the
@@ -921,15 +916,10 @@ bool multi_delete::send_eof()
if (local_error != 0)
error_handled= TRUE; // to force early leave from ::send_error()
- /* Commit or rollback the current SQL statement */
- if (transactional_tables)
- if (ha_autocommit_or_rollback(thd,local_error > 0))
- local_error=1;
-
if (!local_error)
{
thd->row_count_func= deleted;
- ::send_ok(thd, (ha_rows) thd->row_count_func);
+ ::my_ok(thd, (ha_rows) thd->row_count_func);
}
return 0;
}
@@ -983,7 +973,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
my_free((char*) table,MYF(0));
/*
If we return here we will not have logged the truncation to the bin log
- and we will not send_ok() to the client.
+ and we will not my_ok() to the client.
*/
goto end;
}
@@ -1029,7 +1019,7 @@ end:
we don't test current_stmt_binlog_row_based.
*/
write_bin_log(thd, TRUE, thd->query, thd->query_length);
- send_ok(thd); // This should return record count
+ my_ok(thd); // This should return record count
}
VOID(pthread_mutex_lock(&LOCK_open));
unlock_table_name(thd, table_list);
@@ -1055,6 +1045,12 @@ trunc_by_del:
error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
HA_POS_ERROR, LL(0), TRUE);
ha_enable_transaction(thd, TRUE);
+ /*
+ Safety, in case the engine ignored ha_enable_transaction(FALSE)
+ above. Also clears thd->transaction.*.
+ */
+ error= ha_autocommit_or_rollback(thd, error);
+ ha_commit(thd);
thd->options= save_options;
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(error);
diff --git a/sql/sql_do.cc b/sql/sql_do.cc
index a3eb93f87da..8406a9eaf45 100644
--- a/sql/sql_do.cc
+++ b/sql/sql_do.cc
@@ -28,7 +28,17 @@ bool mysql_do(THD *thd, List<Item> &values)
while ((value = li++))
value->val_int();
free_underlaid_joins(thd, &thd->lex->select_lex);
- thd->clear_error(); // DO always is OK
- send_ok(thd);
+
+ if (thd->is_error())
+ {
+ /*
+ Rollback the effect of the statement, since next instruction
+ will clear the error and the rollback in the end of
+ dispatch_command() won't work.
+ */
+ ha_autocommit_or_rollback(thd, thd->is_error());
+ thd->clear_error(); // DO always is OK
+ }
+ my_ok(thd);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 89cff73d153..0b74e3455eb 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -249,6 +249,6 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
if (protocol->write())
DBUG_RETURN(TRUE);
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index a4ba6f1140b..28a9fb5c78e 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -298,7 +298,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
tables->table->open_by_handler= 1;
if (! reopen)
- send_ok(thd);
+ my_ok(thd);
DBUG_PRINT("exit",("OK"));
DBUG_RETURN(FALSE);
@@ -350,7 +350,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
DBUG_RETURN(TRUE);
}
- send_ok(thd);
+ my_ok(thd);
DBUG_PRINT("exit", ("OK"));
DBUG_RETURN(FALSE);
}
@@ -658,7 +658,7 @@ retry:
}
ok:
mysql_unlock_tables(thd,lock);
- send_eof(thd);
+ my_eof(thd);
DBUG_PRINT("exit",("OK"));
DBUG_RETURN(FALSE);
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 0d633ce86ac..e424425272e 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -779,7 +779,7 @@ bool mysqld_help(THD *thd, const char *mask)
if (send_variant_2_list(mem_root,protocol, &categories_list, "Y", 0))
goto error;
}
- send_eof(thd);
+ my_eof(thd);
close_system_tables(thd, &open_tables_state_backup);
DBUG_RETURN(FALSE);
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index c2b1990f6c7..2be932a6040 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -541,6 +541,10 @@ bool open_and_lock_for_insert_delayed(THD *thd, TABLE_LIST *table_list)
/**
INSERT statement implementation
+
+ @note Like implementations of other DDL/DML in MySQL, this function
+ relies on the caller to close the thread tables. This is done in the
+ end of dispatch_command().
*/
bool mysql_insert(THD *thd,TABLE_LIST *table_list,
@@ -893,12 +897,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
}
DBUG_ASSERT(transactional_table || !changed ||
thd->transaction.stmt.modified_non_trans_table);
- if (transactional_table)
- error=ha_autocommit_or_rollback(thd,error);
-
+
if (thd->lock)
{
- mysql_unlock_tables(thd, thd->lock);
/*
Invalidate the table in the query cache if something changed
after unlocking when changes become fisible.
@@ -909,7 +910,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
{
query_cache_invalidate3(thd, table_list, 1);
}
- thd->lock=0;
}
}
thd_proc_info(thd, "end");
@@ -946,7 +946,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->row_count_func= info.copied + info.deleted +
((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
info.touched : info.updated);
- send_ok(thd, (ulong) thd->row_count_func, id);
+ my_ok(thd, (ulong) thd->row_count_func, id);
}
else
{
@@ -961,7 +961,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) (info.deleted + updated), (ulong) thd->cuted_fields);
thd->row_count_func= info.copied + info.deleted + updated;
- ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
+ ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
}
thd->abort_on_warning= 0;
DBUG_RETURN(FALSE);
@@ -2445,7 +2445,7 @@ err:
first call to ha_*_row() instead. Remove code that are used to
cover for the case outlined above.
*/
- ha_rollback_stmt(thd);
+ ha_autocommit_or_rollback(thd, 1);
#ifndef __WIN__
end:
@@ -3139,18 +3139,6 @@ bool select_insert::send_eof()
thd->query, thd->query_length,
trans_table, FALSE, killed_status);
}
- /*
- We will call ha_autocommit_or_rollback() also for
- non-transactional tables under row-based replication: there might
- be events in the binary logs transaction, and we need to write
- them to the binary log.
- */
- if (trans_table || thd->current_stmt_binlog_row_based)
- {
- int error2= ha_autocommit_or_rollback(thd, error);
- if (error2 && !error)
- error= error2;
- }
table->file->ha_release_auto_increment();
if (error)
@@ -3174,7 +3162,7 @@ bool select_insert::send_eof()
(thd->arg_of_last_insert_id_function ?
thd->first_successful_insert_id_in_prev_stmt :
(info.copied ? autoinc_value_of_last_inserted_row : 0));
- ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
+ ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
DBUG_RETURN(0);
}
@@ -3228,7 +3216,6 @@ void select_insert::abort() {
table->file->ha_release_auto_increment();
}
- ha_rollback_stmt(thd);
DBUG_VOID_RETURN;
}
@@ -3667,7 +3654,10 @@ bool select_create::send_eof()
nevertheless.
*/
if (!table->s->tmp_table)
- ha_commit(thd); // Can fail, but we proceed anyway
+ {
+ ha_autocommit_or_rollback(thd, 0);
+ end_active_trans(thd);
+ }
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
@@ -3691,12 +3681,9 @@ void select_create::abort()
by removing the table, even for non-transactional tables.
*/
tmp_disable_binlog(thd);
- select_insert::abort();
- reenable_binlog(thd);
-
/*
- We roll back the statement, including truncating the transaction
- cache of the binary log, if the statement failed.
+ In select_insert::abort() we roll back the statement, including
+ truncating the transaction cache of the binary log.
We roll back the statement prior to deleting the table and prior
to releasing the lock on the table, since there might be potential
@@ -3707,8 +3694,9 @@ void select_create::abort()
of the table succeeded or not, since we need to reset the binary
log state.
*/
- if (thd->current_stmt_binlog_row_based)
- ha_rollback_stmt(thd);
+ select_insert::abort();
+ reenable_binlog(thd);
+
if (m_plock)
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 5352f8efbbb..b07efc62a00 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1947,7 +1947,7 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
}
-void st_select_lex_unit::print(String *str)
+void st_select_lex_unit::print(String *str, enum_query_type query_type)
{
bool union_all= !union_distinct;
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
@@ -1962,7 +1962,7 @@ void st_select_lex_unit::print(String *str)
}
if (sl->braces)
str->append('(');
- sl->print(thd, str);
+ sl->print(thd, str, query_type);
if (sl->braces)
str->append(')');
}
@@ -1971,16 +1971,19 @@ void st_select_lex_unit::print(String *str)
if (fake_select_lex->order_list.elements)
{
str->append(STRING_WITH_LEN(" order by "));
- fake_select_lex->print_order(str,
- (ORDER *) fake_select_lex->
- order_list.first);
+ fake_select_lex->print_order(
+ str,
+ (ORDER *) fake_select_lex->order_list.first,
+ query_type);
}
- fake_select_lex->print_limit(thd, str);
+ fake_select_lex->print_limit(thd, str, query_type);
}
}
-void st_select_lex::print_order(String *str, ORDER *order)
+void st_select_lex::print_order(String *str,
+ ORDER *order,
+ enum_query_type query_type)
{
for (; order; order= order->next)
{
@@ -1991,7 +1994,7 @@ void st_select_lex::print_order(String *str, ORDER *order)
str->append(buffer, length);
}
else
- (*order->item)->print(str);
+ (*order->item)->print(str, query_type);
if (!order->asc)
str->append(STRING_WITH_LEN(" desc"));
if (order->next)
@@ -2000,7 +2003,9 @@ void st_select_lex::print_order(String *str, ORDER *order)
}
-void st_select_lex::print_limit(THD *thd, String *str)
+void st_select_lex::print_limit(THD *thd,
+ String *str,
+ enum_query_type query_type)
{
SELECT_LEX_UNIT *unit= master_unit();
Item_subselect *item= unit->item;
@@ -2019,10 +2024,10 @@ void st_select_lex::print_limit(THD *thd, String *str)
str->append(STRING_WITH_LEN(" limit "));
if (offset_limit)
{
- offset_limit->print(str);
+ offset_limit->print(str, query_type);
str->append(',');
}
- select_limit->print(str);
+ select_limit->print(str, query_type);
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index ef0a9bb11ef..b1a0d506382 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -543,7 +543,7 @@ public:
inline void unclean() { cleaned= 0; }
void reinit_exec_mechanism();
- void print(String *str);
+ void print(String *str, enum_query_type query_type);
bool add_fake_select_lex(THD *thd);
void init_prepare_fake_select_lex(THD *thd);
@@ -762,9 +762,11 @@ public:
init_select();
}
bool setup_ref_array(THD *thd, uint order_group_num);
- void print(THD *thd, String *str);
- static void print_order(String *str, ORDER *order);
- void print_limit(THD *thd, String *str);
+ void print(THD *thd, String *str, enum_query_type query_type);
+ static void print_order(String *str,
+ ORDER *order,
+ enum_query_type query_type);
+ void print_limit(THD *thd, String *str, enum_query_type query_type);
void fix_prepare_information(THD *thd, Item **conds, Item **having_conds);
/*
Destroy the used execution plan (JOIN) of this subtree (this
@@ -1513,10 +1515,8 @@ typedef struct st_lex : public Query_tables_list
/* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert;
- /** Start of SELECT of CREATE VIEW statement */
- const char* create_view_select_start;
- /** End of SELECT of CREATE VIEW statement */
- const char* create_view_select_end;
+ /** SELECT of CREATE VIEW statement */
+ LEX_STRING create_view_select;
/** Start of 'ON table', in trigger statements. */
const char* raw_trg_on_table_name_begin;
@@ -1710,8 +1710,6 @@ typedef struct st_lex : public Query_tables_list
*/
bool use_only_table_context;
- LEX_STRING view_body_utf8;
-
/*
Reference to a struct that contains information in various commands
to add/create/drop/change table spaces.
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index c96fbb80b0c..4d5dc8e6f06 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -470,9 +470,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
}
}
#endif /*!EMBEDDED_LIBRARY*/
- if (transactional_table)
- ha_autocommit_or_rollback(thd,error);
-
error= -1; // Error on read
goto err;
}
@@ -510,20 +507,13 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
}
}
#endif /*!EMBEDDED_LIBRARY*/
- if (transactional_table)
- error=ha_autocommit_or_rollback(thd,error);
/* ok to client sent only after binlog write and engine commit */
- send_ok(thd, info.copied + info.deleted, 0L, name);
+ my_ok(thd, info.copied + info.deleted, 0L, name);
err:
DBUG_ASSERT(transactional_table || !(info.copied || info.deleted) ||
thd->transaction.stmt.modified_non_trans_table);
table->file->ha_release_auto_increment();
- if (thd->lock)
- {
- mysql_unlock_tables(thd, thd->lock);
- thd->lock=0;
- }
table->auto_increment_field_not_null= FALSE;
thd->abort_on_warning= 0;
DBUG_RETURN(error);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4dd600835ce..bc97e783b77 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -913,7 +913,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (!mysql_change_db(thd, &tmp, FALSE))
{
general_log_write(thd, command, thd->db, thd->db_length);
- send_ok(thd);
+ my_ok(thd);
}
break;
}
@@ -921,7 +921,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_REGISTER_SLAVE:
{
if (!register_slave(thd, (uchar*)packet, packet_length))
- send_ok(thd);
+ my_ok(thd);
break;
}
#endif
@@ -1322,7 +1322,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
general_log_print(thd, command, NullS);
if (!reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, &not_used))
- send_ok(thd);
+ my_ok(thd);
break;
}
#ifndef EMBEDDED_LIBRARY
@@ -1348,7 +1348,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
DBUG_PRINT("quit",("Got shutdown command for level %u", level));
general_log_print(thd, command, NullS);
- send_eof(thd);
+ my_eof(thd);
close_thread_tables(thd); // Free before kill
kill_mysql();
error=TRUE;
@@ -1386,7 +1386,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
(uint) (queries_per_second1000 % 1000));
#ifdef EMBEDDED_LIBRARY
/* Store the buffer in permanent memory */
- send_ok(thd, 0, 0, buff);
+ my_ok(thd, 0, 0, buff);
#endif
#ifdef SAFEMALLOC
if (sf_malloc_cur_memory) // Using SAFEMALLOC
@@ -1407,7 +1407,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
case COM_PING:
status_var_increment(thd->status_var.com_other);
- send_ok(thd); // Tell client we are alive
+ my_ok(thd); // Tell client we are alive
break;
case COM_PROCESS_INFO:
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
@@ -1434,11 +1434,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
switch (opt_command) {
case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
- send_eof(thd);
+ my_eof(thd);
break;
case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
- send_eof(thd);
+ my_eof(thd);
break;
default:
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
@@ -1452,7 +1452,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; /* purecov: inspected */
mysql_print_status();
general_log_print(thd, command, NullS);
- send_eof(thd);
+ my_eof(thd);
break;
case COM_SLEEP:
case COM_CONNECT: // Impossible here
@@ -1464,21 +1464,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
}
- thd_proc_info(thd, "closing tables");
- /* Free tables */
- close_thread_tables(thd);
+ /* If commit fails, we should be able to reset the OK status. */
+ thd->main_da.can_overwrite_status= TRUE;
+ ha_autocommit_or_rollback(thd, thd->is_error());
+ thd->main_da.can_overwrite_status= FALSE;
+
+ thd->transaction.stmt.reset();
- /*
- assume handlers auto-commit (if some doesn't - transaction handling
- in MySQL should be redesigned to support it; it's a big change,
- and it's not worth it - better to commit explicitly only writing
- transactions, read-only ones should better take care of themselves.
- saves some work in 2pc too)
- see also sql_base.cc - close_thread_tables()
- */
- bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt));
- if (!thd->active_transaction())
- thd->transaction.xid_state.xid.null();
/* report error issued during command execution */
if (thd->killed_errno())
@@ -1495,6 +1487,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
net_end_statement(thd);
query_cache_end_of_result(thd);
+ thd->proc_info= "closing tables";
+ /* Free tables */
+ close_thread_tables(thd);
+
log_slow_statement(thd);
thd_proc_info(thd, "cleaning up");
@@ -2079,7 +2075,7 @@ mysql_execute_command(THD *thd)
break;
case SQLCOM_EMPTY_QUERY:
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_HELP:
@@ -2246,7 +2242,7 @@ mysql_execute_command(THD *thd)
{
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
"the master info structure does not exist");
- send_ok(thd);
+ my_ok(thd);
}
pthread_mutex_unlock(&LOCK_active_mi);
break;
@@ -2304,7 +2300,7 @@ mysql_execute_command(THD *thd)
if (!fetch_master_table(thd, first_table->db, first_table->table_name,
active_mi, 0, 0))
{
- send_ok(thd);
+ my_ok(thd);
}
pthread_mutex_unlock(&LOCK_active_mi);
break;
@@ -2515,7 +2511,7 @@ mysql_execute_command(THD *thd)
&alter_info, 0, 0);
}
if (!res)
- send_ok(thd);
+ my_ok(thd);
}
/* put tables back for PS rexecuting */
@@ -3010,10 +3006,8 @@ end_with_restore_list:
/* INSERT ... SELECT should invalidate only the very first table */
TABLE_LIST *save_table= first_table->next_local;
first_table->next_local= 0;
- mysql_unlock_tables(thd, thd->lock);
query_cache_invalidate3(thd, first_table, 1);
first_table->next_local= save_table;
- thd->lock=0;
}
delete sel_result;
}
@@ -3200,7 +3194,7 @@ end_with_restore_list:
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
if (!mysql_change_db(thd, &db_str, FALSE))
- send_ok(thd);
+ my_ok(thd);
break;
}
@@ -3253,7 +3247,7 @@ end_with_restore_list:
about the ONE_SHOT property of that SET. So we use a |= instead of = .
*/
thd->one_shot_set|= lex->one_shot_set;
- send_ok(thd);
+ my_ok(thd);
}
break;
}
@@ -3273,7 +3267,7 @@ end_with_restore_list:
}
if (thd->global_read_lock)
unlock_global_read_lock(thd);
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_LOCK_TABLES:
unlock_locked_tables(thd);
@@ -3294,7 +3288,7 @@ end_with_restore_list:
#endif /*HAVE_QUERY_CACHE*/
thd->locked_tables=thd->lock;
thd->lock=0;
- send_ok(thd);
+ my_ok(thd);
}
else
{
@@ -3431,7 +3425,7 @@ end_with_restore_list:
res= mysql_upgrade_db(thd, db);
if (!res)
- send_ok(thd);
+ my_ok(thd);
break;
}
case SQLCOM_ALTER_DB:
@@ -3516,7 +3510,7 @@ end_with_restore_list:
}
DBUG_PRINT("info",("DDL error code=%d", res));
if (!res)
- send_ok(thd);
+ my_ok(thd);
} while (0);
/* Don't do it, if we are inside a SP */
@@ -3535,7 +3529,7 @@ end_with_restore_list:
if (!(res= Events::drop_event(thd,
lex->spname->m_db, lex->spname->m_name,
lex->drop_if_exists)))
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_CREATE_FUNCTION: // UDF function
{
@@ -3543,7 +3537,7 @@ end_with_restore_list:
break;
#ifdef HAVE_DLOPEN
if (!(res = mysql_create_function(thd, &lex->udf)))
- send_ok(thd);
+ my_ok(thd);
#else
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
res= TRUE;
@@ -3560,7 +3554,7 @@ end_with_restore_list:
goto error;
/* Conditionally writes to binlog */
if (!(res= mysql_create_user(thd, lex->users_list)))
- send_ok(thd);
+ my_ok(thd);
break;
}
case SQLCOM_DROP_USER:
@@ -3572,7 +3566,7 @@ end_with_restore_list:
goto error;
/* Conditionally writes to binlog */
if (!(res= mysql_drop_user(thd, lex->users_list)))
- send_ok(thd);
+ my_ok(thd);
break;
}
case SQLCOM_RENAME_USER:
@@ -3584,7 +3578,7 @@ end_with_restore_list:
goto error;
/* Conditionally writes to binlog */
if (!(res= mysql_rename_user(thd, lex->users_list)))
- send_ok(thd);
+ my_ok(thd);
break;
}
case SQLCOM_REVOKE_ALL:
@@ -3596,7 +3590,7 @@ end_with_restore_list:
break;
/* Conditionally writes to binlog */
if (!(res = mysql_revoke_all(thd, lex->users_list)))
- send_ok(thd);
+ my_ok(thd);
break;
}
case SQLCOM_REVOKE:
@@ -3733,7 +3727,7 @@ end_with_restore_list:
{
write_bin_log(thd, FALSE, thd->query, thd->query_length);
}
- send_ok(thd);
+ my_ok(thd);
}
break;
@@ -3805,19 +3799,19 @@ end_with_restore_list:
}
if (begin_trans(thd))
goto error;
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_COMMIT:
if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
goto error;
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_ROLLBACK:
if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
goto error;
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_RELEASE_SAVEPOINT:
{
@@ -3834,7 +3828,7 @@ end_with_restore_list:
if (ha_release_savepoint(thd, sv))
res= TRUE; // cannot happen
else
- send_ok(thd);
+ my_ok(thd);
thd->transaction.savepoints=sv->prev;
}
else
@@ -3863,7 +3857,7 @@ end_with_restore_list:
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
- send_ok(thd);
+ my_ok(thd);
}
thd->transaction.savepoints=sv;
}
@@ -3874,7 +3868,7 @@ end_with_restore_list:
case SQLCOM_SAVEPOINT:
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
thd->in_sub_stmt) || !opt_using_transactions)
- send_ok(thd);
+ my_ok(thd);
else
{
SAVEPOINT **sv, *newsv;
@@ -3911,7 +3905,7 @@ end_with_restore_list:
{
newsv->prev=thd->transaction.savepoints;
thd->transaction.savepoints=newsv;
- send_ok(thd);
+ my_ok(thd);
}
}
break;
@@ -3984,7 +3978,6 @@ end_with_restore_list:
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_GRANT_FAIL,
ER(ER_PROC_AUTO_GRANT_FAIL));
- close_thread_tables(thd);
}
#endif
break;
@@ -4012,7 +4005,7 @@ end_with_restore_list:
create_sp_error:
if (sp_result != SP_OK )
goto error;
- send_ok(thd);
+ my_ok(thd);
break; /* break super switch */
} /* end case group bracket */
case SQLCOM_CALL:
@@ -4105,8 +4098,8 @@ create_sp_error:
thd->server_status&= ~bits_to_be_cleared;
if (!res)
- send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
- thd->row_count_func));
+ my_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
+ thd->row_count_func));
else
{
DBUG_ASSERT(thd->is_error() || thd->killed);
@@ -4183,7 +4176,7 @@ create_sp_error:
switch (sp_result)
{
case SP_OK:
- send_ok(thd);
+ my_ok(thd);
break;
case SP_KEY_NOT_FOUND:
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
@@ -4248,7 +4241,7 @@ create_sp_error:
if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
{
- send_ok(thd);
+ my_ok(thd);
break;
}
}
@@ -4265,7 +4258,7 @@ create_sp_error:
res= sp_result;
switch (sp_result) {
case SP_OK:
- send_ok(thd);
+ my_ok(thd);
break;
case SP_KEY_NOT_FOUND:
if (lex->drop_if_exists)
@@ -4274,7 +4267,7 @@ create_sp_error:
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
SP_COM_STRING(lex), lex->spname->m_name.str);
res= FALSE;
- send_ok(thd);
+ my_ok(thd);
break;
}
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
@@ -4406,7 +4399,7 @@ create_sp_error:
break;
}
thd->transaction.xid_state.xa_state=XA_ACTIVE;
- send_ok(thd);
+ my_ok(thd);
break;
}
if (thd->lex->xa_opt != XA_NONE)
@@ -4437,7 +4430,7 @@ create_sp_error:
thd->transaction.all.modified_non_trans_table= FALSE;
thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_XA_END:
/* fake it */
@@ -4458,7 +4451,7 @@ create_sp_error:
break;
}
thd->transaction.xid_state.xa_state=XA_IDLE;
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_XA_PREPARE:
if (thd->transaction.xid_state.xa_state != XA_IDLE)
@@ -4480,7 +4473,7 @@ create_sp_error:
break;
}
thd->transaction.xid_state.xa_state=XA_PREPARED;
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_XA_COMMIT:
if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
@@ -4492,7 +4485,7 @@ create_sp_error:
{
ha_commit_or_rollback_by_xid(thd->lex->xid, 1);
xid_cache_delete(xs);
- send_ok(thd);
+ my_ok(thd);
}
break;
}
@@ -4503,7 +4496,7 @@ create_sp_error:
if ((r= ha_commit(thd)))
my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
else
- send_ok(thd);
+ my_ok(thd);
}
else if (thd->transaction.xid_state.xa_state == XA_PREPARED &&
thd->lex->xa_opt == XA_NONE)
@@ -4518,7 +4511,7 @@ create_sp_error:
if (ha_commit_one_phase(thd, 1))
my_error(ER_XAER_RMERR, MYF(0));
else
- send_ok(thd);
+ my_ok(thd);
start_waiting_global_read_lock(thd);
}
}
@@ -4544,7 +4537,7 @@ create_sp_error:
{
ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
xid_cache_delete(xs);
- send_ok(thd);
+ my_ok(thd);
}
break;
}
@@ -4558,7 +4551,7 @@ create_sp_error:
if (ha_rollback(thd))
my_error(ER_XAER_RMERR, MYF(0));
else
- send_ok(thd);
+ my_ok(thd);
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
@@ -4572,16 +4565,16 @@ create_sp_error:
if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0, thd->db ? is_schema_db(thd->db) : 0))
break;
if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_INSTALL_PLUGIN:
if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
&thd->lex->ident)))
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_UNINSTALL_PLUGIN:
if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
- send_ok(thd);
+ my_ok(thd);
break;
case SQLCOM_BINLOG_BASE64_EVENT:
{
@@ -4608,7 +4601,7 @@ create_sp_error:
my_error(error, MYF(0), lex->server_options.server_name);
break;
}
- send_ok(thd, 1);
+ my_ok(thd, 1);
break;
}
case SQLCOM_ALTER_SERVER:
@@ -4627,7 +4620,7 @@ create_sp_error:
my_error(error, MYF(0), lex->server_options.server_name);
break;
}
- send_ok(thd, 1);
+ my_ok(thd, 1);
break;
}
case SQLCOM_DROP_SERVER:
@@ -4649,18 +4642,18 @@ create_sp_error:
}
else
{
- send_ok(thd, 0);
+ my_ok(thd, 0);
}
break;
}
- send_ok(thd, 1);
+ my_ok(thd, 1);
break;
}
default:
#ifndef EMBEDDED_LIBRARY
DBUG_ASSERT(0); /* Impossible */
#endif
- send_ok(thd);
+ my_ok(thd);
break;
}
thd_proc_info(thd, "query end");
@@ -4736,7 +4729,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
char buff[1024];
String str(buff,(uint32) sizeof(buff), system_charset_info);
str.length(0);
- thd->lex->unit.print(&str);
+ thd->lex->unit.print(&str, QT_ORDINARY);
str.append('\0');
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_YES, str.ptr());
@@ -6459,6 +6452,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
{
thd->thread_stack= (char*) &tmp_thd;
thd->store_globals();
+ lex_start(thd);
}
if (thd)
{
@@ -6671,7 +6665,7 @@ void sql_kill(THD *thd, ulong id, bool only_kill_query)
{
uint error;
if (!(error= kill_one_thread(thd, id, only_kill_query)))
- send_ok(thd);
+ my_ok(thd);
else
my_error(error, MYF(0), id);
}
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index eabf4526f7b..45a82782de0 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -3968,31 +3968,35 @@ static int fast_end_partition(THD *thd, ulonglong copied,
bool written_bin_log)
{
int error;
+ char tmp_name[80];
DBUG_ENTER("fast_end_partition");
thd->proc_info="end";
+
if (!is_empty)
query_cache_invalidate3(thd, table_list, 0);
- error= ha_commit_stmt(thd);
- if (ha_commit(thd))
+
+ error= ha_autocommit_or_rollback(thd, 0);
+ if (end_active_trans(thd))
error= 1;
- if (!error || is_empty)
- {
- char tmp_name[80];
- if ((!is_empty) && (!written_bin_log) &&
- (!thd->lex->no_write_to_binlog))
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
- close_thread_tables(thd);
- my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
- (ulong) (copied + deleted),
- (ulong) deleted,
- (ulong) 0);
- send_ok(thd, (ha_rows) (copied+deleted),0L,tmp_name);
- DBUG_RETURN(FALSE);
+
+ if (error)
+ {
+ /* If error during commit, no need to rollback, it's done. */
+ table->file->print_error(error, MYF(0));
+ DBUG_RETURN(TRUE);
}
- table->file->print_error(error, MYF(0));
- close_thread_tables(thd);
- DBUG_RETURN(TRUE);
+
+ if ((!is_empty) && (!written_bin_log) &&
+ (!thd->lex->no_write_to_binlog))
+ write_bin_log(thd, FALSE, thd->query, thd->query_length);
+
+ my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
+ (ulong) (copied + deleted),
+ (ulong) deleted,
+ (ulong) 0);
+ my_ok(thd, (ha_rows) (copied+deleted),0L, tmp_name);
+ DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 5a903a4fe1c..a027ffe9daa 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1524,6 +1524,44 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
/**
+ @brief Validate and prepare for execution CREATE VIEW statement
+
+ @param stmt prepared statement
+
+ @note This function handles create view commands.
+
+ @retval FALSE Operation was a success.
+ @retval TRUE An error occured.
+*/
+
+static bool mysql_test_create_view(Prepared_statement *stmt)
+{
+ DBUG_ENTER("mysql_test_create_view");
+ THD *thd= stmt->thd;
+ LEX *lex= stmt->lex;
+ bool res= TRUE;
+ /* Skip first table, which is the view we are creating */
+ bool link_to_local;
+ TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
+ TABLE_LIST *tables= lex->query_tables;
+
+ if (create_view_precheck(thd, tables, view, lex->create_view_mode))
+ goto err;
+
+ if (open_normal_and_derived_tables(thd, tables, 0))
+ goto err;
+
+ lex->view_prepare_mode= 1;
+ res= select_like_stmt_test(stmt, 0, 0);
+
+err:
+ /* put view back for PS rexecuting */
+ lex->link_first_table_back(view, link_to_local);
+ DBUG_RETURN(res);
+}
+
+
+/*
Validate and prepare for execution a multi update statement.
@param stmt prepared statement
@@ -1735,6 +1773,7 @@ static bool check_prepared_statement(Prepared_statement *stmt,
my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0));
goto error;
}
+ res= mysql_test_create_view(stmt);
break;
case SQLCOM_DO:
res= mysql_test_do_fields(stmt, tables, lex->insert_list);
@@ -2111,7 +2150,7 @@ void mysql_sql_stmt_prepare(THD *thd)
thd->stmt_map.erase(stmt);
}
else
- send_ok(thd, 0L, 0L, "Statement prepared");
+ my_ok(thd, 0L, 0L, "Statement prepared");
DBUG_VOID_RETURN;
}
@@ -2494,7 +2533,9 @@ void mysql_stmt_reset(THD *thd, char *packet)
stmt->state= Query_arena::PREPARED;
- send_ok(thd);
+ general_log_print(thd, thd->command, NullS);
+
+ my_ok(thd);
DBUG_VOID_RETURN;
}
@@ -2523,6 +2564,7 @@ void mysql_stmt_close(THD *thd, char *packet)
*/
DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
(void) stmt->deallocate();
+ general_log_print(thd, thd->command, NullS);
thd->main_da.disable_status();
@@ -2557,7 +2599,7 @@ void mysql_sql_stmt_close(THD *thd)
}
if (stmt->deallocate() == 0)
- send_ok(thd);
+ my_ok(thd);
}
/**
@@ -2630,6 +2672,9 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
stmt->last_errno= ER_OUTOFMEMORY;
sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0);
}
+
+ general_log_print(thd, thd->command, NullS);
+
DBUG_VOID_RETURN;
}
@@ -2662,7 +2707,7 @@ bool Select_fetch_protocol_binary::send_fields(List<Item> &list, uint flags)
bool Select_fetch_protocol_binary::send_eof()
{
- ::send_eof(thd);
+ ::my_eof(thd);
return FALSE;
}
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 1922fa3bc2b..c62cf6401ba 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -456,7 +456,7 @@ bool PROFILING::show_profiles()
if (protocol->write())
DBUG_RETURN(TRUE);
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 9dd8e1b70d4..fc87356e452 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -178,7 +178,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
if (!silent && !error)
{
write_bin_log(thd, TRUE, thd->query, thd->query_length);
- send_ok(thd);
+ my_ok(thd);
}
if (!error)
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index cdce2fa695b..932b7a67b4d 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -252,7 +252,7 @@ bool purge_error_message(THD* thd, int res)
my_message(errmsg, ER(errmsg), MYF(0));
return TRUE;
}
- send_ok(thd);
+ my_ok(thd);
return FALSE;
}
@@ -262,7 +262,7 @@ bool purge_master_logs(THD* thd, const char* to_log)
char search_file_name[FN_REFLEN];
if (!mysql_bin_log.is_open())
{
- send_ok(thd);
+ my_ok(thd);
return FALSE;
}
@@ -277,7 +277,7 @@ bool purge_master_logs_before_date(THD* thd, time_t purge_time)
{
if (!mysql_bin_log.is_open())
{
- send_ok(thd);
+ my_ok(thd);
return 0;
}
return purge_error_message(thd,
@@ -738,7 +738,7 @@ end:
end_io_cache(&log);
(void)my_close(file, MYF(MY_WME));
- send_eof(thd);
+ my_eof(thd);
thd_proc_info(thd, "Waiting to finalize termination");
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = 0;
@@ -884,7 +884,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
DBUG_RETURN(1);
}
else if (net_report)
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(0);
}
@@ -936,7 +936,7 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
DBUG_RETURN(1);
}
else if (net_report)
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(0);
}
@@ -1279,7 +1279,7 @@ bool change_master(THD* thd, Master_info* mi)
unlock_slave_threads(mi);
thd_proc_info(thd, 0);
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(FALSE);
}
@@ -1453,7 +1453,7 @@ err:
my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
"SHOW BINLOG EVENTS", errmsg);
else
- send_eof(thd);
+ my_eof(thd);
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = 0;
@@ -1490,7 +1490,7 @@ bool show_binlog_info(THD* thd)
if (protocol->write())
DBUG_RETURN(TRUE);
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -1572,7 +1572,7 @@ bool show_binlogs(THD* thd)
goto err;
}
mysql_bin_log.unlock_index();
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
err:
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d7e7be87d23..a520f9c57cf 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -945,7 +945,8 @@ JOIN::optimize()
make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0);
DBUG_EXECUTE("where",
print_where(table_independent_conds,
- "where after opt_sum_query()"););
+ "where after opt_sum_query()",
+ QT_ORDINARY););
conds= table_independent_conds;
}
}
@@ -1025,7 +1026,10 @@ JOIN::optimize()
{
conds= substitute_for_best_equal_field(conds, cond_equal, map2table);
conds->update_used_tables();
- DBUG_EXECUTE("where", print_where(conds, "after substitute_best_equal"););
+ DBUG_EXECUTE("where",
+ print_where(conds,
+ "after substitute_best_equal",
+ QT_ORDINARY););
}
/*
@@ -2088,12 +2092,14 @@ JOIN::exec()
curr_table->select_cond= curr_table->select->cond;
curr_table->select_cond->top_level_item();
DBUG_EXECUTE("where",print_where(curr_table->select->cond,
- "select and having"););
+ "select and having",
+ QT_ORDINARY););
curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having,
~ (table_map) 0,
~used_tables);
DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
- "having after sort"););
+ "having after sort",
+ QT_ORDINARY););
}
}
{
@@ -5837,7 +5843,8 @@ static void add_not_null_conds(JOIN *join)
if (notnull->fix_fields(join->thd, &notnull))
DBUG_VOID_RETURN;
DBUG_EXECUTE("where",print_where(notnull,
- referred_tab->table->alias););
+ referred_tab->table->alias,
+ QT_ORDINARY););
add_cond_and_fix(&referred_tab->select_cond, notnull);
}
}
@@ -5995,7 +6002,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
make_cond_for_table(cond,
join->const_table_map,
(table_map) 0);
- DBUG_EXECUTE("where",print_where(const_cond,"constants"););
+ DBUG_EXECUTE("where",print_where(const_cond,"constants", QT_ORDINARY););
for (JOIN_TAB *tab= join->join_tab+join->const_tables;
tab < join->join_tab+join->tables ; tab++)
{
@@ -6096,7 +6103,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
if (tmp || !cond)
{
- DBUG_EXECUTE("where",print_where(tmp,tab->table->alias););
+ DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY););
SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
thd->memdup((uchar*) select,
sizeof(*select)));
@@ -6136,7 +6143,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
tab->select_cond= sel->cond= NULL;
sel->head=tab->table;
- DBUG_EXECUTE("where",print_where(tmp,tab->table->alias););
+ DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY););
if (tab->quick)
{
/* Use quick key read if it's a constant and it's not used
@@ -6248,7 +6255,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
current_map,
current_map)))
{
- DBUG_EXECUTE("where",print_where(tmp,"cache"););
+ DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
tab->cache.select=(SQL_SELECT*)
thd->memdup((uchar*) sel, sizeof(SQL_SELECT));
tab->cache.select->cond=tmp;
@@ -8872,10 +8879,10 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
predicate. Substitute a constant instead of this field if the
multiple equality contains a constant.
*/
- DBUG_EXECUTE("where", print_where(conds, "original"););
+ DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY););
conds= build_equal_items(join->thd, conds, NULL, join_list,
&join->cond_equal);
- DBUG_EXECUTE("where",print_where(conds,"after equal_items"););
+ DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
/* change field = field to field = const for each found field = const */
propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
@@ -8883,9 +8890,9 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
Remove all instances of item == item
Remove all and-levels where CONST item != CONST item
*/
- DBUG_EXECUTE("where",print_where(conds,"after const change"););
+ DBUG_EXECUTE("where",print_where(conds,"after const change", QT_ORDINARY););
conds= remove_eq_conds(thd, conds, cond_value) ;
- DBUG_EXECUTE("info",print_where(conds,"after remove"););
+ DBUG_EXECUTE("info",print_where(conds,"after remove", QT_ORDINARY););
}
DBUG_RETURN(conds);
}
@@ -13357,7 +13364,7 @@ static bool fix_having(JOIN *join, Item **having)
JOIN_TAB *table=&join->join_tab[join->const_tables];
table_map used_tables= join->const_table_map | table->table->map;
- DBUG_EXECUTE("where",print_where(*having,"having"););
+ DBUG_EXECUTE("where",print_where(*having,"having", QT_ORDINARY););
Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables);
if (sort_table_cond)
{
@@ -13374,9 +13381,11 @@ static bool fix_having(JOIN *join, Item **having)
table->select_cond=table->select->cond;
table->select_cond->top_level_item();
DBUG_EXECUTE("where",print_where(table->select_cond,
- "select and having"););
+ "select and having",
+ QT_ORDINARY););
*having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
- DBUG_EXECUTE("where",print_where(*having,"having after make_cond"););
+ DBUG_EXECUTE("where",
+ print_where(*having,"having after make_cond", QT_ORDINARY););
}
return 0;
}
@@ -15043,7 +15052,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
char buff[256];
String str(buff,sizeof(buff),&my_charset_bin);
str.length(0);
- item->print(&str);
+ item->print(&str, QT_ORDINARY);
item_field->name= sql_strmake(str.ptr(),str.length());
}
#endif
@@ -16084,7 +16093,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (thd->lex->describe & DESCRIBE_EXTENDED)
{
extra.append(STRING_WITH_LEN(": "));
- ((COND *)pushed_cond)->print(&extra);
+ ((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
}
}
else
@@ -16233,9 +16242,13 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
@param thd thread handler
@param str string where table should be printed
@param tables list of tables in join
+ @query_type type of the query is being generated
*/
-static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
+static void print_join(THD *thd,
+ String *str,
+ List<TABLE_LIST> *tables,
+ enum_query_type query_type)
{
/* List is reversed => we should reverse it before using */
List_iterator_fast<TABLE_LIST> ti(*tables);
@@ -16248,7 +16261,7 @@ static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
*t= ti++;
DBUG_ASSERT(tables->elements >= 1);
- (*table)->print(thd, str);
+ (*table)->print(thd, str, query_type);
TABLE_LIST **end= table + tables->elements;
for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
@@ -16263,11 +16276,11 @@ static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
str->append(STRING_WITH_LEN(" straight_join "));
else
str->append(STRING_WITH_LEN(" join "));
- curr->print(thd, str);
+ curr->print(thd, str, query_type);
if (curr->on_expr)
{
str->append(STRING_WITH_LEN(" on("));
- curr->on_expr->print(str);
+ curr->on_expr->print(str, query_type);
str->append(')');
}
}
@@ -16314,15 +16327,15 @@ Index_hint::print(THD *thd, String *str)
/**
Print table as it should be in join list.
- @param str string where table should bbe printed
+ @param str string where table should be printed
*/
-void TABLE_LIST::print(THD *thd, String *str)
+void TABLE_LIST::print(THD *thd, String *str, enum_query_type query_type)
{
if (nested_join)
{
str->append('(');
- print_join(thd, str, &nested_join->join_list);
+ print_join(thd, str, &nested_join->join_list, query_type);
str->append(')');
}
else
@@ -16345,7 +16358,7 @@ void TABLE_LIST::print(THD *thd, String *str)
{
// A derived table
str->append('(');
- derived->print(str);
+ derived->print(str, query_type);
str->append(')');
cmp_name= ""; // Force printing of alias
}
@@ -16405,7 +16418,7 @@ void TABLE_LIST::print(THD *thd, String *str)
}
-void st_select_lex::print(THD *thd, String *str)
+void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
{
/* QQ: thd may not be set for sub queries, but this should be fixed */
if (!thd)
@@ -16453,7 +16466,7 @@ void st_select_lex::print(THD *thd, String *str)
first= 0;
else
str->append(',');
- item->print_item_w_name(str);
+ item->print_item_w_name(str, query_type);
}
/*
@@ -16464,7 +16477,7 @@ void st_select_lex::print(THD *thd, String *str)
{
str->append(STRING_WITH_LEN(" from "));
/* go through join tree */
- print_join(thd, str, &top_join_list);
+ print_join(thd, str, &top_join_list, query_type);
}
// Where
@@ -16475,7 +16488,7 @@ void st_select_lex::print(THD *thd, String *str)
{
str->append(STRING_WITH_LEN(" where "));
if (cur_where)
- cur_where->print(str);
+ cur_where->print(str, query_type);
else
str->append(cond_value != Item::COND_FALSE ? "1" : "0");
}
@@ -16484,7 +16497,7 @@ void st_select_lex::print(THD *thd, String *str)
if (group_list.elements)
{
str->append(STRING_WITH_LEN(" group by "));
- print_order(str, (ORDER *) group_list.first);
+ print_order(str, (ORDER *) group_list.first, query_type);
switch (olap)
{
case CUBE_TYPE:
@@ -16507,7 +16520,7 @@ void st_select_lex::print(THD *thd, String *str)
{
str->append(STRING_WITH_LEN(" having "));
if (cur_having)
- cur_having->print(str);
+ cur_having->print(str, query_type);
else
str->append(having_value != Item::COND_FALSE ? "1" : "0");
}
@@ -16515,11 +16528,11 @@ void st_select_lex::print(THD *thd, String *str)
if (order_list.elements)
{
str->append(STRING_WITH_LEN(" order by "));
- print_order(str, (ORDER *) order_list.first);
+ print_order(str, (ORDER *) order_list.first, query_type);
}
// limit
- print_limit(thd, str);
+ print_limit(thd, str, query_type);
// PROCEDURE unsupported here
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 6d817cb0620..2c4251f0fde 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -224,7 +224,7 @@ bool mysqld_show_authors(THD *thd)
if (protocol->write())
DBUG_RETURN(TRUE);
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -258,7 +258,7 @@ bool mysqld_show_contributors(THD *thd)
if (protocol->write())
DBUG_RETURN(TRUE);
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -331,7 +331,7 @@ bool mysqld_show_privileges(THD *thd)
if (protocol->write())
DBUG_RETURN(TRUE);
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -419,7 +419,7 @@ bool mysqld_show_column_types(THD *thd)
if (protocol->write())
DBUG_RETURN(TRUE);
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -666,7 +666,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
if (protocol->write())
DBUG_RETURN(TRUE);
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -747,7 +747,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
if (protocol->write())
DBUG_RETURN(TRUE);
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
}
@@ -789,7 +789,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
table->use_all_columns();
if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
DBUG_VOID_RETURN;
- send_eof(thd);
+ my_eof(thd);
DBUG_VOID_RETURN;
}
@@ -1582,7 +1582,7 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
We can't just use table->query, because our SQL_MODE may trigger
a different syntax, like when ANSI_QUOTES is defined.
*/
- table->view->unit.print(buff);
+ table->view->unit.print(buff, QT_ORDINARY);
if (table->with_check != VIEW_CHECK_NONE)
{
@@ -1738,7 +1738,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if (protocol->write())
break; /* purecov: inspected */
}
- send_eof(thd);
+ my_eof(thd);
DBUG_VOID_RETURN;
}
@@ -6760,7 +6760,7 @@ static bool show_create_trigger_impl(THD *thd,
ret_code= p->write();
if (!ret_code)
- send_eof(thd);
+ my_eof(thd);
return ret_code != 0;
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 505bcd1b421..c62d0545fda 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1497,7 +1497,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
if (error)
DBUG_RETURN(TRUE);
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(FALSE);
}
@@ -3001,6 +3001,37 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
(qsort_cmp) sort_keys);
create_info->null_bits= null_fields;
+ /* Check fields. */
+ it.rewind();
+ while ((sql_field=it++))
+ {
+ Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
+
+ if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
+ !sql_field->def &&
+ sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
+ (sql_field->flags & NOT_NULL_FLAG) &&
+ (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
+ {
+ /*
+ An error should be reported if:
+ - NO_ZERO_DATE SQL mode is active;
+ - there is no explicit DEFAULT clause (default column value);
+ - this is a TIMESTAMP column;
+ - the column is not NULL;
+ - this is not the DEFAULT CURRENT_TIMESTAMP column.
+
+ In other words, an error should be reported if
+ - NO_ZERO_DATE SQL mode is active;
+ - the column definition is equivalent to
+ 'column_name TIMESTAMP DEFAULT 0'.
+ */
+
+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
+ DBUG_RETURN(TRUE);
+ }
+ }
+
DBUG_RETURN(FALSE);
}
@@ -4131,6 +4162,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
switch ((*prepare_func)(thd, table, check_opt)) {
case 1: // error, message written to net
ha_autocommit_or_rollback(thd, 1);
+ end_trans(thd, ROLLBACK);
close_thread_tables(thd);
DBUG_PRINT("admin", ("simple error, admin next table"));
continue;
@@ -4189,6 +4221,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
table_name);
protocol->store(buff, length, system_charset_info);
ha_autocommit_or_rollback(thd, 0);
+ end_trans(thd, COMMIT);
close_thread_tables(thd);
lex->reset_query_tables_list(FALSE);
table->table=0; // For query cache
@@ -4461,17 +4494,19 @@ send_result_message:
}
}
ha_autocommit_or_rollback(thd, 0);
+ end_trans(thd, COMMIT);
close_thread_tables(thd);
table->table=0; // For query cache
if (protocol->write())
goto err;
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
- err:
+err:
ha_autocommit_or_rollback(thd, 1);
+ end_trans(thd, ROLLBACK);
close_thread_tables(thd); // Shouldn't be needed
if (table)
table->table=0;
@@ -4994,8 +5029,8 @@ mysql_discard_or_import_tablespace(THD *thd,
query_cache_invalidate3(thd, table_list, 0);
/* The ALTER TABLE is always in its own transaction */
- error = ha_commit_stmt(thd);
- if (ha_commit(thd))
+ error = ha_autocommit_or_rollback(thd, 0);
+ if (end_active_trans(thd))
error=1;
if (error)
goto err;
@@ -5003,12 +5038,11 @@ mysql_discard_or_import_tablespace(THD *thd,
err:
ha_autocommit_or_rollback(thd, error);
- close_thread_tables(thd);
thd->tablespace_op=FALSE;
if (error == 0)
{
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(0);
}
@@ -5972,7 +6006,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
mysql_bin_log.write(&qinfo);
}
- send_ok(thd);
+ my_ok(thd);
}
unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
@@ -6210,7 +6244,7 @@ view_err:
if (!error)
{
write_bin_log(thd, TRUE, thd->query, thd->query_length);
- send_ok(thd);
+ my_ok(thd);
}
else if (error > 0)
{
@@ -6526,8 +6560,8 @@ view_err:
VOID(pthread_mutex_unlock(&LOCK_open));
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
alter_info->keys_onoff);
- error= ha_commit_stmt(thd);
- if (ha_commit(thd))
+ error= ha_autocommit_or_rollback(thd, 0);
+ if (end_active_trans(thd))
error= 1;
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
@@ -6615,7 +6649,7 @@ view_err:
/* Need to commit before a table is unlocked (NDB requirement). */
DBUG_PRINT("info", ("Committing before unlocking table"));
- if (ha_commit_stmt(thd) || ha_commit(thd))
+ if (ha_autocommit_or_rollback(thd, 0) || end_active_trans(thd))
goto err1;
committed= 1;
}
@@ -6846,7 +6880,7 @@ end_temporary:
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) (copied + deleted), (ulong) deleted,
(ulong) thd->cuted_fields);
- send_ok(thd, copied + deleted, 0L, tmp_name);
+ my_ok(thd, copied + deleted, 0L, tmp_name);
thd->some_tables_deleted=0;
DBUG_RETURN(FALSE);
@@ -7116,9 +7150,9 @@ copy_data_between_tables(TABLE *from,TABLE *to,
Ensure that the new table is saved properly to disk so that we
can do a rename
*/
- if (ha_commit_stmt(thd))
+ if (ha_autocommit_or_rollback(thd, 0))
error=1;
- if (ha_commit(thd))
+ if (end_active_trans(thd))
error=1;
err:
@@ -7277,7 +7311,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
goto err;
}
- send_eof(thd);
+ my_eof(thd);
DBUG_RETURN(FALSE);
err:
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 0fe299d4505..0bce4eb4a82 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -49,14 +49,14 @@ static const char *lock_descriptions[] =
#ifndef DBUG_OFF
void
-print_where(COND *cond,const char *info)
+print_where(COND *cond,const char *info, enum_query_type query_type)
{
if (cond)
{
char buff[256];
String str(buff,(uint32) sizeof(buff), system_charset_info);
str.length(0);
- cond->print(&str);
+ cond->print(&str, query_type);
str.append('\0');
DBUG_LOCK_FILE;
(void) fprintf(DBUG_FILE,"\nWHERE:(%s) ",info);
@@ -143,7 +143,7 @@ void TEST_filesort(SORT_FIELD *sortorder,uint s_length)
else
{
str.length(0);
- sortorder->item->print(&str);
+ sortorder->item->print(&str, QT_ORDINARY);
out.append(str);
}
}
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 4cd1d542375..d426904e4b2 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -516,7 +516,7 @@ end:
start_waiting_global_read_lock(thd);
if (!result)
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(result);
}
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 30e8829d764..ae3f43eba5b 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -382,6 +382,14 @@ static udf_func *add_udf(LEX_STRING *name, Item_result ret, char *dl,
}
+/**
+ Create a user defined function.
+
+ @note Like implementations of other DDL/DML in MySQL, this function
+ relies on the caller to close the thread tables. This is done in the
+ end of dispatch_command().
+*/
+
int mysql_create_function(THD *thd,udf_func *udf)
{
int error;
@@ -489,7 +497,6 @@ int mysql_create_function(THD *thd,udf_func *udf)
table->field[3]->store((longlong) u_d->type, TRUE);
error = table->file->ha_write_row(table->record[0]);
- close_thread_tables(thd);
if (error)
{
my_error(ER_ERROR_ON_WRITE, MYF(0), "mysql.func", error);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 4d075e3308d..7c9ead7591c 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -319,7 +319,7 @@ int mysql_update(THD *thd,
if (prune_partitions(thd, table, conds))
{
free_underlaid_joins(thd, select_lex);
- send_ok(thd); // No matching records
+ my_ok(thd); // No matching records
DBUG_RETURN(0);
}
#endif
@@ -336,7 +336,7 @@ int mysql_update(THD *thd,
{
DBUG_RETURN(1); // Error in where
}
- send_ok(thd); // No matching records
+ my_ok(thd); // No matching records
DBUG_RETURN(0);
}
if (!select && limit != HA_POS_ERROR)
@@ -643,14 +643,6 @@ int mysql_update(THD *thd,
updated++;
else
error= 0;
-
- if (table->triggers &&
- table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
- TRG_ACTION_AFTER, TRUE))
- {
- error= 1;
- break;
- }
}
else if (!ignore ||
table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
@@ -669,6 +661,14 @@ int mysql_update(THD *thd,
}
}
+ if (table->triggers &&
+ table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
+ TRG_ACTION_AFTER, TRUE))
+ {
+ error= 1;
+ break;
+ }
+
if (!--limit && using_limit)
{
/*
@@ -803,17 +803,6 @@ int mysql_update(THD *thd,
}
DBUG_ASSERT(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table);
free_underlaid_joins(thd, select_lex);
- if (transactional_table)
- {
- if (ha_autocommit_or_rollback(thd, error >= 0))
- error=1;
- }
-
- if (thd->lock)
- {
- mysql_unlock_tables(thd, thd->lock);
- thd->lock=0;
- }
/* If LAST_INSERT_ID(X) was used, report X */
id= thd->arg_of_last_insert_id_function ?
@@ -826,7 +815,7 @@ int mysql_update(THD *thd,
(ulong) thd->cuted_fields);
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
- send_ok(thd, (ulong) thd->row_count_func, id, buff);
+ my_ok(thd, (ulong) thd->row_count_func, id, buff);
DBUG_PRINT("info",("%ld records updated", (long) updated));
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
@@ -1644,12 +1633,12 @@ bool multi_update::send_data(List<Item> &not_used_values)
trans_safe= 0;
thd->transaction.stmt.modified_non_trans_table= TRUE;
}
- if (table->triggers &&
- table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
- TRG_ACTION_AFTER, TRUE))
- DBUG_RETURN(1);
}
}
+ if (table->triggers &&
+ table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
+ TRG_ACTION_AFTER, TRUE))
+ DBUG_RETURN(1);
}
else
{
@@ -1716,13 +1705,8 @@ void multi_update::abort()
If not attempt to do remaining updates.
*/
- if (trans_safe)
+ if (! trans_safe)
{
- DBUG_ASSERT(transactional_tables);
- (void) ha_autocommit_or_rollback(thd, 1);
- }
- else
- {
DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table);
if (do_update && table_count > 1)
{
@@ -1754,11 +1738,6 @@ void multi_update::abort()
thd->transaction.all.modified_non_trans_table= TRUE;
}
DBUG_ASSERT(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
-
- if (transactional_tables)
- {
- (void) ha_autocommit_or_rollback(thd, 1);
- }
}
@@ -1881,12 +1860,12 @@ int multi_update::do_updates()
updated++;
else
local_error= 0;
-
- if (table->triggers &&
- table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
- TRG_ACTION_AFTER, TRUE))
- goto err2;
}
+
+ if (table->triggers &&
+ table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
+ TRG_ACTION_AFTER, TRUE))
+ goto err2;
}
if (updated != org_updated)
@@ -1996,12 +1975,6 @@ bool multi_update::send_eof()
if (local_error != 0)
error_handled= TRUE; // to force early leave from ::send_error()
- if (transactional_tables)
- {
- if (ha_autocommit_or_rollback(thd, local_error != 0))
- local_error=1;
- }
-
if (local_error > 0) // if the above log write did not fail ...
{
/* Safety: If we haven't got an error before (can happen in do_updates) */
@@ -2016,6 +1989,6 @@ bool multi_update::send_eof()
(ulong) thd->cuted_fields);
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
- ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
+ ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 1a4d7d515a8..a654721de37 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -182,10 +182,33 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
TABLE_LIST decoy;
memcpy (&decoy, view, sizeof (TABLE_LIST));
- if (!open_table(thd, &decoy, thd->mem_root, &not_used, OPEN_VIEW_NO_PARSE) &&
- !decoy.view)
+
+ /*
+ Let's reset decoy.view before calling open_table(): when we start
+ supporting ALTER VIEW in PS/SP that may save us from a crash.
+ */
+
+ decoy.view= NULL;
+
+ /*
+ open_table() will return NULL if 'decoy' is idenitifying a view *and*
+ there is no TABLE object for that view in the table cache. However,
+ decoy.view will be set to 1.
+
+ If there is a TABLE-instance for the oject identified by 'decoy',
+ open_table() will return that instance no matter if it is a table or
+ a view.
+
+ Thus, there is no need to check for the return value of open_table(),
+ since the return value itself does not mean anything.
+ */
+
+ open_table(thd, &decoy, thd->mem_root, &not_used, OPEN_VIEW_NO_PARSE);
+
+ if (!decoy.view)
{
- /* It's a table */
+ /* It's a table. */
+ my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
return TRUE;
}
@@ -204,104 +227,31 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
return FALSE;
}
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
/**
- Creating/altering VIEW procedure
+ @brief CREATE VIEW privileges pre-check.
@param thd thread handler
+ @param tables tables used in the view
@param views views to create
@param mode VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
- @note This function handles both create and alter view commands.
-
@retval FALSE Operation was a success.
@retval TRUE An error occured.
*/
-bool mysql_create_view(THD *thd, TABLE_LIST *views,
- enum_view_create_mode mode)
+bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
+ enum_view_create_mode mode)
{
LEX *lex= thd->lex;
- bool link_to_local;
/* first table in list is target VIEW name => cut off it */
- TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
- TABLE_LIST *tables= lex->query_tables;
TABLE_LIST *tbl;
SELECT_LEX *select_lex= &lex->select_lex;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
SELECT_LEX *sl;
-#endif
- SELECT_LEX_UNIT *unit= &lex->unit;
- bool res= FALSE;
- DBUG_ENTER("mysql_create_view");
-
- /* This is ensured in the parser. */
- DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
- !lex->param_list.elements && !lex->derived_tables);
-
- if (mode != VIEW_CREATE_NEW)
- {
- if (mode == VIEW_ALTER &&
- fill_defined_view_parts(thd, view))
- {
- res= TRUE;
- goto err;
- }
- sp_cache_invalidate();
- }
-
- if (!lex->definer)
- {
- /*
- DEFINER-clause is missing; we have to create default definer in
- persistent arena to be PS/SP friendly.
- If this is an ALTER VIEW then the current user should be set as
- the definer.
- */
- Query_arena original_arena;
- Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
-
- if (!(lex->definer= create_default_definer(thd)))
- res= TRUE;
-
- if (ps_arena)
- thd->restore_active_arena(ps_arena, &original_arena);
+ bool res= TRUE;
+ DBUG_ENTER("create_view_precheck");
- if (res)
- goto err;
- }
-
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- /*
- check definer of view:
- - same as current user
- - current user has SUPER_ACL
- */
- if (lex->definer &&
- (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) != 0 ||
- my_strcasecmp(system_charset_info,
- lex->definer->host.str,
- thd->security_ctx->priv_host) != 0))
- {
- if (!(thd->security_ctx->master_access & SUPER_ACL))
- {
- my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
- res= TRUE;
- goto err;
- }
- else
- {
- if (!is_acl_user(lex->definer->host.str,
- lex->definer->user.str))
- {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_NO_SUCH_USER,
- ER(ER_NO_SUCH_USER),
- lex->definer->user.str,
- lex->definer->host.str);
- }
- }
- }
/*
Privilege check for view creation:
- user has CREATE VIEW privilege on view table
@@ -323,10 +273,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
(check_access(thd, DROP_ACL, view->db, &view->grant.privilege,
0, 0, is_schema_db(view->db)) ||
check_grant(thd, DROP_ACL, view, 0, 1, 0))))
- {
- res= TRUE;
goto err;
- }
+
for (sl= select_lex; sl; sl= sl->next_select())
{
for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
@@ -340,7 +288,6 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"ANY", thd->security_ctx->priv_user,
thd->security_ctx->priv_host, tbl->table_name);
- res= TRUE;
goto err;
}
/*
@@ -376,10 +323,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
if (check_access(thd, SELECT_ACL, tbl->db,
&tbl->grant.privilege, 0, 0, test(tbl->schema_table)) ||
check_grant(thd, SELECT_ACL, tbl, 0, 1, 0))
- {
- res= TRUE;
goto err;
- }
}
}
}
@@ -403,8 +347,126 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
}
}
}
+
+ res= FALSE;
+
+err:
+ DBUG_RETURN(res || thd->is_error());
+}
+
+#else
+
+bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
+ enum_view_create_mode mode)
+{
+ return FALSE;
+}
+
#endif
+
+/**
+ @brief Creating/altering VIEW procedure
+
+ @param thd thread handler
+ @param views views to create
+ @param mode VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
+
+ @note This function handles both create and alter view commands.
+
+ @retval FALSE Operation was a success.
+ @retval TRUE An error occured.
+*/
+
+bool mysql_create_view(THD *thd, TABLE_LIST *views,
+ enum_view_create_mode mode)
+{
+ LEX *lex= thd->lex;
+ bool link_to_local;
+ /* first table in list is target VIEW name => cut off it */
+ TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
+ TABLE_LIST *tables= lex->query_tables;
+ TABLE_LIST *tbl;
+ SELECT_LEX *select_lex= &lex->select_lex;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ SELECT_LEX *sl;
+#endif
+ SELECT_LEX_UNIT *unit= &lex->unit;
+ bool res= FALSE;
+ DBUG_ENTER("mysql_create_view");
+
+ /* This is ensured in the parser. */
+ DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
+ !lex->param_list.elements);
+
+ if (mode != VIEW_CREATE_NEW)
+ {
+ if (mode == VIEW_ALTER &&
+ fill_defined_view_parts(thd, view))
+ {
+ res= TRUE;
+ goto err;
+ }
+ sp_cache_invalidate();
+ }
+
+ if (!lex->definer)
+ {
+ /*
+ DEFINER-clause is missing; we have to create default definer in
+ persistent arena to be PS/SP friendly.
+ If this is an ALTER VIEW then the current user should be set as
+ the definer.
+ */
+ Query_arena original_arena;
+ Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
+
+ if (!(lex->definer= create_default_definer(thd)))
+ res= TRUE;
+
+ if (ps_arena)
+ thd->restore_active_arena(ps_arena, &original_arena);
+
+ if (res)
+ goto err;
+ }
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ /*
+ check definer of view:
+ - same as current user
+ - current user has SUPER_ACL
+ */
+ if (lex->definer &&
+ (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) != 0 ||
+ my_strcasecmp(system_charset_info,
+ lex->definer->host.str,
+ thd->security_ctx->priv_host) != 0))
+ {
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
+ {
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+ res= TRUE;
+ goto err;
+ }
+ else
+ {
+ if (!is_acl_user(lex->definer->host.str,
+ lex->definer->user.str))
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_NO_SUCH_USER,
+ ER(ER_NO_SUCH_USER),
+ lex->definer->user.str,
+ lex->definer->host.str);
+ }
+ }
+ }
+#endif
+
+ if ((res= create_view_precheck(thd, tables, view, mode)))
+ goto err;
+
if (open_and_lock_tables(thd, tables))
{
res= TRUE;
@@ -599,7 +661,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
if (res)
goto err;
- send_ok(thd);
+ my_ok(thd);
lex->link_first_table_back(view, link_to_local);
DBUG_RETURN(0);
@@ -696,8 +758,42 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
enum_view_create_mode mode)
{
LEX *lex= thd->lex;
- char buff[4096];
- String view_query(buff, sizeof (buff), thd->charset());
+
+ /*
+ View definition query -- a SELECT statement that fully defines view. It
+ is generated from the Item-tree built from the original (specified by
+ the user) query. The idea is that generated query should eliminates all
+ ambiguities and fix view structure at CREATE-time (once for all).
+ Item::print() virtual operation is used to generate view definition
+ query.
+
+ INFORMATION_SCHEMA query (IS query) -- a SQL statement describing a
+ view that is shown in INFORMATION_SCHEMA. Basically, it is 'view
+ definition query' with text literals converted to UTF8 and without
+ character set introducers.
+
+ For example:
+ Let's suppose we have:
+ CREATE TABLE t1(a INT, b INT);
+ User specified query:
+ CREATE VIEW v1(x, y) AS SELECT * FROM t1;
+ Generated query:
+ SELECT a AS x, b AS y FROM t1;
+ IS query:
+ SELECT a AS x, b AS y FROM t1;
+
+ View definition query is stored in the client character set.
+ */
+ char view_query_buff[4096];
+ String view_query(view_query_buff,
+ sizeof (view_query_buff),
+ thd->charset());
+
+ char is_query_buff[4096];
+ String is_query(is_query_buff,
+ sizeof (is_query_buff),
+ system_charset_info);
+
char md5[MD5_BUFF_LENGTH];
bool can_be_merged;
char dir_buff[FN_REFLEN], path_buff[FN_REFLEN];
@@ -705,12 +801,16 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
int error= 0;
DBUG_ENTER("mysql_register_view");
- /* print query */
+ /* Generate view definition and IS queries. */
view_query.length(0);
+ is_query.length(0);
{
ulong sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES;
thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
- lex->unit.print(&view_query);
+
+ lex->unit.print(&view_query, QT_ORDINARY);
+ lex->unit.print(&is_query, QT_IS);
+
thd->variables.sql_mode|= sql_mode;
}
DBUG_PRINT("info", ("View: %s", view_query.ptr()));
@@ -718,11 +818,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
/* fill structure */
view->select_stmt.str= view_query.c_ptr_safe();
view->select_stmt.length= view_query.length();
-
- view->source.str= (char*) thd->lex->create_view_select_start;
- view->source.length= (thd->lex->create_view_select_end
- - thd->lex->create_view_select_start);
- trim_whitespace(thd->charset(), & view->source);
+ view->source= thd->lex->create_view_select;
view->file_version= 1;
view->calc_md5(md5);
@@ -853,7 +949,8 @@ loop_out:
lex_string_set(&view->view_connection_cl_name,
view->view_creation_ctx->get_connection_cl()->name);
- view->view_body_utf8= lex->view_body_utf8;
+ view->view_body_utf8.str= is_query.c_ptr_safe();
+ view->view_body_utf8.length= is_query.length();
/*
Check that table of main select do not used in subqueries.
@@ -1552,7 +1649,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
{
DBUG_RETURN(TRUE);
}
- send_ok(thd);
+ my_ok(thd);
DBUG_RETURN(FALSE);
}
@@ -1581,7 +1678,7 @@ frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
DBUG_RETURN(FRMTYPE_ERROR);
- error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_WME | MY_NABP));
+ error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
my_close(file, MYF(MY_WME));
if (error)
diff --git a/sql/sql_view.h b/sql/sql_view.h
index d3c83c82f44..b8138663489 100644
--- a/sql/sql_view.h
+++ b/sql/sql_view.h
@@ -15,6 +15,9 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
+ enum_view_create_mode mode);
+
bool mysql_create_view(THD *thd, TABLE_LIST *view,
enum_view_create_mode mode);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c98228424a5..7c669851db4 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9823,8 +9823,11 @@ text_literal:
}
| UNDERSCORE_CHARSET TEXT_STRING
{
- $$= new Item_string($2.str, $2.length, $1);
- ((Item_string*) $$)->set_repertoire_from_value();
+ Item_string *str= new Item_string($2.str, $2.length, $1);
+ str->set_repertoire_from_value();
+ str->set_cs_specified(TRUE);
+
+ $$= str;
}
| text_literal TEXT_STRING_literal
{
@@ -9927,15 +9930,22 @@ literal:
String *str= tmp ?
tmp->quick_fix_field(), tmp->val_str((String*) 0) :
(String*) 0;
- $$= new Item_string(NULL, /* name will be set in select_item */
- str ? str->ptr() : "",
- str ? str->length() : 0,
- $1);
- if (!$$ || !$$->check_well_formed_result(&$$->str_value, TRUE))
+
+ Item_string *item_str=
+ new Item_string(NULL, /* name will be set in select_item */
+ str ? str->ptr() : "",
+ str ? str->length() : 0,
+ $1);
+ if (!item_str ||
+ !item_str->check_well_formed_result(&item_str->str_value, TRUE))
{
MYSQL_YYABORT;
}
- ((Item_string *) $$)->set_repertoire_from_value();
+
+ item_str->set_repertoire_from_value();
+ item_str->set_cs_specified(TRUE);
+
+ $$= item_str;
}
| UNDERSCORE_CHARSET BIN_NUM
{
@@ -9947,14 +9957,21 @@ literal:
String *str= tmp ?
tmp->quick_fix_field(), tmp->val_str((String*) 0) :
(String*) 0;
- $$= new Item_string(NULL, /* name will be set in select_item */
- str ? str->ptr() : "",
- str ? str->length() : 0,
- $1);
- if (!$$ || !$$->check_well_formed_result(&$$->str_value, TRUE))
+
+ Item_string *item_str=
+ new Item_string(NULL, /* name will be set in select_item */
+ str ? str->ptr() : "",
+ str ? str->length() : 0,
+ $1);
+ if (!item_str ||
+ !item_str->check_well_formed_result(&item_str->str_value, TRUE))
{
MYSQL_YYABORT;
}
+
+ item_str->set_cs_specified(TRUE);
+
+ $$= item_str;
}
| DATE_SYM text_literal { $$ = $2; }
| TIME_SYM text_literal { $$ = $2; }
@@ -11988,27 +12005,7 @@ view_tail:
if (!lex->select_lex.add_table_to_list(thd, $3, NULL, TL_OPTION_UPDATING))
MYSQL_YYABORT;
}
- view_list_opt AS
- {
- THD *thd= YYTHD;
- Lex_input_stream *lip= thd->m_lip;
-
- lip->body_utf8_start(thd, lip->get_cpp_ptr());
- }
- view_select
- {
- THD *thd= YYTHD;
- LEX *lex= thd->lex;
- Lex_input_stream *lip= thd->m_lip;
-
- lip->body_utf8_append(lip->get_cpp_ptr());
-
- lex->view_body_utf8.str= thd->strmake(lip->get_body_utf8_str(),
- lip->get_body_utf8_length());
- lex->view_body_utf8.length= lip->get_body_utf8_length();
-
- trim_whitespace(&my_charset_utf8_general_ci, &lex->view_body_utf8);
- }
+ view_list_opt AS view_select
;
view_list_opt:
@@ -12039,18 +12036,22 @@ view_select:
lex->parsing_options.allows_select_into= FALSE;
lex->parsing_options.allows_select_procedure= FALSE;
lex->parsing_options.allows_derived= FALSE;
- lex->create_view_select_start= lip->get_cpp_ptr();
+ lex->create_view_select.str= (char *) lip->get_cpp_ptr();
}
view_select_aux view_check_option
{
THD *thd= YYTHD;
LEX *lex= Lex;
Lex_input_stream *lip= thd->m_lip;
+ uint len= lip->get_cpp_ptr() - lex->create_view_select.str;
+ void *create_view_select= thd->memdup(lex->create_view_select.str, len);
+ lex->create_view_select.length= len;
+ lex->create_view_select.str= (char *) create_view_select;
+ trim_whitespace(thd->charset(), &lex->create_view_select);
lex->parsing_options.allows_variable= TRUE;
lex->parsing_options.allows_select_into= TRUE;
lex->parsing_options.allows_select_procedure= TRUE;
lex->parsing_options.allows_derived= TRUE;
- lex->create_view_select_end= lip->get_cpp_ptr();
}
;
diff --git a/sql/table.h b/sql/table.h
index 284885658e0..941964ee24e 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1148,7 +1148,7 @@ struct TABLE_LIST
return derived || view || schema_table || create && !table->db_stat ||
!table;
}
- void print(THD *thd, String *str);
+ void print(THD *thd, String *str, enum_query_type query_type);
bool check_single_table(TABLE_LIST **table, table_map map,
TABLE_LIST *view);
bool set_insert_values(MEM_ROOT *mem_root);
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 5b2af6550fd..188a051f874 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -289,6 +289,8 @@ static void client_connect(ulong flag)
myerror("mysql_init() failed");
exit(1);
}
+ /* enable local infile, in non-binary builds often disabled by default */
+ mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0);
if (!(mysql_real_connect(mysql, opt_host, opt_user,
opt_password, opt_db ? opt_db:"test", opt_port,
@@ -2421,7 +2423,7 @@ static uint query_cache_hits(MYSQL *conn)
*/
static void test_ps_query_cache()
{
- MYSQL *lmysql;
+ MYSQL *lmysql= mysql;
MYSQL_STMT *stmt;
int rc;
MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */
@@ -2456,7 +2458,6 @@ static void test_ps_query_cache()
TEST_QCACHE_ON_OFF
};
enum enum_test_ps_query_cache iteration;
- LINT_INIT(lmysql);
myheader("test_ps_query_cache");
@@ -2476,15 +2477,14 @@ static void test_ps_query_cache()
for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++)
{
- switch (iteration)
- {
+ switch (iteration) {
case TEST_QCACHE_ON:
case TEST_QCACHE_ON_OFF:
- rc= mysql_query(mysql, "set global query_cache_size=1000000");
+ rc= mysql_query(lmysql, "set global query_cache_size=1000000");
myquery(rc);
break;
case TEST_QCACHE_OFF_ON:
- rc= mysql_query(mysql, "set global query_cache_size=0");
+ rc= mysql_query(lmysql, "set global query_cache_size=0");
myquery(rc);
break;
case TEST_QCACHE_ON_WITH_OTHER_CONN:
@@ -2492,37 +2492,35 @@ static void test_ps_query_cache()
fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
{
- myerror("mysql_init() failed");
- exit(1);
+ printf("mysql_init() failed");
+ DIE_UNLESS(0);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket, 0)))
{
- myerror("connection failed");
+ printf("connection failed");
mysql_close(lmysql);
- exit(1);
+ DIE_UNLESS(0);
}
if (!opt_silent)
fprintf(stdout, "OK");
- mysql= lmysql;
}
strmov(query, "select id1, value1 from t1 where id1= ? or "
"CONVERT(value1 USING utf8)= ?");
- stmt= mysql_simple_prepare(mysql, query);
+ stmt= mysql_simple_prepare(lmysql, query);
check_stmt(stmt);
verify_param_count(stmt, 2);
- switch(iteration)
- {
+ switch (iteration) {
case TEST_QCACHE_OFF_ON:
- rc= mysql_query(mysql, "set global query_cache_size=1000000");
+ rc= mysql_query(lmysql, "set global query_cache_size=1000000");
myquery(rc);
break;
case TEST_QCACHE_ON_OFF:
- rc= mysql_query(mysql, "set global query_cache_size=0");
+ rc= mysql_query(lmysql, "set global query_cache_size=0");
myquery(rc);
default:
break;
@@ -2560,11 +2558,11 @@ static void test_ps_query_cache()
test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
/* now retry with the same parameter values and see qcache hits */
- hits1= query_cache_hits(mysql);
+ hits1= query_cache_hits(lmysql);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
- hits2= query_cache_hits(mysql);
+ hits2= query_cache_hits(lmysql);
switch(iteration) {
case TEST_QCACHE_ON_WITH_OTHER_CONN:
case TEST_QCACHE_ON: /* should have hit */
@@ -2582,7 +2580,7 @@ static void test_ps_query_cache()
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
- hits1= query_cache_hits(mysql);
+ hits1= query_cache_hits(lmysql);
switch(iteration) {
case TEST_QCACHE_ON:
@@ -2599,7 +2597,7 @@ static void test_ps_query_cache()
check_execute(stmt, rc);
test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
- hits2= query_cache_hits(mysql);
+ hits2= query_cache_hits(lmysql);
mysql_stmt_close(stmt);
@@ -2618,9 +2616,11 @@ static void test_ps_query_cache()
} /* for(iteration=...) */
+ if (lmysql != mysql)
+ mysql_close(lmysql);
+
rc= mysql_query(mysql, "set global query_cache_size=0");
myquery(rc);
-
}
@@ -8971,8 +8971,8 @@ static void test_sqlmode()
strmov(c1, "My"); strmov(c2, "SQL");
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
-
mysql_stmt_close(stmt);
+
verify_col_data("test_piping", "name", "MySQL");
rc= mysql_query(mysql, "DELETE FROM test_piping");
@@ -8983,6 +8983,7 @@ static void test_sqlmode()
fprintf(stdout, "\n query: %s", query);
stmt= mysql_simple_prepare(mysql, query);
check_stmt(stmt);
+ mysql_stmt_close(stmt);
/* ANSI */
strmov(query, "SET SQL_MODE= \"ANSI\"");
@@ -13280,7 +13281,7 @@ from t2);");
static void test_bug8378()
{
#if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
- MYSQL *old_mysql=mysql;
+ MYSQL *lmysql;
char out[9]; /* strlen(TEST_BUG8378)*2+1 */
char buf[256];
int len, rc;
@@ -13289,17 +13290,17 @@ static void test_bug8378()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(mysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
exit(1);
}
- if (mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "gbk"))
+ if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
{
myerror("mysql_options() failed");
exit(1);
}
- if (!(mysql_real_connect(mysql, opt_host, opt_user,
+ if (!(mysql_real_connect(lmysql, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket, 0)))
{
@@ -13309,19 +13310,17 @@ static void test_bug8378()
if (!opt_silent)
fprintf(stdout, "OK");
- len= mysql_real_escape_string(mysql, out, TEST_BUG8378_IN, 4);
+ len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4);
/* No escaping should have actually happened. */
DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
sprintf(buf, "SELECT '%s'", out);
- rc=mysql_real_query(mysql, buf, strlen(buf));
+ rc=mysql_real_query(lmysql, buf, strlen(buf));
myquery(rc);
- mysql_close(mysql);
-
- mysql=old_mysql;
+ mysql_close(lmysql);
#endif
}
@@ -15158,7 +15157,7 @@ static void test_opt_reconnect()
if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
{
myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
- exit(1);
+ DIE_UNLESS(0);
}
/* reconnect should be 1 */
@@ -15171,7 +15170,7 @@ static void test_opt_reconnect()
opt_unix_socket, 0)))
{
myerror("connection failed");
- exit(1);
+ DIE_UNLESS(0);
}
/* reconnect should still be 1 */
@@ -15185,7 +15184,7 @@ static void test_opt_reconnect()
if (!(lmysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
- exit(1);
+ DIE_UNLESS(0);
}
if (!opt_silent)
@@ -15197,7 +15196,7 @@ static void test_opt_reconnect()
opt_unix_socket, 0)))
{
myerror("connection failed");
- exit(1);
+ DIE_UNLESS(0);
}
/* reconnect should still be 0 */
@@ -15215,32 +15214,32 @@ static void test_opt_reconnect()
static void test_bug12744()
{
MYSQL_STMT *prep_stmt = NULL;
+ MYSQL *lmysql;
int rc;
myheader("test_bug12744");
- prep_stmt= mysql_stmt_init(mysql);
- rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
- DIE_UNLESS(rc==0);
-
- mysql_close(mysql);
+ lmysql= mysql_init(NULL);
+ DIE_UNLESS(lmysql);
- if ((rc= mysql_stmt_execute(prep_stmt)))
+ if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
+ current_db, opt_port, opt_unix_socket, 0))
{
- if ((rc= mysql_stmt_reset(prep_stmt)))
- printf("OK!\n");
- else
- {
- printf("Error!");
- DIE_UNLESS(1==0);
- }
- }
- else
- {
- fprintf(stderr, "expected error but no error occured\n");
- DIE_UNLESS(1==0);
+ fprintf(stderr, "Failed to connect to the database\n");
+ DIE_UNLESS(0);
}
+
+ prep_stmt= mysql_stmt_init(lmysql);
+ rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
+ DIE_UNLESS(rc == 0);
+
+ mysql_close(lmysql);
+
+ rc= mysql_stmt_execute(prep_stmt);
+ DIE_UNLESS(rc);
+ rc= mysql_stmt_reset(prep_stmt);
+ DIE_UNLESS(rc);
rc= mysql_stmt_close(prep_stmt);
- client_connect(0);
+ DIE_UNLESS(rc == 0);
}
#endif /* EMBEDDED_LIBRARY */
@@ -16104,11 +16103,104 @@ static void test_bug24179()
mysql_stmt_error(stmt));
}
DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
+ mysql_stmt_close(stmt);
DBUG_VOID_RETURN;
}
+/**
+ Bug#32265 Server returns different metadata if prepared statement is used
+*/
+
+static void test_bug32265()
+{
+ int rc;
+ MYSQL_STMT *stmt;
+ MYSQL_FIELD *field;
+ MYSQL_RES *metadata;
+
+ DBUG_ENTER("test_bug32265");
+ myheader("test_bug32265");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE TABLE t1 (a INTEGER)");
+ myquery(rc);
+ rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
+ myquery(rc);
+
+ stmt= open_cursor("SELECT * FROM t1");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(field);
+ DIE_UNLESS(strcmp(field->table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ stmt= open_cursor("SELECT a '' FROM t1 ``");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(strcmp(field->table, "") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ stmt= open_cursor("SELECT a '' FROM t1 ``");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(strcmp(field->table, "") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ stmt= open_cursor("SELECT * FROM v1");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(strcmp(field->table, "v1") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_field(metadata);
+ DIE_UNLESS(strcmp(field->table, "v1") == 0);
+ DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
+ DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
+ mysql_free_result(metadata);
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "DROP VIEW v1");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP TABLE t1");
+ myquery(rc);
+
+ DBUG_VOID_RETURN;
+}
+
/*
Bug#28075 "COM_DEBUG crashes mysqld"
*/
@@ -16168,6 +16260,7 @@ static void test_bug27876()
myquery(rc);
result= mysql_store_result(mysql);
mytest(result);
+ mysql_free_result(result);
sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
rc= mysql_query(mysql, query);
@@ -16184,6 +16277,7 @@ static void test_bug27876()
myquery(rc);
result= mysql_store_result(mysql);
mytest(result);
+ mysql_free_result(result);
sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
rc= mysql_query(mysql, query);
@@ -16821,7 +16915,7 @@ static void test_bug30472()
/* Change connection-default character set in the client. */
- con.options.charset_name= my_strdup("utf8", MYF(MY_FAE));
+ mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8");
/*
Call mysql_change_user() in order to check that new connection will
@@ -17231,6 +17325,92 @@ static void test_bug31669()
DBUG_VOID_RETURN;
}
+
+/**
+ Bug#28386 the general log is incomplete
+*/
+
+static void test_bug28386()
+{
+ int rc;
+ MYSQL_STMT *stmt;
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ MYSQL_BIND bind;
+ const char hello[]= "hello world!";
+
+ DBUG_ENTER("test_bug28386");
+ myheader("test_bug28386");
+
+ rc= mysql_query(mysql, "select @@global.log_output");
+ myquery(rc);
+
+ result= mysql_store_result(mysql);
+ DIE_UNLESS(result);
+
+ row= mysql_fetch_row(result);
+ if (! strstr(row[0], "TABLE"))
+ {
+ mysql_free_result(result);
+ if (! opt_silent)
+ printf("Skipping the test since logging to tables is not enabled\n");
+ /* Log output is not to tables */
+ return;
+ }
+ mysql_free_result(result);
+
+ rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "set @@global.general_log=on");
+ myquery(rc);
+
+ rc= mysql_query(mysql, "truncate mysql.general_log");
+ myquery(rc);
+
+ stmt= mysql_simple_prepare(mysql, "SELECT ?");
+ check_stmt(stmt);
+
+ memset(&bind, 0, sizeof(bind));
+
+ bind.buffer_type= MYSQL_TYPE_STRING;
+ bind.buffer= (void *) hello;
+ bind.buffer_length= sizeof(hello);
+
+ mysql_stmt_bind_param(stmt, &bind);
+ mysql_stmt_send_long_data(stmt, 0, hello, sizeof(hello));
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ rc= my_process_stmt_result(stmt);
+ DIE_UNLESS(rc == 1);
+
+ rc= mysql_stmt_reset(stmt);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_close(stmt);
+ DIE_UNLESS(!rc);
+
+ rc= mysql_query(mysql, "select * from mysql.general_log where "
+ "command_type='Close stmt' or "
+ "command_type='Reset stmt' or "
+ "command_type='Long Data'");
+ myquery(rc);
+
+ result= mysql_store_result(mysql);
+ mytest(result);
+
+ DIE_UNLESS(mysql_num_rows(result) == 3);
+
+ mysql_free_result(result);
+
+ rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
+ myquery(rc);
+
+ DBUG_VOID_RETURN;
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -17517,6 +17697,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug21726", test_bug21726 },
{ "test_bug15518", test_bug15518 },
{ "test_bug23383", test_bug23383 },
+ { "test_bug32265", test_bug32265 },
{ "test_bug21635", test_bug21635 },
{ "test_status", test_status },
{ "test_bug24179", test_bug24179 },
@@ -17535,6 +17716,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug20023", test_bug20023 },
{ "test_bug31418", test_bug31418 },
{ "test_bug31669", test_bug31669 },
+ { "test_bug28386", test_bug28386 },
{ 0, 0 }
};