summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <mskold@mysql.com>2005-11-21 10:46:17 +0100
committerunknown <mskold@mysql.com>2005-11-21 10:46:17 +0100
commit76611e3b53679eab6eb2e655e0f3a33df00a5f3a (patch)
treecf76f66b624c01c37a714e6eaa76678598e1fceb
parent55a82cd031244647f896a92cfa25f50a63e7767f (diff)
parent32e6e6aac6520dca9af8b6e00a49f25c2f2a4d73 (diff)
downloadmariadb-git-76611e3b53679eab6eb2e655e0f3a33df00a5f3a.tar.gz
Merge mskold@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/usr/local/home/marty/MySQL/mysql-5.0
-rw-r--r--mysql-test/r/func_gconcat.result15
-rw-r--r--mysql-test/r/sp-error.result2
-rw-r--r--mysql-test/r/sp.result19
-rw-r--r--mysql-test/r/sp_trans.result195
-rw-r--r--mysql-test/r/view.result8
-rw-r--r--mysql-test/t/func_gconcat.test16
-rw-r--r--mysql-test/t/sp-error.test4
-rw-r--r--mysql-test/t/sp.test21
-rw-r--r--mysql-test/t/sp_trans.test180
-rw-r--r--mysql-test/t/view.test9
-rw-r--r--sql/ha_innodb.cc12
-rw-r--r--sql/handler.cc15
-rw-r--r--sql/sql_class.cc18
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_cursor.cc3
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sql_yacc.yy3
-rw-r--r--tests/mysql_client_test.c44
19 files changed, 554 insertions, 17 deletions
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 90884dcc596..7987ceca712 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -596,3 +596,18 @@ GROUP_CONCAT(a ORDER BY a)
,x
,z
DROP TABLE t1;
+set names latin1;
+create table t1 (a char, b char);
+insert into t1 values ('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'b');
+create table t2 select group_concat(b) as a from t1 where a = 'a';
+create table t3 (select group_concat(a) as a from t1 where a = 'a') union
+(select group_concat(b) as a from t1 where a = 'b');
+select charset(a) from t2;
+charset(a)
+latin1
+select charset(a) from t3;
+charset(a)
+latin1
+latin1
+drop table t1, t2, t3;
+set names default;
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 26bb0fa4694..858f7d0bb16 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -845,6 +845,8 @@ set password = 'foo1';
select password;
end|
ERROR 42000: Variable 'password' must be quoted with `...`, or renamed
+set names='foo2'|
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
create procedure bug13510_2()
begin
declare names varchar(10);
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 1e49f966bc4..93332af21a9 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3648,4 +3648,23 @@ call bug14723();;
42
drop function bug14723|
drop procedure bug14723|
+create procedure bug14845()
+begin
+declare a char(255);
+declare done int default 0;
+declare c cursor for select count(*) from t1 where 1 = 0;
+declare continue handler for sqlstate '02000' set done = 1;
+open c;
+repeat
+fetch c into a;
+if not done then
+select a;
+end if;
+until done end repeat;
+close c;
+end|
+call bug14845()|
+a
+0
+drop procedure bug14845|
drop table t1,t2;
diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result
index 6077087ab87..bb742d0d3d7 100644
--- a/mysql-test/r/sp_trans.result
+++ b/mysql-test/r/sp_trans.result
@@ -174,3 +174,198 @@ ERROR HY000: Explicit or implicit commit is not allowed in stored function or tr
drop procedure bug10015_8|
drop function bug10015_7|
drop table t1, t2|
+drop function if exists bug13825_0|
+drop function if exists bug13825_1|
+drop function if exists bug13825_2|
+drop function if exists bug13825_3|
+drop function if exists bug13825_4|
+drop function if exists bug13825_5|
+drop procedure if exists bug13825_0|
+drop procedure if exists bug13825_1|
+drop procedure if exists bug13825_2|
+drop table if exists t1|
+create table t1 (i int) engine=innodb|
+create table t2 (i int) engine=innodb|
+create function bug13825_0() returns int
+begin
+rollback to savepoint x;
+return 1;
+end|
+create function bug13825_1() returns int
+begin
+release savepoint x;
+return 1;
+end|
+create function bug13825_2() returns int
+begin
+insert into t1 values (2);
+savepoint x;
+insert into t1 values (3);
+rollback to savepoint x;
+insert into t1 values (4);
+return 1;
+end|
+create procedure bug13825_0()
+begin
+rollback to savepoint x;
+end|
+create procedure bug13825_1()
+begin
+release savepoint x;
+end|
+create procedure bug13825_2()
+begin
+savepoint x;
+end|
+insert into t2 values (1)|
+create trigger t2_bi before insert on t2 for each row
+rollback to savepoint x|
+create trigger t2_bu before update on t2 for each row
+release savepoint x|
+create trigger t2_bd before delete on t2 for each row
+begin
+insert into t1 values (2);
+savepoint x;
+insert into t1 values (3);
+rollback to savepoint x;
+insert into t1 values (4);
+end|
+create function bug13825_3(rb int) returns int
+begin
+insert into t1 values(1);
+savepoint x;
+insert into t1 values(2);
+if rb then
+rollback to savepoint x;
+end if;
+insert into t1 values(3);
+return rb;
+end|
+create function bug13825_4() returns int
+begin
+savepoint x;
+insert into t1 values(2);
+rollback to savepoint x;
+return 0;
+end|
+create function bug13825_5(p int) returns int
+begin
+savepoint x;
+insert into t2 values(p);
+rollback to savepoint x;
+insert into t2 values(p+1);
+return p;
+end|
+set autocommit= 0|
+begin |
+insert into t1 values (1)|
+savepoint x|
+set @a:= bug13825_0()|
+ERROR 42000: SAVEPOINT x does not exist
+insert into t2 values (2)|
+ERROR 42000: SAVEPOINT x does not exist
+set @a:= bug13825_1()|
+ERROR 42000: SAVEPOINT x does not exist
+update t2 set i = 2|
+ERROR 42000: SAVEPOINT x does not exist
+set @a:= bug13825_2()|
+select * from t1|
+i
+1
+2
+4
+rollback to savepoint x|
+select * from t1|
+i
+1
+delete from t2|
+select * from t1|
+i
+1
+2
+4
+rollback to savepoint x|
+select * from t1|
+i
+1
+release savepoint x|
+set @a:= bug13825_2()|
+select * from t1|
+i
+1
+2
+4
+rollback to savepoint x|
+ERROR 42000: SAVEPOINT x does not exist
+delete from t1|
+commit|
+begin|
+insert into t1 values (5)|
+savepoint x|
+insert into t1 values (6)|
+call bug13825_0()|
+select * from t1|
+i
+5
+call bug13825_1()|
+rollback to savepoint x|
+ERROR 42000: SAVEPOINT x does not exist
+savepoint x|
+insert into t1 values (7)|
+call bug13825_2()|
+rollback to savepoint x|
+select * from t1|
+i
+5
+7
+delete from t1|
+commit|
+set autocommit= 1|
+select bug13825_3(0)|
+bug13825_3(0)
+0
+select * from t1|
+i
+1
+2
+3
+delete from t1|
+select bug13825_3(1)|
+bug13825_3(1)
+1
+select * from t1|
+i
+1
+3
+delete from t1|
+set autocommit= 0|
+begin|
+insert into t1 values (1)|
+set @a:= bug13825_4()|
+select * from t1|
+i
+1
+delete from t1|
+commit|
+set autocommit= 1|
+drop table t2|
+create table t2 (i int) engine=innodb|
+insert into t1 values (1), (bug13825_5(2)), (3)|
+select * from t1|
+i
+1
+2
+3
+select * from t2|
+i
+3
+drop function bug13825_0|
+drop function bug13825_1|
+drop function bug13825_2|
+drop function bug13825_3|
+drop function bug13825_4|
+drop function bug13825_5|
+drop procedure bug13825_0|
+drop procedure bug13825_1|
+drop procedure bug13825_2|
+drop table t1, t2|
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 9a3dc950c10..ebb2c190eb1 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -2338,6 +2338,14 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
DROP VIEW v1,v2;
DROP TABLE t1,t2,t3;
+create table t1 (f1 int);
+create view v1 as select t1.f1 as '123
+456' from t1;
+select * from v1;
+123
+456
+drop view v1;
+drop table t1;
create table t1 (f1 int, f2 int);
insert into t1 values(1,1),(1,2),(1,3);
create view v1 as select f1 ,group_concat(f2 order by f2 asc) from t1 group by f1;
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index a519d51e0b5..cd686585dd8 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -390,3 +390,19 @@ SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY id;
DROP TABLE t1;
# End of 4.1 tests
+
+#
+# Bug#8568 "GROUP_CONCAT returns string, unless in a UNION in which case
+# returns BLOB": add a test case, the bug can not be repeated any more.
+#
+
+set names latin1;
+create table t1 (a char, b char);
+insert into t1 values ('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'b');
+create table t2 select group_concat(b) as a from t1 where a = 'a';
+create table t3 (select group_concat(a) as a from t1 where a = 'a') union
+ (select group_concat(b) as a from t1 where a = 'b');
+select charset(a) from t2;
+select charset(a) from t3;
+drop table t1, t2, t3;
+set names default;
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index 4cc141fea4b..5057dd0d9f8 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -1233,6 +1233,10 @@ begin
select password;
end|
+# Check that an error message is sent
+--error ER_PARSE_ERROR
+set names='foo2'|
+
--error ER_SP_BAD_VAR_SHADOW
create procedure bug13510_2()
begin
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 362faec167c..5ad2b9287aa 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -4572,6 +4572,27 @@ delimiter |;;
drop function bug14723|
drop procedure bug14723|
+#
+# Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
+# Check that when fetching from a cursor, COUNT(*) works properly.
+#
+create procedure bug14845()
+begin
+ declare a char(255);
+ declare done int default 0;
+ declare c cursor for select count(*) from t1 where 1 = 0;
+ declare continue handler for sqlstate '02000' set done = 1;
+ open c;
+ repeat
+ fetch c into a;
+ if not done then
+ select a;
+ end if;
+ until done end repeat;
+ close c;
+end|
+call bug14845()|
+drop procedure bug14845|
#
# BUG#NNNN: New bug synopsis
diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test
index 82e1cd2f1c9..d72eaf5dca0 100644
--- a/mysql-test/t/sp_trans.test
+++ b/mysql-test/t/sp_trans.test
@@ -176,6 +176,186 @@ drop table t1, t2|
#
+# BUG#13825 "Triggers: crash if release savepoint".
+# Also general test for handling of savepoints in stored routines.
+#
+# According to SQL standard we should establish new savepoint
+# level before executing stored function/trigger and destroy
+# this savepoint level after execution. Stored procedures by
+# default should be executed using the same savepoint level
+# as their caller (to execute stored procedure using new
+# savepoint level one should explicitly specify NEW SAVEPOINT
+# LEVEL clause in procedure creation statement which MySQL
+# does not support yet).
+--disable_warnings
+drop function if exists bug13825_0|
+drop function if exists bug13825_1|
+drop function if exists bug13825_2|
+drop function if exists bug13825_3|
+drop function if exists bug13825_4|
+drop function if exists bug13825_5|
+drop procedure if exists bug13825_0|
+drop procedure if exists bug13825_1|
+drop procedure if exists bug13825_2|
+drop table if exists t1|
+--enable_warnings
+create table t1 (i int) engine=innodb|
+create table t2 (i int) engine=innodb|
+create function bug13825_0() returns int
+begin
+ rollback to savepoint x;
+ return 1;
+end|
+create function bug13825_1() returns int
+begin
+ release savepoint x;
+ return 1;
+end|
+create function bug13825_2() returns int
+begin
+ insert into t1 values (2);
+ savepoint x;
+ insert into t1 values (3);
+ rollback to savepoint x;
+ insert into t1 values (4);
+ return 1;
+end|
+create procedure bug13825_0()
+begin
+ rollback to savepoint x;
+end|
+create procedure bug13825_1()
+begin
+ release savepoint x;
+end|
+create procedure bug13825_2()
+begin
+ savepoint x;
+end|
+insert into t2 values (1)|
+create trigger t2_bi before insert on t2 for each row
+ rollback to savepoint x|
+create trigger t2_bu before update on t2 for each row
+ release savepoint x|
+create trigger t2_bd before delete on t2 for each row
+begin
+ insert into t1 values (2);
+ savepoint x;
+ insert into t1 values (3);
+ rollback to savepoint x;
+ insert into t1 values (4);
+end|
+create function bug13825_3(rb int) returns int
+begin
+ insert into t1 values(1);
+ savepoint x;
+ insert into t1 values(2);
+ if rb then
+ rollback to savepoint x;
+ end if;
+ insert into t1 values(3);
+ return rb;
+end|
+create function bug13825_4() returns int
+begin
+ savepoint x;
+ insert into t1 values(2);
+ rollback to savepoint x;
+ return 0;
+end|
+create function bug13825_5(p int) returns int
+begin
+ savepoint x;
+ insert into t2 values(p);
+ rollback to savepoint x;
+ insert into t2 values(p+1);
+ return p;
+end|
+set autocommit= 0|
+# Test of savepoint level handling for stored functions and triggers
+begin |
+insert into t1 values (1)|
+savepoint x|
+--error ER_SP_DOES_NOT_EXIST
+set @a:= bug13825_0()|
+--error ER_SP_DOES_NOT_EXIST
+insert into t2 values (2)|
+--error ER_SP_DOES_NOT_EXIST
+set @a:= bug13825_1()|
+--error ER_SP_DOES_NOT_EXIST
+update t2 set i = 2|
+set @a:= bug13825_2()|
+select * from t1|
+rollback to savepoint x|
+select * from t1|
+delete from t2|
+select * from t1|
+rollback to savepoint x|
+select * from t1|
+# Of course savepoints set in function should not be visible from its caller
+release savepoint x|
+set @a:= bug13825_2()|
+select * from t1|
+--error ER_SP_DOES_NOT_EXIST
+rollback to savepoint x|
+delete from t1|
+commit|
+# Test of savepoint level handling for stored procedures
+begin|
+insert into t1 values (5)|
+savepoint x|
+insert into t1 values (6)|
+call bug13825_0()|
+select * from t1|
+call bug13825_1()|
+--error ER_SP_DOES_NOT_EXIST
+rollback to savepoint x|
+savepoint x|
+insert into t1 values (7)|
+call bug13825_2()|
+rollback to savepoint x|
+select * from t1|
+delete from t1|
+commit|
+set autocommit= 1|
+# Let us test that savepoints work inside of functions
+# even in auto-commit mode
+select bug13825_3(0)|
+select * from t1|
+delete from t1|
+select bug13825_3(1)|
+select * from t1|
+delete from t1|
+# Curious case: rolling back to savepoint which is set by first
+# statement in function should not rollback whole transaction.
+set autocommit= 0|
+begin|
+insert into t1 values (1)|
+set @a:= bug13825_4()|
+select * from t1|
+delete from t1|
+commit|
+set autocommit= 1|
+# Other curious case: savepoint in the middle of statement
+drop table t2|
+create table t2 (i int) engine=innodb|
+insert into t1 values (1), (bug13825_5(2)), (3)|
+select * from t1|
+select * from t2|
+# Cleanup
+drop function bug13825_0|
+drop function bug13825_1|
+drop function bug13825_2|
+drop function bug13825_3|
+drop function bug13825_4|
+drop function bug13825_5|
+drop procedure bug13825_0|
+drop procedure bug13825_1|
+drop procedure bug13825_2|
+drop table t1, t2|
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index ad51597fd6f..ac103278f08 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -2188,6 +2188,15 @@ DROP VIEW v1,v2;
DROP TABLE t1,t2,t3;
#
+# Bug #13622 Wrong view .frm created if some field's alias contain \n
+#
+create table t1 (f1 int);
+create view v1 as select t1.f1 as '123
+456' from t1;
+select * from v1;
+drop view v1;
+drop table t1;
+
# Bug #14466 lost sort order in GROUP_CONCAT() in a view
#
create table t1 (f1 int, f2 int);
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 60ec6f8e2bb..56e5fd8923f 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2198,11 +2198,13 @@ innobase_savepoint(
DBUG_ENTER("innobase_savepoint");
- if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
- /* In the autocommit state there is no sense to set a
- savepoint: we return immediate success */
- DBUG_RETURN(0);
- }
+ /*
+ In the autocommit mode there is no sense to set a savepoint
+ (unless we are in sub-statement), so SQL layer ensures that
+ this method is never called in such situation.
+ */
+ DBUG_ASSERT(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
+ thd->in_sub_stmt);
trx = check_trx_exists(thd);
diff --git a/sql/handler.cc b/sql/handler.cc
index 7724b27949e..866d9bdf0b5 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1145,10 +1145,10 @@ int ha_update_statistics()
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
- THD_TRANS *trans=&thd->transaction.all;
+ THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
+ &thd->transaction.all);
handlerton **ht=trans->ht, **end_ht;
DBUG_ENTER("ha_rollback_to_savepoint");
- DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
trans->nht=sv->nht;
trans->no_2pc=0;
@@ -1176,7 +1176,7 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
for (; *ht ; ht++)
{
int err;
- if ((err= (*(*ht)->rollback)(thd, 1)))
+ if ((err= (*(*ht)->rollback)(thd, !thd->in_sub_stmt)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
@@ -1196,10 +1196,10 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
int ha_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
- THD_TRANS *trans=&thd->transaction.all;
+ THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
+ &thd->transaction.all);
handlerton **ht=trans->ht;
DBUG_ENTER("ha_savepoint");
- DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
#ifdef USING_TRANSACTIONS
for (; *ht; ht++)
{
@@ -1225,9 +1225,10 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv)
int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
- handlerton **ht=thd->transaction.all.ht, **end_ht;
+ THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
+ &thd->transaction.all);
+ handlerton **ht=trans->ht, **end_ht;
DBUG_ENTER("ha_release_savepoint");
- DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
end_ht=ht+sv->nht;
for (; ht < end_ht; ht++)
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7ffe60ec2b2..c52addf3995 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1916,6 +1916,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
- Value for found_rows() is reset and restored
- examined_row_count is added to the total
- cuted_fields is added to the total
+ - new savepoint level is created and destroyed
NOTES:
Seed for random() is saved for the first! usage of RAND()
@@ -1939,6 +1940,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
backup->sent_row_count= sent_row_count;
backup->cuted_fields= cuted_fields;
backup->client_capabilities= client_capabilities;
+ backup->savepoints= transaction.savepoints;
if (!lex->requires_prelocking() || is_update_query(lex->sql_command))
options&= ~OPTION_BIN_LOG;
@@ -1951,6 +1953,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
examined_row_count= 0;
sent_row_count= 0;
cuted_fields= 0;
+ transaction.savepoints= 0;
#ifndef EMBEDDED_LIBRARY
/* Surpress OK packets in case if we will execute statements */
@@ -1961,6 +1964,21 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
void THD::restore_sub_statement_state(Sub_statement_state *backup)
{
+ /*
+ To save resources we want to release savepoints which were created
+ during execution of function or trigger before leaving their savepoint
+ level. It is enough to release first savepoint set on this level since
+ all later savepoints will be released automatically.
+ */
+ if (transaction.savepoints)
+ {
+ SAVEPOINT *sv;
+ for (sv= transaction.savepoints; sv->prev; sv= sv->prev)
+ {}
+ /* ha_release_savepoint() never returns error. */
+ (void)ha_release_savepoint(this, sv);
+ }
+ transaction.savepoints= backup->savepoints;
options= backup->options;
in_sub_stmt= backup->in_sub_stmt;
net.no_send_ok= backup->no_send_ok;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index eaa8291e697..ed6f5732ca8 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1091,6 +1091,7 @@ public:
uint in_sub_stmt;
bool enable_slow_log, insert_id_used;
my_bool no_send_ok;
+ SAVEPOINT *savepoints;
};
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index fc169fe18e8..89c160cd70a 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -661,11 +661,10 @@ Materialized_cursor::~Materialized_cursor()
bool Select_materialize::send_fields(List<Item> &list, uint flags)
{
- bool rc;
DBUG_ASSERT(table == 0);
if (create_result_table(unit->thd, unit->get_unit_column_types(),
FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
return TRUE;
- return rc;
+ return FALSE;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 1e6810e0036..793dd18e56b 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4033,8 +4033,8 @@ end_with_restore_list:
break;
}
case SQLCOM_SAVEPOINT:
- if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
- !opt_using_transactions)
+ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
+ thd->in_sub_stmt) || !opt_using_transactions)
send_ok(thd);
else
{
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index b642d24b30d..4067201bf18 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -495,7 +495,7 @@ static const int num_view_backups= 3;
static File_option view_parameters[]=
{{{(char*) STRING_WITH_LEN("query")},
offsetof(TABLE_LIST, query),
- FILE_OPTIONS_STRING},
+ FILE_OPTIONS_ESTRING},
{{(char*) STRING_WITH_LEN("md5")},
offsetof(TABLE_LIST, md5),
FILE_OPTIONS_STRING},
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 339091ed4e8..2dc06642259 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -7925,6 +7925,9 @@ option_value:
names.length= 5;
if (spc && spc->find_pvar(&names))
my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str);
+ else
+ yyerror(ER(ER_SYNTAX_ERROR));
+
YYABORT;
}
| NAMES_SYM charset_name_or_default opt_collate
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index e0f3fd91e5c..ce732690700 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -14546,6 +14546,49 @@ static void test_bug13524()
myquery(rc);
}
+/*
+ Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
+*/
+
+static void test_bug14845()
+{
+ MYSQL_STMT *stmt;
+ int rc;
+ const ulong type= CURSOR_TYPE_READ_ONLY;
+ const char *query= "select count(*) from t1 where 1 = 0";
+
+ myheader("test_bug14845");
+
+ rc= mysql_query(mysql, "drop table if exists t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "create table t1 (id int(11) default null, "
+ "name varchar(20) default null)"
+ "engine=MyISAM DEFAULT CHARSET=utf8");
+ myquery(rc);
+ rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')");
+ myquery(rc);
+
+ stmt= mysql_stmt_init(mysql);
+ rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_prepare(stmt, query, strlen(query));
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc == 0);
+
+ rc= mysql_stmt_fetch(stmt);
+ DIE_UNLESS(rc == MYSQL_NO_DATA);
+
+ /* Cleanup */
+ mysql_stmt_close(stmt);
+ rc= mysql_query(mysql, "drop table t1");
+ myquery(rc);
+}
/*
Read and parse arguments and MySQL options from my.cnf
@@ -14805,6 +14848,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug14210", test_bug14210 },
{ "test_bug13488", test_bug13488 },
{ "test_bug13524", test_bug13524 },
+ { "test_bug14845", test_bug14845 },
{ 0, 0 }
};