summaryrefslogtreecommitdiffstats
path: root/mysql-test/main/sp-lock.result
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:00:34 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:00:34 +0000
commit3f619478f796eddbba6e39502fe941b285dd97b1 (patch)
treee2c7b5777f728320e5b5542b6213fd3591ba51e2 /mysql-test/main/sp-lock.result
parentInitial commit. (diff)
downloadmariadb-3f619478f796eddbba6e39502fe941b285dd97b1.tar.xz
mariadb-3f619478f796eddbba6e39502fe941b285dd97b1.zip
Adding upstream version 1:10.11.6.upstream/1%10.11.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mysql-test/main/sp-lock.result')
-rw-r--r--mysql-test/main/sp-lock.result832
1 files changed, 832 insertions, 0 deletions
diff --git a/mysql-test/main/sp-lock.result b/mysql-test/main/sp-lock.result
new file mode 100644
index 00000000..e7ebc3ae
--- /dev/null
+++ b/mysql-test/main/sp-lock.result
@@ -0,0 +1,832 @@
+#
+# Test coverage for changes performed by the fix
+# for Bug#30977 "Concurrent statement using stored function
+# and DROP FUNCTION breaks SBR.
+#
+#
+# 1) Verify that the preceding transaction is
+# (implicitly) committed before CREATE/ALTER/DROP
+# PROCEDURE. Note, that this is already tested
+# in implicit_commit.test, but here we use an alternative
+# approach.
+#
+# Start a transaction, create a savepoint,
+# then call a DDL operation on a procedure, and then check
+# that the savepoint is no longer present.
+create table t1 (a int);
+#
+# Test 'CREATE PROCEDURE'.
+#
+begin;
+savepoint sv;
+create procedure p1() begin end;
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'ALTER PROCEDURE'.
+#
+begin;
+savepoint sv;
+alter procedure p1 comment 'changed comment';
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'DROP PROCEDURE'.
+#
+begin;
+savepoint sv;
+drop procedure p1;
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'CREATE FUNCTION'.
+#
+begin;
+savepoint sv;
+create function f1() returns int return 1;
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'ALTER FUNCTION'.
+#
+begin;
+savepoint sv;
+alter function f1 comment 'new comment';
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# Test 'DROP FUNCTION'.
+#
+begin;
+savepoint sv;
+drop function f1;
+rollback to savepoint sv;
+ERROR 42000: SAVEPOINT sv does not exist
+#
+# 2) Verify that procedure DDL operations fail
+# under lock tables.
+#
+# Auxiliary routines to test ALTER.
+create procedure p1() begin end;
+create function f1() returns int return 1;
+lock table t1 write;
+create procedure p2() begin end;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter procedure p1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+drop procedure p1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+create function f2() returns int return 1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter function f1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+lock table t1 read;
+create procedure p2() begin end;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter procedure p1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+drop procedure p1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+create function f2() returns int return 1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter function f1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+unlock tables;
+#
+# Even if we locked a temporary table.
+# Todo: this is a restriction we could possibly lift.
+#
+drop table t1;
+create temporary table t1 (a int);
+lock table t1 read;
+create procedure p2() begin end;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter procedure p1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+drop procedure p1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+create function f2() returns int return 1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+alter function f1 comment 'changed comment';
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+unlock tables;
+drop function f1;
+drop procedure p1;
+drop temporary table t1;
+#
+# 3) Verify that CREATE/ALTER/DROP routine grab an
+# exclusive lock.
+#
+# For that, start a transaction, use a routine. In a concurrent
+# connection, try to drop or alter the routine. It should place
+# a pending or exclusive lock and block. In another concurrnet
+# connection, try to use the routine.
+# That should block on the pending exclusive lock.
+#
+connect con1, localhost, root,,;
+connect con2, localhost, root,,;
+connect con3, localhost, root,,;
+#
+# Test DROP PROCEDURE.
+#
+connection default;
+create procedure p1() begin end;
+create function f1() returns int
+begin
+call p1();
+return 1;
+end|
+begin;
+select f1();
+f1()
+1
+connection con1;
+# Sending 'drop procedure p1'...
+drop procedure p1;
+connection con2;
+# Waiting for 'drop procedure t1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+connection con3;
+# Waiting for 'select f1()' to get blocked by a pending MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'drop procedure p1'...
+connection con2;
+# Reaping 'select f1()'
+ERROR 42000: PROCEDURE test.p1 does not exist
+connection default;
+#
+# Test CREATE PROCEDURE.
+#
+create procedure p1() begin end;
+begin;
+select f1();
+f1()
+1
+connection con1;
+# Sending 'create procedure p1'...
+create procedure p1() begin end;
+connection con2;
+# Waiting for 'create procedure t1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+connection con3;
+# Waiting for 'select f1()' to get blocked by a pending MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'create procedure p1'...
+ERROR 42000: PROCEDURE p1 already exists
+connection con2;
+# Reaping 'select f1()'
+f1()
+1
+connection default;
+#
+# Test ALTER PROCEDURE.
+#
+begin;
+select f1();
+f1()
+1
+connection con1;
+# Sending 'alter procedure p1'...
+alter procedure p1 contains sql;
+connection con2;
+# Waiting for 'alter procedure t1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+connection con3;
+# Waiting for 'select f1()' to get blocked by a pending MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'alter procedure p1'...
+connection con2;
+# Reaping 'select f1()'
+f1()
+1
+connection default;
+#
+# Test DROP FUNCTION.
+#
+begin;
+select f1();
+f1()
+1
+connection con1;
+# Sending 'drop function f1'...
+drop function f1;
+connection con2;
+# Waiting for 'drop function f1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+connection con3;
+# Waiting for 'select f1()' to get blocked by a pending MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'drop function f1'...
+connection con2;
+# Reaping 'select f1()'
+ERROR 42000: FUNCTION test.f1 does not exist
+connection default;
+#
+# Test CREATE FUNCTION.
+#
+create function f1() returns int return 1;
+begin;
+select f1();
+f1()
+1
+connection con1;
+# Sending 'create function f1'...
+create function f1() returns int return 2;
+connection con2;
+# Waiting for 'create function f1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+connection con3;
+# Waiting for 'select f1()' to get blocked by a pending MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'create function f1'...
+ERROR 42000: FUNCTION f1 already exists
+connection con2;
+# Reaping 'select f1()'
+f1()
+1
+connection default;
+#
+# Test ALTER FUNCTION.
+#
+begin;
+select f1();
+f1()
+1
+connection con1;
+# Sending 'alter function f1'...
+alter function f1 contains sql;
+connection con2;
+# Waiting for 'alter function f1' to get blocked on MDL lock...
+# Demonstrate that there is a pending exclusive lock.
+# Sending 'select f1()'...
+select f1();
+connection con3;
+# Waiting for 'select f1()' to get blocked by a pending MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'alter function f1'...
+connection con2;
+# Reaping 'select f1()'
+f1()
+1
+connection default;
+drop function f1;
+drop procedure p1;
+#
+# 4) MDL lock should not be taken for
+# unrolled CALL statements.
+# The primary goal of metadata locks is a consistent binary log.
+# When a call statement is unrolled, it doesn't get to the
+# binary log, instead the statements that are contained
+# in the procedure body do. This can nest to any level.
+#
+create procedure p1() begin end;
+create procedure p2() begin end;
+create table t1 (a int);
+create procedure p3()
+begin
+call p1();
+call p1();
+call p2();
+end|
+create procedure p4()
+begin
+call p1();
+call p1();
+call p2();
+call p2();
+call p3();
+end|
+begin;
+select * from t1;
+a
+savepoint sv;
+call p4();
+# Prepared statement should not add any locks either.
+prepare stmt from "call p4()";
+execute stmt;
+execute stmt;
+connection con1;
+drop procedure p1;
+drop procedure p2;
+drop procedure p3;
+drop procedure p4;
+connection default;
+# This is to verify there was no implicit commit.
+rollback to savepoint sv;
+call p4();
+ERROR 42000: PROCEDURE test.p4 does not exist
+commit;
+drop table t1;
+#
+# 5) Locks should be taken on routines
+# used indirectly by views or triggers.
+#
+#
+# A function is used from a trigger.
+#
+create function f1() returns int return 1;
+create table t1 (a int);
+create table t2 (a int, b int);
+create trigger t1_ai after insert on t1 for each row
+insert into t2 (a, b) values (new.a, f1());
+begin;
+insert into t1 (a) values (1);
+connection con1;
+# Sending 'drop function f1'
+drop function f1;
+connection con2;
+# Waiting for 'drop function f1' to get blocked on MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'drop function f1'...
+connection default;
+#
+# A function is used from a view.
+#
+create function f1() returns int return 1;
+create view v1 as select f1() as a;
+begin;
+select * from v1;
+a
+1
+connection con1;
+# Sending 'drop function f1'
+drop function f1;
+connection con2;
+# Waiting for 'drop function f1' to get blocked on MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'drop function f1'...
+connection default;
+#
+# A procedure is used from a function.
+#
+create function f1() returns int
+begin
+declare v_out int;
+call p1(v_out);
+return v_out;
+end|
+create procedure p1(out v_out int) set v_out=3;
+begin;
+select * from v1;
+a
+3
+connection con1;
+# Sending 'drop procedure p1'
+drop procedure p1;
+connection con2;
+# Waiting for 'drop procedure p1' to get blocked on MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'drop procedure p1'...
+connection default;
+#
+# Deep nesting: a function is used from a procedure used
+# from a function used from a view used in a trigger.
+#
+create function f2() returns int return 4;
+create procedure p1(out v_out int) set v_out=f2();
+drop trigger t1_ai;
+create trigger t1_ai after insert on t1 for each row
+insert into t2 (a, b) values (new.a, (select max(a) from v1));
+begin;
+insert into t1 (a) values (3);
+connection con1;
+# Sending 'drop function f2'
+drop function f2;
+connection con2;
+# Waiting for 'drop function f2' to get blocked on MDL lock...
+connection default;
+commit;
+connection con1;
+# Reaping 'drop function f2'...
+connection default;
+drop view v1;
+drop function f1;
+drop procedure p1;
+drop table t1, t2;
+#
+# 6) Check that ER_LOCK_DEADLOCK is reported if
+# acquisition of a shared lock fails during a transaction or
+# we need to back off to flush the sp cache.
+#
+# Sic: now this situation does not require a back off since we
+# flush the cache on the fly.
+#
+create function f1() returns int return 7;
+create table t1 (a int);
+begin;
+select * from t1;
+a
+select f1();
+f1()
+7
+commit;
+drop table t1;
+drop function f1;
+#
+# 7) Demonstrate that under LOCK TABLES we accumulate locks
+# on stored routines, and release metadata locks in
+# ROLLBACK TO SAVEPOINT. That is done only for those stored
+# routines that are not part of LOCK TABLES prelocking list.
+# Those stored routines that are part of LOCK TABLES
+# prelocking list are implicitly locked when entering
+# LOCK TABLES, and ROLLBACK TO SAVEPOINT has no effect on
+# them.
+#
+create function f1() returns varchar(20) return "f1()";
+create function f2() returns varchar(20) return "f2()";
+create view v1 as select f1() as a;
+lock table v1 read;
+start transaction;
+select * from v1;
+a
+f1()
+savepoint sv;
+select f2();
+f2()
+f2()
+connection con1;
+# Sending 'drop function f1'...
+drop function f1;
+connection con2;
+# Waiting for 'drop function f1' to get blocked on MDL lock...
+# Sending 'drop function f2'...
+drop function f2;
+connection default;
+# Waiting for 'drop function f2' to get blocked on MDL lock...
+rollback to savepoint sv;
+connection con2;
+# Reaping 'drop function f2'...
+connection default;
+unlock tables;
+commit;
+connection con1;
+# Reaping 'drop function f1'...
+connection default;
+drop function f1;
+ERROR 42000: FUNCTION test.f1 does not exist
+drop function f2;
+ERROR 42000: FUNCTION test.f2 does not exist
+drop view v1;
+#
+# 8) Check the situation when we're preparing or executing a
+# prepared statement, and as part of that try to flush the
+# session sp cache. However, one of the procedures that
+# needs a flush is in use. Verify that there is no infinite
+# reprepare loop and no crash.
+#
+create function f1() returns int return 1;
+#
+# We just mention p1() in the body of f2() to make
+# sure that p1() metadata is validated when validating
+# 'select f2()'.
+# Recursion is not allowed in stored functions, so
+# an attempt to just invoke p1() from f2() which is in turn
+# called from p1() would have given a run-time error.
+#
+create function f2() returns int
+begin
+if @var is null then
+call p1();
+end if;
+return 1;
+end|
+create procedure p1()
+begin
+select f1() into @var;
+execute stmt;
+end|
+connection con2;
+prepare stmt from "select f2()";
+connection default;
+begin;
+select f1();
+f1()
+1
+connection con1;
+# Sending 'alter function f1 ...'...
+alter function f1 comment "comment";
+connection con2;
+# Waiting for 'alter function f1 ...' to get blocked on MDL lock...
+# Sending 'call p1()'...
+call p1();
+connection default;
+# Waiting for 'call p1()' to get blocked on MDL lock on f1...
+# Let 'alter function f1 ...' go through...
+commit;
+connection con1;
+# Reaping 'alter function f1 ...'
+connection con2;
+# Reaping 'call p1()'...
+f2()
+1
+deallocate prepare stmt;
+connection default;
+drop function f1;
+drop function f2;
+drop procedure p1;
+#
+# 9) Check the situation when a stored function is invoked
+# from a stored procedure, and recursively invokes the
+# stored procedure that is in use. But for the second
+# invocation, a cache flush is requested. We can't
+# flush the procedure that's in use, and are forced
+# to use an old version. It is not a violation of
+# consistency, since we unroll top-level calls.
+# Just verify the code works.
+#
+create function f1() returns int return 1;
+begin;
+select f1();
+f1()
+1
+connection con1;
+# Sending 'alter function f1 ...'...
+alter function f1 comment "comment";
+connection con2;
+# Waiting for 'alter function f1 ...' to get blocked on MDL lock...
+#
+# We just mention p1() in the body of f2() to make
+# sure that p1() is prelocked for f2().
+# Recursion is not allowed in stored functions, so
+# an attempt to just invoke p1() from f2() which is in turn
+# called from p1() would have given a run-time error.
+#
+create function f2() returns int
+begin
+if @var is null then
+call p1();
+end if;
+return 1;
+end|
+create procedure p1()
+begin
+select f1() into @var;
+select f2() into @var;
+end|
+# Sending 'call p1()'...
+call p1();
+connection default;
+# Waiting for 'call p1()' to get blocked on MDL lock on f1...
+# Let 'alter function f1 ...' go through...
+commit;
+connection con1;
+# Reaping 'alter function f1 ...'
+connection con2;
+# Reaping 'call p1()'...
+connection default;
+drop function f1;
+drop function f2;
+drop procedure p1;
+#
+# 10) A select from information_schema.routines now
+# flushes the stored routines caches. Test that this
+# does not remove from the cache a stored routine
+# that is already prelocked.
+#
+create function f1() returns int return get_lock("30977", 100000);
+create function f2() returns int return 2;
+create function f3() returns varchar(255)
+begin
+declare res varchar(255);
+declare c cursor for select routine_name from
+information_schema.routines where routine_name='f1';
+select f1() into @var;
+open c;
+fetch c into res;
+close c;
+select f2() into @var;
+return res;
+end|
+connection con1;
+select get_lock("30977", 0);
+get_lock("30977", 0)
+1
+connection default;
+# Sending 'select f3()'...
+select f3();
+connection con1;
+# Waiting for 'select f3()' to get blocked on the user level lock...
+# Do something to change the cache version.
+create function f4() returns int return 4;
+drop function f4;
+select release_lock("30977");
+release_lock("30977")
+1
+connection default;
+# Reaping 'select f3()'...
+# Routine 'f2()' should exist and get executed successfully.
+f3()
+f1
+select @var;
+@var
+2
+drop function f1;
+drop function f2;
+drop function f3;
+# 11) Check the situation when the connection is flushing the
+# SP cache which contains a procedure that is being executed.
+#
+# Function f1() calls p1(). Procedure p1() has a DROP
+# VIEW statement, which, we know, invalidates the routines cache.
+# During cache flush p1() must not be flushed since it's in
+# use.
+#
+create function f1() returns int
+begin
+call p1();
+return 1;
+end|
+create procedure p1()
+begin
+create view v1 as select 1;
+drop view v1;
+select f1() into @var;
+set @exec_count=@exec_count+1;
+end|
+set @exec_count=0;
+call p1();
+ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p1
+select @exec_count;
+@exec_count
+0
+set @@session.max_sp_recursion_depth=5;
+set @exec_count=0;
+call p1();
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+select @exec_count;
+@exec_count
+0
+drop procedure p1;
+drop function f1;
+set @@session.max_sp_recursion_depth=default;
+connection con1;
+disconnect con1;
+connection con2;
+disconnect con2;
+connection con3;
+disconnect con3;
+connection default;
+#
+# SHOW CREATE PROCEDURE p1 called from p1, after p1 was altered
+#
+CREATE PROCEDURE p1()
+BEGIN
+SELECT get_lock("test", 10);
+SHOW CREATE PROCEDURE p1;
+END|
+connect con2, localhost, root;
+connect con3, localhost, root;
+connection default;
+SELECT get_lock("test", 10);
+get_lock("test", 10)
+1
+connection con2;
+# Will halt before executing SHOW CREATE PROCEDURE p1
+# Sending:
+CALL p1();
+connection con3;
+# Alter p1
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1() BEGIN END;
+connection default;
+# Resume CALL p1, now with new p1
+SELECT release_lock("test");
+release_lock("test")
+1
+connection con2;
+# Reaping: CALL p1()
+get_lock("test", 10)
+1
+Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
+p1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+BEGIN END latin1 latin1_swedish_ci latin1_swedish_ci
+connection con3;
+disconnect con3;
+connection con2;
+disconnect con2;
+connection default;
+DROP PROCEDURE p1;
+#
+# Bug#57663 Concurrent statement using stored function and DROP DATABASE
+# breaks SBR
+#
+connect con1, localhost, root;
+connect con2, localhost, root;
+# Test 1: Check that DROP DATABASE block if a function is used
+# by an active transaction.
+connection default;
+CREATE DATABASE db1;
+CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1;
+START TRANSACTION;
+SELECT db1.f1();
+db1.f1()
+1
+connection con1;
+# Sending:
+DROP DATABASE db1;
+connection default;
+# Waiting for DROP DATABASE to be blocked by the lock on f1()
+COMMIT;
+connection con1;
+# Reaping: DROP DATABASE db1
+# Test 2: Check that DROP DATABASE blocks if a procedure is
+# used by an active transaction.
+connection default;
+CREATE DATABASE db1;
+CREATE PROCEDURE db1.p1() BEGIN END;
+CREATE FUNCTION f1() RETURNS INTEGER
+BEGIN
+CALL db1.p1();
+RETURN 1;
+END|
+START TRANSACTION;
+SELECT f1();
+f1()
+1
+connection con1;
+# Sending:
+DROP DATABASE db1;
+connection default;
+# Waiting for DROP DATABASE to be blocked by the lock on p1()
+COMMIT;
+connection con1;
+# Reaping: DROP DATABASE db1
+# Test 3: Check that DROP DATABASE is not selected as a victim if a
+# deadlock is discovered with DML statements.
+connection default;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1;
+START TRANSACTION;
+SELECT db1.f1();
+db1.f1()
+1
+connection con1;
+# Sending:
+DROP DATABASE db1;
+connection default;
+# Waiting for DROP DATABASE to be blocked by the lock on f1()
+SELECT * FROM db1.t1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+COMMIT;
+connection con1;
+# Reaping: DROP DATABASE db1
+# Test 4: Check that active DROP DATABASE blocks stored routine DDL.
+connection default;
+CREATE DATABASE db1;
+CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1;
+CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 2;
+START TRANSACTION;
+SELECT db1.f2();
+db1.f2()
+2
+connection con1;
+# Sending:
+DROP DATABASE db1;
+connection con2;
+# Waiting for DROP DATABASE to be blocked by the lock on f2()
+# Sending:
+ALTER FUNCTION db1.f1 COMMENT "test";
+connection default;
+# Waiting for ALTER FUNCTION to be blocked by the schema lock on db1
+COMMIT;
+connection con1;
+# Reaping: DROP DATABASE db1
+disconnect con1;
+connection con2;
+# Reaping: ALTER FUNCTION f1 COMMENT 'test'
+ERROR 42000: FUNCTION db1.f1 does not exist
+disconnect con2;
+connection default;
+DROP FUNCTION f1;
+#
+# End of 5.5 tests
+#