diff options
Diffstat (limited to 'mysql-test/suite/compat/oracle/r')
78 files changed, 30409 insertions, 0 deletions
diff --git a/mysql-test/suite/compat/oracle/r/anonymous_derived.result b/mysql-test/suite/compat/oracle/r/anonymous_derived.result new file mode 100644 index 00000000..6b482d7b --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/anonymous_derived.result @@ -0,0 +1,86 @@ +# +# MDEV-19162: anonymous derived tables part +# +set @save_sql_mode=@@sql_mode; +set session sql_mode=ORACLE; +SELECT * FROM (SELECT 1 FROM DUAL), (SELECT 2 FROM DUAL); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def __2 1 1 3 1 1 N 32769 0 63 +def __3 2 2 3 1 1 N 32769 0 63 +1 2 +1 2 +create table t1 (a int); +insert into t1 values (2),(3); +create table t2 (a int); +insert into t2 values (2),(3); +select t1.a from t1, (select * from t2 where t2.a<= 2); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 t1 a a 3 11 1 Y 32768 0 63 +a +2 +3 +select t1.a, b from t1, (select a as b from t2 where t2.a<= 2); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 t1 a a 3 11 1 Y 32768 0 63 +def test __2 __2 b b 3 11 1 Y 32768 0 63 +a b +2 2 +3 2 +select t1.a, b from t1, (select max(a) as b from t2); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 t1 a a 3 11 1 Y 32768 0 63 +def t2 __2 b b 3 11 1 Y 32768 0 63 +a b +2 3 +3 3 +explain extended +select t1.a, b from t1, (select max(a) as b from t2); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) +2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","__2"."b" AS "b" from "test"."t1" join (/* select#2 */ select max("test"."t2"."a") AS "b" from "test"."t2") "__2" +select * from (select tt.* from (select * from t1) as tt) where tt.a > 0; +ERROR 42S22: Unknown column 'tt.a' in 'where clause' +select * from (select tt.* from (select * from t1) as tt) where a > 0; +a +2 +3 +create view v1 as select t1.a, b from t1, (select max(a) as b from t2); +select * from v1; +a b +2 3 +3 3 +create procedure p1 +as +begin +select t1.a, b from t1, (select max(a) as b from t2); +end/ +call p1; +a b +2 3 +3 3 +SET sql_mode=default; +select * from v1; +a b +2 3 +3 3 +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`,`__3`.`b` AS `b` from (`t1` join (select max(`t2`.`a`) AS `b` from `t2`) `__3`) latin1 latin1_swedish_ci +call p1; +a b +2 3 +3 3 +show create procedure p1; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +p1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +as +begin +select t1.a, b from t1, (select max(a) as b from t2); +end latin1 latin1_swedish_ci latin1_swedish_ci +drop view v1; +drop procedure p1; +drop table t1,t2; +set session sql_mode=@save_sql_mode; diff --git a/mysql-test/suite/compat/oracle/r/binlog_ptr_mysqlbinlog.result b/mysql-test/suite/compat/oracle/r/binlog_ptr_mysqlbinlog.result new file mode 100644 index 00000000..0656a685 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/binlog_ptr_mysqlbinlog.result @@ -0,0 +1,100 @@ +SET @@SQL_MODE = 'ORACLE'; +########################################################################## +# Test verifies Gtid_log_event/Xid_log_event specific print # +########################################################################## +CREATE TABLE tm (f INT) ENGINE=MYISAM; +INSERT INTO tm VALUES (10); +CREATE TABLE t(f INT) ENGINE=INNODB; +INSERT INTO t VALUES (10); +CREATE OR REPLACE PROCEDURE simpleproc (param1 OUT INT) AS +BEGIN +SELECT COUNT(*) INTO param1 FROM t; +END; +/ +CREATE FUNCTION f1 RETURN INT +AS +BEGIN +RETURN 10; +END; +/ +FLUSH LOGS; +########################################################################## +# Delete data from master so that it can be restored from binlog # +########################################################################## +DROP FUNCTION f1; +DROP PROCEDURE simpleproc; +DROP TABLE tm; +DROP TABLE t; +########################################################################## +# Post recovery using mysqlbinlog # +########################################################################## +SHOW TABLES; +Tables_in_test +t +tm +SELECT * FROM tm; +f +10 +SELECT * FROM t; +f +10 +SELECT f1(); +f1() +10 +CALL simpleproc(@a); +SELECT @a; +@a +1 +"***** Clean Up *****" +DROP TABLE t,tm; +DROP PROCEDURE simpleproc; +DROP FUNCTION f1; +RESET MASTER; +########################################################################## +# Test verifies Gtid_log_event/Xid_log_event/Qery_log_event # +# specific print along with flashback option # +########################################################################## +CREATE TABLE tm(f INT) ENGINE=MYISAM; +INSERT INTO tm VALUES (10); +INSERT INTO tm VALUES (20); +CREATE TABLE t(f INT) ENGINE=INNODB; +INSERT INTO t VALUES (10); +INSERT INTO t VALUES (20); +########################################################################## +# Initial data # +########################################################################## +SELECT * FROM tm; +f +10 +20 +SELECT * FROM t; +f +10 +20 +FLUSH LOGS; +DELETE FROM tm WHERE f=20; +DELETE FROM t WHERE f=20; +FLUSH LOGS; +########################################################################## +# Data after deletion # +########################################################################## +SELECT * FROM tm; +f +10 +SELECT * FROM t; +f +10 +FOUND 2 /START TRANSACTION/ in test.sql +########################################################################## +# Data after recovery using flashback # +########################################################################## +SELECT * FROM tm; +f +10 +20 +SELECT * FROM t; +f +10 +20 +"***** Clean Up *****" +DROP TABLE t,tm; diff --git a/mysql-test/suite/compat/oracle/r/binlog_stm_ps.result b/mysql-test/suite/compat/oracle/r/binlog_stm_ps.result new file mode 100644 index 00000000..01fe3be3 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/binlog_stm_ps.result @@ -0,0 +1,98 @@ +SET sql_mode=ORACLE; +# +# MDEV-10801 sql_mode: dynamic SQL placeholders +# +CREATE TABLE t1 (a INT, b INT); +SET @a=10, @b=20; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (?,?)'; +EXECUTE stmt USING @a, @b; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (:a,:b)'; +EXECUTE stmt USING @a, @b; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (:aaa,:bbb)'; +EXECUTE stmt USING @a, @b; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (:"a",:"b")'; +EXECUTE stmt USING @a, @b; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (:"aaa",:"bbb")'; +EXECUTE stmt USING @a, @b; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (:1,:2)'; +EXECUTE stmt USING @a, @b; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (:222,:111)'; +EXECUTE stmt USING @a, @b; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (:0,:65535)'; +EXECUTE stmt USING @a, @b; +PREPARE stmt FROM 'INSERT INTO t1 VALUES (:65535,:0)'; +EXECUTE stmt USING @a, @b; +SELECT * FROM t1; +a b +10 20 +10 20 +10 20 +10 20 +10 20 +10 20 +10 20 +10 20 +10 20 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b INT) +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20) +master-bin.000001 # Query # # COMMIT +DROP TABLE t1; +# +# MDEV-16095 Oracle-style placeholder inside GROUP BY..WITH ROLLUP breaks replication +# +FLUSH LOGS; +CREATE TABLE t1 (d DATE); +INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24'); +CREATE TABLE t2 (d DATE, c BIGINT); +BEGIN +EXECUTE IMMEDIATE 'INSERT INTO t2 SELECT d, COUNT(*) FROM t1 GROUP BY d, :param' USING 1; +EXECUTE IMMEDIATE 'INSERT INTO t2 SELECT d, COUNT(*) FROM t1 GROUP BY d, :param WITH ROLLUP' USING 1; +END; +$$ +DROP TABLE t1,t2; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000002 # Binlog_checkpoint # # master-bin.000002 +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE TABLE t1 (d DATE) +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24') +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE TABLE t2 (d DATE, c BIGINT) +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t2 SELECT d, COUNT(*) FROM t1 GROUP BY d, 1 +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t2 SELECT d, COUNT(*) FROM t1 GROUP BY d, 1 WITH ROLLUP +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; DROP TABLE "t1","t2" /* generated by server */ diff --git a/mysql-test/suite/compat/oracle/r/binlog_stm_sp.result b/mysql-test/suite/compat/oracle/r/binlog_stm_sp.result new file mode 100644 index 00000000..468309a0 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/binlog_stm_sp.result @@ -0,0 +1,510 @@ +SET sql_mode=ORACLE; +# +# MDEV-10914 ROW data type for stored routine variables +# +CREATE TABLE t1 (a INT, b INT); +CREATE PROCEDURE p1 +AS +rec ROW(a INT,b INT); +BEGIN +rec.a:=100; +rec.b:=200; +INSERT INTO t1 VALUES (rec.a,rec.b); +INSERT INTO t1 VALUES (10, rec=ROW(100,200)); +INSERT INTO t1 VALUES (10, ROW(100,200)=rec); +INSERT INTO t1 SELECT 10, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 10, 21 FROM DUAL WHERE ROW(100,200)=rec; +rec.a:=NULL; +INSERT INTO t1 VALUES (11, rec=ROW(100,200)); +INSERT INTO t1 VALUES (11, rec=ROW(100,201)); +INSERT INTO t1 VALUES (11, ROW(100,200)=rec); +INSERT INTO t1 VALUES (11, ROW(100,201)=rec); +INSERT INTO t1 SELECT 11, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 11, 21 FROM DUAL WHERE ROW(100,200)=rec; +rec.b:=NULL; +INSERT INTO t1 VALUES (12, rec=ROW(100,200)); +INSERT INTO t1 VALUES (12, ROW(100,200)=rec); +INSERT INTO t1 SELECT 12, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 12, 21 FROM DUAL WHERE ROW(100,200)=rec; +END; +$$ +CALL p1(); +SELECT * FROM t1; +a b +100 200 +10 1 +10 1 +10 20 +10 21 +11 NULL +11 0 +11 NULL +11 0 +12 NULL +12 NULL +DROP TABLE t1; +DROP PROCEDURE p1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +rec ROW(a INT,b INT); +BEGIN +rec.a:=100; +rec.b:=200; +INSERT INTO t1 VALUES (rec.a,rec.b); +INSERT INTO t1 VALUES (10, rec=ROW(100,200)); +INSERT INTO t1 VALUES (10, ROW(100,200)=rec); +INSERT INTO t1 SELECT 10, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 10, 21 FROM DUAL WHERE ROW(100,200)=rec; +rec.a:=NULL; +INSERT INTO t1 VALUES (11, rec=ROW(100,200)); +INSERT INTO t1 VALUES (11, rec=ROW(100,201)); +INSERT INTO t1 VALUES (11, ROW(100,200)=rec); +INSERT INTO t1 VALUES (11, ROW(100,201)=rec); +INSERT INTO t1 SELECT 11, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 11, 21 FROM DUAL WHERE ROW(100,200)=rec; +rec.b:=NULL; +INSERT INTO t1 VALUES (12, rec=ROW(100,200)); +INSERT INTO t1 VALUES (12, ROW(100,200)=rec); +INSERT INTO t1 SELECT 12, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 12, 21 FROM DUAL WHERE ROW(100,200)=rec; +END +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES ( NAME_CONST('rec.a',100), NAME_CONST('rec.b',200)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10, ROW(100,200)=ROW(100,200)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10, ROW(100,200)=ROW(100,200)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 SELECT 10, 20 FROM DUAL WHERE ROW(100,200)=ROW(100,200) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 SELECT 10, 21 FROM DUAL WHERE ROW(100,200)=ROW(100,200) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (11, ROW(NULL,200)=ROW(100,200)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (11, ROW(NULL,200)=ROW(100,201)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (11, ROW(100,200)=ROW(NULL,200)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (11, ROW(100,201)=ROW(NULL,200)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 SELECT 11, 20 FROM DUAL WHERE ROW(NULL,200)=ROW(100,200) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 SELECT 11, 21 FROM DUAL WHERE ROW(100,200)=ROW(NULL,200) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (12, ROW(NULL,NULL)=ROW(100,200)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (12, ROW(100,200)=ROW(NULL,NULL)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 SELECT 12, 20 FROM DUAL WHERE ROW(NULL,NULL)=ROW(100,200) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 SELECT 12, 21 FROM DUAL WHERE ROW(100,200)=ROW(NULL,NULL) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE "t1" /* generated by server */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PROCEDURE p1 +# +# Testing ROW fields in LIMIT +# +FLUSH LOGS; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(10); +CREATE TABLE t2 (a INT); +CREATE PROCEDURE p1() +AS +a INT:= 1; +rec ROW(a INT); +BEGIN +rec.a:= 1; +INSERT INTO t2 SELECT 1 FROM t1 LIMIT a; +INSERT INTO t2 SELECT 2 FROM t1 LIMIT rec.a; +END; +$$ +CALL p1(); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted +DROP TABLE t1,t2; +DROP PROCEDURE p1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000002 # Binlog_checkpoint # # master-bin.000002 +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE TABLE t1 (a INT) +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (10),(10) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE TABLE t2 (a INT) +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +a INT:= 1; +rec ROW(a INT); +BEGIN +rec.a:= 1; +INSERT INTO t2 SELECT 1 FROM t1 LIMIT a; +INSERT INTO t2 SELECT 2 FROM t1 LIMIT rec.a; +END +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t2 SELECT 1 FROM t1 LIMIT 1 +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t2 SELECT 2 FROM t1 LIMIT 1 +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; DROP TABLE "t1","t2" /* generated by server */ +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; DROP PROCEDURE p1 +# +# End of MDEV-10914 ROW data type for stored routine variables +# +# +# MDEV-12133 sql_mode=ORACLE: table%ROWTYPE in variable declarations +# +CREATE TABLE t1 (a INT, b INT); +CREATE PROCEDURE p1 +AS +rec t1%ROWTYPE; +BEGIN +rec.a:=100; +rec.b:=200; +SELECT rec=ROW(100,200) AS true1, ROW(100,200)=rec AS true2; +INSERT INTO t1 VALUES (rec.a,rec.b); +INSERT INTO t1 VALUES (10, rec=ROW(100,200)); +INSERT INTO t1 VALUES (10, ROW(100,200)=rec); +INSERT INTO t1 SELECT 10, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 10, 21 FROM DUAL WHERE ROW(100,200)=rec; +rec.a:=NULL; +INSERT INTO t1 VALUES (11, rec=ROW(100,200)); +INSERT INTO t1 VALUES (11, rec=ROW(100,201)); +INSERT INTO t1 VALUES (11, ROW(100,200)=rec); +INSERT INTO t1 VALUES (11, ROW(100,201)=rec); +INSERT INTO t1 SELECT 11, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 11, 21 FROM DUAL WHERE ROW(100,200)=rec; +rec.b:=NULL; +INSERT INTO t1 VALUES (12, rec=ROW(100,200)); +INSERT INTO t1 VALUES (12, ROW(100,200)=rec); +INSERT INTO t1 SELECT 12, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 12, 21 FROM DUAL WHERE ROW(100,200)=rec; +END; +$$ +CALL p1(); +true1 true2 +1 1 +SELECT * FROM t1; +a b +100 200 +10 1 +10 1 +10 20 +10 21 +11 NULL +11 0 +11 NULL +11 0 +12 NULL +12 NULL +DROP TABLE t1; +DROP PROCEDURE p1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000002 # Binlog_checkpoint # # master-bin.000002 +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE TABLE t1 (a INT) +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (10),(10) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE TABLE t2 (a INT) +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +a INT:= 1; +rec ROW(a INT); +BEGIN +rec.a:= 1; +INSERT INTO t2 SELECT 1 FROM t1 LIMIT a; +INSERT INTO t2 SELECT 2 FROM t1 LIMIT rec.a; +END +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t2 SELECT 1 FROM t1 LIMIT 1 +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t2 SELECT 2 FROM t1 LIMIT 1 +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; DROP TABLE "t1","t2" /* generated by server */ +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; DROP PROCEDURE p1 +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE TABLE t1 (a INT, b INT) +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +rec t1%ROWTYPE; +BEGIN +rec.a:=100; +rec.b:=200; +SELECT rec=ROW(100,200) AS true1, ROW(100,200)=rec AS true2; +INSERT INTO t1 VALUES (rec.a,rec.b); +INSERT INTO t1 VALUES (10, rec=ROW(100,200)); +INSERT INTO t1 VALUES (10, ROW(100,200)=rec); +INSERT INTO t1 SELECT 10, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 10, 21 FROM DUAL WHERE ROW(100,200)=rec; +rec.a:=NULL; +INSERT INTO t1 VALUES (11, rec=ROW(100,200)); +INSERT INTO t1 VALUES (11, rec=ROW(100,201)); +INSERT INTO t1 VALUES (11, ROW(100,200)=rec); +INSERT INTO t1 VALUES (11, ROW(100,201)=rec); +INSERT INTO t1 SELECT 11, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 11, 21 FROM DUAL WHERE ROW(100,200)=rec; +rec.b:=NULL; +INSERT INTO t1 VALUES (12, rec=ROW(100,200)); +INSERT INTO t1 VALUES (12, ROW(100,200)=rec); +INSERT INTO t1 SELECT 12, 20 FROM DUAL WHERE rec=ROW(100,200); +INSERT INTO t1 SELECT 12, 21 FROM DUAL WHERE ROW(100,200)=rec; +END +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES ( NAME_CONST('rec.a',100), NAME_CONST('rec.b',200)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (10, ROW(100,200)=ROW(100,200)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (10, ROW(100,200)=ROW(100,200)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 SELECT 10, 20 FROM DUAL WHERE ROW(100,200)=ROW(100,200) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 SELECT 10, 21 FROM DUAL WHERE ROW(100,200)=ROW(100,200) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (11, ROW(NULL,200)=ROW(100,200)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (11, ROW(NULL,200)=ROW(100,201)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (11, ROW(100,200)=ROW(NULL,200)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (11, ROW(100,201)=ROW(NULL,200)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 SELECT 11, 20 FROM DUAL WHERE ROW(NULL,200)=ROW(100,200) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 SELECT 11, 21 FROM DUAL WHERE ROW(100,200)=ROW(NULL,200) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (12, ROW(NULL,NULL)=ROW(100,200)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (12, ROW(100,200)=ROW(NULL,NULL)) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 SELECT 12, 20 FROM DUAL WHERE ROW(NULL,NULL)=ROW(100,200) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t1 SELECT 12, 21 FROM DUAL WHERE ROW(100,200)=ROW(NULL,NULL) +master-bin.000002 # Query # # COMMIT +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; DROP TABLE "t1" /* generated by server */ +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; DROP PROCEDURE p1 +# +# MDEV-12291 Allow ROW variables as SELECT INTO targets +# +FLUSH LOGS; +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10, 'b10'); +CREATE TABLE t2 LIKE t1; +CREATE PROCEDURE p1 +AS +rec1 ROW(a INT, b VARCHAR(32)); +BEGIN +SELECT * INTO rec1 FROM t1; +INSERT INTO t2 VALUES (rec1.a, rec1.b); +END; +$$ +CALL p1(); +SELECT * FROM t1; +a b +10 b10 +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000003 # Binlog_checkpoint # # master-bin.000003 +master-bin.000003 # Gtid # # GTID #-#-# +master-bin.000003 # Query # # use `test`; CREATE TABLE t1 (a INT, b VARCHAR(32)) +master-bin.000003 # Gtid # # BEGIN GTID #-#-# +master-bin.000003 # Query # # use `test`; INSERT INTO t1 VALUES (10, 'b10') +master-bin.000003 # Query # # COMMIT +master-bin.000003 # Gtid # # GTID #-#-# +master-bin.000003 # Query # # use `test`; CREATE TABLE t2 LIKE t1 +master-bin.000003 # Gtid # # GTID #-#-# +master-bin.000003 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +rec1 ROW(a INT, b VARCHAR(32)); +BEGIN +SELECT * INTO rec1 FROM t1; +INSERT INTO t2 VALUES (rec1.a, rec1.b); +END +master-bin.000003 # Gtid # # BEGIN GTID #-#-# +master-bin.000003 # Query # # use `test`; INSERT INTO t2 VALUES ( NAME_CONST('rec1.a',10), NAME_CONST('rec1.b',_latin1'b10' COLLATE 'latin1_swedish_ci')) +master-bin.000003 # Query # # COMMIT +master-bin.000003 # Gtid # # GTID #-#-# +master-bin.000003 # Query # # use `test`; DROP TABLE "t1" /* generated by server */ +master-bin.000003 # Gtid # # GTID #-#-# +master-bin.000003 # Query # # use `test`; DROP TABLE "t2" /* generated by server */ +master-bin.000003 # Gtid # # GTID #-#-# +master-bin.000003 # Query # # use `test`; DROP PROCEDURE p1 +FLUSH LOGS; +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10, 'b10'); +CREATE TABLE t2 LIKE t1; +CREATE PROCEDURE p1 +AS +rec1 t1%ROWTYPE; +BEGIN +SELECT * INTO rec1 FROM t1; +INSERT INTO t2 VALUES (rec1.a, rec1.b); +END; +$$ +CALL p1(); +SELECT * FROM t1; +a b +10 b10 +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000004 # Binlog_checkpoint # # master-bin.000004 +master-bin.000004 # Gtid # # GTID #-#-# +master-bin.000004 # Query # # use `test`; CREATE TABLE t1 (a INT, b VARCHAR(32)) +master-bin.000004 # Gtid # # BEGIN GTID #-#-# +master-bin.000004 # Query # # use `test`; INSERT INTO t1 VALUES (10, 'b10') +master-bin.000004 # Query # # COMMIT +master-bin.000004 # Gtid # # GTID #-#-# +master-bin.000004 # Query # # use `test`; CREATE TABLE t2 LIKE t1 +master-bin.000004 # Gtid # # GTID #-#-# +master-bin.000004 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +rec1 t1%ROWTYPE; +BEGIN +SELECT * INTO rec1 FROM t1; +INSERT INTO t2 VALUES (rec1.a, rec1.b); +END +master-bin.000004 # Gtid # # BEGIN GTID #-#-# +master-bin.000004 # Query # # use `test`; INSERT INTO t2 VALUES ( NAME_CONST('rec1.a',10), NAME_CONST('rec1.b',_latin1'b10' COLLATE 'latin1_swedish_ci')) +master-bin.000004 # Query # # COMMIT +master-bin.000004 # Gtid # # GTID #-#-# +master-bin.000004 # Query # # use `test`; DROP TABLE "t1" /* generated by server */ +master-bin.000004 # Gtid # # GTID #-#-# +master-bin.000004 # Query # # use `test`; DROP TABLE "t2" /* generated by server */ +master-bin.000004 # Gtid # # GTID #-#-# +master-bin.000004 # Query # # use `test`; DROP PROCEDURE p1 +FLUSH LOGS; +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10, 'b10'); +CREATE TABLE t2 LIKE t1; +CREATE PROCEDURE p1 +AS +CURSOR cur1 IS SELECT * FROM t1; +rec1 cur1%ROWTYPE; +BEGIN +SELECT * INTO rec1 FROM t1; +INSERT INTO t2 VALUES (rec1.a, rec1.b); +END; +$$ +CALL p1(); +SELECT * FROM t1; +a b +10 b10 +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000005 # Binlog_checkpoint # # master-bin.000005 +master-bin.000005 # Gtid # # GTID #-#-# +master-bin.000005 # Query # # use `test`; CREATE TABLE t1 (a INT, b VARCHAR(32)) +master-bin.000005 # Gtid # # BEGIN GTID #-#-# +master-bin.000005 # Query # # use `test`; INSERT INTO t1 VALUES (10, 'b10') +master-bin.000005 # Query # # COMMIT +master-bin.000005 # Gtid # # GTID #-#-# +master-bin.000005 # Query # # use `test`; CREATE TABLE t2 LIKE t1 +master-bin.000005 # Gtid # # GTID #-#-# +master-bin.000005 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +CURSOR cur1 IS SELECT * FROM t1; +rec1 cur1%ROWTYPE; +BEGIN +SELECT * INTO rec1 FROM t1; +INSERT INTO t2 VALUES (rec1.a, rec1.b); +END +master-bin.000005 # Gtid # # BEGIN GTID #-#-# +master-bin.000005 # Query # # use `test`; INSERT INTO t2 VALUES ( NAME_CONST('rec1.a',10), NAME_CONST('rec1.b',_latin1'b10' COLLATE 'latin1_swedish_ci')) +master-bin.000005 # Query # # COMMIT +master-bin.000005 # Gtid # # GTID #-#-# +master-bin.000005 # Query # # use `test`; DROP TABLE "t1" /* generated by server */ +master-bin.000005 # Gtid # # GTID #-#-# +master-bin.000005 # Query # # use `test`; DROP TABLE "t2" /* generated by server */ +master-bin.000005 # Gtid # # GTID #-#-# +master-bin.000005 # Query # # use `test`; DROP PROCEDURE p1 +# +# MDEV-16020 SP variables inside GROUP BY..WITH ROLLUP break replication +# +FLUSH LOGS; +CREATE TABLE t1 (d DATE); +INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24'); +CREATE TABLE t2 (d DATE, c BIGINT); +DECLARE +var INT; +BEGIN +INSERT INTO t2 SELECT d, COUNT(*) FROM t1 GROUP BY d, var; +INSERT INTO t2 SELECT d, COUNT(*) FROM t1 GROUP BY d, var WITH ROLLUP; +END; +$$ +DROP TABLE t1,t2; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000006 # Binlog_checkpoint # # master-bin.000006 +master-bin.000006 # Gtid # # GTID #-#-# +master-bin.000006 # Query # # use `test`; CREATE TABLE t1 (d DATE) +master-bin.000006 # Gtid # # BEGIN GTID #-#-# +master-bin.000006 # Query # # use `test`; INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24') +master-bin.000006 # Query # # COMMIT +master-bin.000006 # Gtid # # GTID #-#-# +master-bin.000006 # Query # # use `test`; CREATE TABLE t2 (d DATE, c BIGINT) +master-bin.000006 # Gtid # # BEGIN GTID #-#-# +master-bin.000006 # Query # # use `test`; INSERT INTO t2 SELECT d, COUNT(*) FROM t1 GROUP BY d, NAME_CONST('var',NULL) +master-bin.000006 # Query # # COMMIT +master-bin.000006 # Gtid # # BEGIN GTID #-#-# +master-bin.000006 # Query # # use `test`; INSERT INTO t2 SELECT d, COUNT(*) FROM t1 GROUP BY d, NAME_CONST('var',NULL) WITH ROLLUP +master-bin.000006 # Query # # COMMIT +master-bin.000006 # Gtid # # GTID #-#-# +master-bin.000006 # Query # # use `test`; DROP TABLE "t1","t2" /* generated by server */ diff --git a/mysql-test/suite/compat/oracle/r/binlog_stm_sp_package.result b/mysql-test/suite/compat/oracle/r/binlog_stm_sp_package.result new file mode 100644 index 00000000..8c1ee056 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/binlog_stm_sp_package.result @@ -0,0 +1,268 @@ +SET sql_mode=ORACLE; +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE IF NOT EXISTS p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +Warnings: +Note 1304 PACKAGE p1 already exists +CREATE PACKAGE BODY p1 AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +END; +$$ +DROP PACKAGE BODY p1; +DROP PACKAGE p1; +DROP PACKAGE IF EXISTS p1; +Warnings: +Note 1305 PACKAGE test.p1 does not exist +# +# Creating a package with a COMMENT clause +# +CREATE PACKAGE p1 COMMENT 'package-p1-comment' AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 COMMENT 'package-body-p1-comment' AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END; +$$ +DROP PACKAGE p1; +# +# Creating a package with a different DEFINER +# +CREATE DEFINER=xxx@localhost PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +Warnings: +Note 1449 The user specified as a definer ('xxx'@'localhost') does not exist +CREATE DEFINER=xxx@localhost PACKAGE BODY p1 AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END; +$$ +Warnings: +Note 1449 The user specified as a definer ('xxx'@'localhost') does not exist +DROP PACKAGE p1; +# +# Creating a package with a different DEFINER, with SQL SECURITY INVOKER +# +CREATE DEFINER=xxx@localhost PACKAGE p1 SQL SECURITY INVOKER AS +PROCEDURE p1; +END; +$$ +Warnings: +Note 1449 The user specified as a definer ('xxx'@'localhost') does not exist +CREATE DEFINER=xxx@localhost PACKAGE BODY p1 SQL SECURITY INVOKER AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END; +$$ +Warnings: +Note 1449 The user specified as a definer ('xxx'@'localhost') does not exist +DROP PACKAGE p1; +# +# Creating a new package in a remote database +# +CREATE DATABASE test2; +CREATE PACKAGE test2.test2 COMMENT 'package-test2-comment' AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END +$$ +CREATE PACKAGE BODY test2.test2 COMMENT 'package-body-test2-comment' AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +PROCEDURE p1 AS BEGIN SELECT f1(); END; +END; +$$ +DROP PACKAGE BODY test2.test2; +DROP PACKAGE test2.test2; +DROP DATABASE test2; +# +# MDEV-13139 Package-wide variables in CREATE PACKAGE +# +CREATE TABLE t1 (a INT); +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +a INT:=0; +PROCEDURE p1 AS +BEGIN +INSERT INTO t1 VALUES (a); +a:=a+1; +END; +BEGIN +a:=10; +END; +$$ +CALL p1.p1(); +CALL p1.p1(); +SELECT * FROM t1; +a +10 +11 +# sp-cache-invalidate +CALL p1.p1(); +CALL p1.p1(); +SELECT * FROM t1; +a +10 +11 +10 +11 +DROP PACKAGE p1; +DROP TABLE t1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE "p1" AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE IF NOT EXISTS "p1" AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE BODY "p1" AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE BODY p1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE p1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE IF EXISTS p1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE "p1" COMMENT 'package-p1-comment' + AS +PROCEDURE p1; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE BODY "p1" COMMENT 'package-body-p1-comment' + AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE p1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="xxx"@"localhost" PACKAGE "p1" AS +PROCEDURE p1; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="xxx"@"localhost" PACKAGE BODY "p1" AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE p1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="xxx"@"localhost" PACKAGE "p1" SQL SECURITY INVOKER + AS +PROCEDURE p1; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="xxx"@"localhost" PACKAGE BODY "p1" SQL SECURITY INVOKER + AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE p1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # CREATE DATABASE test2 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE "test2"."test2" COMMENT 'package-test2-comment' + AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE BODY "test2"."test2" COMMENT 'package-body-test2-comment' + AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +PROCEDURE p1 AS BEGIN SELECT f1(); END; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE BODY test2.test2 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE test2.test2 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # DROP DATABASE test2 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE "p1" AS +PROCEDURE p1; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" PACKAGE BODY "p1" AS +a INT:=0; +PROCEDURE p1 AS +BEGIN +INSERT INTO t1 VALUES (a); +a:=a+1; +END; +BEGIN +a:=10; +END +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES ( NAME_CONST('a',10)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES ( NAME_CONST('a',11)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER="root"@"localhost" FUNCTION "dummy"() RETURN int(11) +AS +BEGIN +RETURN 1; +END +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP FUNCTION dummy +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES ( NAME_CONST('a',10)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES ( NAME_CONST('a',11)) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP PACKAGE p1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE "t1" /* generated by server */ diff --git a/mysql-test/suite/compat/oracle/r/column_compression.result b/mysql-test/suite/compat/oracle/r/column_compression.result new file mode 100644 index 00000000..2709fe04 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/column_compression.result @@ -0,0 +1,1333 @@ +SET sql_mode=ORACLE; +SET column_compression_zlib_wrap=true; +CREATE TABLE t1 (a BLOB COMPRESSED); +INSERT INTO t1 VALUES (REPEAT('a',10000)); +SELECT DATA_LENGTH<100 AS c FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; +c +1 +DROP TABLE t1; +# +# MDEV-17363 - Compressed columns cannot be restored from dump +# +CREATE TABLE t1(a INT NOT NULL COMPRESSED); +ERROR 42000: Incorrect column specifier for column 'a' +SHOW WARNINGS; +Level Code Message +Error 1063 Incorrect column specifier for column 'a' +CREATE TABLE t1( +a JSON COMPRESSED, +b VARCHAR(1000) COMPRESSED BINARY, +c NVARCHAR(1000) COMPRESSED BINARY, +d TINYTEXT COMPRESSED BINARY +); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid("a")), + "b" varchar(1000) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, + "c" varchar(1000) /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL, + "d" tinytext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +# +# VARCHAR and TEXT variants +# +# +# The following statements run without warnings. +# The `compressed opt_binary` grammar sequence is covered. +# +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BINARY); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BINARY ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BYTE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED UNICODE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED CHARACTER SET utf8); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BYTE DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(10) /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BINARY DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED ASCII DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED CHARACTER SET utf8 DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED CHARACTER SET utf8 GENERATED ALWAYS AS (REPEAT('a',100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci GENERATED ALWAYS AS (repeat('a',100)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a VARCHAR(10) BINARY COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) ASCII COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) BYTE COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BYTE COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BINARY COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED ASCII COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED CHARACTER SET utf8 COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BYTE DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED BINARY DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED ASCII DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED CHARACTER SET utf8 DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# The `compressed opt_binary` grammar sequence is covered. +# +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BINARY); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BINARY ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BYTE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED UNICODE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED CHARACTER SET utf8); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BYTE DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(10) /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BINARY DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED ASCII DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED CHARACTER SET utf8 DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED CHARACTER SET utf8 GENERATED ALWAYS AS (REPEAT('a',100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci GENERATED ALWAYS AS (repeat('a',100)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a VARCHAR2(10) BINARY COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) ASCII COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR2(10) BYTE COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BYTE COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BINARY COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED ASCII COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED CHARACTER SET utf8 COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BYTE DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED BINARY DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED ASCII DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR2(10) COMPRESSED CHARACTER SET utf8 DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# The `compressed opt_binary` grammar sequence is covered. +# +CREATE TABLE t1 (a TINYTEXT COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED BINARY); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED BINARY ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED BYTE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED UNICODE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED CHARACTER SET utf8); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a TINYTEXT COMPRESSED BYTE DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED BINARY DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED ASCII DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED CHARACTER SET utf8 DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT COMPRESSED CHARACTER SET utf8 GENERATED ALWAYS AS (REPEAT('a',100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci GENERATED ALWAYS AS (repeat('a',100)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a TINYTEXT BINARY COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT ASCII COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinytext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYTEXT BYTE COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a TINYTEXT COMPRESSED BYTE COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TINYTEXT COMPRESSED BINARY COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TINYTEXT COMPRESSED ASCII COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TINYTEXT COMPRESSED CHARACTER SET utf8 COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a TINYTEXT COMPRESSED BYTE DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TINYTEXT COMPRESSED BINARY DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TINYTEXT COMPRESSED ASCII DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TINYTEXT COMPRESSED CHARACTER SET utf8 DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# The `compressed opt_binary` grammar sequence is covered. +# +CREATE TABLE t1 (a TEXT COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED BINARY); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED BINARY ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED BYTE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" blob(65535) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED UNICODE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED CHARACTER SET utf8); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a TEXT COMPRESSED BYTE DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" blob(65535) /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED BINARY DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED ASCII DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED CHARACTER SET utf8 DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT COMPRESSED CHARACTER SET utf8 GENERATED ALWAYS AS (REPEAT('a',100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci GENERATED ALWAYS AS (repeat('a',100)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a TEXT BINARY COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT ASCII COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" text /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TEXT BYTE COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" blob(65535) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a TEXT COMPRESSED BYTE COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TEXT COMPRESSED BINARY COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TEXT COMPRESSED ASCII COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TEXT COMPRESSED CHARACTER SET utf8 COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a TEXT COMPRESSED BYTE DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TEXT COMPRESSED BINARY DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TEXT COMPRESSED ASCII DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TEXT COMPRESSED CHARACTER SET utf8 DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# The `compressed opt_binary` grammar sequence is covered. +# +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BINARY); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BINARY ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BYTE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED UNICODE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED CHARACTER SET utf8); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BYTE DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BINARY DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED ASCII DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED CHARACTER SET utf8 DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED CHARACTER SET utf8 GENERATED ALWAYS AS (REPEAT('a',100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci GENERATED ALWAYS AS (repeat('a',100)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a MEDIUMTEXT BINARY COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT ASCII COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumtext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMTEXT BYTE COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BYTE COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BINARY COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED ASCII COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED CHARACTER SET utf8 COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BYTE DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED BINARY DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED ASCII DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a MEDIUMTEXT COMPRESSED CHARACTER SET utf8 DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# The `compressed opt_binary` grammar sequence is covered. +# +CREATE TABLE t1 (a LONGTEXT COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED BINARY); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED BINARY ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED BYTE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED ASCII); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED UNICODE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED CHARACTER SET utf8); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a LONGTEXT COMPRESSED BYTE DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED BINARY DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED ASCII DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED CHARACTER SET utf8 DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT COMPRESSED CHARACTER SET utf8 GENERATED ALWAYS AS (REPEAT('a',100))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci GENERATED ALWAYS AS (repeat('a',100)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a LONGTEXT BINARY COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT ASCII COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGTEXT BYTE COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a LONGTEXT COMPRESSED BYTE COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a LONGTEXT COMPRESSED BINARY COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a LONGTEXT COMPRESSED ASCII COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a LONGTEXT COMPRESSED CHARACTER SET utf8 COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a LONGTEXT COMPRESSED BYTE DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a LONGTEXT COMPRESSED BINARY DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a LONGTEXT COMPRESSED ASCII DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a LONGTEXT COMPRESSED CHARACTER SET utf8 DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# VARBINARY and BLOB variables +# +# +# The following statements run without warnings. +# +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED GENERATED ALWAYS AS (REPEAT('a',10))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ GENERATED ALWAYS AS (repeat('a',10)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a VARCHAR(10) DEFAULT '' COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) NULL COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a VARCHAR(10) COMPRESSED NULL COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# +CREATE TABLE t1 (a TINYBLOB COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a TINYBLOB COMPRESSED DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYBLOB COMPRESSED NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYBLOB COMPRESSED GENERATED ALWAYS AS (REPEAT('a',10))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ GENERATED ALWAYS AS (repeat('a',10)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a TINYBLOB DEFAULT '' COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a TINYBLOB NULL COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" tinyblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a TINYBLOB COMPRESSED COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a TINYBLOB COMPRESSED DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a TINYBLOB COMPRESSED NULL COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# +CREATE TABLE t1 (a BLOB COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a BLOB COMPRESSED DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a BLOB COMPRESSED NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a BLOB COMPRESSED GENERATED ALWAYS AS (REPEAT('a',10))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ GENERATED ALWAYS AS (repeat('a',10)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a BLOB DEFAULT '' COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a BLOB NULL COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a BLOB COMPRESSED COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a BLOB COMPRESSED DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a BLOB COMPRESSED NULL COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# +CREATE TABLE t1 (a MEDIUMBLOB COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a MEDIUMBLOB COMPRESSED DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMBLOB COMPRESSED NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMBLOB COMPRESSED GENERATED ALWAYS AS (REPEAT('a',10))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ GENERATED ALWAYS AS (repeat('a',10)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a MEDIUMBLOB DEFAULT '' COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a MEDIUMBLOB NULL COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mediumblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a MEDIUMBLOB COMPRESSED COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a MEDIUMBLOB COMPRESSED DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a MEDIUMBLOB COMPRESSED NULL COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements run without warnings. +# +CREATE TABLE t1 (a LONGBLOB COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements run without warnings. +# They have extra column attributes (or GENERATED) after COMPRESSED. +# +CREATE TABLE t1 (a LONGBLOB COMPRESSED DEFAULT ''); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGBLOB COMPRESSED NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGBLOB COMPRESSED GENERATED ALWAYS AS (REPEAT('a',10))); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ GENERATED ALWAYS AS (repeat('a',10)) VIRTUAL +) +DROP TABLE t1; +# +# The following statements return deprecated syntax warnings +# +CREATE TABLE t1 (a LONGBLOB DEFAULT '' COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT '' +) +DROP TABLE t1; +CREATE TABLE t1 (a LONGBLOB NULL COMPRESSED); +Warnings: +Warning 1287 '<data type> <character set clause> ... COMPRESSED...' is deprecated and will be removed in a future release. Please use '<data type> COMPRESSED... <character set clause> ...' instead +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob /*!100301 COMPRESSED*/ DEFAULT NULL +) +DROP TABLE t1; +# +# The following statements fail by the grammar, +# because COMPRESSED immediately follows 'field_type'. +# +CREATE TABLE t1 (a LONGBLOB COMPRESSED COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# The following statements are not prohibited by the *.yy grammar, +# because the sequence `field_type attribute COMPRESSED` is allowed +# (notice there is at least one attribute after `field_type`). +# The first COMPRESSED is parsed inside `field_type`. +# The second COMPRESSED passes through the parser but then is caught +# inside Column_definition::set_compressed_deprecated_with_type_check() +# and a syntax error is raised. +# +CREATE TABLE t1 (a LONGBLOB COMPRESSED DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a LONGBLOB COMPRESSED NULL COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +# +# NVARCHAR +# +CREATE TABLE t1 (a NVARCHAR(10) COMPRESSED); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) /*!100301 COMPRESSED*/ CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a NVARCHAR(10) COMPRESSED BINARY COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 +CREATE TABLE t1 (a NVARCHAR(10) COMPRESSED DEFAULT '' COMPRESSED); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COMPRESSED)' at line 1 diff --git a/mysql-test/suite/compat/oracle/r/custom_aggregate_functions.result b/mysql-test/suite/compat/oracle/r/custom_aggregate_functions.result new file mode 100644 index 00000000..21fac193 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/custom_aggregate_functions.result @@ -0,0 +1,136 @@ +SET sql_mode=ORACLE; +create aggregate function f1(x INT) return INT AS +begin +insert into t1(sal) values (x); +return x; +end| +ERROR HY000: Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function +create function f1(x INT) return INT AS +begin +set x=5; +fetch group next row; +return x+1; +end | +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +CREATE TABLE marks(stud_id INT, grade_count INT); +INSERT INTO marks VALUES (1,6), (2,4), (3,7), (4,5), (5,8); +SELECT * FROM marks; +stud_id grade_count +1 6 +2 4 +3 7 +4 5 +5 8 +# Using PL/SQL syntax: EXCEPTION WHEN NO_DATA_FOUND +CREATE AGGREGATE FUNCTION IF NOT EXISTS aggregate_count(x INT) RETURN INT AS +count_students INT DEFAULT 0; +BEGIN +LOOP +FETCH GROUP NEXT ROW; +IF x THEN +count_students:= count_students + 1; +END IF; +END LOOP; +EXCEPTION +WHEN NO_DATA_FOUND THEN +RETURN count_students; +END aggregate_count // +SELECT aggregate_count(stud_id) FROM marks; +aggregate_count(stud_id) +5 +DROP FUNCTION IF EXISTS aggregate_count; +# Using SQL/PSM systax: CONTINUE HANDLER +CREATE AGGREGATE FUNCTION IF NOT EXISTS aggregate_count(x INT) RETURN INT AS +count_students INT DEFAULT 0; +CONTINUE HANDLER FOR NOT FOUND RETURN count_students; +BEGIN +LOOP +FETCH GROUP NEXT ROW; +IF x THEN +SET count_students= count_students + 1; +END IF; +END LOOP; +END // +SELECT aggregate_count(stud_id) FROM marks; +aggregate_count(stud_id) +5 +DROP FUNCTION IF EXISTS aggregate_count; +DROP TABLE marks; +# +# MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW +# +CREATE PROCEDURE p1 AS +BEGIN +FETCH GROUP NEXT ROW; +END; +$$ +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +BEGIN NOT ATOMIC +FETCH GROUP NEXT ROW; +END; +$$ +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +CREATE DEFINER=root@localhost FUNCTION f1 RETURN INT AS +BEGIN +FETCH GROUP NEXT ROW; +RETURN 0; +END; +$$ +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 +AFTER INSERT ON t1 FOR EACH ROW +FETCH GROUP NEXT ROW; +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +DROP TABLE t1; +CREATE EVENT ev1 +ON SCHEDULE EVERY 1 HOUR +STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH +ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK +DO FETCH GROUP NEXT ROW; +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS +BEGIN +FETCH GROUP NEXT ROW; -- In a package procedure +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 0; +END; +END; +$$ +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +FUNCTION f1 RETURN INT AS +BEGIN +FETCH GROUP NEXT ROW; -- In a package function +RETURN 0; +END; +END; +$$ +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 0; +END; +BEGIN +FETCH GROUP NEXT ROW; -- In a package executable section +END; +$$ +ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context +DROP PACKAGE pkg1; diff --git a/mysql-test/suite/compat/oracle/r/empty_string_literal.result b/mysql-test/suite/compat/oracle/r/empty_string_literal.result new file mode 100644 index 00000000..4af576e9 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/empty_string_literal.result @@ -0,0 +1,181 @@ +USE test; +# +# MDEV-14013 : sql_mode=EMPTY_STRING_IS_NULL +# +set @mode='ORACLE,EMPTY_STRING_IS_NULL'; +SET SESSION character_set_connection=latin2; +SET SESSION character_set_client=cp1250; +# +# Test litteral +# +SET sql_mode=@mode; +select @@sql_mode; +@@sql_mode +PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT +SELECT '',CHARSET(''), null, CHARSET(null), CAST(null as char(10)), CHARSET(CAST(null as char(10))), 'x', CHARSET('x'); +NULL CHARSET('') NULL CHARSET(null) CAST(null as char(10)) CHARSET(CAST(null as char(10))) x CHARSET('x') +NULL latin2 NULL binary NULL latin2 x latin2 +SELECT CHARSET(NULLIF('','')),NULLIF('',''); +CHARSET(NULLIF('','')) NULLIF('','') +latin2 NULL +SET sql_mode=default; +SELECT '',CHARSET(''), null, CHARSET(null), CAST(null as char(10)), CHARSET(CAST(null as char(10))), 'x', CHARSET('x'); + CHARSET('') NULL CHARSET(null) CAST(null as char(10)) CHARSET(CAST(null as char(10))) x CHARSET('x') + latin2 NULL binary NULL latin2 x latin2 +SELECT CHARSET(NULLIF('','')),NULLIF('',''); +CHARSET(NULLIF('','')) NULLIF('','') +latin2 NULL +# +# Test NCHAR litteral +# +SET sql_mode=@mode; +SELECT N'',CHARSET(N''), N'x', CHARSET(N'x'); +NULL CHARSET(N'') x CHARSET(N'x') +NULL utf8mb3 x utf8mb3 +SELECT CHARSET(NULLIF(N'',N'')),NULLIF(N'',N''); +CHARSET(NULLIF(N'',N'')) NULLIF(N'',N'') +utf8mb3 NULL +SET sql_mode=default; +SELECT N'',CHARSET(N''), N'x', CHARSET(N'x'); + CHARSET(N'') x CHARSET(N'x') + utf8mb3 x utf8mb3 +SELECT CHARSET(NULLIF(N'',N'')),NULLIF(N'',N''); +CHARSET(NULLIF(N'',N'')) NULLIF(N'',N'') +utf8mb3 NULL +# +# Test CHARSET prefix litteral +# +SET sql_mode=@mode; +SELECT _cp1250 '',CHARSET(_cp1250 ''), _cp1250 'x', CHARSET(_cp1250 'x'); +NULL CHARSET(_cp1250 '') x CHARSET(_cp1250 'x') +NULL cp1250 x cp1250 +SELECT CHARSET(NULLIF(_cp1250 '',_cp1250 '')),NULLIF(_cp1250 '',_cp1250 ''); +CHARSET(NULLIF(_cp1250 '',_cp1250 '')) NULLIF(_cp1250 '',_cp1250 '') +cp1250 NULL +SET sql_mode=default; +SELECT _cp1250 '',CHARSET(_cp1250 ''), _cp1250 'x', CHARSET(_cp1250 'x'); + CHARSET(_cp1250 '') x CHARSET(_cp1250 'x') + cp1250 x cp1250 +SELECT CHARSET(NULLIF(_cp1250 '',_cp1250 '')),NULLIF(_cp1250 '',_cp1250 ''); +CHARSET(NULLIF(_cp1250 '',_cp1250 '')) NULLIF(_cp1250 '',_cp1250 '') +cp1250 NULL +SET sql_mode=@mode; +# +# Test litteral concat +# +SELECT 'a' 'b'; +a +ab +SELECT 'a' ''; +a +a +SELECT '' 'b'; +b +b +SELECT '' ''; +NULL +NULL +SELECT '' 'b' 'c'; +b +bc +SELECT '' '' 'c'; +c +c +SELECT 'a' '' 'c'; +a +ac +SELECT 'a' '' ''; +a +a +SELECT '' '' ''; +NULL +NULL +SELECT '' '' '',CHARSET('' '' ''); +NULL CHARSET('' '' '') +NULL latin2 +SELECT _latin1'' '' '',CHARSET(_latin1'' '' ''); +NULL CHARSET(_latin1'' '' '') +NULL latin1 +SELECT N'' '' '',CHARSET(N'' '' ''); +NULL CHARSET(N'' '' '') +NULL utf8mb3 +# +# UNION - implicit group by +# +SELECT 1, null +UNION +SELECT 1 , '' +ORDER BY 1; +1 NULL +1 NULL +SELECT 1, null +UNION +SELECT 1 , N'' +ORDER BY 1; +1 NULL +1 NULL +SELECT 1, null +UNION +SELECT 1 , _cp1250 '' +ORDER BY 1; +1 NULL +1 NULL +SELECT NULLIF(_cp1250 '',_cp1250 '') +UNION +SELECT NULLIF(N'',N''); +NULLIF(_cp1250 '',_cp1250 '') +NULL +SELECT 1 , _latin2 '' +UNION +SELECT 1 , _cp1250 ''; +ERROR HY000: Illegal mix of collations (latin2_general_ci,IGNORABLE) and (cp1250_general_ci,IGNORABLE) for operation 'UNION' +SELECT 1, null +UNION +SELECT 1 , '' +UNION +SELECT 1 , N''; +1 NULL +1 NULL +CREATE TABLE t1 (c1 INT,c2 VARCHAR(10)); +INSERT INTO t1 VALUES (1,'one'); +INSERT INTO t1 VALUES (1,''); +INSERT INTO t1 VALUES (1,null); +# +# Test in a view +# +CREATE VIEW v1 +AS SELECT c1, c2 +FROM t1 +UNION +SELECT c1 , '' + FROM t1 +ORDER BY 1,2; +SELECT * FROM v1; +c1 c2 +1 NULL +1 one +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select "t1"."c1" AS "c1","t1"."c2" AS "c2" from "t1" union select "t1"."c1" AS "c1",NULL AS "NULL" from "t1" order by 1,2 cp1250 latin2_general_ci +DROP VIEW v1; +DROP TABLE t1; +EXPLAIN EXTENDED SELECT ''; +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" +EXPLAIN EXTENDED SELECT _latin1''; +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" +EXPLAIN EXTENDED SELECT N''; +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" +EXPLAIN EXTENDED SELECT '' ''; +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" diff --git a/mysql-test/suite/compat/oracle/r/events.result b/mysql-test/suite/compat/oracle/r/events.result new file mode 100644 index 00000000..1f62e2e5 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/events.result @@ -0,0 +1,27 @@ +set sql_mode='ORACLE'; +# +# MDEV-16891 EVENTs created with SQL_MODE=ORACLE fail to execute +# +SET GLOBAL event_scheduler=off; +SET sql_mode='ORACLE'; +CREATE TABLE t1 (a TIMESTAMP); +CREATE EVENT e1 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MICROSECOND +DO INSERT INTO t1 VALUES(NOW()); +Warnings: +Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. +SET GLOBAL event_scheduler=on; +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +DROP TABLE t1; +SET GLOBAL event_scheduler=off; +# +# MDEV-28588 SIGSEGV in __memmove_avx_unaligned_erms, strmake_root +# +CREATE EVENT ev ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO BEGIN END; +Warnings: +Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. +SELECT EVENT_DEFINITION FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA='test' AND EVENT_NAME='ev'; +EVENT_DEFINITION BEGIN END +DROP EVENT ev; diff --git a/mysql-test/suite/compat/oracle/r/exception.result b/mysql-test/suite/compat/oracle/r/exception.result new file mode 100644 index 00000000..3bd23980 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/exception.result @@ -0,0 +1,409 @@ +SET sql_mode=ORACLE; +# +# sql_mode=ORACLE: Predefined exceptions: TOO_MANY_ROWS, NO_DATA_FOUND, DUP_VAL_ON_INDEX +# +# +# Testing NO_DATA_FOUND and TOO_MANY_ROWS +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +SELECT a INTO a FROM t1 LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN res:='--- too_many_rows cought ---'; +WHEN NO_DATA_FOUND THEN res:='--- no_data_found cought ---'; +END; +$$ +SET @res=''; +CALL p1(0, @res); +SELECT @res; +@res +--- no_data_found cought --- +CALL p1(2, @res); +SELECT @res; +@res +--- too_many_rows cought --- +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing DUP_VAL_ON_INDEX +# +CREATE TABLE t1 (a INT PRIMARY KEY); +CREATE PROCEDURE p1(res OUT VARCHAR) +AS +BEGIN +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (10); +EXCEPTION +WHEN DUP_VAL_ON_INDEX THEN res:='--- dup_val_on_index cought ---'; +END; +$$ +SET @res=''; +CALL p1(@res); +SELECT @res; +@res +--- dup_val_on_index cought --- +SELECT * FROM t1; +a +10 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-10840 sql_mode=ORACLE: RAISE statement for predefined exceptions +# +# +# RAISE outside of an SP context +# +RAISE NO_DATA_FOUND; +ERROR 42000: Undefined CONDITION: NO_DATA_FOUND +RAISE INVALID_CURSOR; +ERROR 42000: Undefined CONDITION: INVALID_CURSOR +RAISE DUP_VAL_ON_INDEX; +ERROR 42000: Undefined CONDITION: DUP_VAL_ON_INDEX +RAISE TOO_MANY_ROWS; +ERROR 42000: Undefined CONDITION: TOO_MANY_ROWS +RAISE; +ERROR 0K000: RESIGNAL when handler not active +# +# RAISE for an undefinite exception +# +CREATE PROCEDURE p1 +AS +BEGIN +RAISE xxx; +END; +$$ +ERROR 42000: Undefined CONDITION: xxx +# +# RAISE for predefined exceptions +# +CREATE PROCEDURE p1 +AS +BEGIN +RAISE no_data_found; +END; +$$ +CALL p1(); +Warnings: +Warning 1329 No data - zero rows fetched, selected, or processed +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +BEGIN +RAISE invalid_cursor; +END; +$$ +CALL p1(); +ERROR 24000: Cursor is not open +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +BEGIN +RAISE dup_val_on_index; +END; +$$ +CALL p1(); +ERROR 23000: Duplicate entry '%-.192T' for key %d +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +BEGIN +raise too_many_rows; +END; +$$ +CALL p1(); +ERROR 42000: Result consisted of more than one row +DROP PROCEDURE p1; +# +# RAISE with no exception name (resignal) +# +CREATE PROCEDURE p1() +AS +BEGIN +RAISE; +END; +$$ +CALL p1(); +ERROR 0K000: RESIGNAL when handler not active +DROP PROCEDURE p1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1(lim INT) +AS +a INT; +BEGIN +SELECT a INTO a FROM t1 LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN RAISE; +WHEN NO_DATA_FOUND THEN RAISE; +END; +$$ +CALL p1(0); +Warnings: +Warning 1329 No data - zero rows fetched, selected, or processed +CALL p1(2); +ERROR 42000: Result consisted of more than one row +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1(lim INT) +AS +a INT; +BEGIN +SELECT a INTO a FROM t1 LIMIT lim; +EXCEPTION +WHEN OTHERS THEN RAISE; +END; +$$ +CALL p1(0); +Warnings: +Warning 1329 No data - zero rows fetched, selected, or processed +CALL p1(2); +ERROR 42000: Result consisted of more than one row +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1() +AS +a INT; +CURSOR c IS SELECT a FROM t1; +BEGIN +FETCH c INTO a; +EXCEPTION +WHEN INVALID_CURSOR THEN RAISE; +END; +$$ +CALL p1(); +ERROR 24000: Cursor is not open +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1() +AS +a INT; +CURSOR c IS SELECT a FROM t1; +BEGIN +FETCH c INTO a; +EXCEPTION +WHEN OTHERS THEN RAISE; +END; +$$ +CALL p1(); +ERROR 24000: Cursor is not open +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing that warning-alike errors are caught by OTHERS +# +CREATE TABLE t1 (a INT); +CREATE FUNCTION f1 RETURN VARCHAR +AS +a INT:=10; +BEGIN +SELECT a INTO a FROM t1; +RETURN 'OK'; +EXCEPTION +WHEN OTHERS THEN RETURN 'Exception'; +END; +$$ +SELECT f1() FROM DUAL; +f1() +Exception +DROP FUNCTION f1; +DROP TABLE t1; +# +# End of MDEV-10840 sql_mode=ORACLE: RAISE statement for predefined exceptions +# +# +# MDEV-10587 sql_mode=ORACLE: User defined exceptions +# +# +# Checking that duplicate WHEN clause is not allowed +# +CREATE FUNCTION f1() RETURN VARCHAR +AS +e EXCEPTION; +BEGIN +RETURN 'Got no exceptions'; +EXCEPTION +WHEN e THEN RETURN 'Got exception e'; +WHEN e THEN RETURN 'Got exception e'; +END; +$$ +ERROR 42000: Duplicate handler declared in the same block +# +# Checking that raised user exceptions are further caught by name +# +CREATE FUNCTION f1(c VARCHAR) RETURN VARCHAR +AS +e EXCEPTION; +f EXCEPTION; +BEGIN +IF c = 'e' THEN RAISE e; END IF; +IF c = 'f' THEN RAISE f; END IF; +RETURN 'Got no exceptions'; +EXCEPTION +WHEN e THEN RETURN 'Got exception e'; +END; +$$ +SELECT f1(''); +f1('') +Got no exceptions +SELECT f1('e'); +f1('e') +Got exception e +SELECT f1('f'); +ERROR 45000: Unhandled user-defined exception condition +DROP FUNCTION f1; +# +# Checking that raised user exceptions are further caught by OTHERS +# +CREATE FUNCTION f1(c VARCHAR) RETURN VARCHAR +AS +e EXCEPTION; +f EXCEPTION; +BEGIN +IF c = 'e' THEN RAISE e; END IF; +IF c = 'f' THEN RAISE f; END IF; +RETURN 'Got no exceptions'; +EXCEPTION +WHEN OTHERS THEN RETURN 'Got some exception'; +END; +$$ +SELECT f1(''); +f1('') +Got no exceptions +SELECT f1('e'); +f1('e') +Got some exception +SELECT f1('f'); +f1('f') +Got some exception +DROP FUNCTION f1; +# +# Checking that 'WHEN e .. WHEN f' does not produce ER_SP_DUP_HANDLER +# +CREATE FUNCTION f1(c VARCHAR) RETURN VARCHAR +AS +e EXCEPTION; +f EXCEPTION; +a VARCHAR(64):=''; +BEGIN +BEGIN +IF c = 'e' THEN RAISE e; END IF; +IF c = 'f' THEN RAISE f; END IF; +EXCEPTION +WHEN e THEN BEGIN a:='Got EXCEPTION1/e; '; RAISE e; END; +WHEN f THEN BEGIN a:='Got EXCEPTION1/f; '; RAISE f; END; +END; +RETURN 'Got no exceptions'; +EXCEPTION +WHEN OTHERS THEN RETURN a || 'Got EXCEPTION2/OTHERS;'; +END; +$$ +SELECT f1(''); +f1('') +Got no exceptions +SELECT f1('e'); +f1('e') +Got EXCEPTION1/e; Got EXCEPTION2/OTHERS; +SELECT f1('f'); +f1('f') +Got EXCEPTION1/f; Got EXCEPTION2/OTHERS; +DROP FUNCTION f1; +# +# Checking that resignaled user exceptions are further caught by name +# +CREATE FUNCTION f1(c VARCHAR) RETURN VARCHAR +AS +e EXCEPTION; +f EXCEPTION; +a VARCHAR(64):=''; +BEGIN +BEGIN +IF c = 'e' THEN RAISE e; END IF; +IF c = 'f' THEN RAISE f; END IF; +EXCEPTION +WHEN e THEN BEGIN a:='Got EXCEPTION1/e; '; RAISE; END; +WHEN f THEN BEGIN a:='Got EXCEPTION1/f; '; RAISE; END; +END; +RETURN 'Got no exceptions'; +EXCEPTION +WHEN e THEN RETURN a || 'Got EXCEPTION2/e;'; +END; +$$ +SELECT f1(''); +f1('') +Got no exceptions +SELECT f1('e'); +f1('e') +Got EXCEPTION1/e; Got EXCEPTION2/e; +SELECT f1('f'); +ERROR 45000: Unhandled user-defined exception condition +DROP FUNCTION f1; +# +# Checking that resignaled user exceptions are further caught by OTHERS +# +CREATE FUNCTION f1(c VARCHAR) RETURN VARCHAR +AS +e EXCEPTION; +f EXCEPTION; +a VARCHAR(64):=''; +BEGIN +BEGIN +IF c = 'e' THEN RAISE e; END IF; +IF c = 'f' THEN RAISE f; END IF; +EXCEPTION +WHEN e THEN BEGIN a:='Got EXCEPTION1/e; '; RAISE; END; +WHEN f THEN BEGIN a:='Got EXCEPTION1/f; '; RAISE; END; +END; +RETURN 'Got no exceptions'; +EXCEPTION +WHEN OTHERS THEN RETURN a || 'Got EXCEPTION2/OTHERS;'; +END; +$$ +SELECT f1(''); +f1('') +Got no exceptions +SELECT f1('e'); +f1('e') +Got EXCEPTION1/e; Got EXCEPTION2/OTHERS; +SELECT f1('f'); +f1('f') +Got EXCEPTION1/f; Got EXCEPTION2/OTHERS; +DROP FUNCTION f1; +# +# End of MDEV-10587 sql_mode=ORACLE: User defined exceptions +# +# +# MDEV-12088 sql_mode=ORACLE: Do not require BEGIN..END in multi-statement exception handlers in THEN clause +# +CREATE TABLE t1 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (10),(20),(30); +CREATE PROCEDURE p1(a INT) AS +BEGIN +INSERT INTO t1 (a) VALUES (a); +EXCEPTION +WHEN DUP_VAL_ON_INDEX THEN +a:= a+1; +INSERT INTO t1 VALUES (a); +WHEN OTHERS THEN +NULL; +NULL; +END; +$$ +CALL p1(30); +SELECT * FROM t1; +a +10 +20 +30 +31 +DROP PROCEDURE p1; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/func_add_months.result b/mysql-test/suite/compat/oracle/r/func_add_months.result new file mode 100644 index 00000000..0502c20f --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_add_months.result @@ -0,0 +1,91 @@ +Test for ADD_MONTHS +CREATE TABLE t1(c1 int, c2 datetime, c3 date, c4 time, c5 timestamp); +INSERT INTO t1 VALUES (1, '2011-11-12 12:10:11', '2011-11-12', '12:10:11', '2011-11-12 12:10:11'); +INSERT INTO t1 VALUES (2, '2021-11-12 00:23:12', '2021-11-12', '00:23:12', '2021-11-12 00:23:12'); +INSERT INTO t1 VALUES (3, '2011-01-22 16:45:45', '2011-01-22', '16:45:45', '2011-01-22 16:45:45'); +INSERT INTO t1 VALUES (4, '2031-05-12 04:11:34', '2031-05-12', '04:11:34', '2031-05-12 04:11:34'); +INSERT INTO t1 VALUES (5, '2031-09-02 08:15:22', '2031-09-02', '08:15:22', '2031-09-02 08:15:22'); +INSERT INTO t1 VALUES (6, '0000-09-02 00:00:00', '0000-09-02', '00:00:00', '1980-09-02 00:00:00'); +INSERT INTO t1 VALUES (7, '9999-09-02', '9999-09-02', '00:00:00', '1980-09-02'); +SELECT c1, ADD_MONTHS(c2, 2), ADD_MONTHS(c3, 2), ADD_MONTHS(c5, 2) FROM t1; +c1 ADD_MONTHS(c2, 2) ADD_MONTHS(c3, 2) ADD_MONTHS(c5, 2) +1 2012-01-12 12:10:11 2012-01-12 2012-01-12 12:10:11 +2 2022-01-12 00:23:12 2022-01-12 2022-01-12 00:23:12 +3 2011-03-22 16:45:45 2011-03-22 2011-03-22 16:45:45 +4 2031-07-12 04:11:34 2031-07-12 2031-07-12 04:11:34 +5 2031-11-02 08:15:22 2031-11-02 2031-11-02 08:15:22 +6 0000-11-02 00:00:00 0000-11-02 1980-11-02 00:00:00 +7 9999-11-02 00:00:00 9999-11-02 1980-11-02 00:00:00 +SELECT c1, ADD_MONTHS(c2, 15), ADD_MONTHS(c3, 200), ADD_MONTHS(c5, 2000) FROM t1; +c1 ADD_MONTHS(c2, 15) ADD_MONTHS(c3, 200) ADD_MONTHS(c5, 2000) +1 2013-02-12 12:10:11 2028-07-12 2178-07-12 12:10:11 +2 2023-02-12 00:23:12 2038-07-12 2188-07-12 00:23:12 +3 2012-04-22 16:45:45 2027-09-22 2177-09-22 16:45:45 +4 2032-08-12 04:11:34 2048-01-12 2198-01-12 04:11:34 +5 2032-12-02 08:15:22 2048-05-02 2198-05-02 08:15:22 +6 0001-12-02 00:00:00 0017-05-02 2147-05-02 00:00:00 +7 NULL NULL 2147-05-02 00:00:00 +Warnings: +Warning 1441 Datetime function: datetime field overflow +Warning 1441 Datetime function: datetime field overflow +SELECT c1, ADD_MONTHS(c2, 0), ADD_MONTHS(c3, -200), ADD_MONTHS(c5, -2) FROM t1; +c1 ADD_MONTHS(c2, 0) ADD_MONTHS(c3, -200) ADD_MONTHS(c5, -2) +1 2011-11-12 12:10:11 1995-03-12 2011-09-12 12:10:11 +2 2021-11-12 00:23:12 2005-03-12 2021-09-12 00:23:12 +3 2011-01-22 16:45:45 1994-05-22 2010-11-22 16:45:45 +4 2031-05-12 04:11:34 2014-09-12 2031-03-12 04:11:34 +5 2031-09-02 08:15:22 2015-01-02 2031-07-02 08:15:22 +6 0000-09-02 00:00:00 NULL 1980-07-02 00:00:00 +7 9999-09-02 00:00:00 9983-01-02 1980-07-02 00:00:00 +Warnings: +Warning 1441 Datetime function: datetime field overflow +SELECT c1, ADD_MONTHS(c2, -15), ADD_MONTHS(c3, -111), ADD_MONTHS(c5, 2) FROM t1; +c1 ADD_MONTHS(c2, -15) ADD_MONTHS(c3, -111) ADD_MONTHS(c5, 2) +1 2010-08-12 12:10:11 2002-08-12 2012-01-12 12:10:11 +2 2020-08-12 00:23:12 2012-08-12 2022-01-12 00:23:12 +3 2009-10-22 16:45:45 2001-10-22 2011-03-22 16:45:45 +4 2030-02-12 04:11:34 2022-02-12 2031-07-12 04:11:34 +5 2030-06-02 08:15:22 2022-06-02 2031-11-02 08:15:22 +6 NULL NULL 1980-11-02 00:00:00 +7 9998-06-02 00:00:00 9990-06-02 1980-11-02 00:00:00 +Warnings: +Warning 1441 Datetime function: datetime field overflow +Warning 1441 Datetime function: datetime field overflow +SELECT ADD_MONTHS(c4, 11) FROM t1 WHERE c1 = 1; +ADD_MONTHS(c4, 11) +NULL +Warnings: +Warning 1441 Datetime function: time field overflow +UPDATE t1 SET c2=ADD_MONTHS(c2, 2); +SELECT c2 FROM t1; +c2 +2012-01-12 12:10:11 +2022-01-12 00:23:12 +2011-03-22 16:45:45 +2031-07-12 04:11:34 +2031-11-02 08:15:22 +0000-11-02 00:00:00 +9999-11-02 00:00:00 +EXPLAIN EXTENDED SELECT c1, ADD_MONTHS(c2, -15) FROM t1 WHERE c1 = 1; +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 +Warnings: +Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t1`.`c2` + interval -15 month AS `ADD_MONTHS(c2, -15)` from `test`.`t1` where `test`.`t1`.`c1` = 1 +SELECT ADD_MONTHS("2000-10-10", 12); +ADD_MONTHS("2000-10-10", 12) +2001-10-10 +SELECT ADD_MONTHS("2000:10:10", 12); +ADD_MONTHS("2000:10:10", 12) +2001-10-10 +SELECT ADD_MONTHS(2000, 12); +ADD_MONTHS(2000, 12) +NULL +Warnings: +Warning 1292 Incorrect datetime value: '2000' +SELECT ADD_MONTHS('2011-01-31', 1), ADD_MONTHS('2012-01-31', 1), ADD_MONTHS('2012-01-31', 2), ADD_MONTHS('2012-01-31', 3); +ADD_MONTHS('2011-01-31', 1) ADD_MONTHS('2012-01-31', 1) ADD_MONTHS('2012-01-31', 2) ADD_MONTHS('2012-01-31', 3) +2011-02-28 2012-02-29 2012-03-31 2012-04-30 +SELECT ADD_MONTHS('2011-01-30', 1), ADD_MONTHS('2012-01-30', 1), ADD_MONTHS('2012-01-30', 2), ADD_MONTHS('2012-01-30', 3); +ADD_MONTHS('2011-01-30', 1) ADD_MONTHS('2012-01-30', 1) ADD_MONTHS('2012-01-30', 2) ADD_MONTHS('2012-01-30', 3) +2011-02-28 2012-02-29 2012-03-30 2012-04-30 +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/func_case.result b/mysql-test/suite/compat/oracle/r/func_case.result new file mode 100644 index 00000000..dfe2d165 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_case.result @@ -0,0 +1,7 @@ +SET sql_mode=ORACLE; +SELECT NVL(NULL, 'a'), NVL('a', 'b'); +NVL(NULL, 'a') NVL('a', 'b') +a a +SELECT NVL2(NULL, 'a', 'b'), NVL2('a', 'b', 'c'); +NVL2(NULL, 'a', 'b') NVL2('a', 'b', 'c') +b b diff --git a/mysql-test/suite/compat/oracle/r/func_concat.result b/mysql-test/suite/compat/oracle/r/func_concat.result new file mode 100644 index 00000000..392d5797 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_concat.result @@ -0,0 +1,393 @@ +SET sql_mode=ORACLE; +EXPLAIN EXTENDED SELECT 'a'||'b'||'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 +Warnings: +Note 1003 select concat_operator_oracle(concat_operator_oracle('a','b'),'c') AS "'a'||'b'||'c'" +EXPLAIN EXTENDED SELECT CONCAT('a'||'b'||'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 +Warnings: +Note 1003 select concat_operator_oracle(concat_operator_oracle(concat_operator_oracle('a','b'),'c')) AS "CONCAT('a'||'b'||'c')" +SELECT '' || ''; +'' || '' + +SELECT '' || 'b'; +'' || 'b' +b +SELECT '' || NULL; +'' || NULL + +SELECT 'a' || ''; +'a' || '' +a +SELECT 'a' || 'b'; +'a' || 'b' +ab +SELECT 'a' || NULL; +'a' || NULL +a +SELECT NULL || ''; +NULL || '' + +SELECT NULL || 'b'; +NULL || 'b' +b +SELECT NULL || NULL; +NULL || NULL +NULL +SELECT '' || '' || ''; +'' || '' || '' + +SELECT '' || '' || 'c'; +'' || '' || 'c' +c +SELECT '' || '' || NULL; +'' || '' || NULL + +SELECT '' || 'b' || ''; +'' || 'b' || '' +b +SELECT '' || 'b' || 'c'; +'' || 'b' || 'c' +bc +SELECT '' || 'b' || NULL; +'' || 'b' || NULL +b +SELECT '' || NULL || ''; +'' || NULL || '' + +SELECT '' || NULL || 'c'; +'' || NULL || 'c' +c +SELECT '' || NULL || NULL; +'' || NULL || NULL + +SELECT 'a' || '' || ''; +'a' || '' || '' +a +SELECT 'a' || '' || 'c'; +'a' || '' || 'c' +ac +SELECT 'a' || '' || NULL; +'a' || '' || NULL +a +SELECT 'a' || 'b' || ''; +'a' || 'b' || '' +ab +SELECT 'a' || 'b' || 'c'; +'a' || 'b' || 'c' +abc +SELECT 'a' || 'b' || NULL; +'a' || 'b' || NULL +ab +SELECT 'a' || NULL || ''; +'a' || NULL || '' +a +SELECT 'a' || NULL || 'c'; +'a' || NULL || 'c' +ac +SELECT 'a' || NULL || NULL; +'a' || NULL || NULL +a +SELECT NULL || '' || ''; +NULL || '' || '' + +SELECT NULL || '' || 'c'; +NULL || '' || 'c' +c +SELECT NULL || '' || NULL; +NULL || '' || NULL + +SELECT NULL || 'b' || ''; +NULL || 'b' || '' +b +SELECT NULL || 'b' || 'c'; +NULL || 'b' || 'c' +bc +SELECT NULL || 'b' || NULL; +NULL || 'b' || NULL +b +SELECT NULL || NULL || ''; +NULL || NULL || '' + +SELECT NULL || NULL || 'c'; +NULL || NULL || 'c' +c +SELECT NULL || NULL || NULL; +NULL || NULL || NULL +NULL +CREATE TABLE t1 (a VARCHAR(10), b VARCHAR(10), c VARCHAR(10)); +INSERT INTO t1 VALUES ('', '', ''); +INSERT INTO t1 VALUES ('', '', 'c'); +INSERT INTO t1 VALUES ('', '', NULL); +INSERT INTO t1 VALUES ('', 'b', ''); +INSERT INTO t1 VALUES ('', 'b', 'c'); +INSERT INTO t1 VALUES ('', 'b', NULL); +INSERT INTO t1 VALUES ('', NULL, ''); +INSERT INTO t1 VALUES ('', NULL, 'c'); +INSERT INTO t1 VALUES ('', NULL, NULL); +INSERT INTO t1 VALUES ('a', '', ''); +INSERT INTO t1 VALUES ('a', '', 'c'); +INSERT INTO t1 VALUES ('a', '', NULL); +INSERT INTO t1 VALUES ('a', 'b', ''); +INSERT INTO t1 VALUES ('a', 'b', 'c'); +INSERT INTO t1 VALUES ('a', 'b', NULL); +INSERT INTO t1 VALUES ('a', NULL, ''); +INSERT INTO t1 VALUES ('a', NULL, 'c'); +INSERT INTO t1 VALUES ('a', NULL, NULL); +INSERT INTO t1 VALUES (NULL, '', ''); +INSERT INTO t1 VALUES (NULL, '', 'c'); +INSERT INTO t1 VALUES (NULL, '', NULL); +INSERT INTO t1 VALUES (NULL, 'b', ''); +INSERT INTO t1 VALUES (NULL, 'b', 'c'); +INSERT INTO t1 VALUES (NULL, 'b', NULL); +INSERT INTO t1 VALUES (NULL, NULL, ''); +INSERT INTO t1 VALUES (NULL, NULL, 'c'); +INSERT INTO t1 VALUES (NULL, NULL, NULL); +SELECT LENGTH(a||b||c), a||b||c FROM t1 ORDER BY a,b,c; +LENGTH(a||b||c) a||b||c +NULL NULL +0 +1 c +0 +0 +1 c +1 b +1 b +2 bc +0 +0 +1 c +0 +0 +1 c +1 b +1 b +2 bc +1 a +1 a +2 ac +1 a +1 a +2 ac +2 ab +2 ab +3 abc +SELECT LENGTH(CONCAT(a||b||c)), CONCAT(a||b||c) FROM t1 ORDER BY a,b,c; +LENGTH(CONCAT(a||b||c)) CONCAT(a||b||c) +NULL NULL +0 +1 c +0 +0 +1 c +1 b +1 b +2 bc +0 +0 +1 c +0 +0 +1 c +1 b +1 b +2 bc +1 a +1 a +2 ac +1 a +1 a +2 ac +2 ab +2 ab +3 abc +DROP TABLE t1; +# +# MDEV-12478 CONCAT function inside view casts values incorrectly with Oracle sql_mode +# +SET sql_mode=ORACLE; +CREATE VIEW v1 AS SELECT 'foo'||NULL||'bar' AS test; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select concat_operator_oracle(concat_operator_oracle('foo',NULL),'bar') AS "test" latin1 latin1_swedish_ci +SELECT * FROM v1; +test +foobar +SET sql_mode=DEFAULT; +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 concat_operator_oracle(concat_operator_oracle('foo',NULL),'bar') AS `test` latin1 latin1_swedish_ci +SELECT * FROM v1; +test +foobar +DROP VIEW v1; +SET sql_mode=DEFAULT; +CREATE VIEW v1 AS SELECT CONCAT('foo',NULL,'bar') AS test; +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 concat('foo',NULL,'bar') AS `test` latin1 latin1_swedish_ci +SELECT * FROM v1; +test +NULL +SET sql_mode=ORACLE; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select concat('foo',NULL,'bar') AS "test" latin1 latin1_swedish_ci +SELECT * FROM v1; +test +NULL +DROP VIEW v1; +SET sql_mode=DEFAULT; +CREATE VIEW v1 AS SELECT '0'||'1' AS test; +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 '0' or '1' AS `test` latin1 latin1_swedish_ci +SELECT * FROM v1; +test +1 +SET sql_mode=ORACLE; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select '0' or '1' AS "test" latin1 latin1_swedish_ci +SELECT * FROM v1; +test +1 +DROP VIEW v1; +# +# MDEV-16186 Concatenation operator || returns wrong results in sql_mode=ORACLE +# +SELECT -1<<1||1 AS a FROM DUAL; +a +18446744073709549568 +SELECT -1||0<<1 AS a FROM DUAL; +a +18446744073709551596 +EXPLAIN EXTENDED SELECT -1<<1||1 AS a FROM DUAL; +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 -1 << concat_operator_oracle(1,1) AS "a" +EXPLAIN EXTENDED SELECT -1||0<<1 AS a FROM DUAL; +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_operator_oracle(-1,0) << 1 AS "a" +SELECT -1+1||1 AS a FROM DUAL; +a +01 +SELECT -1||0+1 AS a FROM DUAL; +a +-9 +EXPLAIN EXTENDED SELECT -1+1||1 AS a FROM DUAL; +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_operator_oracle(-1 + 1,1) AS "a" +EXPLAIN EXTENDED SELECT -1||0+1 AS a FROM DUAL; +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_operator_oracle(-1,0) + 1 AS "a" +SELECT 1*1||-1 AS a FROM DUAL; +a +1-1 +SELECT 1||1*-1 AS a FROM DUAL; +a +1-1 +EXPLAIN EXTENDED SELECT 1*1||-1 AS a FROM DUAL; +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_operator_oracle(1 * 1,-1) AS "a" +EXPLAIN EXTENDED SELECT 1||1*-1 AS a FROM DUAL; +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_operator_oracle(1,1 * -1) AS "a" +SELECT -1^1||1 AS a FROM DUAL; +a +184467440737095516141 +SELECT -1||0^1 AS a FROM DUAL; +a +-11 +EXPLAIN EXTENDED SELECT -1^1||1 AS a FROM DUAL; +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_operator_oracle(-1 ^ 1,1) AS "a" +EXPLAIN EXTENDED SELECT -1||0^1 AS a FROM DUAL; +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_operator_oracle(-1,0 ^ 1) AS "a" +# +# MDEV-17359 Concatenation operator || in like expression failed in sql_mode=ORACLE +# +SELECT 'abc' LIKE 'a'||'%'; +'abc' LIKE 'a'||'%' +1 +EXPLAIN EXTENDED SELECT 'abc' LIKE '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 'abc' like concat_operator_oracle('a','%') AS "'abc' LIKE 'a'||'%'" +SELECT 'x' FROM DUAL WHERE 11 LIKE 1||1; +x +x +SELECT 'x' FROM DUAL WHERE 1||1 LIKE 11; +x +x +SELECT 'x' FROM DUAL WHERE 1||1 LIKE 1||1; +x +x +CREATE TABLE t1 (c1 VARCHAR(10),c2 VARCHAR(10), ord INTEGER); +INSERT INTO t1 VALUES ('a', 'ab' ,1); +INSERT INTO t1 VALUES ('ab', 'ab', 2); +INSERT INTO t1 VALUES ('abc', 'ab', 3); +SELECT c1 FROM t1 WHERE c1 LIKE '%'||'b' ORDER BY ord; +c1 +ab +EXPLAIN EXTENDED SELECT c1 FROM t1 WHERE c1 LIKE '%'||'b' ORDER BY ord; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort +Warnings: +Note 1003 select "test"."t1"."c1" AS "c1" from "test"."t1" where "test"."t1"."c1" like <cache>(concat_operator_oracle('%','b')) order by "test"."t1"."ord" +SELECT c1 FROM t1 WHERE c1 LIKE c2||'%'||'c' ORDER BY ord; +c1 +abc +EXPLAIN EXTENDED SELECT c1 FROM t1 WHERE c1 LIKE c2||'%'||'c' ORDER BY ord; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort +Warnings: +Note 1003 select "test"."t1"."c1" AS "c1" from "test"."t1" where "test"."t1"."c1" like concat_operator_oracle(concat_operator_oracle("test"."t1"."c2",'%'),'c') order by "test"."t1"."ord" +SELECT 'x' FROM t1 WHERE c1||c2 LIKE 'aa%'; +x +x +EXPLAIN EXTENDED SELECT 'x' FROM t1 WHERE c1||c2 LIKE 'aa%'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select 'x' AS "x" from "test"."t1" where concat_operator_oracle("test"."t1"."c1","test"."t1"."c2") like 'aa%' +SELECT 'x' FROM t1 WHERE c1||c2 LIKE c2||c1; +x +x +EXPLAIN EXTENDED SELECT 'x' FROM t1 WHERE c1||c2 LIKE c2||c1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select 'x' AS "x" from "test"."t1" where concat_operator_oracle("test"."t1"."c1","test"."t1"."c2") like concat_operator_oracle("test"."t1"."c2","test"."t1"."c1") +CREATE VIEW v1 AS SELECT c1, c2, c1 LIKE c2||'_' FROM t1 ORDER BY ord; +SELECT * FROM v1; +c1 c2 c1 LIKE c2||'_' +a ab 0 +ab ab 0 +abc ab 1 +EXPLAIN EXTENDED SELECT * FROM v1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using filesort +Warnings: +Note 1003 select "test"."t1"."c1" AS "c1","test"."t1"."c2" AS "c2","test"."t1"."c1" like concat_operator_oracle("test"."t1"."c2",'_') AS "c1 LIKE c2||'_'" from "test"."t1" order by "test"."t1"."ord" +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/func_decode.result b/mysql-test/suite/compat/oracle/r/func_decode.result new file mode 100644 index 00000000..2809e971 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_decode.result @@ -0,0 +1,177 @@ +SET sql_mode=ORACLE; +SELECT DECODE(10); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SELECT DECODE(10,10); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SELECT DECODE(10,10,'x10'); +DECODE(10,10,'x10') +x10 +SELECT DECODE(11,10,'x10'); +DECODE(11,10,'x10') +NULL +SELECT DECODE(10,10,'x10','def'); +DECODE(10,10,'x10','def') +x10 +SELECT DECODE(11,10,'x10','def'); +DECODE(11,10,'x10','def') +def +SELECT DECODE(10,10,'x10',11,'x11','def'); +DECODE(10,10,'x10',11,'x11','def') +x10 +SELECT DECODE(11,10,'x10',11,'x11','def'); +DECODE(11,10,'x10',11,'x11','def') +x11 +SELECT DECODE(12,10,'x10',11,'x11','def'); +DECODE(12,10,'x10',11,'x11','def') +def +EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11','def'); +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_oracle(12,10,'x10',11,'x11','def') AS "DECODE(12,10,'x10',11,'x11','def')" +CREATE TABLE decode (decode int); +DROP TABLE decode; +# +# MDEV-13863 sql_mode=ORACLE: DECODE does not treat two NULLs as equivalent +# +SELECT DECODE(10); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SELECT DECODE(10,10); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE' +SELECT DECODE_ORACLE(10); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE_ORACLE' +SELECT DECODE_ORACLE(10,10); +ERROR 42000: Incorrect parameter count in the call to native function 'DECODE_ORACLE' +EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11'); +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_oracle(12,10,'x10',11,'x11') AS "DECODE(12,10,'x10',11,'x11')" +EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11','def'); +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_oracle(12,10,'x10',11,'x11','def') AS "DECODE(12,10,'x10',11,'x11','def')" +EXPLAIN EXTENDED SELECT DECODE_ORACLE(12,10,'x10',11,'x11'); +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_oracle(12,10,'x10',11,'x11') AS "DECODE_ORACLE(12,10,'x10',11,'x11')" +EXPLAIN EXTENDED SELECT DECODE_ORACLE(12,10,'x10',11,'x11','def'); +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_oracle(12,10,'x10',11,'x11','def') AS "DECODE_ORACLE(12,10,'x10',11,'x11','def')" +CREATE TABLE t1 (a INT); +CREATE VIEW v1 AS +SELECT +DECODE(a,1,'x1',NULL,'xNULL') AS d1, +DECODE(a,1,'x1',NULL,'xNULL','xELSE') AS d2, +DECODE_ORACLE(a,1,'x1',NULL,'xNULL') AS d3, +DECODE_ORACLE(a,1,'x1',NULL,'xNULL','xELSE') AS d4 +FROM t1; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select decode_oracle("t1"."a",1,'x1',NULL,'xNULL') AS "d1",decode_oracle("t1"."a",1,'x1',NULL,'xNULL','xELSE') AS "d2",decode_oracle("t1"."a",1,'x1',NULL,'xNULL') AS "d3",decode_oracle("t1"."a",1,'x1',NULL,'xNULL','xELSE') AS "d4" from "t1" latin1 latin1_swedish_ci +DROP VIEW v1; +DROP TABLE t1; +SELECT DECODE(TIME'10:20:31','10:20:31','then1','10:20:32','then2','def'); +DECODE(TIME'10:20:31','10:20:31','then1','10:20:32','then2','def') +then1 +SELECT DECODE(TIME'10:20:32','10:20:31','then1','10:20:32','then2','def'); +DECODE(TIME'10:20:32','10:20:31','then1','10:20:32','then2','def') +then2 +SELECT DECODE(TIME'10:20:33','10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def'); +DECODE(TIME'10:20:33','10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def') +then3 +SELECT DECODE(NULL,TIME'10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def'); +DECODE(NULL,TIME'10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def') +then2NULL +SELECT DECODE(TIMESTAMP'2001-01-01 10:20:31','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def'); +DECODE(TIMESTAMP'2001-01-01 10:20:31','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def') +then1 +SELECT DECODE(TIMESTAMP'2001-01-01 10:20:32','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def'); +DECODE(TIMESTAMP'2001-01-01 10:20:32','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def') +then2 +SELECT DECODE(TIMESTAMP'2001-01-01 10:20:33','2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def'); +DECODE(TIMESTAMP'2001-01-01 10:20:33','2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def') +then3 +SELECT DECODE(NULL,TIMESTAMP'2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def'); +DECODE(NULL,TIMESTAMP'2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def') +then2NULL +SELECT DECODE('w1','w1','then1','w2','then2','def'); +DECODE('w1','w1','then1','w2','then2','def') +then1 +SELECT DECODE('w2','w1','then1','w2','then2','def'); +DECODE('w2','w1','then1','w2','then2','def') +then2 +SELECT DECODE('w3','w1','then1',NULL,'then2NULL','w3','then3','def'); +DECODE('w3','w1','then1',NULL,'then2NULL','w3','then3','def') +then3 +SELECT DECODE(NULL,'w1','then1',NULL,'then2NULL','w3','then3','def'); +DECODE(NULL,'w1','then1',NULL,'then2NULL','w3','then3','def') +then2NULL +SELECT DECODE(1,1,'then1',2,'then2','def'); +DECODE(1,1,'then1',2,'then2','def') +then1 +SELECT DECODE(2,1,'then1',2,'then2','def'); +DECODE(2,1,'then1',2,'then2','def') +then2 +SELECT DECODE(3,1,'then1',NULL,'then2NULL',3,'then3','def'); +DECODE(3,1,'then1',NULL,'then2NULL',3,'then3','def') +then3 +SELECT DECODE(NULL,1,'then1',NULL,'then2NULL',3,'then3','def'); +DECODE(NULL,1,'then1',NULL,'then2NULL',3,'then3','def') +then2NULL +SELECT DECODE(CAST(NULL AS SIGNED),1,'then1',NULL,'then2NULL',3,'then3','def'); +DECODE(CAST(NULL AS SIGNED),1,'then1',NULL,'then2NULL',3,'then3','def') +then2NULL +SELECT DECODE(1.0,1.0,'then1',2.0,'then2','def'); +DECODE(1.0,1.0,'then1',2.0,'then2','def') +then1 +SELECT DECODE(2.0,1.0,'then1',2.0,'then2','def'); +DECODE(2.0,1.0,'then1',2.0,'then2','def') +then2 +SELECT DECODE(3.0,1.0,'then1',NULL,'then2NULL',3.0,'then3','def'); +DECODE(3.0,1.0,'then1',NULL,'then2NULL',3.0,'then3','def') +then3 +SELECT DECODE(NULL,1.0,'then1',NULL,'then2NULL',3.0,'then3','def'); +DECODE(NULL,1.0,'then1',NULL,'then2NULL',3.0,'then3','def') +then2NULL +SELECT DECODE(CAST(NULL AS DECIMAL),1.0,'then1',NULL,'then2NULL',3.0,'then3','def'); +DECODE(CAST(NULL AS DECIMAL),1.0,'then1',NULL,'then2NULL',3.0,'then3','def') +then2NULL +SELECT DECODE(1e0,1e0,'then1',2e0,'then2','def'); +DECODE(1e0,1e0,'then1',2e0,'then2','def') +then1 +SELECT DECODE(2e0,1e0,'then1',2e0,'then2','def'); +DECODE(2e0,1e0,'then1',2e0,'then2','def') +then2 +SELECT DECODE(3e0,1e0,'then1',NULL,'then2NULL',3e0,'then3','def'); +DECODE(3e0,1e0,'then1',NULL,'then2NULL',3e0,'then3','def') +then3 +SELECT DECODE(NULL,1e0,'then1',NULL,'then2NULL',3e0,'then3','def'); +DECODE(NULL,1e0,'then1',NULL,'then2NULL',3e0,'then3','def') +then2NULL +SELECT DECODE(CAST(NULL AS DOUBLE),1e0,'then1',NULL,'then2NULL',3e0,'then3','def'); +DECODE(CAST(NULL AS DOUBLE),1e0,'then1',NULL,'then2NULL',3e0,'then3','def') +then2NULL +SELECT DECODE(NULL,NULL,1,2) FROM DUAL; +DECODE(NULL,NULL,1,2) +1 +SELECT DECODE(NULL,10,10,NULL,1,2) FROM DUAL; +DECODE(NULL,10,10,NULL,1,2) +1 +SELECT DECODE_ORACLE(NULL,NULL,1,2) FROM DUAL; +DECODE_ORACLE(NULL,NULL,1,2) +1 +SELECT DECODE_ORACLE(NULL,10,10,NULL,1,2) FROM DUAL; +DECODE_ORACLE(NULL,10,10,NULL,1,2) +1 +CREATE OR REPLACE TABLE t1 (a VARCHAR(10) DEFAULT NULL); +INSERT INTO t1 VALUES (NULL),(1); +SELECT a, DECODE(a,NULL,1,2) FROM t1; +a DECODE(a,NULL,1,2) +NULL 1 +1 2 +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/func_length.result b/mysql-test/suite/compat/oracle/r/func_length.result new file mode 100644 index 00000000..e260f5ad --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_length.result @@ -0,0 +1,21 @@ +SET sql_mode=ORACLE; +# +# MDEV-12783 sql_mode=ORACLE: Functions LENGTH() and LENGTHB() +# +SELECT LENGTH(null), LENGTH('a'), LENGTH(123); +LENGTH(null) LENGTH('a') LENGTH(123) +NULL 1 3 +SELECT LENGTHB(null), LENGTHB('a'), LENGTHB(123); +LENGTHB(null) LENGTHB('a') LENGTHB(123) +NULL 1 3 +SELECT LENGTH(_utf8 0xC39F), LENGTH(CHAR(14844588 USING utf8)); +LENGTH(_utf8 0xC39F) LENGTH(CHAR(14844588 USING utf8)) +1 1 +SELECT LENGTHB(_utf8 0xC39F), LENGTHB(CHAR(14844588 USING utf8)); +LENGTHB(_utf8 0xC39F) LENGTHB(CHAR(14844588 USING utf8)) +2 3 +EXPLAIN EXTENDED SELECT LENGTH('a'), LENGTHB('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 char_length('a') AS "LENGTH('a')",octet_length('a') AS "LENGTHB('a')" diff --git a/mysql-test/suite/compat/oracle/r/func_misc.result b/mysql-test/suite/compat/oracle/r/func_misc.result new file mode 100644 index 00000000..28f27873 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_misc.result @@ -0,0 +1,319 @@ +SET sql_mode=ORACLE; +# +# MDEV-10578 sql_mode=ORACLE: SP control functions SQLCODE, SQLERRM +# +# +# Using SQLCODE and SQLERRM outside of an SP +# +SELECT SQLCODE; +ERROR 42S22: Unknown column 'SQLCODE' in 'field list' +SELECT SQLERRM; +ERROR 42S22: Unknown column 'SQLERRM' in 'field list' +CREATE TABLE t1 (SQLCODE INT, SQLERRM VARCHAR(10)); +INSERT INTO t1 VALUES (10, 'test'); +SELECT SQLCODE, SQLERRM FROM t1; +SQLCODE SQLERRM +10 test +DROP TABLE t1; +# +# Normal SQLCODE and SQLERRM usage +# +CREATE PROCEDURE p1(stmt VARCHAR) +AS +BEGIN +EXECUTE IMMEDIATE stmt; +SELECT 'Error1: ' || SQLCODE || ' ' || SQLERRM; +EXCEPTION +WHEN OTHERS THEN +SELECT 'Error2: ' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CALL p1('SELECT 1'); +1 +1 +'Error1: ' || SQLCODE || ' ' || SQLERRM +Error1: 0 normal, successful completion +CALL p1('xxx'); +'Error2: ' || SQLCODE || ' ' || SQLERRM +Error2: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +CALL p1('SELECT 1'); +1 +1 +'Error1: ' || SQLCODE || ' ' || SQLERRM +Error1: 0 normal, successful completion +DROP PROCEDURE p1; +# +# SQLCODE and SQLERRM hidden by local variables +# +CREATE PROCEDURE p1() +AS +sqlcode INT:= 10; +sqlerrm VARCHAR(64) := 'test'; +BEGIN +SELECT 'Error: ' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CALL p1; +'Error: ' || SQLCODE || ' ' || SQLERRM +Error: 10 test +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +sqlcode INT; +sqlerrm VARCHAR(64); +BEGIN +SQLCODE:= 10; +sqlerrm:= 'test'; +SELECT 'Error: ' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CALL p1; +'Error: ' || SQLCODE || ' ' || SQLERRM +Error: 10 test +DROP PROCEDURE p1; +# +# SQLCODE and SQLERRM hidden by parameters +# +CREATE PROCEDURE p1(sqlcode INT, sqlerrm VARCHAR) +AS +BEGIN +SELECT 'Error: ' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CALL p1(10, 'test'); +'Error: ' || SQLCODE || ' ' || SQLERRM +Error: 10 test +DROP PROCEDURE p1; +# +# SQLCODE and SQLERRM in CREATE..SELECT +# +CREATE PROCEDURE p1 +AS +BEGIN +CREATE TABLE t1 AS SELECT SQLCODE, SQLERRM; +END; +$$ +CALL p1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "SQLCODE" int(11) NOT NULL, + "SQLERRM" varchar(512) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# SQLCODE and SQLERRM in EXPLAIN EXTENDED SELECT +# +CREATE PROCEDURE p1 +AS +BEGIN +EXPLAIN EXTENDED SELECT SQLCode, SQLErrm; +END; +$$ +CALL p1; +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 SQLCODE AS "SQLCode",SQLERRM AS "SQLErrm" +DROP PROCEDURE p1; +# +# Warning-alike errors in stored functions +# +CREATE TABLE t1 (a INT); +CREATE FUNCTION f1 RETURN VARCHAR +AS +a INT; +BEGIN +SELECT a INTO a FROM t1; +RETURN 'No exception ' || SQLCODE || ' ' || SQLERRM; +EXCEPTION +WHEN NO_DATA_FOUND THEN +RETURN 'Exception ' || SQLCODE || ' ' || SQLERRM; +END; +$$ +SELECT f1() FROM DUAL; +f1() +Exception 1329 No data - zero rows fetched, selected, or processed +DROP FUNCTION f1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE FUNCTION f1 RETURN VARCHAR +AS +a INT; +BEGIN +SELECT a INTO a FROM t1; +RETURN 'No exception ' || SQLCODE || ' ' || SQLERRM; +EXCEPTION +WHEN OTHERS THEN +RETURN 'Exception ' || SQLCODE || ' ' || SQLERRM; +END; +$$ +SELECT f1() FROM DUAL; +f1() +Exception 1329 No data - zero rows fetched, selected, or processed +DROP FUNCTION f1; +DROP TABLE t1; +# +# Warning-alike errors in stored procedures +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1(res OUT VARCHAR) +AS +a INT; +BEGIN +SELECT a INTO a FROM t1; +res:= 'No exception ' || SQLCODE || ' ' || SQLERRM; +EXCEPTION +WHEN NO_DATA_FOUND THEN +res:= 'Exception ' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CALL p1(@a); +SELECT @a; +@a +Exception 1329 No data - zero rows fetched, selected, or processed +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1(res OUT VARCHAR) +AS +a INT; +BEGIN +SELECT a INTO a FROM t1; +res:= 'No exception ' || SQLCODE || ' ' || SQLERRM; +EXCEPTION +WHEN OTHERS THEN +res:= 'Exception ' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CALL p1(@a); +SELECT @a; +@a +Exception 1329 No data - zero rows fetched, selected, or processed +DROP PROCEDURE p1; +DROP TABLE t1; +# +# SQLCODE and SQLERRM are cleared on RETURN +# +CREATE TABLE t1 (a INT); +CREATE FUNCTION f1 RETURN VARCHAR +AS +a INT:=10; +BEGIN +SELECT a INTO a FROM t1; +RETURN 'Value=' || a; +EXCEPTION +WHEN NO_DATA_FOUND THEN RETURN 'Exception|' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CREATE FUNCTION f2 RETURN VARCHAR +AS +a VARCHAR(128); +BEGIN +RETURN f1() || '|' || SQLCODE || ' ' || SQLERRM; +END; +$$ +SELECT f1() FROM DUAL; +f1() +Exception|1329 No data - zero rows fetched, selected, or processed +SELECT f2() FROM DUAL; +f2() +Exception|1329 No data - zero rows fetched, selected, or processed|0 normal, successful completion +DROP TABLE t1; +DROP FUNCTION f2; +DROP FUNCTION f1; +CREATE TABLE t1 (a INT); +CREATE FUNCTION f1 RETURN VARCHAR +AS +a INT:=10; +BEGIN +SELECT a INTO a FROM t1; +RETURN 'Value=' || a; +EXCEPTION +WHEN OTHERS THEN RETURN 'Exception|' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CREATE FUNCTION f2 RETURN VARCHAR +AS +a VARCHAR(128); +BEGIN +RETURN f1() || '|' || SQLCODE || ' ' || SQLERRM; +END; +$$ +SELECT f1() FROM DUAL; +f1() +Exception|1329 No data - zero rows fetched, selected, or processed +SELECT f2() FROM DUAL; +f2() +Exception|1329 No data - zero rows fetched, selected, or processed|0 normal, successful completion +DROP TABLE t1; +DROP FUNCTION f2; +DROP FUNCTION f1; +# +# SQLCODE and SQLERRM are cleared on a return from a PROCEDURE +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1(res OUT VARCHAR) +AS +a INT:=10; +BEGIN +SELECT a INTO a FROM t1; +res:='Value=' || a; +EXCEPTION +WHEN NO_DATA_FOUND THEN res:='Exception|' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CREATE FUNCTION f2 RETURN VARCHAR +AS +res VARCHAR(128); +BEGIN +CALL p1(res); +RETURN res || '|' || SQLCODE || ' ' || SQLERRM; +END; +$$ +SELECT f2() FROM DUAL; +f2() +Exception|1329 No data - zero rows fetched, selected, or processed|0 normal, successful completion +DROP FUNCTION f2; +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1(res OUT VARCHAR) +AS +a INT:=10; +BEGIN +SELECT a INTO a FROM t1; +res:='Value=' || a; +EXCEPTION +WHEN OTHERS THEN res:='Exception|' || SQLCODE || ' ' || SQLERRM; +END; +$$ +CREATE FUNCTION f2 RETURN VARCHAR +AS +res VARCHAR(128); +BEGIN +CALL p1(res); +RETURN res || '|' || SQLCODE || ' ' || SQLERRM; +END; +$$ +SELECT f2() FROM DUAL; +f2() +Exception|1329 No data - zero rows fetched, selected, or processed|0 normal, successful completion +DROP FUNCTION f2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# End of MDEV-10578 sql_mode=ORACLE: SP control functions SQLCODE, SQLERRM +# +# +# MDEV-12854 Synchronize CREATE..SELECT data type and result set metadata data type for INT functions +# +BEGIN +SELECT SQLCODE; +END +$$ +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def SQLCODE 3 11 1 N 32897 0 63 +SQLCODE +0 diff --git a/mysql-test/suite/compat/oracle/r/func_pad.result b/mysql-test/suite/compat/oracle/r/func_pad.result new file mode 100644 index 00000000..ca7d52cd --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_pad.result @@ -0,0 +1,71 @@ +SET sql_mode=ORACLE; +# +# MDEV-15739 - sql_mode=ORACLE: Make LPAD and RPAD return NULL instead of empty string +# +SELECT RPAD('a',0), RPAD('abc',1), RPAD('abc',2) ; +RPAD('a',0) RPAD('abc',1) RPAD('abc',2) +NULL a ab +SELECT RPAD('a',0,'.'), RPAD('abc',1,'.'), RPAD('abc',2,'.') ; +RPAD('a',0,'.') RPAD('abc',1,'.') RPAD('abc',2,'.') +NULL a ab +SELECT LPAD('a',0), LPAD('abc',1), LPAD('abc',2) ; +LPAD('a',0) LPAD('abc',1) LPAD('abc',2) +NULL a ab +SELECT LPAD('a',0,'.'), LPAD('abc',1,'.'), LPAD('abc',2,'.') ; +LPAD('a',0,'.') LPAD('abc',1,'.') LPAD('abc',2,'.') +NULL a ab +CREATE TABLE t1 (c1 VARCHAR(10),c2 INTEGER, c3 VARCHAR(10), ord INTEGER); +INSERT INTO t1 VALUES ('a',1,null,1); +INSERT INTO t1 VALUES ('a',null,'.',2); +INSERT INTO t1 VALUES (null,1,'.',3); +INSERT INTO t1 VALUES ('a',-1,'.',4); +INSERT INTO t1 VALUES ('a',0,'.',5); +INSERT INTO t1 VALUES ('a',1,'.',6); +INSERT INTO t1 VALUES ('a',2,'.',7); +SELECT LPAD(c1,c2,c3), LPAD(c1,c2) FROM t1 ORDER BY ord; +LPAD(c1,c2,c3) LPAD(c1,c2) +NULL a +NULL NULL +NULL NULL +NULL NULL +NULL NULL +a a +.a a +SELECT RPAD(c1,c2,c3), RPAD(c1,c2) FROM t1 ORDER BY ord; +RPAD(c1,c2,c3) RPAD(c1,c2) +NULL a +NULL NULL +NULL NULL +NULL NULL +NULL NULL +a a +a. a +EXPLAIN EXTENDED SELECT RPAD('a',0,'.'), LPAD('a',0,'.'), LPAD(c1,c2,c3), LPAD(c1,c2), RPAD(c1,c2,c3), RPAD(c1,c2) FROM t1 ORDER BY ord; +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 filesort +Warnings: +Note 1003 select rpad_oracle('a',0,'.') AS "RPAD('a',0,'.')",lpad_oracle('a',0,'.') AS "LPAD('a',0,'.')",lpad_oracle("test"."t1"."c1","test"."t1"."c2","test"."t1"."c3") AS "LPAD(c1,c2,c3)",lpad_oracle("test"."t1"."c1","test"."t1"."c2") AS "LPAD(c1,c2)",rpad_oracle("test"."t1"."c1","test"."t1"."c2","test"."t1"."c3") AS "RPAD(c1,c2,c3)",rpad_oracle("test"."t1"."c1","test"."t1"."c2") AS "RPAD(c1,c2)" from "test"."t1" order by "test"."t1"."ord" +CREATE VIEW v1 AS SELECT RPAD('a',0,'.') AS "C1", LPAD('a',0,'.') AS "C2", LPAD(c1,c2,c3) AS "C3", LPAD(c1,c2) AS "C4", RPAD(c1,c2,c3) AS "C5", RPAD(c1,c2) AS "C6" FROM t1 ORDER BY ord; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select rpad_oracle('a',0,'.') AS "C1",lpad_oracle('a',0,'.') AS "C2",lpad_oracle("t1"."c1","t1"."c2","t1"."c3") AS "C3",lpad_oracle("t1"."c1","t1"."c2") AS "C4",rpad_oracle("t1"."c1","t1"."c2","t1"."c3") AS "C5",rpad_oracle("t1"."c1","t1"."c2") AS "C6" from "t1" order by "t1"."ord" latin1 latin1_swedish_ci +SELECT * FROM v1; +C1 C2 C3 C4 C5 C6 +NULL NULL NULL a NULL a +NULL NULL NULL NULL NULL NULL +NULL NULL NULL NULL NULL NULL +NULL NULL NULL NULL NULL NULL +NULL NULL NULL NULL NULL NULL +NULL NULL a a a a +NULL NULL .a a a. a +SELECT c1||'-'||c2||'-'||c3||'-'||c4||'-'||c5||'-'||c6 FROM v1; +c1||'-'||c2||'-'||c3||'-'||c4||'-'||c5||'-'||c6 +---a--a +----- +----- +----- +----- +--a-a-a-a +--.a- a-a.-a +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/func_replace.result b/mysql-test/suite/compat/oracle/r/func_replace.result new file mode 100644 index 00000000..02516096 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_replace.result @@ -0,0 +1,32 @@ +SET sql_mode=ORACLE; +# +# MDEV-13003 - Oracle compatibility : Replace function +# +SELECT REPLACE(null,'a','b') ; +REPLACE(null,'a','b') +NULL +SELECT REPLACE('ab',null,'b') ; +REPLACE('ab',null,'b') +ab +SELECT REPLACE('ab','a',null) ; +REPLACE('ab','a',null) +b +SELECT REPLACE('ab',null,null) ; +REPLACE('ab',null,null) +ab +SELECT REPLACE('aaa','a',null) ; +REPLACE('aaa','a',null) +NULL +EXPLAIN EXTENDED SELECT REPLACE('ab','a',null) ; +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_oracle('ab','a',NULL) AS "REPLACE('ab','a',null)" +CREATE VIEW v1 AS SELECT REPLACE('ab','a',null) ; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select replace_oracle('ab','a',NULL) AS "REPLACE('ab','a',null)" latin1 latin1_swedish_ci +SELECT * FROM v1; +REPLACE('ab','a',null) +b +DROP VIEW v1; diff --git a/mysql-test/suite/compat/oracle/r/func_substr.result b/mysql-test/suite/compat/oracle/r/func_substr.result new file mode 100644 index 00000000..5d9fdd5f --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_substr.result @@ -0,0 +1,87 @@ +# +# MDEV-14012 - sql_mode=Oracle: substr(): treat position 0 as position 1 +# MDEV-10574 - sql_mode=Oracle: return null instead of empty string +# +SET sql_mode=ORACLE; +SELECT SUBSTR('abc',2,1),SUBSTR('abc',1,1), SUBSTR('abc',0,1) FROM dual; +SUBSTR('abc',2,1) SUBSTR('abc',1,1) SUBSTR('abc',0,1) +b a a +SELECT SUBSTR('abc',2),SUBSTR('abc',1), SUBSTR('abc',0) FROM dual; +SUBSTR('abc',2) SUBSTR('abc',1) SUBSTR('abc',0) +bc abc abc +SELECT SUBSTR(null,2,1),SUBSTR(null,1), SUBSTR(null,0) FROM dual; +SUBSTR(null,2,1) SUBSTR(null,1) SUBSTR(null,0) +NULL NULL NULL +SELECT SUBSTR('abc',-2),SUBSTR('abc',-1), SUBSTR('abc',-0) FROM dual; +SUBSTR('abc',-2) SUBSTR('abc',-1) SUBSTR('abc',-0) +bc c abc +SELECT SUBSTR('abc',-2,1),SUBSTR('abc',-1,1), SUBSTR('abc',-0,1) FROM dual; +SUBSTR('abc',-2,1) SUBSTR('abc',-1,1) SUBSTR('abc',-0,1) +b c a +SELECT SUBSTR('abc',null) FROM dual; +SUBSTR('abc',null) +NULL +SELECT SUBSTR('abc',2,null),SUBSTR('abc',1,null), SUBSTR('abc',0,null) FROM dual; +SUBSTR('abc',2,null) SUBSTR('abc',1,null) SUBSTR('abc',0,null) +NULL NULL NULL +SELECT SUBSTR('abc',2,0),SUBSTR('abc',1,0), SUBSTR('abc',0,0) FROM dual; +SUBSTR('abc',2,0) SUBSTR('abc',1,0) SUBSTR('abc',0,0) +NULL NULL NULL +SELECT SUBSTR('abc',2,-1),SUBSTR('abc',1,-1), SUBSTR('abc',0,-1) FROM dual; +SUBSTR('abc',2,-1) SUBSTR('abc',1,-1) SUBSTR('abc',0,-1) +NULL NULL NULL +SELECT SUBSTR(SPACE(0),1) FROM DUAL; +SUBSTR(SPACE(0),1) +NULL +CREATE TABLE t1 (c1 VARCHAR(10),start INTEGER, length INTEGER); +INSERT INTO t1 VALUES ('abc', 1, 1); +INSERT INTO t1 VALUES ('abc', 0, 1); +INSERT INTO t1 VALUES (null, 1, 1); +INSERT INTO t1 VALUES (null, 0, 1); +INSERT INTO t1 VALUES ('abc', 1, 0); +INSERT INTO t1 VALUES ('abc', 0, 0); +INSERT INTO t1 VALUES (null, 1, 0); +INSERT INTO t1 VALUES (null, 0, 0); +INSERT INTO t1 VALUES ('abc', 1, -1); +INSERT INTO t1 VALUES ('abc', 0, -1); +INSERT INTO t1 VALUES (null, 1, -1); +INSERT INTO t1 VALUES (null, 0, -1); +INSERT INTO t1 VALUES (SPACE(0), 0, 1); +SELECT SUBSTR(c1,start,length) FROM t1; +SUBSTR(c1,start,length) +a +a +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 VARCHAR(10) NOT NULL); +CREATE TABLE t2 AS SELECT SUBSTR(C1,1,1) AS C1 from t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "C1" varchar(1) DEFAULT NULL +) +DROP TABLE t2; +DROP TABLE t1; +EXPLAIN EXTENDED SELECT SUBSTR('abc',2,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 substr_oracle('abc',2,1) AS "SUBSTR('abc',2,1)" +CREATE VIEW v1 AS SELECT SUBSTR('abc',2,1) ; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select substr_oracle('abc',2,1) AS "SUBSTR('abc',2,1)" latin1 latin1_swedish_ci +SELECT * FROM v1; +SUBSTR('abc',2,1) +b +DROP VIEW v1; diff --git a/mysql-test/suite/compat/oracle/r/func_time.result b/mysql-test/suite/compat/oracle/r/func_time.result new file mode 100644 index 00000000..06316340 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_time.result @@ -0,0 +1,31 @@ +SET sql_mode=ORACLE; +# +# Start of 10.3 tests +# +# +# MDEV-16152 Expressions with INTERVAL return bad results in some cases +# +SELECT TIMESTAMP'2001-01-01 10:20:30' - INTERVAL '10' YEAR AS c1, +-INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' AS c2; +c1 c2 +1991-01-01 10:20:30 1991-01-01 10:20:30 +SELECT TIMESTAMP'2001-01-01 10:20:30' + INTERVAL '10' YEAR AS c1, +INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' AS c2, ++INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' AS c3; +c1 c2 c3 +2011-01-01 10:20:30 2011-01-01 10:20:30 2011-01-01 10:20:30 +EXPLAIN EXTENDED SELECT +TIMESTAMP'2001-01-01 10:20:30' - INTERVAL '10' YEAR AS c1, +-INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' AS c2; +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 TIMESTAMP'2001-01-01 10:20:30' - interval '10' year AS "c1",TIMESTAMP'2001-01-01 10:20:30' - interval '10' year AS "c2" +EXPLAIN EXTENDED SELECT +TIMESTAMP'2001-01-01 10:20:30' + INTERVAL '10' YEAR AS c1, +INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' AS c2, ++INTERVAL '10' YEAR + TIMESTAMP'2001-01-01 10:20:30' AS c3; +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 TIMESTAMP'2001-01-01 10:20:30' + interval '10' year AS "c1",TIMESTAMP'2001-01-01 10:20:30' + interval '10' year AS "c2",TIMESTAMP'2001-01-01 10:20:30' + interval '10' year AS "c3" diff --git a/mysql-test/suite/compat/oracle/r/func_to_char.result b/mysql-test/suite/compat/oracle/r/func_to_char.result new file mode 100644 index 00000000..1f95acec --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_to_char.result @@ -0,0 +1,448 @@ +set @save_sql_mode=@@sql_mode; +# +# test for datetime +# +CREATE TABLE t_to_char1(c0 int, c1 date, c2 time, c3 datetime); +INSERT INTO t_to_char1 VALUES (1, '1000-1-1', '00:00:00', '1000-1-1 00:00:00'); +INSERT INTO t_to_char1 VALUES (2, '9999-12-31', '23:59:59', '9999-12-31 23:59:59'); +INSERT INTO t_to_char1 VALUES (3, '2021-01-03', '08:30:00', '2021-01-03 08:30:00'); +INSERT INTO t_to_char1 VALUES (4, '2021-07-03', '18:30:00', '2021-07-03 18:30:00'); +CREATE TABLE t_to_char2(c1 timestamp); +INSERT INTO t_to_char2 VALUES ('1980-01-11 04:50:39'); +INSERT INTO t_to_char2 VALUES ('2000-11-11 12:50:00'); +INSERT INTO t_to_char2 VALUES ('2030-11-11 18:20:10'); +SELECT TO_CHAR(c1, 'YYYY-MM-DD') FROM t_to_char2; +TO_CHAR(c1, 'YYYY-MM-DD') +1980-01-11 +2000-11-11 +2030-11-11 +SELECT TO_CHAR(c1, 'HH24-MI-SS') FROM t_to_char2; +TO_CHAR(c1, 'HH24-MI-SS') +04-50-39 +12-50-00 +18-20-10 +# +# test YYYY/YY/MM/DD/HH/HH24/MI/SS +# +SELECT TO_CHAR(c1, 'YYYY-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'YY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +1000-01-01 12:00:00 00-01-01 00:00:00 +9999-12-31 11:59:59 99-12-31 23:59:59 +2021-01-03 08:30:00 21-01-03 08:30:00 +2021-07-03 06:30:00 21-07-03 18:30:00 +SELECT TO_CHAR(c1, 'yyyy-mm-dd') AS C1, TO_CHAR(c2, 'hh:mi:ss') AS C2, TO_CHAR(c3, 'yy-mm-dd hh24:mi:ss') AS C3 FROM t_to_char1; +C1 C2 C3 +1000-01-01 12:00:00 00-01-01 00:00:00 +9999-12-31 11:59:59 99-12-31 23:59:59 +2021-01-03 08:30:00 21-01-03 08:30:00 +2021-07-03 06:30:00 21-07-03 18:30:00 +# +# test YYY/Y/MON/DD/DY/HH/HH12/MI/SS +# +SELECT TO_CHAR(c1, 'YYY-MON-DD') AS C1, TO_CHAR(c2, 'HH12:MI:SS') AS C2, TO_CHAR(c3, 'Y-MONTH-DY HH:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +000-Jan-01 12:00:00 0-January -Wed 12:00:00 +999-Dec-31 11:59:59 9-December -Fri 11:59:59 +021-Jan-03 08:30:00 1-January -Sun 08:30:00 +021-Jul-03 06:30:00 1-July -Sat 06:30:00 +SELECT TO_CHAR(c1, 'yyy-Mon-Dd') AS C1, TO_CHAR(c2, 'Hh12:mi:Ss') AS C2, TO_CHAR(c3, 'y-Month-Dy Hh:Mi:Ss') AS C3 FROM t_to_char1; +C1 C2 C3 +000-Jan-01 12:00:00 0-January -Wed 12:00:00 +999-Dec-31 11:59:59 9-December -Fri 11:59:59 +021-Jan-03 08:30:00 1-January -Sun 08:30:00 +021-Jul-03 06:30:00 1-July -Sat 06:30:00 +# +# test RRRR/RR/DAY +# +SELECT TO_CHAR(c1, 'RRRR-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'RRRR-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +1000-01-01 12:00:00 1000-01-01 00:00:00 +9999-12-31 11:59:59 9999-12-31 23:59:59 +2021-01-03 08:30:00 2021-01-03 08:30:00 +2021-07-03 06:30:00 2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'RR-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'YY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +00-01-01 12:00:00 00-01-01 00:00:00 +99-12-31 11:59:59 99-12-31 23:59:59 +21-01-03 08:30:00 21-01-03 08:30:00 +21-07-03 06:30:00 21-07-03 18:30:00 +SELECT TO_CHAR(c1, 'Rrrr-Mm-Dd') AS C1, TO_CHAR(c2, 'hh:mi:ss') AS C2, TO_CHAR(c3, 'Rrrr-mm-dd Hh24:mi:ss') AS C3 FROM t_to_char1; +C1 C2 C3 +1000-01-01 12:00:00 1000-01-01 00:00:00 +9999-12-31 11:59:59 9999-12-31 23:59:59 +2021-01-03 08:30:00 2021-01-03 08:30:00 +2021-07-03 06:30:00 2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'rr-mm-dd') AS C1, TO_CHAR(c2, 'hh:mi:ss') AS C2, TO_CHAR(c3, 'yy-mm-dd hh24:Mi:ss') AS C3 FROM t_to_char1; +C1 C2 C3 +00-01-01 12:00:00 00-01-01 00:00:00 +99-12-31 11:59:59 99-12-31 23:59:59 +21-01-03 08:30:00 21-01-03 08:30:00 +21-07-03 06:30:00 21-07-03 18:30:00 +# +# test AD/A.D./BC/B.C./AM/A.M./PM/P.M. +# +SELECT TO_CHAR(c1, 'ADYYYY-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'AD.YYYY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +AD1000-01-01 12:00:00 AD.1000-01-01 00:00:00 +AD9999-12-31 11:59:59 AD.9999-12-31 23:59:59 +AD2021-01-03 08:30:00 AD.2021-01-03 08:30:00 +AD2021-07-03 06:30:00 AD.2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'A.D.YYYY-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'A.D..YYYY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +A.D.1000-01-01 12:00:00 A.D..1000-01-01 00:00:00 +A.D.9999-12-31 11:59:59 A.D..9999-12-31 23:59:59 +A.D.2021-01-03 08:30:00 A.D..2021-01-03 08:30:00 +A.D.2021-07-03 06:30:00 A.D..2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'ADYYYY-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'AD.YYYY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +AD1000-01-01 12:00:00 AD.1000-01-01 00:00:00 +AD9999-12-31 11:59:59 AD.9999-12-31 23:59:59 +AD2021-01-03 08:30:00 AD.2021-01-03 08:30:00 +AD2021-07-03 06:30:00 AD.2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'A.D.YYYY-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'A.D..YYYY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +A.D.1000-01-01 12:00:00 A.D..1000-01-01 00:00:00 +A.D.9999-12-31 11:59:59 A.D..9999-12-31 23:59:59 +A.D.2021-01-03 08:30:00 A.D..2021-01-03 08:30:00 +A.D.2021-07-03 06:30:00 A.D..2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'BCYYYY-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'BCYYYY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +AD1000-01-01 12:00:00 AD1000-01-01 00:00:00 +AD9999-12-31 11:59:59 AD9999-12-31 23:59:59 +AD2021-01-03 08:30:00 AD2021-01-03 08:30:00 +AD2021-07-03 06:30:00 AD2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'B.C.YYYY-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'B.C.YYYY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +A.D.1000-01-01 12:00:00 A.D.1000-01-01 00:00:00 +A.D.9999-12-31 11:59:59 A.D.9999-12-31 23:59:59 +A.D.2021-01-03 08:30:00 A.D.2021-01-03 08:30:00 +A.D.2021-07-03 06:30:00 A.D.2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'bcyyyy-mm-dd') AS C1, TO_CHAR(c2, 'hh:mi:ss') AS C2, TO_CHAR(c3, 'BcYYyy-MM-DD Hh24:mi:sS') AS C3 FROM t_to_char1; +C1 C2 C3 +AD1000-01-01 12:00:00 AD1000-01-01 00:00:00 +AD9999-12-31 11:59:59 AD9999-12-31 23:59:59 +AD2021-01-03 08:30:00 AD2021-01-03 08:30:00 +AD2021-07-03 06:30:00 AD2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'b.c.yyyy-mm-dd') AS C1, TO_CHAR(c2, 'hh:mI:Ss') AS C2, TO_CHAR(c3, 'b.C.Yyyy-Mm-dd hH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +A.D.1000-01-01 12:00:00 A.D.1000-01-01 00:00:00 +A.D.9999-12-31 11:59:59 A.D.9999-12-31 23:59:59 +A.D.2021-01-03 08:30:00 A.D.2021-01-03 08:30:00 +A.D.2021-07-03 06:30:00 A.D.2021-07-03 18:30:00 +SELECT TO_CHAR(c1, 'A.D.YYYY-MM-DD') AS C1, TO_CHAR(c2, 'PMHH:MI:SS') AS C2, TO_CHAR(c3, 'A.D..YYYY-MM-DD P.M.HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +A.D.1000-01-01 AM12:00:00 A.D..1000-01-01 A.M.00:00:00 +A.D.9999-12-31 PM11:59:59 A.D..9999-12-31 P.M.23:59:59 +A.D.2021-01-03 AM08:30:00 A.D..2021-01-03 A.M.08:30:00 +A.D.2021-07-03 PM06:30:00 A.D..2021-07-03 P.M.18:30:00 +SELECT TO_CHAR(c1, 'A.D.YYYY-MM-DD') AS C1, TO_CHAR(c2, 'pmHH:MI:SS') AS C2, TO_CHAR(c3, 'A.D..YYYY-MM-DD p.m.HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +A.D.1000-01-01 AM12:00:00 A.D..1000-01-01 A.M.00:00:00 +A.D.9999-12-31 PM11:59:59 A.D..9999-12-31 P.M.23:59:59 +A.D.2021-01-03 AM08:30:00 A.D..2021-01-03 A.M.08:30:00 +A.D.2021-07-03 PM06:30:00 A.D..2021-07-03 P.M.18:30:00 +SELECT TO_CHAR(c1, 'A.D.YYYY-MM-DD') AS C1, TO_CHAR(c2, 'AMHH:MI:SS') AS C2, TO_CHAR(c3, 'A.D..YYYY-MM-DD A.m.HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +A.D.1000-01-01 AM12:00:00 A.D..1000-01-01 A.M.00:00:00 +A.D.9999-12-31 PM11:59:59 A.D..9999-12-31 P.M.23:59:59 +A.D.2021-01-03 AM08:30:00 A.D..2021-01-03 A.M.08:30:00 +A.D.2021-07-03 PM06:30:00 A.D..2021-07-03 P.M.18:30:00 +SELECT TO_CHAR(c1, 'A.D.YYYY-MM-DD') AS C1, TO_CHAR(c2, 'amHH:MI:SS') AS C2, TO_CHAR(c3, 'A.D..YYYY-MM-DD a.M.HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +A.D.1000-01-01 AM12:00:00 A.D..1000-01-01 A.M.00:00:00 +A.D.9999-12-31 PM11:59:59 A.D..9999-12-31 P.M.23:59:59 +A.D.2021-01-03 AM08:30:00 A.D..2021-01-03 A.M.08:30:00 +A.D.2021-07-03 PM06:30:00 A.D..2021-07-03 P.M.18:30:00 +# +# test format without order +# +SELECT TO_CHAR(c1, 'MM-YYYY-DD') AS C1, TO_CHAR(c2, 'HH:SS:MI') AS C2, TO_CHAR(c3, 'DD-YY-MM MI:SS:HH24') AS C3 FROM t_to_char1; +C1 C2 C3 +01-1000-01 12:00:00 01-00-01 00:00:00 +12-9999-31 11:59:59 31-99-12 59:59:23 +01-2021-03 08:00:30 03-21-01 30:00:08 +07-2021-03 06:00:30 03-21-07 30:00:18 +SELECT TO_CHAR(c1, 'yyy-Dd-Mon') AS C1, TO_CHAR(c2, 'mi:Hh12:Ss') AS C2, TO_CHAR(c3, 'Ss:Hh:Mi Dy-y-Month') AS C3 FROM t_to_char1; +C1 C2 C3 +000-01-Jan 00:12:00 00:12:00 Wed-0-January +999-31-Dec 59:11:59 59:11:59 Fri-9-December +021-03-Jan 30:08:00 00:08:30 Sun-1-January +021-03-Jul 30:06:00 00:06:30 Sat-1-July +SELECT TO_CHAR(c1, 'Dd-Mm-Rrrr') AS C1, TO_CHAR(c2, 'ss:hh:mi') AS C2, TO_CHAR(c3, 'ss:Rrrr-hh24-dd mon:mi') AS C3 FROM t_to_char1; +C1 C2 C3 +01-01-1000 00:12:00 00:1000-00-01 Jan:00 +31-12-9999 59:11:59 59:9999-23-31 Dec:59 +03-01-2021 00:08:30 00:2021-08-03 Jan:30 +03-07-2021 00:06:30 00:2021-18-03 Jul:30 +SELECT TO_CHAR(c1, 'YYYYA.D.-MM-DD') AS C1, TO_CHAR(c2, 'HH:MI:SS') AS C2, TO_CHAR(c3, 'A.D..YYYY-MM-DD HH24:MI:SS') AS C3 FROM t_to_char1; +C1 C2 C3 +1000A.D.-01-01 12:00:00 A.D..1000-01-01 00:00:00 +9999A.D.-12-31 11:59:59 A.D..9999-12-31 23:59:59 +2021A.D.-01-03 08:30:00 A.D..2021-01-03 08:30:00 +2021A.D.-07-03 06:30:00 A.D..2021-07-03 18:30:00 +# +# test for special characters +# +SELECT TO_CHAR(c1, 'YYYYMMDD') AS C1, TO_CHAR(c2, 'HHMISS') AS C2, TO_CHAR(c3, 'YYMMDDHH24MISS') AS C3 FROM t_to_char1; +C1 C2 C3 +10000101 120000 000101000000 +99991231 115959 991231235959 +20210103 083000 210103083000 +20210703 063000 210703183000 +SELECT TO_CHAR(c1, 'YYYY!!MM@DD') AS C1, TO_CHAR(c2, 'HH#MI$SS') AS C2, TO_CHAR(c3, 'YY%MM^DD*HH24(MI)SS') AS C3 FROM t_to_char1; +C1 C2 C3 +1000!!01@01 12#00$00 00%01^01*00(00)00 +9999!!12@31 11#59$59 99%12^31*23(59)59 +2021!!01@03 08#30$00 21%01^03*08(30)00 +2021!!07@03 06#30$00 21%07^03*18(30)00 +SELECT TO_CHAR(c1, 'YYYY_MM+DD') AS C1, TO_CHAR(c2, 'HH=MI{SS') AS C2, TO_CHAR(c3, 'YY}MMDDHH24MISS') AS C3 FROM t_to_char1; +C1 C2 C3 +1000_01+01 12=00{00 00}0101000000 +9999_12+31 11=59{59 99}1231235959 +2021_01+03 08=30{00 21}0103083000 +2021_07+03 06=30{00 21}0703183000 +SELECT TO_CHAR(c1, 'YYYY,MM.DD') AS C1, TO_CHAR(c2, 'HH/MI;SS') AS C2, TO_CHAR(c3, 'YY>MM<DD]HH24[MI\SS') AS C3 FROM t_to_char1; +C1 C2 C3 +1000,01.01 12/00;00 00>01<01]00[0000 +9999,12.31 11/59;59 99>12<31]23[5959 +2021,01.03 08/30;00 21>01<03]08[3000 +2021,07.03 06/30;00 21>07<03]18[3000 +SELECT TO_CHAR(c1, 'YYYY||||MM|DD') AS C1, TO_CHAR(c2, 'HH&|MI|&|SS') AS C2, TO_CHAR(c3, 'YY&&&\\MM|&&|DD HH24|| MI&||"abx"|SS') AS C3 FROM t_to_char1; +C1 C2 C3 +1000|||0101 12&|00&|00 00&&&\01&&|01 00| 00&||abx00 +9999|||1231 11&|59&|59 99&&&\12&&|31 23| 59&||abx59 +2021|||0103 08&|30&|00 21&&&\01&&|03 08| 30&||abx00 +2021|||0703 06&|30&|00 21&&&\07&&|03 18| 30&||abx00 +SELECT TO_CHAR(c1, 'YYYY&MM-DD') FROM t_to_char1 where c0=1; +ERROR HY000: Invalid argument error: date format not recognized at &MM-DD in function to_char. +SELECT TO_CHAR(c1, 'YYYY"abx"MM"bsz"DD') AS C1 FROM t_to_char1; +C1 +1000abx01bsz01 +9999abx12bsz31 +2021abx01bsz03 +2021abx07bsz03 +# +# test for other locale +# +SET character_set_client='utf8'; +SET character_set_connection='utf8'; +SET character_set_results='utf8'; +SET lc_time_names='zh_TW'; +SELECT TO_CHAR(c1, 'YYYY-MON-DAY') FROM t_to_char1; +TO_CHAR(c1, 'YYYY-MON-DAY') +1000- 1月-週三 +9999-12月-週五 +2021- 1月-週日 +2021- 7月-é€±å… +SET lc_time_names='de_DE'; +SELECT TO_CHAR(c1, 'YYYY-MON-DAY') FROM t_to_char1; +TO_CHAR(c1, 'YYYY-MON-DAY') +1000-Jan-Mittwoch +9999-Dez-Freitag +2021-Jan-Sonntag +2021-Jul-Samstag +SET lc_time_names='en_US'; +SELECT TO_CHAR(c1, 'YYYY-MON-DAY') FROM t_to_char1; +TO_CHAR(c1, 'YYYY-MON-DAY') +1000-Jan-Wednesday +9999-Dec-Friday +2021-Jan-Sunday +2021-Jul-Saturday +SET lc_time_names='zh_CN'; +SELECT TO_CHAR(c1, 'YYYY-MON-DAY') FROM t_to_char1; +TO_CHAR(c1, 'YYYY-MON-DAY') +1000- 1月-星期三 +9999-12月-星期五 +2021- 1月-星期日 +2021- 7月-æ˜ŸæœŸå… +# +# test for invalid format +# +SELECT TO_CHAR(c1, 'YYYYaxMON-DAY') FROM t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at axMON-DA in function to_char. +SELECT TO_CHAR(c1, 'YYYY\nMON-DAY') FROM t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at +MON-DAY in function to_char. +SELECT TO_CHAR(c1, 'YYYY\rMON-DAY') FROM t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at
MON-DAY in function to_char. +SELECT TO_CHAR(c1, 'YYYY分隔MON-DAY') FROM t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at 分隔MO in function to_char. +SELECT TO_CHAR(c1, 'YYYY-分隔MON-DAY') FROM t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at 分隔MO in function to_char. +select to_char(c3, 'YYYYxDDD') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at xDDD in function to_char. +select to_char(c3, 'YYYY&DDD') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at &DDD in function to_char. +select to_char(c3, 'xxYYYY-DD') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at xxYYYY-D in function to_char. +SET character_set_client='latin1'; +SET character_set_connection='latin1'; +SET character_set_results='latin1'; +# +# test for unusual format +# +select to_char(c3, 'YYYYYYYYYYYYYYY') from t_to_char1; +to_char(c3, 'YYYYYYYYYYYYYYY') +100010001000000 +999999999999999 +202120212021021 +202120212021021 +select to_char(c3, 'YYYYYYYYYYYYYYYDDDDDD') from t_to_char1; +to_char(c3, 'YYYYYYYYYYYYYYYDDDDDD') +100010001000000010101 +999999999999999313131 +202120212021021030303 +202120212021021030303 +# +# oracle max length is 144 +# +select to_char(c3, 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: datetime format string is too long in function to_char. +CREATE TABLE t_f(c1 varchar(150)); +insert into t_f values('YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY-DD'); +select to_char('2000-11-11', c1) from t_f; +to_char('2000-11-11', c1) +NULL +Warnings: +Warning 3047 Invalid argument error: datetime format string is too long in function to_char. +DROP TABLE t_f; +select to_char(c3, 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY-DD-MM') from t_to_char1 where c0 = 1; +to_char(c3, 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY-DD-MM') +100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000-01-01 +# +# now only support two parameter. +# +select to_char(c3) from t_to_char1 where c0 =1; +to_char(c3) +1000-01-01 00:00:00 +select to_char(c3, "YYYY-MM-DD HH:MI:SS") from t_to_char1 where c0 =1; +to_char(c3, "YYYY-MM-DD HH:MI:SS") +1000-01-01 12:00:00 +select to_char(c3, "YYYY-MM-DD HH:MI:SS", "zh_CN") from t_to_char1 where c0 = 1; +ERROR 42000: Incorrect parameter count in the call to native function 'to_char' +select to_char(c3, "YYYY-MM-DD HH:MI:SS", "NLS_DATE_LANGUAGE = zh_CN") from t_to_char1 where c0 = 1; +ERROR 42000: Incorrect parameter count in the call to native function 'to_char' +# +# oracle support format but mariadb does not support +# +select to_char(c3, 'DDD') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at D in function to_char. +select to_char(c3, 'D') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at D in function to_char. +select to_char(c3, 'DS') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at DS in function to_char. +select to_char(c3, 'IY') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at IY in function to_char. +select to_char(c3, 'IYYY') from t_to_char1 where c0 = 1; +ERROR HY000: Invalid argument error: date format not recognized at IYYY in function to_char. +# +# test for first argument data type +# +select to_char(1, 'yyyy'); +ERROR HY000: Invalid argument error: data type of first argument must be type date/datetime/time or string in function to_char. +select to_char(1.1, 'yyyy'); +ERROR HY000: Invalid argument error: data type of first argument must be type date/datetime/time or string in function to_char. +CREATE TABLE t_a(c1 int, c2 float, c3 decimal, c4 char(20), c5 varchar(20), c6 nchar(20), c7 nvarchar(20)); +insert into t_a VALUES (1, 3.2, 2002.02, '2000-11-11', '2000-11-11', '2000-11-11', '2000-11-11'); +Warnings: +Note 1265 Data truncated for column 'c3' at row 1 +SELECT TO_CHAR(c1, 'YYYY') from t_a; +ERROR HY000: Invalid argument error: data type of first argument must be type date/datetime/time or string in function to_char. +SELECT TO_CHAR(c2, 'YYYY') from t_a; +ERROR HY000: Invalid argument error: data type of first argument must be type date/datetime/time or string in function to_char. +SELECT TO_CHAR(c3, 'YYYY') from t_a; +ERROR HY000: Invalid argument error: data type of first argument must be type date/datetime/time or string in function to_char. +SELECT TO_CHAR(c4, 'YYYY') from t_a; +TO_CHAR(c4, 'YYYY') +2000 +SELECT TO_CHAR(c5, 'YYYY') from t_a; +TO_CHAR(c5, 'YYYY') +2000 +SELECT TO_CHAR(c6, 'YYYY') from t_a; +TO_CHAR(c6, 'YYYY') +2000 +SELECT TO_CHAR(c7, 'YYYY') from t_a; +TO_CHAR(c7, 'YYYY') +2000 +DROP TABLE t_a; +CREATE TABLE t_b(c0 int, c1 char(20), c2 varchar(20), c3 nchar(20), c4 nvarchar(20)); +INSERT INTO t_b VALUES (1111, 'YYYY-MM-DD', 'YYYY-MM-DD', 'YYYY-MM-DD', 'YYYY-MM-DD'); +SELECT TO_CHAR('2000-11-11', c0) FROM t_b; +TO_CHAR('2000-11-11', c0) +NULL +Warnings: +Warning 3047 Invalid argument error: date format not recognized at 1111 in function to_char. +SELECT TO_CHAR('2000-11-11', c1) FROM t_b; +TO_CHAR('2000-11-11', c1) +2000-11-11 +SELECT TO_CHAR('2000-11-11', c2) FROM t_b; +TO_CHAR('2000-11-11', c2) +2000-11-11 +SELECT TO_CHAR('2000-11-11', c3) FROM t_b; +TO_CHAR('2000-11-11', c3) +2000-11-11 +SELECT TO_CHAR('2000-11-11', c4) FROM t_b; +TO_CHAR('2000-11-11', c4) +2000-11-11 +DROP TABLE t_b; +EXPLAIN EXTENDED SELECT TO_CHAR(c1, 'YYYY-MM-DD') FROM t_to_char1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t_to_char1 ALL NULL NULL NULL NULL 4 100.00 +Warnings: +Note 1003 select to_char(`test`.`t_to_char1`.`c1`,'YYYY-MM-DD') AS `TO_CHAR(c1, 'YYYY-MM-DD')` from `test`.`t_to_char1` +# +# test for time type with date format string +# +SELECT TO_CHAR(c2, 'YYYY-MM-DD HH:MI:SS') from t_to_char1; +TO_CHAR(c2, 'YYYY-MM-DD HH:MI:SS') +0000-00-00 12:00:00 +0000-00-00 11:59:59 +0000-00-00 08:30:00 +0000-00-00 06:30:00 +SELECT TO_CHAR(c2, 'YYYY-MON-DY HH:MI:SS') from t_to_char1; +TO_CHAR(c2, 'YYYY-MON-DY HH:MI:SS') +0000-00-00 12:00:00 +0000-00-00 11:59:59 +0000-00-00 08:30:00 +0000-00-00 06:30:00 +SELECT TO_CHAR(c2, 'MON-YYYY-DY HH:MI:SS') from t_to_char1; +TO_CHAR(c2, 'MON-YYYY-DY HH:MI:SS') +00-0000-00 12:00:00 +00-0000-00 11:59:59 +00-0000-00 08:30:00 +00-0000-00 06:30:00 +SELECT TO_CHAR(c2, 'YYYY-MONTH-DAY HH:MI:SS') from t_to_char1; +TO_CHAR(c2, 'YYYY-MONTH-DAY HH:MI:SS') +0000-00-00 12:00:00 +0000-00-00 11:59:59 +0000-00-00 08:30:00 +0000-00-00 06:30:00 +DROP TABLE t_to_char1; +DROP TABLE t_to_char2; +# +# Test strict mode +# +create table t1 (a datetime, b int, f varchar(30)) engine=myisam; +insert into t1 values ("2021-01-24 19:22:10", 2014, "YYYY-MM-DD"); +insert into t1 values ("2021-01-24 19:22:10", 2014, "YYYY-MQ-DD"); +create table t2 (a varchar(30)) engine=myisam; +insert into t2 select to_char(a,f) from t1; +Warnings: +Warning 3047 Invalid argument error: date format not recognized at MQ-DD in function to_char. +set @@sql_mode="STRICT_ALL_TABLES"; +insert into t2 select to_char(a,f) from t1; +ERROR HY000: Invalid argument error: date format not recognized at MQ-DD in function to_char. +select * from t2; +a +2021-01-24 +NULL +2021-01-24 +drop table t1,t2; +set @local.sql_mode=@sql_mode; +# +# MDEV-29152: Assertion failed ... upon TO_CHAR with wrong argument +# +SELECT TO_CHAR((VALUES('2022-12-12','2020-10-10'))); +ERROR HY000: Illegal parameter data type row for operation 'to_char' +SELECT TO_CHAR((STR_TO_DATE('2023-01-01', '%d-%m-%Y'), 'YYYY-MM-DD') ); +ERROR HY000: Illegal parameter data type row for operation 'to_char' diff --git a/mysql-test/suite/compat/oracle/r/func_trim.result b/mysql-test/suite/compat/oracle/r/func_trim.result new file mode 100644 index 00000000..bed8dadf --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/func_trim.result @@ -0,0 +1,170 @@ +SET sql_mode=ORACLE; +# +# MDEV-15664 sql_mode=ORACLE: Make TRIM return NULL instead of empty string +# +SELECT TRIM('abc'), TRIM('abc ')||'.', '.'||TRIM(' abc ')||'.', TRIM(' '), TRIM(NULL), TRIM(SPACE(0)),TRIM(SPACE(10)) FROM dual; +TRIM('abc') TRIM('abc ')||'.' '.'||TRIM(' abc ')||'.' TRIM(' ') TRIM(NULL) TRIM(SPACE(0)) TRIM(SPACE(10)) +abc abc. .abc. NULL NULL NULL NULL +SELECT TRIM(TRAILING 'abc' FROM 'abc'); +TRIM(TRAILING 'abc' FROM 'abc') +NULL +SELECT TRIM(TRAILING 'abc' FROM 'abc '); +TRIM(TRAILING 'abc' FROM 'abc ') +abc +SELECT TRIM(TRAILING 'abc' FROM ' abc'); +TRIM(TRAILING 'abc' FROM ' abc') + +SELECT TRIM(LEADING 'abc' FROM 'abc'); +TRIM(LEADING 'abc' FROM 'abc') +NULL +SELECT TRIM(LEADING 'abc' FROM 'abc '); +TRIM(LEADING 'abc' FROM 'abc ') + +SELECT TRIM(LEADING 'abc' FROM ' abc'); +TRIM(LEADING 'abc' FROM ' abc') + abc +SELECT TRIM(BOTH 'abc' FROM 'abc'); +TRIM(BOTH 'abc' FROM 'abc') +NULL +SELECT TRIM(BOTH 'abc' FROM 'abc '); +TRIM(BOTH 'abc' FROM 'abc ') + +SELECT TRIM(BOTH 'abc' FROM ' abc'); +TRIM(BOTH 'abc' FROM ' abc') + +SELECT RTRIM('abc'), RTRIM('abc ')||'.', RTRIM(' abc ')||'.', RTRIM(' '), RTRIM(NULL), RTRIM(SPACE(0)),RTRIM(SPACE(10)) FROM dual; +RTRIM('abc') RTRIM('abc ')||'.' RTRIM(' abc ')||'.' RTRIM(' ') RTRIM(NULL) RTRIM(SPACE(0)) RTRIM(SPACE(10)) +abc abc. abc. NULL NULL NULL NULL +SELECT LTRIM('abc'), LTRIM('abc '), LTRIM(' abc '), LTRIM(' '), LTRIM(NULL), LTRIM(SPACE(0)),LTRIM(SPACE(10)) FROM dual; +LTRIM('abc') LTRIM('abc ') LTRIM(' abc ') LTRIM(' ') LTRIM(NULL) LTRIM(SPACE(0)) LTRIM(SPACE(10)) +abc abc abc NULL NULL NULL NULL +CREATE TABLE t1 (c1 VARCHAR(10),ord INTEGER); +INSERT INTO t1 VALUES ('abc',1); +INSERT INTO t1 VALUES (SPACE(0),2); +INSERT INTO t1 VALUES ('',3); +INSERT INTO t1 VALUES (' ',4); +INSERT INTO t1 VALUES (' ',5); +INSERT INTO t1 VALUES (' a ',6); +INSERT INTO t1 VALUES ('aa',7); +INSERT INTO t1 VALUES ('aabb',8); +INSERT INTO t1 VALUES ('bbaa',9); +INSERT INTO t1 VALUES ('aabbaa',10); +SELECT ord,'['||c1||']','.'||COALESCE(TRIM(LEADING 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord; +ord '['||c1||']' '.'||COALESCE(TRIM(LEADING 'a' FROM c1),'NULL')||'.' +1 [abc] .bc. +2 [] .NULL. +3 [] .NULL. +4 [ ] . . +5 [ ] . . +6 [ a ] . a . +7 [aa] .NULL. +8 [aabb] .bb. +9 [bbaa] .bbaa. +10 [aabbaa] .bbaa. +SELECT ord,'['||c1||']','.'||COALESCE(TRIM(TRAILING 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord; +ord '['||c1||']' '.'||COALESCE(TRIM(TRAILING 'a' FROM c1),'NULL')||'.' +1 [abc] .abc. +2 [] .NULL. +3 [] .NULL. +4 [ ] . . +5 [ ] . . +6 [ a ] . a . +7 [aa] .NULL. +8 [aabb] .aabb. +9 [bbaa] .bb. +10 [aabbaa] .aabb. +SELECT ord,'['||c1||']','.'||COALESCE(TRIM(BOTH 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord; +ord '['||c1||']' '.'||COALESCE(TRIM(BOTH 'a' FROM c1),'NULL')||'.' +1 [abc] .bc. +2 [] .NULL. +3 [] .NULL. +4 [ ] . . +5 [ ] . . +6 [ a ] . a . +7 [aa] .NULL. +8 [aabb] .bb. +9 [bbaa] .bb. +10 [aabbaa] .bb. +SELECT ord,'['||c1||']',COALESCE(LTRIM(c1),'NULL') FROM t1 ORDER BY ord; +ord '['||c1||']' COALESCE(LTRIM(c1),'NULL') +1 [abc] abc +2 [] NULL +3 [] NULL +4 [ ] NULL +5 [ ] NULL +6 [ a ] a +7 [aa] aa +8 [aabb] aabb +9 [bbaa] bbaa +10 [aabbaa] aabbaa +SELECT ord,'['||c1||']',COALESCE(RTRIM(c1),'NULL')||'.' FROM t1 ORDER BY ord; +ord '['||c1||']' COALESCE(RTRIM(c1),'NULL')||'.' +1 [abc] abc. +2 [] NULL. +3 [] NULL. +4 [ ] NULL. +5 [ ] NULL. +6 [ a ] a. +7 [aa] aa. +8 [aabb] aabb. +9 [bbaa] bbaa. +10 [aabbaa] aabbaa. +EXPLAIN EXTENDED SELECT TRIM('abc'), +TRIM(BOTH 'a' FROM 'abc'), +TRIM(LEADING 'a' FROM 'abc'), +TRIM(TRAILING 'a' FROM '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 trim_oracle('abc') AS "TRIM('abc')",trim_oracle(both 'a' from 'abc') AS "TRIM(BOTH 'a' FROM 'abc')",trim_oracle(leading 'a' from 'abc') AS "TRIM(LEADING 'a' FROM 'abc')",trim_oracle(trailing 'a' from 'abc') AS "TRIM(TRAILING 'a' FROM 'abc')" +EXPLAIN EXTENDED SELECT RTRIM('abc'), +LTRIM('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 rtrim_oracle('abc') AS "RTRIM('abc')",ltrim_oracle('abc') AS "LTRIM('abc')" +CREATE VIEW v1 AS SELECT ord,TRIM('abc'),RTRIM('abc'),LTRIM('abc'), +'['||c1||']', +TRIM(LEADING 'a' FROM c1), +TRIM(TRAILING 'a' FROM c1), +TRIM(BOTH 'a' FROM c1), +LTRIM(c1), +RTRIM(c1) +FROM t1 ORDER BY ord ; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select "t1"."ord" AS "ord",trim_oracle('abc') AS "TRIM('abc')",rtrim_oracle('abc') AS "RTRIM('abc')",ltrim_oracle('abc') AS "LTRIM('abc')",concat_operator_oracle(concat_operator_oracle('[',"t1"."c1"),']') AS "'['||c1||']'",trim_oracle(leading 'a' from "t1"."c1") AS "TRIM(LEADING 'a' FROM c1)",trim_oracle(trailing 'a' from "t1"."c1") AS "TRIM(TRAILING 'a' FROM c1)",trim_oracle(both 'a' from "t1"."c1") AS "TRIM(BOTH 'a' FROM c1)",ltrim_oracle("t1"."c1") AS "LTRIM(c1)",rtrim_oracle("t1"."c1") AS "RTRIM(c1)" from "t1" order by "t1"."ord" latin1 latin1_swedish_ci +SELECT * FROM v1; +ord TRIM('abc') RTRIM('abc') LTRIM('abc') '['||c1||']' TRIM(LEADING 'a' FROM c1) TRIM(TRAILING 'a' FROM c1) TRIM(BOTH 'a' FROM c1) LTRIM(c1) RTRIM(c1) +1 abc abc abc [abc] bc abc bc abc abc +2 abc abc abc [] NULL NULL NULL NULL NULL +3 abc abc abc [] NULL NULL NULL NULL NULL +4 abc abc abc [ ] NULL NULL +5 abc abc abc [ ] NULL NULL +6 abc abc abc [ a ] a a a a a +7 abc abc abc [aa] NULL NULL NULL aa aa +8 abc abc abc [aabb] bb aabb bb aabb aabb +9 abc abc abc [bbaa] bbaa bb bb bbaa bbaa +10 abc abc abc [aabbaa] bbaa aabb bb aabbaa aabbaa +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1 (c1 VARCHAR(10) NOT NULL); +CREATE TABLE t2 AS SELECT TRIM(LEADING 'a' FROM c1) AS C1, +TRIM(TRAILING 'a' FROM c1) AS C2, +TRIM(BOTH 'a' FROM c1) AS C3, +LTRIM(c1) AS C4, +RTRIM(c1) AS C5 +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "C1" varchar(10) DEFAULT NULL, + "C2" varchar(10) DEFAULT NULL, + "C3" varchar(10) DEFAULT NULL, + "C4" varchar(10) DEFAULT NULL, + "C5" varchar(10) DEFAULT NULL +) +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE trim_oracle (trim_oracle int); +DROP TABLE trim_oracle; diff --git a/mysql-test/suite/compat/oracle/r/gis-debug.result b/mysql-test/suite/compat/oracle/r/gis-debug.result new file mode 100644 index 00000000..9ab74e6e --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/gis-debug.result @@ -0,0 +1,24 @@ +SET sql_mode=ORACLE; +# +# Start of 10.5 tests +# +# +# MDEV-19994 Add class Function_collection +# +SET SESSION debug_dbug="+d,make_item_func_call_native_simulate_not_found"; +SELECT CONTAINS(POINT(1,1),POINT(1,1)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(POINT(1,1),POINT(1,1))' at line 1 +SELECT WITHIN(POINT(1,1),POINT(1,1)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(POINT(1,1),POINT(1,1))' at line 1 +SET SESSION debug_dbug="-d,make_item_func_call_native_simulate_not_found"; +# +# MDEV-20009 Add CAST(expr AS pluggable_type) +# +SET SESSION debug_dbug="+d,emulate_geometry_create_typecast_item"; +SELECT AsText(CAST('POINT(0 0)' AS GEOMETRY)); +AsText(CAST('POINT(0 0)' AS GEOMETRY)) +POINT(0 0) +SET SESSION debug_dbug="-d,emulate_geometry_create_typecast_item"; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/compat/oracle/r/gis.result b/mysql-test/suite/compat/oracle/r/gis.result new file mode 100644 index 00000000..113cb0ea --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/gis.result @@ -0,0 +1,69 @@ +SET sql_mode=ORACLE; +SELECT CONTAINS(POINT(1,1), POINT(1,1)); +CONTAINS(POINT(1,1), POINT(1,1)) +1 +SELECT CONTAINS(POINT(1,1), POINT(0,0)); +CONTAINS(POINT(1,1), POINT(0,0)) +0 +SELECT WITHIN(POINT(1,1), POINT(1,1)); +WITHIN(POINT(1,1), POINT(1,1)) +1 +SELECT WITHIN(POINT(1,1), POINT(0,0)); +WITHIN(POINT(1,1), POINT(0,0)) +0 +# +# Start of 10.5 tests +# +# +# MDEV-19994 Add class Function_collection +# +SELECT CONTAINS(); +ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS()' +SELECT CONTAINS(POINT(1,1)); +ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS(POINT(1,1))' +SELECT CONTAINS(POINT(1,1), POINT(1,1), POINT(1,1)); +ERROR 42000: Incorrect parameter count in the call to native function 'CONTAINS(POINT(1,1), POINT(1,1), POINT(1,1))' +SELECT WITHIN(); +ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN()' +SELECT WITHIN(POINT(1,1)); +ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(POINT(1,1))' +SELECT WITHIN(POINT(1,1), POINT(1,1), POINT(1,1)); +ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(POINT(1,1), POINT(1,1), POINT(1,1))' +# +# MDEV-20009 Add CAST(expr AS pluggable_type) +# +SELECT CAST(1 AS GEOMETRY); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +SELECT CAST(1 AS GEOMETRYCOLLECTION); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +SELECT CAST(1 AS POINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +SELECT CAST(1 AS LINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +SELECT CAST(1 AS POLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +SELECT CAST(1 AS MULTIPOINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +SELECT CAST(1 AS MULTILINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +SELECT CAST(1 AS MULTIPOLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +SELECT CONVERT(1, GEOMETRY); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +SELECT CONVERT(1, GEOMETRYCOLLECTION); +ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +SELECT CONVERT(1, POINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +SELECT CONVERT(1, LINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +SELECT CONVERT(1, POLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +SELECT CONVERT(1, MULTIPOINT); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +SELECT CONVERT(1, MULTILINESTRING); +ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +SELECT CONVERT(1, MULTIPOLYGON); +ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/compat/oracle/r/information_schema_parameters.result b/mysql-test/suite/compat/oracle/r/information_schema_parameters.result new file mode 100644 index 00000000..f7e9bfca --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/information_schema_parameters.result @@ -0,0 +1,854 @@ +# +# MDEV-15416 Crash when reading I_S.PARAMETERS +# +# Create in sql_mode=ORACLE, display in sql_mode=ORACLE and sql_mode=DEFAULT +SET sql_mode=ORACLE; +CREATE PROCEDURE p1(a0 t1.a%TYPE, +a1 test.t1.a%TYPE, +b0 t1%ROWTYPE, +b1 test.t1%ROWTYPE, +d ROW(a INT,b DOUBLE)) +AS +BEGIN +NULL; +END; +$$ +SET sql_mode=ORACLE; +SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a0 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "t1"."a"%TYPE +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 2 +PARAMETER_MODE IN +PARAMETER_NAME a1 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "test"."t1"."a"%TYPE +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 3 +PARAMETER_MODE IN +PARAMETER_NAME b0 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "t1"%ROWTYPE +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 4 +PARAMETER_MODE IN +PARAMETER_NAME b1 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "test"."t1"%ROWTYPE +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 5 +PARAMETER_MODE IN +PARAMETER_NAME d +DATA_TYPE ROW +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW +ROUTINE_TYPE PROCEDURE +-------- -------- +SET sql_mode=DEFAULT; +SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a0 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "t1"."a"%TYPE +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 2 +PARAMETER_MODE IN +PARAMETER_NAME a1 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "test"."t1"."a"%TYPE +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 3 +PARAMETER_MODE IN +PARAMETER_NAME b0 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "t1"%ROWTYPE +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 4 +PARAMETER_MODE IN +PARAMETER_NAME b1 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "test"."t1"%ROWTYPE +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 5 +PARAMETER_MODE IN +PARAMETER_NAME d +DATA_TYPE ROW +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW +ROUTINE_TYPE PROCEDURE +-------- -------- +DROP PROCEDURE p1; +SET sql_mode=ORACLE; +CREATE FUNCTION f1(a0 t1.a%TYPE, +a1 test.t1.a%TYPE, +b0 t1%ROWTYPE, +b1 test.t1%ROWTYPE, +d ROW(a INT,b DOUBLE)) +RETURN INT +AS +BEGIN +RETURN 0; +END; +$$ +SET sql_mode=ORACLE; +SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 0 +PARAMETER_MODE NULL +PARAMETER_NAME NULL +DATA_TYPE int +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION 10 +NUMERIC_SCALE 0 +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER int(11) +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a0 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "t1"."a"%TYPE +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 2 +PARAMETER_MODE IN +PARAMETER_NAME a1 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "test"."t1"."a"%TYPE +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 3 +PARAMETER_MODE IN +PARAMETER_NAME b0 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "t1"%ROWTYPE +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 4 +PARAMETER_MODE IN +PARAMETER_NAME b1 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "test"."t1"%ROWTYPE +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 5 +PARAMETER_MODE IN +PARAMETER_NAME d +DATA_TYPE ROW +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW +ROUTINE_TYPE FUNCTION +-------- -------- +SET sql_mode=DEFAULT; +SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 0 +PARAMETER_MODE NULL +PARAMETER_NAME NULL +DATA_TYPE int +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION 10 +NUMERIC_SCALE 0 +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER int(11) +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a0 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "t1"."a"%TYPE +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 2 +PARAMETER_MODE IN +PARAMETER_NAME a1 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "test"."t1"."a"%TYPE +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 3 +PARAMETER_MODE IN +PARAMETER_NAME b0 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "t1"%ROWTYPE +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 4 +PARAMETER_MODE IN +PARAMETER_NAME b1 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER "test"."t1"%ROWTYPE +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 5 +PARAMETER_MODE IN +PARAMETER_NAME d +DATA_TYPE ROW +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW +ROUTINE_TYPE FUNCTION +-------- -------- +DROP FUNCTION f1; +# Create in sql_mode=DEFAULT, display in sql_mode=DEFAULT and sql_mode=ORACLE +SET sql_mode=DEFAULT; +CREATE PROCEDURE p1(a0 TYPE OF t1.a, +a1 TYPE OF test.t1.a, +b0 ROW TYPE OF t1, +b1 ROW TYPE OF test.t1, +d ROW(a INT,b DOUBLE)) +BEGIN +END; +$$ +SET sql_mode=DEFAULT; +SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a0 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER TYPE OF `t1`.`a` +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 2 +PARAMETER_MODE IN +PARAMETER_NAME a1 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER TYPE OF `test`.`t1`.`a` +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 3 +PARAMETER_MODE IN +PARAMETER_NAME b0 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW TYPE OF `t1` +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 4 +PARAMETER_MODE IN +PARAMETER_NAME b1 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW TYPE OF `test`.`t1` +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 5 +PARAMETER_MODE IN +PARAMETER_NAME d +DATA_TYPE ROW +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW +ROUTINE_TYPE PROCEDURE +-------- -------- +SET sql_mode=ORACLE; +SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='p1'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a0 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER TYPE OF `t1`.`a` +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 2 +PARAMETER_MODE IN +PARAMETER_NAME a1 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER TYPE OF `test`.`t1`.`a` +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 3 +PARAMETER_MODE IN +PARAMETER_NAME b0 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW TYPE OF `t1` +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 4 +PARAMETER_MODE IN +PARAMETER_NAME b1 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW TYPE OF `test`.`t1` +ROUTINE_TYPE PROCEDURE +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME p1 +ORDINAL_POSITION 5 +PARAMETER_MODE IN +PARAMETER_NAME d +DATA_TYPE ROW +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW +ROUTINE_TYPE PROCEDURE +-------- -------- +DROP PROCEDURE p1; +SET sql_mode=DEFAULT; +CREATE FUNCTION f1(a0 TYPE OF t1.a, +a1 TYPE OF test.t1.a, +b0 ROW TYPE OF t1, +b1 ROW TYPE OF test.t1, +d ROW(a INT,b DOUBLE)) +RETURNS INT +BEGIN +RETURN 0; +END; +$$ +SET sql_mode=DEFAULT; +SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 0 +PARAMETER_MODE NULL +PARAMETER_NAME NULL +DATA_TYPE int +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION 10 +NUMERIC_SCALE 0 +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER int(11) +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a0 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER TYPE OF `t1`.`a` +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 2 +PARAMETER_MODE IN +PARAMETER_NAME a1 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER TYPE OF `test`.`t1`.`a` +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 3 +PARAMETER_MODE IN +PARAMETER_NAME b0 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW TYPE OF `t1` +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 4 +PARAMETER_MODE IN +PARAMETER_NAME b1 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW TYPE OF `test`.`t1` +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 5 +PARAMETER_MODE IN +PARAMETER_NAME d +DATA_TYPE ROW +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW +ROUTINE_TYPE FUNCTION +-------- -------- +SET sql_mode=ORACLE; +SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME='f1'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 0 +PARAMETER_MODE NULL +PARAMETER_NAME NULL +DATA_TYPE int +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION 10 +NUMERIC_SCALE 0 +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER int(11) +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a0 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER TYPE OF `t1`.`a` +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 2 +PARAMETER_MODE IN +PARAMETER_NAME a1 +DATA_TYPE TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER TYPE OF `test`.`t1`.`a` +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 3 +PARAMETER_MODE IN +PARAMETER_NAME b0 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW TYPE OF `t1` +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 4 +PARAMETER_MODE IN +PARAMETER_NAME b1 +DATA_TYPE ROW TYPE OF +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW TYPE OF `test`.`t1` +ROUTINE_TYPE FUNCTION +-------- -------- +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA test +SPECIFIC_NAME f1 +ORDINAL_POSITION 5 +PARAMETER_MODE IN +PARAMETER_NAME d +DATA_TYPE ROW +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER ROW +ROUTINE_TYPE FUNCTION +-------- -------- +DROP FUNCTION f1; +# +# MDEV 18092 Query with the table I_S.PARAMETERS stop working +# after a package is created +# +SET sql_mode=ORACLE; +CREATE DATABASE db1_mdev18092; +USE db1_mdev18092; +CREATE PROCEDURE p1(a INT) +AS BEGIN +NULL; +END; +$$ +CREATE OR REPLACE PACKAGE employee_tools AS +FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2); +PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2)); +PROCEDURE raiseSalaryStd(eid INT); +PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2)); +END; +$$ +SELECT *, '---------------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA='db1_mdev18092'; +SPECIFIC_CATALOG def +SPECIFIC_SCHEMA db1_mdev18092 +SPECIFIC_NAME p1 +ORDINAL_POSITION 1 +PARAMETER_MODE IN +PARAMETER_NAME a +DATA_TYPE int +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION 10 +NUMERIC_SCALE 0 +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER int(11) +ROUTINE_TYPE PROCEDURE +--------------- --------------- +DROP DATABASE db1_mdev18092; diff --git a/mysql-test/suite/compat/oracle/r/keywords.result b/mysql-test/suite/compat/oracle/r/keywords.result new file mode 100644 index 00000000..bc9d3d9b --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/keywords.result @@ -0,0 +1,26 @@ +SET sql_mode=ORACLE; +# +# MDEV-17363 Compressed columns cannot be restored from dump +# In sql_mode=ORACLE, COMPRESSED is still valid both as an SP label +# and an SP variable name. +# +BEGIN +IF TRUE THEN +GOTO compressed; +END IF; +SELECT 'This should not be reached' AS warn; +<<compressed>> +BEGIN +SELECT 1 AS a; +END; +END +$$ +a +1 +DECLARE compressed INT DEFAULT 1; +BEGIN +SELECT compressed; +END +$$ +compressed +1 diff --git a/mysql-test/suite/compat/oracle/r/minus.result b/mysql-test/suite/compat/oracle/r/minus.result new file mode 100644 index 00000000..67b7e534 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/minus.result @@ -0,0 +1,48 @@ +CREATE TABLE tx1 (c1 int, c2 varchar(30)); +CREATE TABLE tx2 (c1 int, c2 varchar(30)); +CREATE TABLE tx3 (c1 int, c2 varchar(30)); +INSERT INTO tx1 VALUES (1, 'jim'); +INSERT INTO tx1 VALUES (2, 'menny'); +INSERT INTO tx1 VALUES (3, 'linda'); +INSERT INTO tx2 VALUES (1, 'jim'); +INSERT INTO tx2 VALUES (2, 'kris'); +INSERT INTO tx2 VALUES (3, 'shory'); +INSERT INTO tx3 VALUES (1, 'jim'); +INSERT INTO tx3 VALUES (2, 'kris'); +INSERT INTO tx3 VALUES (3, 'linda'); +# +# test when sql_mode is not oracle +# +SELECT c2 FROM tx1 EXCEPT SELECT c2 from tx2; +c2 +menny +linda +SELECT c2 FROM tx1 MINUS SELECT c2 from tx2; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT c2 from tx2' at line 1 +create table MINUS (a int); +drop table MINUS; +# +# test when sql_mode is oracle +# +SET sql_mode=ORACLE; +SELECT c2 FROM tx1 MINUS SELECT c2 from tx2; +c2 +menny +linda +SELECT c2 FROM tx1 MINUS SELECT c2 from tx2 MINUS SELECT c2 from tx3; +c2 +menny +SELECT c2 FROM tx1 MINUS SELECT c2 from tx2 EXCEPT SELECT c2 from tx3; +c2 +menny +SELECT c2 FROM tx1 MINUS SELECT c2 from tx2 UNION SELECT c2 from tx3; +c2 +jim +menny +linda +kris +create table MINUS (a int); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'MINUS (a int)' at line 1 +DROP TABLE tx1; +DROP TABLE tx2; +DROP TABLE tx3; diff --git a/mysql-test/suite/compat/oracle/r/misc.result b/mysql-test/suite/compat/oracle/r/misc.result new file mode 100644 index 00000000..fed7e26c --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/misc.result @@ -0,0 +1,35 @@ +SET sql_mode=ORACLE; +# +# Start of 10.2 tests +# +# +# MDEV-27690 Crash on `CHARACTER SET csname COLLATE DEFAULT` in column definition +# +CREATE TABLE t1 (a CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT); +DROP TABLE t1; +SELECT CAST('a' AS CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT); +CAST('a' AS CHAR(10) CHARACTER SET latin1 COLLATE DEFAULT) +a +SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET latin1 COLLATE DEFAULT) AS c1; +c1 +string +# +# End of 10.2 tests +# +# +# Start of 10.3 tests +# +# +# MDEV-12086 sql_mode=ORACLE: allow SELECT UNIQUE as a synonym for SELECT DISTINCT +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20),(20),(30),(30),(30); +SELECT UNIQUE a FROM t1; +a +10 +20 +30 +DROP TABLE t1; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/compat/oracle/r/mysqldump_restore.result b/mysql-test/suite/compat/oracle/r/mysqldump_restore.result new file mode 100644 index 00000000..f73fa3a3 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/mysqldump_restore.result @@ -0,0 +1,38 @@ +SET sql_mode=ORACLE; +# +# Start of 10.3 tests +# +# +# MDEV-17363 Compressed columns cannot be restored from dump +# +CREATE TABLE t1 (a VARCHAR(1000) COMPRESSED CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL); +INSERT INTO `t1` VALUES (REPEAT('a', 256)); +# Begin testing mysqldump output + restore +# Create 'original table name - <table>_orig +SET @orig_table_name = CONCAT('test.t1', '_orig'); +# Rename original table +ALTER TABLE test.t1 RENAME to test.t1_orig; +# Recreate table from mysqldump output +# Compare original and recreated tables +# Recreated table: test.t1 +# Original table: test.t1_orig +include/diff_tables.inc [test.t1, test.t1_orig] +# Cleanup +DROP TABLE test.t1, test.t1_orig; +CREATE TABLE t1 (a LONGTEXT COMPRESSED CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL); +INSERT INTO `t1` VALUES (REPEAT('a', 256)); +# Begin testing mysqldump output + restore +# Create 'original table name - <table>_orig +SET @orig_table_name = CONCAT('test.t1', '_orig'); +# Rename original table +ALTER TABLE test.t1 RENAME to test.t1_orig; +# Recreate table from mysqldump output +# Compare original and recreated tables +# Recreated table: test.t1 +# Original table: test.t1_orig +include/diff_tables.inc [test.t1, test.t1_orig] +# Cleanup +DROP TABLE test.t1, test.t1_orig; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/compat/oracle/r/parser.result b/mysql-test/suite/compat/oracle/r/parser.result new file mode 100644 index 00000000..32ea444e --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/parser.result @@ -0,0 +1,870 @@ +SET sql_mode=ORACLE; +# +# MDEV-15620 Crash when using "SET @@NEW.a=expr" inside a trigger +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @@NEW.a=0; +ERROR HY000: Unknown structured system variable or ROW routine variable 'NEW' +DROP TABLE t1; +# +# MDEV-15615 Unexpected syntax error instead of "Unknown system variable" inside an SP +# +DECLARE +a INT; +BEGIN +SET GLOBAL a=10; +END; +$$ +ERROR HY000: Unknown system variable 'a' +# +# MDEV-16202 Latest changes made erroneously some keywords reserved in sql_mode=ORACLE +# +CREATE PROCEDURE p1(name VARCHAR(64), pattern TEXT) AS +query TEXT DEFAULT REPLACE(pattern, 'name', name); +BEGIN +SELECT query AS ''; +EXECUTE IMMEDIATE query; +EXCEPTION +WHEN OTHERS THEN +BEGIN +SHOW ERRORS; +END; +END; +$$ +CREATE PROCEDURE p2(name VARCHAR(64)) AS +BEGIN +CALL p1(name, 'DECLARE name INT; BEGIN name:=10; SELECT name; END'); +EXECUTE IMMEDIATE REPLACE('CREATE TABLE t1 (name INT)', 'name', name); +CALL p1(name, 'SELECT name FROM t1'); +CALL p1(name, 'SELECT name ''alias'' FROM t1'); +CALL p1(name, 'SELECT name()'); +CALL p1(name, 'SELECT name.name()'); +CALL p1(name, 'SELECT name DATE FROM t1'); +CALL p1(name, 'SELECT name HISTORY FROM t1'); +CALL p1(name, 'SELECT name NEXT FROM t1'); +CALL p1(name, 'SELECT name PERIOD FROM t1'); +CALL p1(name, 'SELECT name PREVIOUS FROM t1'); +CALL p1(name, 'SELECT name SYSTEM FROM t1'); +CALL p1(name, 'SELECT name SYSTEM_TIME FROM t1'); +CALL p1(name, 'SELECT name TIME FROM t1'); +CALL p1(name, 'SELECT name TIMESTAMP FROM t1'); +CALL p1(name, 'SELECT name TRANSACTION FROM t1'); +CALL p1(name, 'SELECT name VALUE FROM t1'); +CALL p1(name, 'SELECT name VERSIONING FROM t1'); +CALL p1(name, 'SELECT name WITHOUT FROM t1'); +DROP TABLE t1; +END; +$$ +CALL p2('date'); +DECLARE date INT; BEGIN date:=10; SELECT date; END +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INT; BEGIN date:=10; SELECT date; END' at line 1 +SELECT date FROM t1 +SELECT date 'alias' FROM t1 +Error 1525 Incorrect DATE value: 'alias' +SELECT date() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +SELECT date.date() +Error 1630 FUNCTION date.date does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT date DATE FROM t1 +SELECT date HISTORY FROM t1 +SELECT date NEXT FROM t1 +SELECT date PERIOD FROM t1 +SELECT date PREVIOUS FROM t1 +SELECT date SYSTEM FROM t1 +SELECT date SYSTEM_TIME FROM t1 +SELECT date TIME FROM t1 +SELECT date TIMESTAMP FROM t1 +SELECT date TRANSACTION FROM t1 +SELECT date VALUE FROM t1 +SELECT date VERSIONING FROM t1 +SELECT date WITHOUT FROM t1 +CALL p2('history'); +DECLARE history INT; BEGIN history:=10; SELECT history; END +10 +SELECT history FROM t1 +SELECT history 'alias' FROM t1 +SELECT history() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT history.history() +Error 1630 FUNCTION history.history does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT history DATE FROM t1 +SELECT history HISTORY FROM t1 +SELECT history NEXT FROM t1 +SELECT history PERIOD FROM t1 +SELECT history PREVIOUS FROM t1 +SELECT history SYSTEM FROM t1 +SELECT history SYSTEM_TIME FROM t1 +SELECT history TIME FROM t1 +SELECT history TIMESTAMP FROM t1 +SELECT history TRANSACTION FROM t1 +SELECT history VALUE FROM t1 +SELECT history VERSIONING FROM t1 +SELECT history WITHOUT FROM t1 +CALL p2('next'); +DECLARE next INT; BEGIN next:=10; SELECT next; END +10 +SELECT next FROM t1 +SELECT next 'alias' FROM t1 +SELECT next() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT next.next() +Error 1630 FUNCTION next.next does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT next DATE FROM t1 +SELECT next HISTORY FROM t1 +SELECT next NEXT FROM t1 +SELECT next PERIOD FROM t1 +SELECT next PREVIOUS FROM t1 +SELECT next SYSTEM FROM t1 +SELECT next SYSTEM_TIME FROM t1 +SELECT next TIME FROM t1 +SELECT next TIMESTAMP FROM t1 +SELECT next TRANSACTION FROM t1 +SELECT next VALUE FROM t1 +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FROM t1' at line 1 +SELECT next VERSIONING FROM t1 +SELECT next WITHOUT FROM t1 +CALL p2('period'); +DECLARE period INT; BEGIN period:=10; SELECT period; END +10 +SELECT period FROM t1 +SELECT period 'alias' FROM t1 +SELECT period() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT period.period() +Error 1630 FUNCTION period.period does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT period DATE FROM t1 +SELECT period HISTORY FROM t1 +SELECT period NEXT FROM t1 +SELECT period PERIOD FROM t1 +SELECT period PREVIOUS FROM t1 +SELECT period SYSTEM FROM t1 +SELECT period SYSTEM_TIME FROM t1 +SELECT period TIME FROM t1 +SELECT period TIMESTAMP FROM t1 +SELECT period TRANSACTION FROM t1 +SELECT period VALUE FROM t1 +SELECT period VERSIONING FROM t1 +SELECT period WITHOUT FROM t1 +CALL p2('previous'); +DECLARE previous INT; BEGIN previous:=10; SELECT previous; END +10 +SELECT previous FROM t1 +SELECT previous 'alias' FROM t1 +SELECT previous() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT previous.previous() +Error 1630 FUNCTION previous.previous does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT previous DATE FROM t1 +SELECT previous HISTORY FROM t1 +SELECT previous NEXT FROM t1 +SELECT previous PERIOD FROM t1 +SELECT previous PREVIOUS FROM t1 +SELECT previous SYSTEM FROM t1 +SELECT previous SYSTEM_TIME FROM t1 +SELECT previous TIME FROM t1 +SELECT previous TIMESTAMP FROM t1 +SELECT previous TRANSACTION FROM t1 +SELECT previous VALUE FROM t1 +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FROM t1' at line 1 +SELECT previous VERSIONING FROM t1 +SELECT previous WITHOUT FROM t1 +CALL p2('system'); +DECLARE system INT; BEGIN system:=10; SELECT system; END +10 +SELECT system FROM t1 +SELECT system 'alias' FROM t1 +SELECT system() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT system.system() +Error 1630 FUNCTION system.system does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT system DATE FROM t1 +SELECT system HISTORY FROM t1 +SELECT system NEXT FROM t1 +SELECT system PERIOD FROM t1 +SELECT system PREVIOUS FROM t1 +SELECT system SYSTEM FROM t1 +SELECT system SYSTEM_TIME FROM t1 +SELECT system TIME FROM t1 +SELECT system TIMESTAMP FROM t1 +SELECT system TRANSACTION FROM t1 +SELECT system VALUE FROM t1 +SELECT system VERSIONING FROM t1 +SELECT system WITHOUT FROM t1 +CALL p2('system_time'); +DECLARE system_time INT; BEGIN system_time:=10; SELECT system_time; END +10 +SELECT system_time FROM t1 +SELECT system_time 'alias' FROM t1 +SELECT system_time() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT system_time.system_time() +Error 1630 FUNCTION system_time.system_time does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT system_time DATE FROM t1 +SELECT system_time HISTORY FROM t1 +SELECT system_time NEXT FROM t1 +SELECT system_time PERIOD FROM t1 +SELECT system_time PREVIOUS FROM t1 +SELECT system_time SYSTEM FROM t1 +SELECT system_time SYSTEM_TIME FROM t1 +SELECT system_time TIME FROM t1 +SELECT system_time TIMESTAMP FROM t1 +SELECT system_time TRANSACTION FROM t1 +SELECT system_time VALUE FROM t1 +SELECT system_time VERSIONING FROM t1 +SELECT system_time WITHOUT FROM t1 +CALL p2('time'); +DECLARE time INT; BEGIN time:=10; SELECT time; END +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INT; BEGIN time:=10; SELECT time; END' at line 1 +SELECT time FROM t1 +SELECT time 'alias' FROM t1 +Error 1525 Incorrect TIME value: 'alias' +SELECT time() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +SELECT time.time() +Error 1630 FUNCTION time.time does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT time DATE FROM t1 +SELECT time HISTORY FROM t1 +SELECT time NEXT FROM t1 +SELECT time PERIOD FROM t1 +SELECT time PREVIOUS FROM t1 +SELECT time SYSTEM FROM t1 +SELECT time SYSTEM_TIME FROM t1 +SELECT time TIME FROM t1 +SELECT time TIMESTAMP FROM t1 +SELECT time TRANSACTION FROM t1 +SELECT time VALUE FROM t1 +SELECT time VERSIONING FROM t1 +SELECT time WITHOUT FROM t1 +CALL p2('timestamp'); +DECLARE timestamp INT; BEGIN timestamp:=10; SELECT timestamp; END +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INT; BEGIN timestamp:=10; SELECT timestamp; END' at line 1 +SELECT timestamp FROM t1 +SELECT timestamp 'alias' FROM t1 +Error 1525 Incorrect DATETIME value: 'alias' +SELECT timestamp() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +SELECT timestamp.timestamp() +Error 1630 FUNCTION timestamp.timestamp does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT timestamp DATE FROM t1 +SELECT timestamp HISTORY FROM t1 +SELECT timestamp NEXT FROM t1 +SELECT timestamp PERIOD FROM t1 +SELECT timestamp PREVIOUS FROM t1 +SELECT timestamp SYSTEM FROM t1 +SELECT timestamp SYSTEM_TIME FROM t1 +SELECT timestamp TIME FROM t1 +SELECT timestamp TIMESTAMP FROM t1 +SELECT timestamp TRANSACTION FROM t1 +SELECT timestamp VALUE FROM t1 +SELECT timestamp VERSIONING FROM t1 +SELECT timestamp WITHOUT FROM t1 +CALL p2('transaction'); +DECLARE transaction INT; BEGIN transaction:=10; SELECT transaction; END +10 +SELECT transaction FROM t1 +SELECT transaction 'alias' FROM t1 +SELECT transaction() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT transaction.transaction() +Error 1630 FUNCTION transaction.transaction does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT transaction DATE FROM t1 +SELECT transaction HISTORY FROM t1 +SELECT transaction NEXT FROM t1 +SELECT transaction PERIOD FROM t1 +SELECT transaction PREVIOUS FROM t1 +SELECT transaction SYSTEM FROM t1 +SELECT transaction SYSTEM_TIME FROM t1 +SELECT transaction TIME FROM t1 +SELECT transaction TIMESTAMP FROM t1 +SELECT transaction TRANSACTION FROM t1 +SELECT transaction VALUE FROM t1 +SELECT transaction VERSIONING FROM t1 +SELECT transaction WITHOUT FROM t1 +CALL p2('value'); +DECLARE value INT; BEGIN value:=10; SELECT value; END +10 +SELECT value FROM t1 +SELECT value 'alias' FROM t1 +SELECT value() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +SELECT value.value() +Error 1630 FUNCTION value.value does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT value DATE FROM t1 +SELECT value HISTORY FROM t1 +SELECT value NEXT FROM t1 +SELECT value PERIOD FROM t1 +SELECT value PREVIOUS FROM t1 +SELECT value SYSTEM FROM t1 +SELECT value SYSTEM_TIME FROM t1 +SELECT value TIME FROM t1 +SELECT value TIMESTAMP FROM t1 +SELECT value TRANSACTION FROM t1 +SELECT value VALUE FROM t1 +SELECT value VERSIONING FROM t1 +SELECT value WITHOUT FROM t1 +CALL p2('versioning'); +DECLARE versioning INT; BEGIN versioning:=10; SELECT versioning; END +10 +SELECT versioning FROM t1 +SELECT versioning 'alias' FROM t1 +SELECT versioning() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT versioning.versioning() +Error 1630 FUNCTION versioning.versioning does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT versioning DATE FROM t1 +SELECT versioning HISTORY FROM t1 +SELECT versioning NEXT FROM t1 +SELECT versioning PERIOD FROM t1 +SELECT versioning PREVIOUS FROM t1 +SELECT versioning SYSTEM FROM t1 +SELECT versioning SYSTEM_TIME FROM t1 +SELECT versioning TIME FROM t1 +SELECT versioning TIMESTAMP FROM t1 +SELECT versioning TRANSACTION FROM t1 +SELECT versioning VALUE FROM t1 +SELECT versioning VERSIONING FROM t1 +SELECT versioning WITHOUT FROM t1 +CALL p2('without'); +DECLARE without INT; BEGIN without:=10; SELECT without; END +10 +SELECT without FROM t1 +SELECT without 'alias' FROM t1 +SELECT without() +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '()' at line 1 +SELECT without.without() +Error 1630 FUNCTION without.without does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual +SELECT without DATE FROM t1 +SELECT without HISTORY FROM t1 +SELECT without NEXT FROM t1 +SELECT without PERIOD FROM t1 +SELECT without PREVIOUS FROM t1 +SELECT without SYSTEM FROM t1 +SELECT without SYSTEM_TIME FROM t1 +SELECT without TIME FROM t1 +SELECT without TIMESTAMP FROM t1 +SELECT without TRANSACTION FROM t1 +SELECT without VALUE FROM t1 +SELECT without VERSIONING FROM t1 +SELECT without WITHOUT FROM t1 +DROP PROCEDURE p2; +DROP PROCEDURE p1; +# +# MDEV-16244 sql_mode=ORACLE: Some keywords do not work in variable declarations +# +SET sql_mode=ORACLE; +DECLARE +do INT; +BEGIN +SELECT do INTO do FROM DUAL; +END; +/ +DECLARE +handler INT; +BEGIN +SELECT handler INTO handler FROM DUAL; +END; +/ +DECLARE +repair INT; +BEGIN +SELECT repair INTO repair FROM DUAL; +END; +/ +DECLARE +shutdown INT; +BEGIN +SELECT shutdown INTO shutdown FROM DUAL; +END; +/ +DECLARE +truncate INT; +BEGIN +SELECT truncate INTO truncate FROM DUAL; +END; +/ +DECLARE +close INT; +BEGIN +SELECT close INTO close FROM DUAL; +END; +/ +DECLARE +commit INT; +BEGIN +SELECT commit INTO commit FROM DUAL; +END; +/ +DECLARE +open INT; +BEGIN +SELECT open INTO open FROM DUAL; +END; +/ +DECLARE +rollback INT; +BEGIN +SELECT rollback INTO rollback FROM DUAL; +END; +/ +DECLARE +savepoint INT; +BEGIN +SELECT savepoint INTO savepoint FROM DUAL; +END; +/ +DECLARE +contains INT; +BEGIN +SELECT contains INTO contains FROM DUAL; +END; +/ +DECLARE +language INT; +BEGIN +SELECT language INTO language FROM DUAL; +END; +/ +DECLARE +no INT; +BEGIN +SELECT no INTO no FROM DUAL; +END; +/ +DECLARE +charset INT; +BEGIN +SELECT charset INTO charset FROM DUAL; +END; +/ +DECLARE +follows INT; +BEGIN +SELECT follows INTO follows FROM DUAL; +END; +/ +DECLARE +precedes INT; +BEGIN +SELECT precedes INTO precedes FROM DUAL; +END; +/ +# +# MDEV-16464 Oracle Comp.: Sql-Error on "SELECT name, comment FROM mysql.proc" +# +SET sql_mode=ORACLE; +SELECT name, comment FROM mysql.proc WHERE db='test'; +name comment +CREATE TABLE comment (comment INT); +SELECT comment FROM comment; +comment +SELECT comment comment FROM comment comment; +comment +SELECT comment AS comment FROM comment AS comment; +comment +DROP TABLE comment; +DECLARE +comment INT; +BEGIN +SELECT comment INTO comment FROM DUAL; +END; +/ +CREATE PROCEDURE comment COMMENT 'test' AS +BEGIN +SELECT 1; +END; +/ +BEGIN +comment; +END; +/ +1 +1 +CALL comment(); +1 +1 +CALL comment; +1 +1 +DROP PROCEDURE comment; +CREATE FUNCTION comment RETURN INT COMMENT 'test' AS +BEGIN +RETURN 1; +END; +/ +Warnings: +Note 1585 This function 'comment' has the same name as a native function +SELECT test.comment() FROM DUAL; +test.comment() +1 +Warnings: +Note 1585 This function 'comment' has the same name as a native function +DROP FUNCTION comment; +# +# MDEV-17660 sql_mode=ORACLE: Some keywords do not work as label names: history, system, versioning, without +# +BEGIN +<<date_format>> +NULL; +END; +/ +BEGIN +<<decode>> +NULL; +END; +/ +BEGIN +<<history>> +NULL; +END; +/ +BEGIN +<<system>> +NULL; +END; +/ +BEGIN +<<versioning>> +NULL; +END; +/ +BEGIN +<<without>> +NULL; +END; +/ +# +# MDEV-17666 sql_mode=ORACLE: Keyword ELSEIF should not be reserved +# +DECLARE +ELSEIF INT; +BEGIN +ELSEIF:=1; +END; +/ +BEGIN +<<ELSEIF>> +NULL; +END; +/ +# +# MDEV-17693 Shift/reduce conflicts for NAMES,ROLE,PASSWORD in the option_value_no_option_type grammar +# +CREATE TABLE names (names INT); +SELECT names FROM names AS names; +names +DROP TABLE names; +CREATE TABLE password (password INT); +SELECT password FROM password AS password; +password +DROP TABLE password; +CREATE TABLE role (role INT); +SELECT role FROM role AS role; +role +DROP TABLE role; +DECLARE +names VARCHAR(32) DEFAULT '[names]'; +password VARCHAR(32) DEFAULT '[password]'; +role VARCHAR(32) DEFAULT '[role]'; +BEGIN +<<names>> +SELECT names; +<<password>> +SELECT password; +<<role>> +SELECT role; +END; +$$ +names +[names] +password +[password] +role +[role] +DECLARE +names VARCHAR(32); +BEGIN +SET names='[names]'; +END; +$$ +ERROR 42000: Variable 'names' must be quoted with `...`, or renamed +DECLARE +password VARCHAR(32); +BEGIN +SET password='[password]'; +END; +$$ +ERROR 42000: Variable 'password' must be quoted with `...`, or renamed +DECLARE +role VARCHAR(32); +BEGIN +SET role='[role]'; +END; +$$ +SELECT @@GLOBAL.names; +ERROR HY000: Unknown system variable 'names' +SELECT @@GLOBAL.password; +ERROR HY000: Unknown system variable 'password' +SELECT @@GLOBAL.role; +ERROR HY000: Unknown system variable 'role' +# +# MDEV-22822 sql_mode="oracle" cannot declare without variable errors +# +# It's OK to have no declarations between DECLARE and BEGIN. +# +BEGIN +DECLARE +BEGIN +NULL; +END; +EXCEPTION +WHEN OTHERS THEN +NULL; +END; +// +DECLARE +BEGIN +NULL; +EXCEPTION +WHEN OTHERS THEN +NULL; +END; +// +BEGIN +<<lab>> +DECLARE +BEGIN +NULL; +END; +EXCEPTION +WHEN OTHERS THEN +NULL; +END; +// +# +# End of 10.3 tests +# +# +# MDEV-21998: Server crashes in st_select_lex::add_table_to_list +# upon mix of KILL and sequences +# +KILL ( SELECT 1 ) + LASTVAL(s); +ERROR 42000: KILL does not support subqueries or stored functions +KILL LASTVAL(s); +ERROR 42000: KILL does not support subqueries or stored functions +# +# MDEV-23094: Multiple calls to a Stored Procedure from another +# Stored Procedure crashes server +# +create table t1 (id1 int primary key, data1 int); +create table t2 (id2 int primary key, data2 int); +create procedure p1(id int,dt int) as +begin +if (exists(select * from t1 where id1 = id and data1 = dt) or +not exists (select * from t2 where id2 = id and data2 = dt)) +then +select 1; +end if; +end // +call p1(1,2); +1 +1 +call p1(1,2); +1 +1 +drop procedure p1; +create procedure p1(id int, dt int) as +begin +case (exists(select * from t1 where id1 = id and data1 = dt) or +not exists (select * from t2 where id2 = id and data2 = dt)) +when 1 then +select 1; +else +select 0; +end case; +end // +call p1(1,2); +1 +1 +call p1(1,2); +1 +1 +drop procedure p1; +create procedure p1(id int, dt int) as +begin +declare wcont int default 1; +begin +while (exists(select * from t1 where id1 = id and data1 = dt) or +not exists (select * from t2 where id2 = id and data2 = dt)) and wcont +loop +select 1; +set wcont=0; +end loop; +end; +end // +call p1(1,2); +1 +1 +call p1(1,2); +1 +1 +drop procedure p1; +create procedure p1(id int, dt int) as +begin +declare count int default 1; +begin +repeat +select 1; +set count=count+1; +until (exists(select * from t1 where id1 = id and data1 = dt) or +not exists (select * from t2 where id2 = id and data2 = dt)) and +count < 3 +end repeat; +end; +end // +call p1(1,2); +1 +1 +call p1(1,2); +1 +1 +drop procedure p1; +create procedure p1(id int, dt int) as +begin +for i in 1..(exists(select * from t1 where id1 = id and data1 = dt) or +not exists (select * from t2 where id2 = id and data2 = dt)) +loop +select 1; +end loop; +end // +call p1(1,2); +1 +1 +call p1(1,2); +1 +1 +drop procedure p1; +set sql_mode=ORACLE; +create or replace procedure p1(id int, dt int) as +begin +while (1) +loop +exit when (exists(select * from t1 where id1 = id and data1 = dt) or +not exists (select * from t2 where id2 = id and data2 = dt)); +end loop; +end; +// +call p1(1,2); +call p1(1,2); +drop procedure p1; +drop table t1,t2; +# End of 10.4 tests +# +# Start of 10.5 tests +# +# +# MDEV-20734 Allow reserved keywords as user defined type names +# +CREATE TABLE t1 (a DUAL); +ERROR HY000: Unknown data type: 'DUAL' +SELECT CAST(1 AS DUAL); +ERROR HY000: Unknown data type: 'DUAL' +# +# MDEV-20735 Allow non-reserved keywords as user defined type names +# +CREATE TABLE t1 (a ASCII); +ERROR HY000: Unknown data type: 'ASCII' +SELECT CAST(1 AS ASCII); +ERROR HY000: Unknown data type: 'ASCII' +CREATE TABLE t1 (a LANGUAGE); +ERROR HY000: Unknown data type: 'LANGUAGE' +SELECT CAST(1 AS LANGUAGE); +ERROR HY000: Unknown data type: 'LANGUAGE' +CREATE TABLE t1 (a CLOSE); +ERROR HY000: Unknown data type: 'CLOSE' +SELECT CAST(1 AS CLOSE); +ERROR HY000: Unknown data type: 'CLOSE' +CREATE TABLE t1 (a NAMES); +ERROR HY000: Unknown data type: 'NAMES' +SELECT CAST(1 AS NAMES); +ERROR HY000: Unknown data type: 'NAMES' +CREATE TABLE t1 (a END); +ERROR HY000: Unknown data type: 'END' +SELECT CAST(1 AS END); +ERROR HY000: Unknown data type: 'END' +CREATE TABLE t1 (a GLOBAL); +ERROR HY000: Unknown data type: 'GLOBAL' +SELECT CAST(1 AS GLOBAL); +ERROR HY000: Unknown data type: 'GLOBAL' +CREATE TABLE t1 (a ACTION); +ERROR HY000: Unknown data type: 'ACTION' +SELECT CAST(1 AS ACTION); +ERROR HY000: Unknown data type: 'ACTION' +CREATE TABLE t1 (a BEGIN); +ERROR HY000: Unknown data type: 'BEGIN' +SELECT CAST(1 AS BEGIN); +ERROR HY000: Unknown data type: 'BEGIN' +# +# End of 10.5 tests +# +# +# Start of 10.6 tests +# +# +# MDEV-19682 sql_mode="oracle" does not support sysdate +# +SELECT sysdate LIKE '____-__-__ __:__:__'; +sysdate LIKE '____-__-__ __:__:__' +1 +SELECT sysdate = sysdate(); +sysdate = sysdate() +1 +SELECT sysdate = sysdate(0); +sysdate = sysdate(0) +1 +CREATE DATABASE sysdate; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sysdate' at line 1 +CREATE TABLE sysdate (a INT); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sysdate (a INT)' at line 1 +CREATE TABLE t1 (sysdate INT); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sysdate INT)' at line 1 +CREATE TABLE t1 (a sysdate); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sysdate)' at line 1 +CREATE FUNCTION sysdate RETURN INT AS +BEGIN +RETURN 1; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sysdate RETURN INT AS +BEGIN +RETURN 1; +END' at line 1 +CREATE FUNCTION sysdate() RETURN INT AS +BEGIN +RETURN 1; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sysdate() RETURN INT AS +BEGIN +RETURN 1; +END' at line 1 +DECLARE +sysdate INT := 10; +BEGIN +NULL; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sysdate INT := 10; +BEGIN +NULL; +END' at line 2 +BEGIN +<<sysdate>> +NULL; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sysdate>> +NULL; +END' at line 2 +# +# End of 10.6 tests +# diff --git a/mysql-test/suite/compat/oracle/r/plugin.result b/mysql-test/suite/compat/oracle/r/plugin.result new file mode 100644 index 00000000..c885c03e --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/plugin.result @@ -0,0 +1,48 @@ +SET sql_mode=ORACLE; +# +# MDEV-16294: INSTALL PLUGIN IF NOT EXISTS / UNINSTALL PLUGIN IF EXISTS +# +# INSTALL IF NOT EXISTS PLUGIN name SONAME library / +# UNINSTALL IF EXISTS PLUGIN|SONAME name +# +select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%'; +PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE +INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example'; +select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%'; +PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE +EXAMPLE ACTIVE STORAGE ENGINE +INSTALL PLUGIN example SONAME 'ha_example'; +ERROR HY000: Plugin 'example' already installed +INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example'; +Warnings: +Note 1968 Plugin 'example' already installed +SHOW WARNINGS; +Level Code Message +Note 1968 Plugin 'example' already installed +UNINSTALL PLUGIN IF EXISTS example; +select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%'; +PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE +UNINSTALL PLUGIN IF EXISTS example; +Warnings: +Note 1305 PLUGIN example does not exist +SHOW WARNINGS; +Level Code Message +Note 1305 PLUGIN example does not exist +UNINSTALL PLUGIN example; +ERROR 42000: PLUGIN example does not exist +INSTALL SONAME 'ha_example'; +select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%'; +PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE +EXAMPLE ACTIVE STORAGE ENGINE +UNUSABLE ACTIVE DAEMON +UNINSTALL SONAME IF EXISTS 'ha_example'; +UNINSTALL SONAME IF EXISTS 'ha_example'; +Warnings: +Note 1305 SONAME ha_example.so does not exist +SHOW WARNINGS; +Level Code Message +Note 1305 SONAME ha_example.so does not exist +select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%'; +PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE +UNINSTALL SONAME 'ha_example'; +ERROR 42000: SONAME ha_example.so does not exist diff --git a/mysql-test/suite/compat/oracle/r/ps.result b/mysql-test/suite/compat/oracle/r/ps.result new file mode 100644 index 00000000..818c97b0 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/ps.result @@ -0,0 +1,264 @@ +SET sql_mode=ORACLE; +# +# MDEV-10801 sql_mode: dynamic SQL placeholders +# +SET @a=10, @b=20; +PREPARE stmt FROM 'SELECT ?,?'; +EXECUTE stmt USING @a, @b; +? ? +10 20 +PREPARE stmt FROM 'SELECT :a,:b'; +EXECUTE stmt USING @a, @b; +:a :b +10 20 +PREPARE stmt FROM 'SELECT :aaa,:bbb'; +EXECUTE stmt USING @a, @b; +:aaa :bbb +10 20 +PREPARE stmt FROM 'SELECT :"a",:"b"'; +EXECUTE stmt USING @a, @b; +:"a" :"b" +10 20 +PREPARE stmt FROM 'SELECT :"aaa",:"bbb"'; +EXECUTE stmt USING @a, @b; +:"aaa" :"bbb" +10 20 +PREPARE stmt FROM 'SELECT :1,:2'; +EXECUTE stmt USING @a, @b; +:1 :2 +10 20 +PREPARE stmt FROM 'SELECT :222,:111'; +EXECUTE stmt USING @a, @b; +:222 :111 +10 20 +PREPARE stmt FROM 'SELECT :0,:65535'; +EXECUTE stmt USING @a, @b; +:0 :65535 +10 20 +PREPARE stmt FROM 'SELECT :65535,:0'; +EXECUTE stmt USING @a, @b; +:65535 :0 +10 20 +# +# MDEV-10709 Expressions as parameters to Dynamic SQL +# +# +# Testing disallowed expressions in USING +# +PREPARE stmt FROM 'SELECT :1 FROM DUAL'; +EXECUTE stmt USING (SELECT 1); +ERROR 42000: EXECUTE..USING does not support subqueries or stored functions +DEALLOCATE PREPARE stmt; +CREATE FUNCTION f1() RETURN VARCHAR +AS +BEGIN +RETURN 'test'; +END; +$$ +PREPARE stmt FROM 'SELECT ? FROM DUAL'; +EXECUTE stmt USING f1(); +ERROR 42000: EXECUTE..USING does not support subqueries or stored functions +DEALLOCATE PREPARE stmt; +DROP FUNCTION f1; +# +# Using a user variable as a EXECUTE..USING out parameter +# +CREATE PROCEDURE p1(a OUT INT) +AS +BEGIN +a:= 10; +END; +/ +SET @a=1; +CALL p1(@a); +SELECT @a; +@a +10 +SET @a=2; +PREPARE stmt FROM 'CALL p1(?)'; +EXECUTE stmt USING @a; +SELECT @a; +@a +10 +DROP PROCEDURE p1; +# +# Using an SP variable as a EXECUTE..USING out parameter +# +CREATE PROCEDURE p1 (a OUT INT) +AS +BEGIN +a:=10; +END; +/ +CREATE PROCEDURE p2 (a OUT INT) +AS +BEGIN +PREPARE stmt FROM 'CALL p1(?)'; +EXECUTE stmt USING a; +END; +/ +SET @a= 1; +CALL p2(@a); +SELECT @a; +@a +10 +DROP PROCEDURE p2; +DROP PROCEDURE p1; +# +# Using a trigger field as a EXECUTE..USING out parameter +# +CREATE PROCEDURE p1 (a OUT INT) +AS +BEGIN +a:= 10; +END; +/ +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW CALL p1(:NEW.a); +INSERT INTO t1 VALUES (1); +SELECT * FROM t1; +a +10 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Testing re-prepare on a table metadata update between PREPARE and EXECUTE +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1(a IN INT) +AS +BEGIN +INSERT INTO t1 VALUES (a); +END; +/ +PREPARE stmt FROM 'CALL p1(?)'; +EXECUTE stmt USING 10; +SELECT * FROM t1; +a +10 +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW NEW.a:=NEW.a+1; +EXECUTE stmt USING 20; +SELECT * FROM t1; +a +10 +21 +DEALLOCATE PREPARE stmt; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# End of MDEV-10709 Expressions as parameters to Dynamic SQL +# +# +# MDEV-10585 EXECUTE IMMEDIATE statement +# +# +# Testing disallowed expressions in USING +# +EXECUTE IMMEDIATE 'SELECT :1 FROM DUAL' USING (SELECT 1); +ERROR 42000: EXECUTE..USING does not support subqueries or stored functions +CREATE FUNCTION f1() RETURN VARCHAR +AS +BEGIN +RETURN 'test'; +END; +$$ +EXECUTE IMMEDIATE 'SELECT ? FROM DUAL' USING f1(); +ERROR 42000: EXECUTE IMMEDIATE does not support subqueries or stored functions +DROP FUNCTION f1; +# +# Testing simple expressions +# +EXECUTE IMMEDIATE 'SELECT :1 FROM DUAL' USING 10; +:1 +10 +# +# MDEV-10866 Extend PREPARE and EXECUTE IMMEDIATE to understand expressions +# +# +# Testing erroneous and diallowed prepare source +# +EXECUTE IMMEDIATE _latin1'SELECT 1 AS c FROM ' || _latin2 'DUAL'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat_operator_oracle' +PREPARE stmt FROM _latin1'SELECT 1 AS c FROM ' || _latin2 'DUAL'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat_operator_oracle' +EXECUTE IMMEDIATE (SELECT 'SELECT 1'); +ERROR 42000: EXECUTE IMMEDIATE does not support subqueries or stored functions +PREPARE stmt FROM (SELECT 'SELECT 1'); +ERROR 42000: PREPARE..FROM does not support subqueries or stored functions +EXECUTE IMMEDIATE a; +ERROR 42S22: Unknown column 'a' in 'field list' +PREPARE stmt FROM a; +ERROR 42S22: Unknown column 'a' in 'field list' +EXECUTE IMMEDIATE NULL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL' at line 1 +PREPARE stmt FROM NULL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL' at line 1 +EXECUTE IMMEDIATE COALESCE(NULL); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL' at line 1 +PREPARE stmt FROM COALESCE(NULL); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL' at line 1 +CREATE FUNCTION f1() RETURN VARCHAR +AS +BEGIN +RETURN 't1'; +END; +$$ +EXECUTE IMMEDIATE f1(); +ERROR 42000: EXECUTE IMMEDIATE does not support subqueries or stored functions +PREPARE stmt FROM f1(); +ERROR 42000: PREPARE..FROM does not support subqueries or stored functions +DROP FUNCTION f1; +# +# Testing user variables in prepare source +# +SET @table_name='DUAL'; +EXECUTE IMMEDIATE 'SELECT 1 AS a FROM ' || @table_name; +a +1 +PREPARE stmt FROM 'SELECT 1 AS a FROM ' || @table_name; +EXECUTE stmt; +a +1 +DEALLOCATE PREPARE stmt; +# +# Testing SP parameters and variables in prepare source +# +CREATE PROCEDURE p1(table_name VARCHAR) +AS +BEGIN +EXECUTE IMMEDIATE 'SELECT 1 AS c FROM '|| table_name; +END; +$$ +CALL p1('DUAL'); +c +1 +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +table_name VARCHAR(64):='DUAL'; +BEGIN +EXECUTE IMMEDIATE 'SELECT 1 AS c FROM ' || table_name; +END; +$$ +CALL p1(); +c +1 +DROP PROCEDURE p1; +# +# End of MDEV-10866 Extend PREPARE and EXECUTE IMMEDIATE to understand expressions +# +# +# MDEV-12846 sql_mode=ORACLE: using Oracle-style placeholders in direct query execution makes the server crash +# +SELECT ? FROM DUAL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '? FROM DUAL' at line 1 +SELECT :a FROM DUAL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':a FROM DUAL' at line 1 +SELECT :1 FROM DUAL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':1 FROM DUAL' at line 1 +SELECT 1+? FROM DUAL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '? FROM DUAL' at line 1 +SELECT 1+:a FROM DUAL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':a FROM DUAL' at line 1 +SELECT 1+:1 FROM DUAL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':1 FROM DUAL' at line 1 diff --git a/mysql-test/suite/compat/oracle/r/rpl_mariadb_date.result b/mysql-test/suite/compat/oracle/r/rpl_mariadb_date.result new file mode 100644 index 00000000..55da2b74 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/rpl_mariadb_date.result @@ -0,0 +1,86 @@ +include/master-slave.inc +[connection master] +SET SQL_MODE=DEFAULT; +CREATE TABLE t1 (a DATE); +INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 VALUES ('2001-01-01'); +SET SQL_MODE= ORACLE; +CREATE TABLE t2 SELECT * FROM t1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a DATE) +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (NULL) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES ('2001-01-01') +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE "t2" ( + "a" mariadb_schema.date DEFAULT NULL +) +master-bin.000001 # Annotate_rows # # CREATE TABLE t2 SELECT * FROM t1 +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +SET SQL_MODE= DEFAULT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SET SQL_MODE= ORACLE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mariadb_schema.date DEFAULT NULL +) +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" mariadb_schema.date DEFAULT NULL +) +connection slave; +SELECT * FROM t1; +a +NULL +2001-01-01 +SELECT * FROM t2; +a +NULL +2001-01-01 +SET SQL_MODE= DEFAULT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SET SQL_MODE= ORACLE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mariadb_schema.date DEFAULT NULL +) +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" mariadb_schema.date DEFAULT NULL +) +connection master; +DROP TABLE t1, t2; +include/rpl_end.inc diff --git a/mysql-test/suite/compat/oracle/r/rpl_sp_package.result b/mysql-test/suite/compat/oracle/r/rpl_sp_package.result new file mode 100644 index 00000000..4c499526 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/rpl_sp_package.result @@ -0,0 +1,195 @@ +include/master-slave.inc +[connection master] +connection master; +SET sql_mode=ORACLE; +CREATE PACKAGE pack AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pack AS +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +PROCEDURE p1 AS +BEGIN +SELECT f1(); +END; +END pack; +$$ +connection slave; +connection slave; +SELECT * FROM mysql.proc WHERE db='test' AND name='pack'; +db test +name pack +type PACKAGE +specific_name pack +language SQL +sql_data_access CONTAINS_SQL +is_deterministic NO +security_type DEFINER +param_list +returns +body AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END +definer root@localhost +created # +modified # +sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +comment +character_set_client latin1 +collation_connection latin1_swedish_ci +db_collation latin1_swedish_ci +body_utf8 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END +aggregate NONE +db test +name pack +type PACKAGE BODY +specific_name pack +language SQL +sql_data_access CONTAINS_SQL +is_deterministic NO +security_type DEFINER +param_list +returns +body AS +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +PROCEDURE p1 AS +BEGIN +SELECT f1(); +END; +END +definer root@localhost +created # +modified # +sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +comment +character_set_client latin1 +collation_connection latin1_swedish_ci +db_collation latin1_swedish_ci +body_utf8 AS +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +PROCEDURE p1 AS +BEGIN +SELECT f1(); +END; +END +aggregate NONE +SELECT * FROM mysql.proc WHERE db='test' AND name LIKE 'pack.%'; +SET @@sql_mode=ORACLE; +SELECT pack.f1(); +pack.f1() +10 +CALL pack.p1(); +f1() +10 +SET @@sql_mode=DEFAULT; +connection master; +DROP PACKAGE pack; +connection slave; +connection slave; +SELECT COUNT(*) FROM mysql.proc WHERE db='test' AND name='pack'; +COUNT(*) +0 +# +# Creating a package with a COMMENT +# +connection master; +CREATE PACKAGE p1 COMMENT 'package-p1-comment' AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 COMMENT 'package-body-p1-comment' AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END; +$$ +SELECT definer, name, security_type, type, `comment` FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type; +definer name security_type type comment +root@localhost p1 DEFINER PACKAGE package-p1-comment +root@localhost p1 DEFINER PACKAGE BODY package-body-p1-comment +connection slave; +SELECT definer, name, security_type, type, `comment` FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type; +definer name security_type type comment +root@localhost p1 DEFINER PACKAGE package-p1-comment +root@localhost p1 DEFINER PACKAGE BODY package-body-p1-comment +connection master; +DROP PACKAGE p1; +connection slave; +# +# Creating a package with a different DEFINER +# +connection master; +CREATE DEFINER=xxx@localhost PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +Warnings: +Note 1449 The user specified as a definer ('xxx'@'localhost') does not exist +CREATE DEFINER=xxx@localhost PACKAGE BODY p1 AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END; +$$ +Warnings: +Note 1449 The user specified as a definer ('xxx'@'localhost') does not exist +SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type; +definer name security_type type +xxx@localhost p1 DEFINER PACKAGE +xxx@localhost p1 DEFINER PACKAGE BODY +connection slave; +SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type; +definer name security_type type +xxx@localhost p1 DEFINER PACKAGE +xxx@localhost p1 DEFINER PACKAGE BODY +connection master; +DROP PACKAGE p1; +connection slave; +# +# Creating a package with a different DEFINER + SQL SECURITY INVOKER +# +connection master; +CREATE DEFINER=xxx@localhost PACKAGE p1 SQL SECURITY INVOKER AS +PROCEDURE p1; +END; +$$ +Warnings: +Note 1449 The user specified as a definer ('xxx'@'localhost') does not exist +CREATE DEFINER=xxx@localhost PACKAGE BODY p1 SQL SECURITY INVOKER AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END; +$$ +Warnings: +Note 1449 The user specified as a definer ('xxx'@'localhost') does not exist +SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type; +definer name security_type type +xxx@localhost p1 INVOKER PACKAGE +xxx@localhost p1 INVOKER PACKAGE BODY +connection slave; +SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type; +definer name security_type type +xxx@localhost p1 INVOKER PACKAGE +xxx@localhost p1 INVOKER PACKAGE BODY +connection master; +DROP PACKAGE p1; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/compat/oracle/r/rpl_sp_package_variables.result b/mysql-test/suite/compat/oracle/r/rpl_sp_package_variables.result new file mode 100644 index 00000000..764686e4 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/rpl_sp_package_variables.result @@ -0,0 +1,38 @@ +include/master-slave.inc +[connection master] +connection master; +SET sql_mode=ORACLE; +# +# MDEV-13139 Package-wide variables in CREATE PACKAGE +# +connection master; +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +va INT:=10; +PROCEDURE p1 AS +BEGIN +INSERT INTO t1 VALUES (va); +END; +BEGIN +CREATE OR REPLACE TABLE t1 (a INT); +END; +$$ +CALL p1.p1(); +CALL p1.p1(); +SELECT * FROM t1; +a +10 +10 +connection slave; +SELECT * FROM t1; +a +10 +10 +connection master; +DROP PACKAGE p1; +DROP TABLE t1; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/compat/oracle/r/sequence.result b/mysql-test/suite/compat/oracle/r/sequence.result new file mode 100644 index 00000000..dbbabc36 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sequence.result @@ -0,0 +1,77 @@ +SET sql_mode=ORACLE; +CREATE SEQUENCE s1; +SHOW CREATE SEQUENCE s1; +Table Create Table +s1 CREATE SEQUENCE "s1" start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle +SELECT s1.currval; +s1.currval +NULL +SELECT s1.nextval; +s1.nextval +1 +SELECT s1.nextval; +s1.nextval +2 +SELECT s1.nextval; +s1.nextval +3 +EXPLAIN EXTENDED SELECT s1.nextval; +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 nextval("test"."s1") AS "s1.nextval" +SELECT nextval(s1); +nextval(s1) +4 +EXPLAIN EXTENDED SELECT s1.currval; +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 lastval("test"."s1") AS "s1.currval" +SELECT lastval(s1); +lastval(s1) +4 +DROP SEQUENCE s1; +CREATE SEQUENCE s1; +CREATE VIEW v1 AS SELECT s1.nextval AS a; +SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME='v1'; +VIEW_DEFINITION +select nextval(`test`.`s1`) AS `a` +SELECT * FROM v1; +a +1 +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select nextval("test"."s1") AS "a" latin1 latin1_swedish_ci +DROP VIEW v1; +DROP SEQUENCE s1; +CREATE SEQUENCE s1; +CREATE VIEW v1 AS SELECT s1.currval AS a; +SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME='v1'; +VIEW_DEFINITION +select lastval(`test`.`s1`) AS `a` +SELECT * FROM v1; +a +NULL +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select lastval("test"."s1") AS "a" latin1 latin1_swedish_ci +DROP VIEW v1; +DROP SEQUENCE s1; +# +# MDEV-12533 sql_mode=ORACLE: Add support for database qualified sequence names in NEXTVAL and CURRVAL +# +CREATE SEQUENCE s1; +SELECT test.s1.nextval; +test.s1.nextval +1 +SELECT test.s1.currval; +test.s1.currval +1 +SELECT .s1.nextval; +.s1.nextval +2 +SELECT .s1.currval; +.s1.currval +2 +DROP SEQUENCE s1; diff --git a/mysql-test/suite/compat/oracle/r/sp-anchor-row-type-table.result b/mysql-test/suite/compat/oracle/r/sp-anchor-row-type-table.result new file mode 100644 index 00000000..b8780421 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-anchor-row-type-table.result @@ -0,0 +1,131 @@ +SET sql_mode=ORACLE; +# +# MDEV-13581 ROW TYPE OF t1 and t1%ROWTYPE for routine parameters +# +CREATE TABLE t1 (a INT, b TEXT, c ENUM('a','b','c')); +CREATE PROCEDURE p1 (a t1%ROWTYPE) AS +BEGIN +CREATE TABLE t2 AS SELECT a.a AS a, a.b AS b, a.c AS c; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CREATE PROCEDURE p2 AS +a t1%ROWTYPE; +BEGIN +CALL p1(a); +END; +$$ +CALL p2(); +Table Create Table +t2 CREATE TABLE "t2" ( + "a" int(11) DEFAULT NULL, + "b" text DEFAULT NULL, + "c" varchar(1) DEFAULT NULL +) +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT, b TEXT); +CREATE PROCEDURE p1 (a OUT t1%ROWTYPE) AS +BEGIN +SET a.a=10; +SET a.b='text'; +END; +$$ +CREATE PROCEDURE p2 AS +a t1%ROWTYPE; +BEGIN +CALL p1(a); +SELECT a.a, a.b; +END; +$$ +CREATE FUNCTION f1(a t1%ROWTYPE) RETURN TEXT AS +BEGIN +RETURN CONCAT(a.a, ' ', a.b); +END; +$$ +CREATE FUNCTION f2 RETURN TEXT AS +a t1%ROWTYPE; +BEGIN +CALL p1(a); +RETURN f1(a); +END; +$$ +CALL p2(); +a.a a.b +10 text +SELECT f2(); +f2() +10 text +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP FUNCTION f2; +DROP FUNCTION f1; +DROP TABLE t1; +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT, b TEXT); +CREATE PROCEDURE p1 (a OUT db1.t1%ROWTYPE) AS +BEGIN +SET a.a=10; +SET a.b='text'; +END; +$$ +CREATE PROCEDURE p2 AS +a db1.t1%ROWTYPE; +BEGIN +CALL p1(a); +SELECT a.a, a.b; +END; +$$ +CREATE FUNCTION f1(a db1.t1%ROWTYPE) RETURN TEXT AS +BEGIN +RETURN CONCAT(a.a, ' ', a.b); +END; +$$ +CREATE FUNCTION f2() RETURN TEXT AS +a db1.t1%ROWTYPE; +BEGIN +CALL p1(a); +RETURN f1(a); +END; +$$ +CALL p2(); +a.a a.b +10 text +SELECT f2(); +f2() +10 text +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP FUNCTION f2; +DROP FUNCTION f1; +DROP DATABASE db1; +# +# MDEV-14139 Anchored data types for variables +# +CREATE TABLE t1 (int11 INT, text0 TEXT); +DECLARE +row1 t1%ROWTYPE; +a_row1 row1%TYPE; +aa_row1 a_row1%TYPE; +BEGIN +CREATE TABLE t2 AS SELECT a_row1.int11 AS int11, a_row1.text0 AS text0; +SHOW CREATE TABLE t2; +DROP TABLE t2; +CREATE TABLE t2 AS SELECT aa_row1.int11 AS int11, aa_row1.text0 AS text0; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +Table Create Table +t2 CREATE TABLE "t2" ( + "int11" int(11) DEFAULT NULL, + "text0" text DEFAULT NULL +) +Table Create Table +t2 CREATE TABLE "t2" ( + "int11" int(11) DEFAULT NULL, + "text0" text DEFAULT NULL +) +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/sp-anonymous.result b/mysql-test/suite/compat/oracle/r/sp-anonymous.result new file mode 100644 index 00000000..26bce0f4 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-anonymous.result @@ -0,0 +1,220 @@ +SET sql_mode=ORACLE; +# +# MDEV-10655 Anonymous blocks +# +# Testing BEGIN NOT ATOMIC with no declarations +BEGIN NOT ATOMIC +SELECT 1 AS a; +END +/ +a +1 +# Testing BEGIN NOT ATOMIC with declarations +# DECLARE starts a new block and thus must be followed by BEGIN .. END +BEGIN NOT ATOMIC +DECLARE +i INT DEFAULT 5; +x INT DEFAULT 10; +BEGIN +<<label>> +WHILE i > 3 LOOP +i:= i - 1; +SELECT i; +END LOOP label; +END; +END +/ +i +4 +i +3 +# Anonymous blocks with no declarations and no exceptions +BEGIN +SELECT 1 AS a; +END +$$ +a +1 +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(30); +ROLLBACK; +END; +$$ +SELECT * FROM t1; +a +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(30); +END; +$$ +ROLLBACK; +SELECT * FROM t1; +a +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(30); +COMMIT; +END; +$$ +SELECT * FROM t1; +a +10 +20 +30 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(30); +END; +$$ +COMMIT; +SELECT * FROM t1; +a +10 +20 +30 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(20); +END; +$$ +ERROR 23000: Duplicate entry '20' for key 'PRIMARY' +COMMIT; +SELECT * FROM t1; +a +10 +20 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +# Anonymous blocks with no declarations, with exceptions +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +BEGIN +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(20); +EXCEPTION +WHEN DUP_VAL_ON_INDEX THEN NULL; +END; +$$ +COMMIT; +SELECT * FROM t1; +a +10 +20 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +# Anonymous blocks with declarations, with no exceptions +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +a30 INT:=30; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a30); +ROLLBACK; +END; +$$ +SELECT * FROM t1; +a +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +a30 INT:=30; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a30); +END; +$$ +ROLLBACK; +SELECT * FROM t1; +a +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +a30 INT:=30; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a30); +COMMIT; +END; +$$ +SELECT * FROM t1; +a +10 +20 +30 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +a30 INT:=30; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a30); +END; +$$ +COMMIT; +SELECT * FROM t1; +a +10 +20 +30 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; +# Anonymous blocks with declarations, with exceptions +SET AUTOCOMMIT=OFF; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10); +DECLARE +a20 INT:=20; +BEGIN +INSERT INTO t1 VALUES(a20); +INSERT INTO t1 VALUES(a20); +EXCEPTION +WHEN DUP_VAL_ON_INDEX THEN NULL; +END; +$$ +COMMIT; +SELECT * FROM t1; +a +10 +20 +DROP TABLE t1; +SET AUTOCOMMIT=DEFAULT; diff --git a/mysql-test/suite/compat/oracle/r/sp-code.result b/mysql-test/suite/compat/oracle/r/sp-code.result new file mode 100644 index 00000000..0fc980a3 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-code.result @@ -0,0 +1,1516 @@ +SET sql_mode=ORACLE; +# +# Testing exceptions in the top-level blocks +# +# No HANDLER declarations, no exceptions +CREATE FUNCTION f1 RETURN INT +AS +BEGIN +RETURN 10; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 freturn int 10 +SELECT f1(); +f1() +10 +DROP FUNCTION f1; +# No HANDLER declarations, no code, no exceptions +CREATE PROCEDURE p1 () +IS +BEGIN +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump 2 +CALL p1; +DROP PROCEDURE p1; +# No HANDLER declarations, no code, some exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +EXCEPTION +WHEN 1002 THEN v:=225; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump 1 +1 hpush_jump 4 1 EXIT +2 set v@0 225 +3 hreturn 0 4 +4 hpop 1 +set @v= 10; +CALL p1(@v); +SELECT @v; +@v +10 +DROP PROCEDURE p1; +# No HANDLER declarations, some code, some exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=224; +EXCEPTION +WHEN 1002 THEN v:=225; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump 3 +1 set v@0 224 +2 jump 6 +3 hpush_jump 1 1 EXIT +4 set v@0 225 +5 hreturn 0 6 +6 hpop 1 +set @v= 10; +CALL p1(@v); +SELECT @v; +@v +224 +DROP PROCEDURE p1; +# Some HANDLER declarations, no code, no exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +EXIT HANDLER FOR 1000 +BEGIN +v:=123; +END; +BEGIN +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 hpush_jump 3 1 EXIT +1 set v@0 123 +2 hreturn 0 3 +3 hpop 1 +set @v= 10; +CALL p1(@v); +SELECT @v; +@v +10 +DROP PROCEDURE p1; +# Some HANDLER declarations, no code, some exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +EXIT HANDLER FOR 1000 +BEGIN +v:=123; +END; +BEGIN +EXCEPTION +WHEN 1002 THEN v:=225; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 hpush_jump 3 1 EXIT +1 set v@0 123 +2 hreturn 0 6 +3 hpush_jump 6 1 EXIT +4 set v@0 225 +5 hreturn 0 6 +6 hpop 2 +set @v= 10; +CALL p1(@v); +SELECT @v; +@v +10 +DROP PROCEDURE p1; +# Some HANDLER declarations, some code, no exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +EXIT HANDLER FOR 1000 +BEGIN +v:=123; +END; +BEGIN +v:=223; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 hpush_jump 3 1 EXIT +1 set v@0 123 +2 hreturn 0 4 +3 set v@0 223 +4 hpop 1 +set @v= 10; +CALL p1(@v); +SELECT @v; +@v +223 +DROP PROCEDURE p1; +# Some HANDLER declarations, some code, some exceptions +CREATE PROCEDURE p1 (v IN OUT VARCHAR2(20)) +IS +EXIT HANDLER FOR 1000 +BEGIN +v:=123; +END; +CONTINUE HANDLER FOR 1001 +BEGIN +SET v=223; +END; +BEGIN +v:= 1; +EXCEPTION +WHEN 1002 THEN SET v=225; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 hpush_jump 3 1 EXIT +1 set v@0 123 +2 hreturn 0 12 +3 hpush_jump 8 1 CONTINUE +4 set v@0 223 +5 hreturn 1 +6 set v@0 1 +7 jump 12 +8 hpush_jump 6 1 EXIT +9 set v@0 225 +10 hreturn 0 12 +11 jump 6 +12 hpop 3 +DROP PROCEDURE p1; +# +# Testing EXCEPTIONS in internal blocks +# +# No HANDLER declarations, no code, no exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=123; +BEGIN +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v@0 123 +1 jump 5 +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +123 +DROP PROCEDURE p1; +# No HANDLER declarations, no code, some exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=123; +BEGIN +EXCEPTION +WHEN 20002 THEN v:=335; +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v@0 123 +1 jump 2 +2 hpush_jump 5 1 EXIT +3 set v@0 335 +4 hreturn 0 5 +5 hpop 1 +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +123 +DROP PROCEDURE p1; +# No HANDLER declarations, some code, no exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=123; +BEGIN +v:=223; +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v@0 123 +1 set v@0 223 +2 jump 6 +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +223 +DROP PROCEDURE p1; +# No HANDLER declarations, some code, some exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=123; +BEGIN +v:=223; +EXCEPTION +WHEN 20002 THEN v:=335; +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v@0 123 +1 jump 4 +2 set v@0 223 +3 jump 7 +4 hpush_jump 2 1 EXIT +5 set v@0 335 +6 hreturn 0 7 +7 hpop 1 +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +223 +DROP PROCEDURE p1; +# Some HANDLER declarations, no code, no exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=123; +DECLARE +EXIT HANDLER FOR 1000 +BEGIN +v:=323; +END; +BEGIN +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v@0 123 +1 hpush_jump 4 1 EXIT +2 set v@0 323 +3 hreturn 0 4 +4 hpop 1 +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +123 +DROP PROCEDURE p1; +# Some HANDLER declarations, no code, some exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=123; +DECLARE +EXIT HANDLER FOR 1000 +BEGIN +v:=323; +END; +BEGIN +EXCEPTION +WHEN 20002 THEN v:=335; +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v@0 123 +1 hpush_jump 4 1 EXIT +2 set v@0 323 +3 hreturn 0 7 +4 hpush_jump 7 1 EXIT +5 set v@0 335 +6 hreturn 0 7 +7 hpop 2 +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +123 +DROP PROCEDURE p1; +# Some HANDLER declarations, some code, no exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=123; +DECLARE +EXIT HANDLER FOR 1000 +BEGIN +v:=323; +END; +BEGIN +v:= 324; +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v@0 123 +1 hpush_jump 4 1 EXIT +2 set v@0 323 +3 hreturn 0 5 +4 set v@0 324 +5 hpop 1 +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +324 +DROP PROCEDURE p1; +# Some HANDLER declarations, some code, some exceptions +CREATE PROCEDURE p1 (v IN OUT INT) +IS +BEGIN +v:=123; +DECLARE +EXIT HANDLER FOR 1000 +BEGIN +v:=323; +END; +BEGIN +v:= 324; +EXCEPTION WHEN 2002 THEN v:= 325; +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v@0 123 +1 hpush_jump 6 1 EXIT +2 set v@0 323 +3 hreturn 0 9 +4 set v@0 324 +5 jump 9 +6 hpush_jump 4 1 EXIT +7 set v@0 325 +8 hreturn 0 9 +9 hpop 2 +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +324 +DROP PROCEDURE p1; +# +# Testing EXIT statement +# +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +LOOP +i:= i + 1; +IF i >= 5 THEN +EXIT; +END IF; +END LOOP; +RETURN i; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set i@0 0 +1 set i@0 i@0 + 1 +2 jump_if_not 1(1) i@0 >= 5 +3 jump 4 +4 freturn int i@0 +SELECT f1() FROM DUAL; +f1() +5 +DROP FUNCTION f1; +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +LOOP +i:= i + 1; +EXIT WHEN i >=5; +END LOOP; +RETURN i; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set i@0 0 +1 set i@0 i@0 + 1 +2 jump_if_not 1(0) i@0 >= 5 +3 jump 4 +4 freturn int i@0 +SELECT f1() FROM DUAL; +f1() +5 +DROP FUNCTION f1; +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +LOOP +BEGIN +i:= i + 1; +IF i >= 5 THEN +EXIT; +END IF; +EXCEPTION +WHEN OTHERS THEN i:= 1000; +END; +END LOOP; +RETURN i; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set i@0 0 +1 jump 5 +2 set i@0 i@0 + 1 +3 jump_if_not 8(8) i@0 >= 5 +4 jump 10 +5 hpush_jump 2 1 EXIT +6 set i@0 1000 +7 hreturn 0 8 +8 hpop 1 +9 jump 5 +10 freturn int i@0 +SELECT f1() FROM DUAL; +f1() +5 +DROP FUNCTION f1; +CREATE PROCEDURE p1(a IN OUT INT) +IS +i INT := 0; +BEGIN +LOOP +LOOP +BEGIN +i:= i + 1; +IF i >=5 THEN +EXIT; +END IF; +EXCEPTION +WHEN OTHERS THEN a:=1000; +END; +END LOOP; +i:= i + 100; +EXIT; +END LOOP; +a:= i; +EXCEPTION +WHEN OTHERS THEN a:=11; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set i@1 0 +1 jump 14 +2 set i@1 i@1 + 1 +3 jump_if_not 8(8) i@1 >= 5 +4 jump 10 +5 hpush_jump 2 2 EXIT +6 set a@0 1000 +7 hreturn 0 8 +8 hpop 1 +9 jump 5 +10 set i@1 i@1 + 100 +11 jump 12 +12 set a@0 i@1 +13 jump 17 +14 hpush_jump 5 2 EXIT +15 set a@0 11 +16 hreturn 0 17 +17 hpop 1 +set @v= 10; +CALL p1(@v); +SELECT @v; +@v +105 +DROP PROCEDURE p1; +# Testing RETURN in procedures +CREATE PROCEDURE p1 (a IN OUT INT) +AS +BEGIN +IF a < 10 THEN +BEGIN +a:= a + 1; +RETURN; +END; +END IF; +a:= 200; +EXCEPTION +WHEN OTHERS THEN +BEGIN +a:= 100; +RETURN; +END; +END; +/ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump 6 +1 jump_if_not 4(4) a@0 < 10 +2 set a@0 a@0 + 1 +3 preturn +4 set a@0 200 +5 jump 9 +6 hpush_jump 1 1 EXIT +7 set a@0 100 +8 preturn +9 hpop 1 +DROP PROCEDURE p1; +# Testing FOR loop statement +CREATE FUNCTION f1 (a INT, b INT) RETURN INT +AS +total INT := 0; +BEGIN +FOR i IN 1 .. a +LOOP +total:= total + i; +IF i = b THEN +EXIT; +END IF; +END LOOP; +RETURN total; +END +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set total@2 0 +1 set i@3 1 +2 set [target_bound]@4 a@0 +3 jump_if_not 9(9) i@3 <= [target_bound]@4 +4 set total@2 total@2 + i@3 +5 jump_if_not 7(7) i@3 = b@1 +6 jump 9 +7 set i@3 i@3 + 1 +8 jump 3 +9 freturn int total@2 +SELECT f1(3, 100) FROM DUAL; +f1(3, 100) +6 +SELECT f1(3, 2) FROM DUAL; +f1(3, 2) +3 +DROP FUNCTION f1; +CREATE FUNCTION f1 (a INT, b INT) RETURN INT +AS +total INT := 0; +BEGIN +FOR i IN REVERSE 1..a +LOOP +total:= total + i; +IF i = b THEN +EXIT; +END IF; +END LOOP; +RETURN total; +END +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set total@2 0 +1 set i@3 a@0 +2 set [target_bound]@4 1 +3 jump_if_not 9(9) i@3 >= [target_bound]@4 +4 set total@2 total@2 + i@3 +5 jump_if_not 7(7) i@3 = b@1 +6 jump 9 +7 set i@3 i@3 + -1 +8 jump 3 +9 freturn int total@2 +SELECT f1(3, 100) FROM DUAL; +f1(3, 100) +6 +SELECT f1(3, 2) FROM DUAL; +f1(3, 2) +5 +DROP FUNCTION f1; +# Testing labeled FOR LOOP statement +CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURN INT +AS +total INT := 0; +BEGIN +<<la>> +FOR ia IN 1 .. a +LOOP +total:= total + 1000; +<<lb>> +FOR ib IN 1 .. b +LOOP +total:= total + 1; +EXIT lb WHEN ib = limitb; +EXIT la WHEN ia = limita; +END LOOP lb; +END LOOP la; +RETURN total; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set total@4 0 +1 set ia@5 1 +2 set [target_bound]@6 a@0 +3 jump_if_not 17(17) ia@5 <= [target_bound]@6 +4 set total@4 total@4 + 1000 +5 set ib@7 1 +6 set [target_bound]@8 b@2 +7 jump_if_not 15(15) ib@7 <= [target_bound]@8 +8 set total@4 total@4 + 1 +9 jump_if_not 11(0) ib@7 = limitb@3 +10 jump 15 +11 jump_if_not 13(0) ia@5 = limita@1 +12 jump 17 +13 set ib@7 ib@7 + 1 +14 jump 7 +15 set ia@5 ia@5 + 1 +16 jump 3 +17 freturn int total@4 +SELECT f1(2, 1, 2, 2) FROM DUAL; +f1(2, 1, 2, 2) +1001 +SELECT f1(2, 2, 2, 2) FROM DUAL; +f1(2, 2, 2, 2) +2003 +SELECT f1(2, 3, 2, 3) FROM DUAL; +f1(2, 3, 2, 3) +2004 +DROP FUNCTION f1; +# Testing labeled ITERATE in a labeled FOR LOOP +CREATE FUNCTION f1(a INT) RETURN INT +AS +total INT:= 0; +BEGIN +<<li>> +FOR i IN 1 .. a +LOOP +total:= total + 1000; +IF i = 5 THEN +ITERATE li; +END IF; +total:= total + 1; +END LOOP; +RETURN total; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set total@1 0 +1 set i@2 1 +2 set [target_bound]@3 a@0 +3 jump_if_not 11(11) i@2 <= [target_bound]@3 +4 set total@1 total@1 + 1000 +5 jump_if_not 8(8) i@2 = 5 +6 set i@2 i@2 + 1 +7 jump 3 +8 set total@1 total@1 + 1 +9 set i@2 i@2 + 1 +10 jump 3 +11 freturn int total@1 +SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; +f1(3) f1(4) f1(5) f1(6) +3003 4004 5004 6005 +DROP FUNCTION f1; +CREATE FUNCTION f1(a INT) RETURN INT +AS +total INT:= 0; +BEGIN +<<li>> +FOR i IN 1 .. a +LOOP +FOR j IN 1 .. 2 +LOOP +total:= total + 1000; +IF i = 5 THEN +ITERATE li; +END IF; +total:= total + 1; +END LOOP; +END LOOP; +RETURN total; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set total@1 0 +1 set i@2 1 +2 set [target_bound]@3 a@0 +3 jump_if_not 16(16) i@2 <= [target_bound]@3 +4 set j@4 1 +5 set [target_bound]@5 2 +6 jump_if_not 14(14) j@4 <= [target_bound]@5 +7 set total@1 total@1 + 1000 +8 jump_if_not 11(11) i@2 = 5 +9 set i@2 i@2 + 1 +10 jump 3 +11 set total@1 total@1 + 1 +12 set j@4 j@4 + 1 +13 jump 6 +14 set i@2 i@2 + 1 +15 jump 3 +16 freturn int total@1 +SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; +f1(3) f1(4) f1(5) f1(6) +6006 8008 9008 11010 +DROP FUNCTION f1; +CREATE FUNCTION f1(a INT) RETURN INT +AS +total INT:= 0; +BEGIN +<<lj>> +FOR j IN 1 .. 2 +LOOP +<<li>> +FOR i IN 1 .. a +LOOP +total:= total + 1000; +IF i = 5 THEN +ITERATE li; +END IF; +total:= total + 1; +END LOOP; +END LOOP; +RETURN total; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set total@1 0 +1 set j@2 1 +2 set [target_bound]@3 2 +3 jump_if_not 16(16) j@2 <= [target_bound]@3 +4 set i@4 1 +5 set [target_bound]@5 a@0 +6 jump_if_not 14(14) i@4 <= [target_bound]@5 +7 set total@1 total@1 + 1000 +8 jump_if_not 11(11) i@4 = 5 +9 set i@4 i@4 + 1 +10 jump 6 +11 set total@1 total@1 + 1 +12 set i@4 i@4 + 1 +13 jump 6 +14 set j@2 j@2 + 1 +15 jump 3 +16 freturn int total@1 +SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; +f1(3) f1(4) f1(5) f1(6) +6006 8008 10008 12010 +DROP FUNCTION f1; +# Testing CONTINUE statement +CREATE FUNCTION f1(a INT) RETURN INT +AS +total INT:= 0; +BEGIN +FOR i IN 1 .. a +LOOP +CONTINUE WHEN i=5; +total:= total + 1; +END LOOP; +RETURN total; +END; +/ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set total@1 0 +1 set i@2 1 +2 set [target_bound]@3 a@0 +3 jump_if_not 10(10) i@2 <= [target_bound]@3 +4 jump_if_not 7(0) i@2 = 5 +5 set i@2 i@2 + 1 +6 jump 3 +7 set total@1 total@1 + 1 +8 set i@2 i@2 + 1 +9 jump 3 +10 freturn int total@1 +SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; +f1(3) f1(4) f1(5) f1(6) +3 4 4 5 +DROP FUNCTION f1; +# +# Start of MDEV-10597 Cursors with parameters +# +CREATE PROCEDURE p1(arg_value_a VARCHAR, arg_value_b VARCHAR, +arg_pattern_a VARCHAR, arg_pattern_b VARCHAR) +AS +v_a VARCHAR(10); +v_b VARCHAR(20); +CURSOR c (p_value_a VARCHAR, +p_value_b VARCHAR, +p_pattern_a VARCHAR, +p_pattern_b VARCHAR, +p_limit_a INT, +p_limit_b INT, +p_unused TEXT) IS +(SELECT p_value_a, p_value_b FROM DUAL +WHERE p_value_a LIKE p_pattern_a LIMIT p_limit_a) +UNION +(SELECT p_value_b, p_value_a FROM DUAL +WHERE p_value_b LIKE p_pattern_b LIMIT p_limit_b); +BEGIN +OPEN c(arg_value_a, (SELECT arg_value_b), +arg_pattern_a, arg_pattern_b, 100, 101, 'x'); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +SELECT v_a, v_b; +END LOOP; +CLOSE c; +END; +$$ +CALL p1('aaa','bbb','aaa','bbb'); +v_a v_b +aaa bbb +v_a v_b +bbb aaa +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set v_a@4 NULL +1 set v_b@5 NULL +2 cpush c@0 +3 set p_value_a@6 arg_value_a@0 +4 set p_value_b@7 (select arg_value_b@1) +5 set p_pattern_a@8 arg_pattern_a@2 +6 set p_pattern_b@9 arg_pattern_b@3 +7 set p_limit_a@10 100 +8 set p_limit_b@11 101 +9 set p_unused@12 'x' +10 copen c@0 +11 cfetch c@0 v_a@4 v_b@5 +12 jump_if_not 14(0) "c"%NOTFOUND +13 jump 16 +14 stmt 0 "SELECT v_a, v_b" +15 jump 11 +16 cclose c@0 +17 cpop 1 +DROP PROCEDURE p1; +# +# End of MDEV-10597 Cursors with parameters +# +# +# MDEV-10914 ROW data type for stored routine variables +# +CREATE FUNCTION f1() RETURN INT +AS +a ROW(a INT, b INT); +BEGIN +a.b:= 200; +RETURN a.b; +END; +$$ +SHOW FUNCTION CODE f1; +Pos Instruction +0 set a@0 NULL +1 set a.b@0[1] 200 +2 freturn int a.b@0[1] +SELECT f1(); +f1() +200 +DROP FUNCTION f1; +CREATE PROCEDURE p1 +AS +rec ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)); +BEGIN +rec:= ROW(10,20.123456,30.123,'test'); +SELECT rec.a, rec.b, rec.c, rec.d; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set rec@0 NULL +1 set rec@0 (10,20.123456,30.123,'test') +2 stmt 0 "SELECT rec.a, rec.b, rec.c, rec.d" +CALL p1; +rec.a rec.b rec.c rec.d +10 20.123456 30.123 test +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +rec ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)) := +ROW(10,20.123456,30.123,'test'); +BEGIN +SELECT rec.a, rec.b, rec.c, rec.d; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set rec@0 (10,20.123456,30.123,'test') +1 stmt 0 "SELECT rec.a, rec.b, rec.c, rec.d" +CALL p1; +rec.a rec.b rec.c rec.d +10 20.123456 30.123 test +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +rec1 ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)); +rec2 ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)); +BEGIN +rec1:= ROW(10,20.123456,30.123,'test'); +rec2:= rec1; +SELECT rec2.a, rec2.b, rec2.c, rec2.d; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set rec1@0 NULL +1 set rec2@1 NULL +2 set rec1@0 (10,20.123456,30.123,'test') +3 set rec2@1 rec1@0 +4 stmt 0 "SELECT rec2.a, rec2.b, rec2.c, rec2.d" +CALL p1; +rec2.a rec2.b rec2.c rec2.d +10 20.123456 30.123 test +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +rec1 ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)) := +ROW(10,20.123456,30.123,'test'); +rec2 ROW(a INT,b DOUBLE,c DECIMAL(10,3),d VARCHAR(10)) := rec1; +BEGIN +SELECT rec2.a, rec2.b, rec2.c, rec2.d; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set rec1@0 (10,20.123456,30.123,'test') +1 set rec2@1 rec1@0 +2 stmt 0 "SELECT rec2.a, rec2.b, rec2.c, rec2.d" +CALL p1; +rec2.a rec2.b rec2.c rec2.d +10 20.123456 30.123 test +DROP PROCEDURE p1; +# +# End of MDEV-10914 ROW data type for stored routine variables +# +# +# MDEV-12133 sql_mode=ORACLE: table%ROWTYPE in variable declarations +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE; +BEGIN +rec1.a:= 10; +rec1.b:= 'bbb'; +rec1.c:= 10e2; +rec1.d:= 10.12; +rec1.c:= rec1.d; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set rec1@0 NULL +1 set rec1.a@0["a"] 10 +2 set rec1.b@0["b"] 'bbb' +3 set rec1.c@0["c"] 10e2 +4 set rec1.d@0["d"] 10.12 +5 set rec1.c@0["c"] rec1.d@0["d"] +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-12011 sql_mode=ORACLE: cursor%ROWTYPE in variable declarations +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +CURSOR cur2 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1,rec2 cur1%ROWTYPE; +rec3 cur2%ROWTYPE; +BEGIN +rec1.a:= 10; +rec1.b:= 'bbb'; +END; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 cpush cur1@0 +1 cpush cur2@1 +2 cursor_copy_struct cur1 rec1@0 +3 cursor_copy_struct cur1 rec2@1 +4 set rec1@0 NULL +5 set rec2@1 NULL +6 cursor_copy_struct cur2 rec3@2 +7 set rec3@2 NULL +8 set rec1.a@0["a"] 10 +9 set rec1.b@0["b"] 'bbb' +10 jump 11 +11 cpop 2 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-10581 sql_mode=ORACLE: Explicit cursor FOR LOOP +# +CREATE PROCEDURE p1 +AS +CURSOR cur0 IS SELECT 10 AS a, 'b0' AS b; +CURSOR cur1 IS SELECT 10 AS a, 'b0' AS b; +CURSOR cur2 IS SELECT 10 AS a, 'b0' AS b; +BEGIN +FOR rec1 IN cur1 +LOOP +SELECT rec1.a, rec1.b; +rec1.a:= 11; +rec1.b:= 'b1'; +SELECT rec1.a, rec1.b; +END LOOP; +FOR rec0 IN cur0 +LOOP +rec0.a:= 10; +rec0.b:='b0'; +END LOOP; +FOR rec2 IN cur2 +LOOP +rec2.a:= 10; +rec2.b:='b0'; +END LOOP; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 cpush cur0@0 +1 cpush cur1@1 +2 cpush cur2@2 +3 cursor_copy_struct cur1 rec1@0 +4 copen cur1@1 +5 cfetch cur1@1 rec1@0 +6 jump_if_not 13(13) "cur1"%FOUND +7 stmt 0 "SELECT rec1.a, rec1.b" +8 set rec1.a@0["a"] 11 +9 set rec1.b@0["b"] 'b1' +10 stmt 0 "SELECT rec1.a, rec1.b" +11 cfetch cur1@1 rec1@0 +12 jump 6 +13 cclose cur1@1 +14 cursor_copy_struct cur0 rec0@1 +15 copen cur0@0 +16 cfetch cur0@0 rec0@1 +17 jump_if_not 22(22) "cur0"%FOUND +18 set rec0.a@1["a"] 10 +19 set rec0.b@1["b"] 'b0' +20 cfetch cur0@0 rec0@1 +21 jump 17 +22 cclose cur0@0 +23 cursor_copy_struct cur2 rec2@2 +24 copen cur2@2 +25 cfetch cur2@2 rec2@2 +26 jump_if_not 31(31) "cur2"%FOUND +27 set rec2.a@2["a"] 10 +28 set rec2.b@2["b"] 'b0' +29 cfetch cur2@2 rec2@2 +30 jump 26 +31 cclose cur2@2 +32 cpop 3 +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +CURSOR cur0 IS SELECT 10 AS a, 'b0' AS b; +BEGIN +FOR rec0 IN cur0 +LOOP +DECLARE +CURSOR cur1 IS SELECT 11 AS a, 'b1' AS b; +BEGIN +rec0.a:= 11; +rec0.b:= 'b0'; +FOR rec1 IN cur1 +LOOP +rec1.a:= 11; +rec1.b:= 'b1'; +DECLARE +CURSOR cur2 IS SELECT 12 AS a, 'b2' AS b; +BEGIN +FOR rec2 IN cur2 +LOOP +rec2.a:=12; +rec2.b:='b2'; +END LOOP; +END; +END LOOP; +END; +END LOOP; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 cpush cur0@0 +1 cursor_copy_struct cur0 rec0@0 +2 copen cur0@0 +3 cfetch cur0@0 rec0@0 +4 jump_if_not 31(31) "cur0"%FOUND +5 cpush cur1@1 +6 set rec0.a@0["a"] 11 +7 set rec0.b@0["b"] 'b0' +8 cursor_copy_struct cur1 rec1@1 +9 copen cur1@1 +10 cfetch cur1@1 rec1@1 +11 jump_if_not 27(27) "cur1"%FOUND +12 set rec1.a@1["a"] 11 +13 set rec1.b@1["b"] 'b1' +14 cpush cur2@2 +15 cursor_copy_struct cur2 rec2@2 +16 copen cur2@2 +17 cfetch cur2@2 rec2@2 +18 jump_if_not 23(23) "cur2"%FOUND +19 set rec2.a@2["a"] 12 +20 set rec2.b@2["b"] 'b2' +21 cfetch cur2@2 rec2@2 +22 jump 18 +23 cclose cur2@2 +24 cpop 1 +25 cfetch cur1@1 rec1@1 +26 jump 11 +27 cclose cur1@1 +28 cpop 1 +29 cfetch cur0@0 rec0@0 +30 jump 4 +31 cclose cur0@0 +32 cpop 1 +DROP PROCEDURE p1; +# +# MDEV-12098 sql_mode=ORACLE: Implicit cursor FOR loop +# +CREATE PROCEDURE p1 +AS +BEGIN +FOR rec1 IN (SELECT 11 AS a, 'b1' AS b) +LOOP +SELECT rec1.a, rec1.b; +rec1.a:= 11; +rec1.b:= 'b1'; +SELECT rec1.a, rec1.b; +END LOOP; +FOR rec0 IN (SELECT 10 AS a, 'b0' AS b) +LOOP +rec0.a:= 10; +rec0.b:='b0'; +END LOOP; +FOR rec2 IN (SELECT 12 AS a, 'b2' AS b) +LOOP +rec2.a:= 10; +rec2.b:='b0'; +END LOOP; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 cpush [implicit_cursor]@0 +1 cursor_copy_struct [implicit_cursor] rec1@0 +2 copen [implicit_cursor]@0 +3 cfetch [implicit_cursor]@0 rec1@0 +4 jump_if_not 11(11) "[implicit_cursor]"%FOUND +5 stmt 0 "SELECT rec1.a, rec1.b" +6 set rec1.a@0["a"] 11 +7 set rec1.b@0["b"] 'b1' +8 stmt 0 "SELECT rec1.a, rec1.b" +9 cfetch [implicit_cursor]@0 rec1@0 +10 jump 4 +11 cpop 1 +12 cpush [implicit_cursor]@0 +13 cursor_copy_struct [implicit_cursor] rec0@1 +14 copen [implicit_cursor]@0 +15 cfetch [implicit_cursor]@0 rec0@1 +16 jump_if_not 21(21) "[implicit_cursor]"%FOUND +17 set rec0.a@1["a"] 10 +18 set rec0.b@1["b"] 'b0' +19 cfetch [implicit_cursor]@0 rec0@1 +20 jump 16 +21 cpop 1 +22 cpush [implicit_cursor]@0 +23 cursor_copy_struct [implicit_cursor] rec2@2 +24 copen [implicit_cursor]@0 +25 cfetch [implicit_cursor]@0 rec2@2 +26 jump_if_not 31(31) "[implicit_cursor]"%FOUND +27 set rec2.a@2["a"] 10 +28 set rec2.b@2["b"] 'b0' +29 cfetch [implicit_cursor]@0 rec2@2 +30 jump 26 +31 cpop 1 +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +BEGIN +FOR rec0 IN (SELECT 10 AS a, 'b0' AS b) +LOOP +rec0.a:= 11; +rec0.b:= 'b0'; +FOR rec1 IN (SELECT 11 AS a, 'b1' AS b) +LOOP +rec1.a:= 11; +rec1.b:= 'b1'; +FOR rec2 IN (SELECT 12 AS a, 'b2' AS b) +LOOP +rec2.a:=12; +rec2.b:='b2'; +END LOOP; +END LOOP; +END LOOP; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 cpush [implicit_cursor]@0 +1 cursor_copy_struct [implicit_cursor] rec0@0 +2 copen [implicit_cursor]@0 +3 cfetch [implicit_cursor]@0 rec0@0 +4 jump_if_not 29(29) "[implicit_cursor]"%FOUND +5 set rec0.a@0["a"] 11 +6 set rec0.b@0["b"] 'b0' +7 cpush [implicit_cursor]@1 +8 cursor_copy_struct [implicit_cursor] rec1@1 +9 copen [implicit_cursor]@1 +10 cfetch [implicit_cursor]@1 rec1@1 +11 jump_if_not 26(26) "[implicit_cursor]"%FOUND +12 set rec1.a@1["a"] 11 +13 set rec1.b@1["b"] 'b1' +14 cpush [implicit_cursor]@2 +15 cursor_copy_struct [implicit_cursor] rec2@2 +16 copen [implicit_cursor]@2 +17 cfetch [implicit_cursor]@2 rec2@2 +18 jump_if_not 23(23) "[implicit_cursor]"%FOUND +19 set rec2.a@2["a"] 12 +20 set rec2.b@2["b"] 'b2' +21 cfetch [implicit_cursor]@2 rec2@2 +22 jump 18 +23 cpop 1 +24 cfetch [implicit_cursor]@1 rec1@1 +25 jump 11 +26 cpop 1 +27 cfetch [implicit_cursor]@0 rec0@0 +28 jump 4 +29 cpop 1 +DROP PROCEDURE p1; +# +# MDEV-10598 sql_mode=ORACLE: Variable declarations can go after cursor declarations +# +# +# Cursor declaration and cursor%ROWTYPE declaration in the same block +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (1,'a'); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT a FROM t1; +rec1 cur1%ROWTYPE; +BEGIN +rec1.a:= 10; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 cursor_copy_struct cur1 rec1@0 +1 set rec1@0 NULL +2 cpush cur1@0 +3 set rec1.a@0["a"] 10 +4 cpop 1 +CALL p1; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Recursive cursor and cursor%ROWTYPE declarations in the same block +# +CREATE PROCEDURE p1 +AS +a INT:=10; +CURSOR cur1 IS SELECT a; +rec1 cur1%ROWTYPE; +CURSOR cur2 IS SELECT rec1.a + 1 "a"; +rec2 cur2%ROWTYPE; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec1; +CLOSE cur1; +SELECT rec1.a; +open cur2; +FETCH cur2 INTO rec2; +CLOSE cur2; +SELECT rec2.a; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set a@0 10 +1 cursor_copy_struct cur1 rec1@1 +2 set rec1@1 NULL +3 cursor_copy_struct cur2 rec2@2 +4 set rec2@2 NULL +5 cpush cur1@0 +6 cpush cur2@1 +7 copen cur1@0 +8 cfetch cur1@0 rec1@1 +9 cclose cur1@0 +10 stmt 0 "SELECT rec1.a" +11 copen cur2@1 +12 cfetch cur2@1 rec2@2 +13 cclose cur2@1 +14 stmt 0 "SELECT rec2.a" +15 cpop 2 +CALL p1(); +rec1.a +10 +rec2.a +11 +DROP PROCEDURE p1; +# +# MDEV-12441 Variables declared after cursors with parameters lose values +# +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x1 INT:=101; +BEGIN +OPEN cur(10,11); +CLOSE cur; +SELECT x0, x1; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set x0@0 100 +1 set x1@3 101 +2 cpush cur@0 +3 set cp1@1 10 +4 set cp2@2 11 +5 copen cur@0 +6 cclose cur@0 +7 stmt 0 "SELECT x0, x1" +8 cpop 1 +CALL p1(); +x0 x1 +100 101 +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur0(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x1 INT:=101; +CURSOR cur1(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x2 INT:=102; +CURSOR cur2(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x3 INT:=103; +BEGIN +OPEN cur0(0,1); +CLOSE cur0; +SELECT x0, x1, x2, x3; +OPEN cur1(10,11); +CLOSE cur1; +SELECT x0, x1, x2, x3; +OPEN cur2(20,21); +CLOSE cur2; +SELECT x0, x1, x2, x3; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set x0@0 100 +1 set x1@3 101 +2 set x2@6 102 +3 set x3@9 103 +4 cpush cur0@0 +5 cpush cur1@1 +6 cpush cur2@2 +7 set cp1@1 0 +8 set cp2@2 1 +9 copen cur0@0 +10 cclose cur0@0 +11 stmt 0 "SELECT x0, x1, x2, x3" +12 set cp1@4 10 +13 set cp2@5 11 +14 copen cur1@1 +15 cclose cur1@1 +16 stmt 0 "SELECT x0, x1, x2, x3" +17 set cp1@7 20 +18 set cp2@8 21 +19 copen cur2@2 +20 cclose cur2@2 +21 stmt 0 "SELECT x0, x1, x2, x3" +22 cpop 3 +CALL p1(); +x0 x1 x2 x3 +100 101 102 103 +x0 x1 x2 x3 +100 101 102 103 +x0 x1 x2 x3 +100 101 102 103 +DROP PROCEDURE p1; +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x1 t1.a%TYPE:=101; +BEGIN +OPEN cur(10,11); +CLOSE cur; +SELECT x0, x1; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set x0@0 100 +1 set x1@3 101 +2 cpush cur@0 +3 set cp1@1 10 +4 set cp2@2 11 +5 copen cur@0 +6 cclose cur@0 +7 stmt 0 "SELECT x0, x1" +8 cpop 1 +CALL p1(); +x0 x1 +100 101 +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x1 ROW(a INT,b INT):=ROW(101,102); +BEGIN +OPEN cur(10,11); +CLOSE cur; +SELECT x0, x1.a, x1.b; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 set x0@0 100 +1 set x1@3 (101,102) +2 cpush cur@0 +3 set cp1@1 10 +4 set cp2@2 11 +5 copen cur@0 +6 cclose cur@0 +7 stmt 0 "SELECT x0, x1.a, x1.b" +8 cpop 1 +CALL p1(); +x0 x1.a x1.b +100 101 102 +DROP PROCEDURE p1; +# +# MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr +# +CREATE OR REPLACE PROCEDURE p1() AS +BEGIN +SET GLOBAL max_allowed_packet=16000000, max_error_count=60; +SELECT @@GLOBAL.max_allowed_packet, @@GLOBAL.max_error_count; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 stmt 31 "SET GLOBAL max_allowed_packet=16000000" +1 stmt 31 "SET GLOBAL max_error_count=60" +2 stmt 0 "SELECT @@GLOBAL.max_allowed_packet, @..." +DROP PROCEDURE p1; +# +# MDEV-19639 sql_mode=ORACLE: Wrong SHOW PROCEDURE output for sysvar:=expr +# +CREATE OR REPLACE PROCEDURE p1() AS +BEGIN +max_error_count:=10; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 stmt 31 "max_error_count:=10" +DROP PROCEDURE p1; diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor-decl.result b/mysql-test/suite/compat/oracle/r/sp-cursor-decl.result new file mode 100644 index 00000000..275e5756 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-cursor-decl.result @@ -0,0 +1,290 @@ +SET sql_mode=ORACLE; +# +# MDEV-10598 sql_mode=ORACLE: Variable declarations can go after cursor declarations +# +# +# Variable after cursor declaration +# +CREATE TABLE t1 (a INT); +insert into t1 values (1); +insert into t1 values (2); +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT a FROM t1; +var1 varchar(10); +BEGIN +OPEN c; +fetch c into var1; +SELECT c%ROWCOUNT,var1; +close c; +END; +$$ +CALL p1; +c%ROWCOUNT var1 +1 1 +DROP PROCEDURE p1; +drop table t1; +# +# Variable after condition declaration +# +CREATE TABLE t1 (col1 INT); +insert into t1 values (1); +create unique index t1_col1 on t1 (col1); +CREATE PROCEDURE p1 +AS +dup_key CONDITION FOR SQLSTATE '23000'; +var1 varchar(40); +CONTINUE HANDLER FOR dup_key +BEGIN +var1:='duplicate key in index'; +END; +BEGIN +var1:=''; +insert into t1 values (1); +select var1; +END; +$$ +CALL p1; +var1 +duplicate key in index +DROP PROCEDURE p1; +drop table t1; +# +# Condition after cursor declaration +# +CREATE TABLE t1 (col1 INT); +insert into t1 values (1); +create unique index t1_col1 on t1 (col1); +CREATE PROCEDURE p1 +AS +var1 varchar(40); +var2 integer; +CURSOR c IS SELECT col1 FROM t1; +dup_key CONDITION FOR SQLSTATE '23000'; +CONTINUE HANDLER FOR dup_key +BEGIN +var1:='duplicate key in index'; +END; +BEGIN +var1:=''; +insert into t1 values (1); +SELECT var1; +END; +$$ +CALL p1; +var1 +duplicate key in index +DROP PROCEDURE p1; +drop table t1; +# +# Cursor after handler declaration +# +CREATE TABLE t1 (col1 INT); +insert into t1 values (1); +create unique index t1_col1 on t1 (col1); +CREATE PROCEDURE p1 +AS +var1 varchar(40); +var2 integer; +dup_key CONDITION FOR SQLSTATE '23000'; +CONTINUE HANDLER FOR dup_key +BEGIN +var1:='duplicate key in index'; +END; +CURSOR c IS SELECT col1 FROM t1; +BEGIN +var1:=''; +insert into t1 values (1); +SELECT var1; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CURSOR c IS SELECT col1 FROM t1; +BEGIN +var1:=''; +insert into t1 values (1); +S...' at line 10 +drop table t1; +# +# Condition after handler declaration +# +CREATE TABLE t1 (col1 INT); +insert into t1 values (1); +create unique index t1_col1 on t1 (col1); +CREATE PROCEDURE p1 +AS +var1 varchar(40); +var2 integer; +dup_key CONDITION FOR SQLSTATE '23000'; +CURSOR c IS SELECT col1 FROM t1; +CONTINUE HANDLER FOR dup_key +BEGIN +var1:='duplicate key in index'; +END; +divide_by_zero CONDITION FOR SQLSTATE '22012'; +BEGIN +var1:=''; +insert into t1 values (1); +SELECT var1; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'divide_by_zero CONDITION FOR SQLSTATE '22012'; +BEGIN +var1:=''; +insert into t1...' at line 11 +drop table t1; +# +# Variable after handler declaration +# +CREATE TABLE t1 (col1 INT); +insert into t1 values (1); +create unique index t1_col1 on t1 (col1); +CREATE PROCEDURE p1 +AS +var1 varchar(40); +var2 integer; +dup_key CONDITION FOR SQLSTATE '23000'; +CURSOR c IS SELECT col1 FROM t1; +CONTINUE HANDLER FOR dup_key +BEGIN +var1:='duplicate key in index'; +END; +divide_by_zero CONDITION FOR SQLSTATE '22012'; +BEGIN +var1:=''; +insert into t1 values (1); +SELECT var1; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'divide_by_zero CONDITION FOR SQLSTATE '22012'; +BEGIN +var1:=''; +insert into t1...' at line 11 +drop table t1; +# +# Variable after cursor (inner block) +# +CREATE TABLE t1 (col1 INT); +insert into t1 values (1); +insert into t1 values (2); +create unique index t1_col1 on t1 (col1); +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT col1 FROM t1; +var1 varchar(40); +BEGIN +OPEN c; +begin +declare +CURSOR c IS SELECT col1 FROM t1 where col1=2; +var2 integer; +dup_key CONDITION FOR SQLSTATE '23000'; +CONTINUE HANDLER FOR dup_key +BEGIN +var1:='duplicate key in index'; +END; +begin +OPEN c; +fetch c into var1; +SELECT 'inner cursor',var1; +insert into t1 values (2); +close c; +end; +end; +SELECT var1; +fetch c into var1; +SELECT c%ROWCOUNT,var1; +begin +insert into t1 values (2); +exception when 1062 then +begin +SELECT 'dup key caugth'; +end; +end; +close c; +END; +$$ +CALL p1; +inner cursor var1 +inner cursor 2 +var1 +duplicate key in index +c%ROWCOUNT var1 +1 1 +dup key caugth +dup key caugth +DROP PROCEDURE p1; +drop table t1; +# +# Cursor declaration and row type declaration in same block +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +insert into t1 values(1,'a'); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT a FROM t1; +rec1 cur1%ROWTYPE; +BEGIN +rec1.a:= 10; +END; +$$ +call p1; +DROP PROCEDURE p1; +drop table t1; +# +# Recursive cursor and cursor%ROWTYPE declarations in the same block +# +CREATE PROCEDURE p1 +AS +a INT:=10; +b VARCHAR(10):='b0'; +c DOUBLE:=0.1; +CURSOR cur1 IS SELECT a, b, c; +rec1 cur1%ROWTYPE; +CURSOR cur2 IS SELECT rec1.a + 1 "a", rec1.b||'0' AS b, rec1.c AS c; +rec2 cur2%ROWTYPE; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec1; +CLOSE cur1; +SELECT rec1.a; +OPEN cur2; +FETCH cur2 INTO rec2; +CLOSE cur2; +SELECT rec2.a; +CREATE TABLE t2 AS SELECT rec2.a AS a, rec2.b AS b, rec2.c AS c; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +rec1.a +10 +rec2.a +11 +Table Create Table +t2 CREATE TABLE "t2" ( + "a" bigint(20) DEFAULT NULL, + "b" varchar(11) DEFAULT NULL, + "c" double DEFAULT NULL +) +DROP PROCEDURE p1; +# +# MDEV-12916 Wrong column data type for an INT field of a cursor-anchored ROW variable +# +CREATE PROCEDURE p1 +AS +a INT DEFAULT 10; +CURSOR cur1 IS SELECT a; +rec1 cur1%ROWTYPE; +BEGIN +CREATE TABLE t1 AS SELECT rec1.a; +SHOW CREATE TABLE t1; +DROP TABLE t1; +END; +$$ +CALL p1(); +Table Create Table +t1 CREATE TABLE "t1" ( + "rec1.a" int(11) DEFAULT NULL +) +DROP PROCEDURE p1; diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result new file mode 100644 index 00000000..31d794c9 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-cursor-rowtype.result @@ -0,0 +1,1506 @@ +SET sql_mode=ORACLE; +# +# MDEV-12011 sql_mode=ORACLE: cursor%ROWTYPE in variable declarations +# +# +# A complete working example +# +CREATE TABLE t1 (a INT, b VARCHAR(32)); +CREATE TABLE t2 LIKE t1; +INSERT INTO t1 VALUES (10,'b10'); +INSERT INTO t1 VALUES (20,'b20'); +INSERT INTO t1 VALUES (30,'b30'); +CREATE PROCEDURE p1 AS +CURSOR c IS SELECT a,b FROM t1; +BEGIN +DECLARE +rec c%ROWTYPE; +BEGIN +OPEN c; +LOOP +FETCH c INTO rec; +EXIT WHEN c%NOTFOUND; +SELECT 'rec=(' || rec.a ||','|| rec.b||')' AS c FROM dual; +INSERT INTO t2 VALUES (rec.a, rec.b); +END LOOP; +CLOSE c; +END; +END; +$$ +CALL p1(); +c +rec=(10,b10) +c +rec=(20,b20) +c +rec=(30,b30) +SELECT * FROM t2; +a b +10 b10 +20 b20 +30 b30 +DROP PROCEDURE p1; +DROP TABLE t2; +DROP TABLE t1; +# +# cursor%ROWTYPE referring to a table in a non-existing database +# +CREATE PROCEDURE p1() +AS +CURSOR cur IS SELECT * FROM tes2.t1; +BEGIN +DECLARE +rec cur%ROWTYPE; +BEGIN +NULL; +END; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'tes2.t1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CALL p1(); +ERROR 42S02: Table 'tes2.t1' doesn't exist +DROP TABLE t1; +DROP PROCEDURE p1; +# +# cursor%ROWTYPE referring to a table in the current database +# +CREATE PROCEDURE p1() +AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DECLARE +rec cur%ROWTYPE; +BEGIN +CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "rec.a" int(11) DEFAULT NULL, + "rec.b" varchar(10) DEFAULT NULL, + "rec.c" double DEFAULT NULL, + "rec.d" decimal(10,0) DEFAULT NULL +) +DROP TABLE t1; +CALL p1(); +ERROR 42S02: Table 'test.t1' doesn't exist +DROP PROCEDURE p1; +# +# cursor%ROWTYPE referring to a table in an explicitly specified database +# +CREATE PROCEDURE p1() +AS +CURSOR cur IS SELECT * FROM test.t1; +BEGIN +DECLARE +rec cur%ROWTYPE; +BEGIN +CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "rec.a" int(11) DEFAULT NULL, + "rec.b" varchar(10) DEFAULT NULL, + "rec.c" double DEFAULT NULL, + "rec.d" decimal(10,0) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Cursor%ROWTYPE referring to a view in the current database +# +CREATE PROCEDURE p1() +AS +CURSOR cur IS SELECT * FROM v1; +BEGIN +DECLARE +rec cur%ROWTYPE; +BEGIN +CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.v1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CREATE VIEW v1 AS SELECT * FROM t1; +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "rec.a" int(11) DEFAULT NULL, + "rec.b" varchar(10) DEFAULT NULL, + "rec.c" double DEFAULT NULL, + "rec.d" decimal(10,0) DEFAULT NULL +) +DROP VIEW v1; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# cursor%ROWTYPE referring to a view in an explicitly specified database +# +CREATE PROCEDURE p1() +AS +CURSOR cur IS SELECT * FROM test.v1; +BEGIN +DECLARE +rec cur%ROWTYPE; +BEGIN +CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.v1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CREATE VIEW v1 AS SELECT * FROM t1; +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "rec.a" int(11) DEFAULT NULL, + "rec.b" varchar(10) DEFAULT NULL, + "rec.c" double DEFAULT NULL, + "rec.d" decimal(10,0) DEFAULT NULL +) +DROP VIEW v1; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Checking that all cursor%ROWTYPE fields are NULL by default +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +BEGIN +SELECT rec1.a, rec1.b, rec1.c, rec1.d; +END; +END; +$$ +CALL p1(); +rec1.a rec1.b rec1.c rec1.d +NULL NULL NULL NULL +DROP TABLE t1; +DROP PROCEDURE p1; +# +# A cursor%ROWTYPE variable with a ROW expression as a default +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE := ROW(10,'bbb'); +BEGIN +SELECT rec1.a, rec1.b; +END; +END; +$$ +CALL p1(); +rec1.a rec1.b +10 bbb +DROP TABLE t1; +DROP PROCEDURE p1; +# +# A cursor%ROWTYPE variable with an incompatible ROW expression as a default +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE := ROW(10,'bbb','ccc'); +BEGIN +SELECT rec1.a, rec1.b; +END; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# A cursor%ROWTYPE variable with a ROW variable as a default +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 ROW(a INT, b VARCHAR(10)):= ROW(10,'bbb'); +rec2 cur%ROWTYPE := rec1; +BEGIN +SELECT rec2.a, rec2.b; +END; +END; +$$ +CALL p1(); +rec2.a rec2.b +10 bbb +DROP TABLE t1; +DROP PROCEDURE p1; +# +# A ROW variable using a cursor%ROWTYPE variable as a default +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE := ROW(10,'bbb'); +rec2 ROW(a INT, b VARCHAR(10)):= rec1; +BEGIN +SELECT rec2.a, rec2.b; +END; +END; +$$ +CALL p1(); +rec2.a rec2.b +10 bbb +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning cursor%ROWTYPE variables with a different column count +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE); +CREATE TABLE t2 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +CURSOR cur2 IS SELECT * FROM t2; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +rec2 cur2%ROWTYPE; +BEGIN +rec2:=rec1; +END; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +CURSOR cur2 IS SELECT * FROM t2; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +rec2 cur2%ROWTYPE; +BEGIN +rec1:=rec2; +END; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 3 column(s) +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning compatible cursor%ROWTYPE variables (equal number of fields) +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TABLE t2 (x INT, y VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +CURSOR cur2 IS SELECT * FROM t2; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +rec2 cur2%ROWTYPE; +BEGIN +rec1.a:= 10; +rec1.b:= 'bbb'; +rec2:=rec1; +SELECT rec2.x, rec2.y; +END; +END; +$$ +CALL p1(); +rec2.x rec2.y +10 bbb +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning between incompatible cursor%ROWTYPE and explicit ROW variables +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +rec2 ROW(x INT,y INT,z INT); +BEGIN +rec2.x:= 10; +rec2.y:= 20; +rec2.z:= 30; +rec1:= rec2; +END; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning between compatible cursor%ROWTYPE and explicit ROW variables +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +rec2 ROW(x INT,y INT); +BEGIN +rec2.x:= 10; +rec2.y:= 20; +rec1:= rec2; +SELECT rec1.a, rec1.b; +rec1.a:= 11; +rec1.b:= 21; +rec2:= rec1; +SELECT rec2.x, rec2.y; +END; +END; +$$ +CALL p1(); +rec1.a rec1.b +10 20 +rec2.x rec2.y +11 21 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning cursor%ROWTYPE from a ROW expression +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +BEGIN +rec1:= ROW(10,20); +SELECT rec1.a, rec1.b; +END; +END; +$$ +CALL p1(); +rec1.a rec1.b +10 20 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a cursor%ROWTYPE variable with a wrong field count +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); +CREATE TABLE t2 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10,'bb1',111.111e2, 12.31); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +CURSOR cur2 IS SELECT * FROM t2; +BEGIN +DECLARE +rec2 cur2%ROWTYPE; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec2; +CLOSE cur1; +END; +END; +$$ +CALL p1(); +ERROR HY000: Incorrect number of FETCH variables +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a cursor%ROWTYPE variable +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); +CREATE TABLE t2 LIKE t1; +INSERT INTO t1 VALUES (10,'bb1',111.111e2, 12.31); +INSERT INTO t1 VALUES (20,'bb2',222.222e2, 12.32); +INSERT INTO t1 VALUES (30,'bb3',333.333e2, 12.33); +CREATE PROCEDURE p1() +AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DECLARE +rec cur%ROWTYPE; +BEGIN +OPEN cur; +LOOP +FETCH cur INTO rec; +EXIT WHEN cur%NOTFOUND; +SELECT rec.a, rec.b, rec.c, rec.d; +INSERT INTO t2 VALUES (rec.a, rec.b, rec.c, rec.d); +END LOOP; +CLOSE cur; +END; +END; +$$ +CALL p1(); +rec.a rec.b rec.c rec.d +10 bb1 11111.1 12.31 +rec.a rec.b rec.c rec.d +20 bb2 22222.2 12.32 +rec.a rec.b rec.c rec.d +30 bb3 33333.3 12.33 +SELECT * FROM t2; +a b c d +10 bb1 11111.1 12.31 +20 bb2 22222.2 12.32 +30 bb3 33333.3 12.33 +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a cursor%ROWTYPE variable, cur%ROWTYPE declared inside the LOOP +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); +CREATE TABLE t2 LIKE t1; +INSERT INTO t1 VALUES (10,'bb1',111.111e2, 12.31); +INSERT INTO t1 VALUES (20,'bb2',222.222e2, 12.32); +INSERT INTO t1 VALUES (30,'bb3',333.333e2, 12.33); +CREATE PROCEDURE p1() +AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +OPEN cur; +LOOP +DECLARE +rec cur%ROWTYPE; +BEGIN +FETCH cur INTO rec; +EXIT WHEN cur%NOTFOUND; +SELECT rec.a, rec.b, rec.c, rec.d; +INSERT INTO t2 VALUES (rec.a, rec.b, rec.c, rec.d); +END; +END LOOP; +CLOSE cur; +END; +$$ +CALL p1(); +rec.a rec.b rec.c rec.d +10 bb1 11111.1 12.31 +rec.a rec.b rec.c rec.d +20 bb2 22222.2 12.32 +rec.a rec.b rec.c rec.d +30 bb3 33333.3 12.33 +SELECT * FROM t2; +a b c d +10 bb1 11111.1 12.31 +20 bb2 22222.2 12.32 +30 bb3 33333.3 12.33 +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a cursor%ROWTYPE variable with different column names +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TABLE t2 (x INT, y VARCHAR(10)); +INSERT INTO t1 VALUES (10,'bbb'); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +CURSOR cur2 IS SELECT * FROM t2; +BEGIN +DECLARE +rec2 cur2%ROWTYPE; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec2; +SELECT rec2.x, rec2.y; +CLOSE cur1; +END; +END; +$$ +CALL p1(); +rec2.x rec2.y +10 bbb +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a cursor%ROWTYPE variable, with truncation +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TABLE t2 (a INT, b INT); +INSERT INTO t1 VALUES (10,'11x'); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +CURSOR cur2 IS SELECT * FROM t2; +BEGIN +DECLARE +rec2 cur2%ROWTYPE; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec2; +SELECT rec2.a, rec2.b; +CLOSE cur1; +END; +END; +$$ +CALL p1(); +rec2.a rec2.b +10 11 +Warnings: +Warning 1265 Data truncated for column 'b' at row 1 +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# cursor%ROWTYPE variables are not allowed in LIMIT +# +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,2); +CREATE PROCEDURE p1() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE:=(1,2); +BEGIN +SELECT * FROM t1 LIMIT rec1.a; +END; +END; +$$ +ERROR HY000: A variable of a non-integer based type in LIMIT clause +DROP TABLE t1; +# +# cursor%ROWTYPE variable fields as OUT parameters +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1(a OUT INT,b OUT VARCHAR(10)) +AS +BEGIN +a:=10; +b:='bb'; +END; +$$ +CREATE PROCEDURE p2() +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +BEGIN +CALL p1(rec1.a, rec1.b); +SELECT rec1.a, rec1.b; +END; +END; +$$ +CALL p2(); +rec1.a rec1.b +10 bb +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Passing the entire cursor%ROWTYPE variable +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1(a ROW(a INT, b VARCHAR(10))) +AS +BEGIN +SELECT a.a, a.b; +END; +$$ +CREATE PROCEDURE p2() +AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur%ROWTYPE:= ROW(10,'bb'); +BEGIN +CALL p1(rec1); +END; +END; +$$ +CALL p2(); +a.a a.b +10 bb +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Passing the entire cursor%ROWTYPE variable as an OUT parameter +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1(a OUT ROW(a INT, b VARCHAR(10))) +AS +BEGIN +a:= ROW(10,'bb'); +END; +$$ +CREATE PROCEDURE p2() +AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DECLARE +rec1 cur%ROWTYPE; +BEGIN +CALL p1(rec1); +SELECT rec1.a, rec1.b; +END; +END; +$$ +CALL p2(); +rec1.a rec1.b +10 bb +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Assigning a cursor%ROWTYPE field to an OUT parameter +# +CREATE PROCEDURE p1 (res IN OUT INTEGER) +AS +a INT:=10; +CURSOR cur1 IS SELECT a FROM DUAL; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec1; +CLOSE cur1; +res:=rec1.a; +END; +END; +$$ +CALL p1(@res); +SELECT @res; +@res +10 +SET @res=NULL; +DROP PROCEDURE p1; +# +# Testing Item_splocal_row_field_by_name::print +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1 +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec cur1%ROWTYPE:=ROW(10,'bb'); +BEGIN +EXPLAIN EXTENDED SELECT rec.a, rec.b; +END; +END; +$$ +CALL p1(); +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 rec.a@0["a"] AS "rec.a",rec.b@0["b"] AS "rec.b" +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Run time error in the cursor statement +# +CREATE PROCEDURE p1 +AS +CURSOR cur1 IS SELECT +10 AS a, +CONCAT(_latin1'a' COLLATE latin1_bin, +_latin1'a' COLLATE latin1_swedish_ci) AS b; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec1; +CLOSE cur1; +SELECT a,b; +END; +END; +$$ +CALL p1(); +ERROR HY000: Illegal mix of collations (latin1_bin,EXPLICIT) and (latin1_swedish_ci,EXPLICIT) for operation 'concat_operator_oracle' +DROP PROCEDURE p1; +# +# Non-existing field +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1 +AS +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +DECLARE +rec cur1%ROWTYPE; +BEGIN +SELECT rec.c; +END; +END; +$$ +CALL p1(); +ERROR HY000: Row variable 'rec' does not have a field 'c' +ALTER TABLE t1 ADD c INT; +ALTER PROCEDURE p1 COMMENT 'test'; +CALL p1(); +rec.c +NULL +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing that field names are case insensitive +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1 +AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DECLARE +rec cur%ROWTYPE:=ROW(10,'bb'); +BEGIN +SELECT rec.A, rec.B; +END; +END; +$$ +CALL p1(); +rec.A rec.B +10 bb +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing that cursor%ROWTYPE uses temporary tables vs shadowed real tables +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TEMPORARY TABLE t1 (x INT, y VARCHAR(10)); +CREATE PROCEDURE p1 +AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DECLARE +rec cur%ROWTYPE:=ROW(10,'bb'); +BEGIN +SELECT rec.A, rec.B; +END; +END; +$$ +CALL p1(); +ERROR HY000: Row variable 'rec' does not have a field 'A' +DROP TEMPORARY TABLE t1; +ALTER PROCEDURE p1 COMMENT 'test'; +CALL p1(); +rec.A rec.B +10 bb +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing that the structure of cursor%ROWTYPE variables is determined at the CURSOR instantiation time +# +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DROP TABLE t1; +CREATE TABLE t1 (a INT, b VARCHAR(32), c INT); +DECLARE +rec cur%ROWTYPE; -- This has a column "c" + BEGIN +rec.c:=10; +END; +END; +$$ +CALL p1(); +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +CURSOR cur IS SELECT * FROM t1; +BEGIN +DECLARE +rec cur%ROWTYPE; -- This does not have a column "c" + BEGIN +DROP TABLE t1; +CREATE TABLE t1 (a INT, b VARCHAR(32), c INT); +rec.c:=10; +END; +END; +$$ +CALL p1(); +ERROR HY000: Row variable 'rec' does not have a field 'c' +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Duplicate field nams in a cursor referenced by %ROWTYPE +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +CREATE PROCEDURE p1 AS +CURSOR cur IS SELECT * FROM t1, t2; +BEGIN +DECLARE +rec cur%ROWTYPE; +BEGIN +SELECT rec.a; +rec.a:=10; +END; +END; +$$ +CALL p1(); +ERROR 42S21: Duplicate column name 'a' +DROP PROCEDURE p1; +DROP TABLE t2; +DROP TABLE t1; +# +# Tricky field names a cursor referenced by %ROWTYPE +# +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10)); +INSERT INTO t1 VALUES ('a'); +CREATE PROCEDURE p1 AS +CURSOR cur IS SELECT a, CONCAT(a,'a'), CONCAT(a,'ö') FROM t1; +BEGIN +DECLARE +rec cur%ROWTYPE; +BEGIN +OPEN cur; +FETCH cur INTO rec; +CLOSE cur; +SELECT rec.a, rec."CONCAT(a,'a')", rec."CONCAT(a,'ö')"; +END; +END; +$$ +CALL p1(); +rec.a rec."CONCAT(a,'a')" rec."CONCAT(a,'ö')" +a aa aö +DROP PROCEDURE p1; +DROP TABLE t1; +SET NAMES latin1; +# +# Using definitions recursively (cursor%ROWTYPE variables in another cursor SELECT) +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10,'b1'),(20,'b2'),(30,'b3'); +CREATE PROCEDURE p1 AS +CURSOR cur1 IS SELECT a,b FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE:=ROW(0,'b0'); +CURSOR cur2 IS SELECT rec1.a AS a, rec1.b AS b FROM t1; +BEGIN +DECLARE +rec2 cur2%ROWTYPE; +BEGIN +OPEN cur2; +LOOP +FETCH cur2 INTO rec2; +EXIT WHEN cur2%NOTFOUND; +SELECT rec2.a, rec2.b; +END LOOP; +CLOSE cur2; +END; +END; +END; +$$ +CALL p1(); +rec2.a rec2.b +0 b0 +rec2.a rec2.b +0 b0 +rec2.a rec2.b +0 b0 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing queries with auto-generated Items. +# An instance of Item_func_conv_charset is created during the below SELECT query. +# We check here that during an implicit cursor OPEN +# done in sp_instr_cursor_copy_struct::exec_core() +# all temporary Items are created on a proper memory root and are safely destroyed. +# +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1, b VARCHAR(10) CHARACTER SET utf8); +INSERT INTO t1 VALUES (0xFF, 'a'); +CREATE PROCEDURE p1 +AS +CURSOR cur1 IS SELECT CONCAT(a,b) AS c FROM t1; +BEGIN +DECLARE +rec1 cur1%ROWTYPE; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec1; +CLOSE cur1; +SELECT HEX(rec1.c); +END; +END; +$$ +CALL p1(); +HEX(rec1.c) +C3BF61 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-10581 sql_mode=ORACLE: Explicit cursor FOR LOOP +# +# IN followed by a non-identifier +CREATE PROCEDURE p1 AS +CURSOR c1 IS SELECT 'test' AS a FROM DUAL; +BEGIN +FOR rec IN 10 +LOOP +NULL; +END LOOP; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'LOOP +NULL; +END LOOP; +END' at line 6 +# IN followed by a quoted identifier: table.column +CREATE PROCEDURE p1 AS +CURSOR c1 IS SELECT 'test' AS a FROM DUAL; +BEGIN +FOR rec IN c1.c2 +LOOP +NULL; +END LOOP; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'LOOP +NULL; +END LOOP; +END' at line 6 +# IN followed by a quoted identifier: .table.column +CREATE PROCEDURE p1 AS +CURSOR c1 IS SELECT 'test' AS a FROM DUAL; +BEGIN +FOR rec IN .c1.c2 +LOOP +NULL; +END LOOP; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'LOOP +NULL; +END LOOP; +END' at line 6 +# IN followed by a quoted identifier: schema.table.column +CREATE PROCEDURE p1 AS +CURSOR c1 IS SELECT 'test' AS a FROM DUAL; +BEGIN +FOR rec IN c1.c2.c3 +LOOP +NULL; +END LOOP; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'LOOP +NULL; +END LOOP; +END' at line 6 +# IN followed by an unknown cursor name +CREATE PROCEDURE p1 AS +CURSOR c1 IS SELECT 'test' AS a FROM DUAL; +BEGIN +FOR rec IN c2 +LOOP +NULL; +END LOOP; +END; +$$ +ERROR 42000: Undeclared variable: c2 +# Make sure "rec" shadows other declarations outside the loop +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10, 'b0'); +CREATE PROCEDURE p1 AS +rec INT:=10; +CURSOR c1 IS SELECT a,b FROM t1; +BEGIN +FOR rec IN c1 +LOOP +SELECT rec.a; +END LOOP; +SELECT rec; +END; +$$ +CALL p1; +rec.a +10 +rec +10 +DROP PROCEDURE p1; +DROP TABLE t1; +# Make sure "rec" is not visible after END LOOP +CREATE PROCEDURE p1 AS +CURSOR c1 IS SELECT 'test' AS a FROM DUAL; +BEGIN +FOR rec IN c1 +LOOP +NULL; +END LOOP; +rec.a:= 10; +END; +$$ +ERROR HY000: Unknown structured system variable or ROW routine variable 'rec' +# Make sure that duplicate column names are not allowed +CREATE PROCEDURE p1 AS +CURSOR cur IS SELECT 'a' AS a, 'A' as a; +BEGIN +FOR rec IN cur +LOOP +NULL; +END LOOP; +END; +$$ +CALL p1; +ERROR 42S21: Duplicate column name 'a' +DROP PROCEDURE p1; +# A complete working example +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10,'b0'); +INSERT INTO t1 VALUES (11,'b1'); +INSERT INTO t1 VALUES (12,'b2'); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; +CREATE PROCEDURE p1 AS +CURSOR cur IS SELECT a, b FROM t1; +BEGIN +FOR rec IN cur +LOOP +SELECT rec.a, rec.b; +INSERT INTO t2 VALUES (rec.a, rec.b); +rec.a:= rec.a + 1000; +rec.b:= 'b' || rec.b; +INSERT INTO t3 VALUES (rec.a, rec.b); +END LOOP; +END; +$$ +CALL p1(); +rec.a rec.b +10 b0 +rec.a rec.b +11 b1 +rec.a rec.b +12 b2 +SELECT * FROM t2; +a b +10 b0 +11 b1 +12 b2 +SELECT * FROM t3; +a b +1010 bb0 +1011 bb1 +1012 bb2 +DROP PROCEDURE p1; +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; +# +# MDEV-12314 Implicit cursor FOR LOOP for cursors with parameters +# +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b0'); +INSERT INTO t1 VALUES (11,'b1'); +INSERT INTO t1 VALUES (12,'b2'); +CREATE PROCEDURE p1(pa INT, pb VARCHAR(32)) AS +CURSOR cur(va INT, vb VARCHAR(32)) IS +SELECT a, b FROM t1 WHERE a=va AND b=vb; +BEGIN +FOR rec IN cur(pa,pb) +LOOP +SELECT rec.a, rec.b; +END LOOP; +END; +$$ +CALL p1(10,'B0'); +rec.a rec.b +10 b0 +CALL p1(11,'B1'); +rec.a rec.b +11 b1 +CALL p1(12,'B2'); +rec.a rec.b +12 b2 +CALL p1(12,'non-existing'); +DROP TABLE t1; +DROP PROCEDURE p1; +# +# MDEV-12098 sql_mode=ORACLE: Implicit cursor FOR loop +# +# Parse error in the cursor SELECT statement +CREATE PROCEDURE p1 AS +BEGIN +FOR rec IN (SELECT a, b FROM) +LOOP +SELECT rec.a, rec.b; +END LOOP; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') +LOOP +SELECT rec.a, rec.b; +END LOOP; +END' at line 3 +# Make sure "rec" is not visible after END LOOP +CREATE PROCEDURE p1 AS +BEGIN +FOR rec IN (SELECT 'test' AS a) +LOOP +NULL; +END LOOP; +rec.a:= 10; +END; +$$ +ERROR HY000: Unknown structured system variable or ROW routine variable 'rec' +# Make sure "rec" is not visible inside the SELECT statement +CREATE PROCEDURE p1 AS +BEGIN +FOR rec IN (SELECT rec) +LOOP +NULL; +END LOOP; +END; +$$ +CALL p1; +ERROR 42S22: Unknown column 'rec' in 'field list' +DROP PROCEDURE p1; +CREATE PROCEDURE p1 AS +BEGIN +FOR rec IN (SELECT rec.a) +LOOP +NULL; +END LOOP; +END; +$$ +CALL p1; +ERROR 42S02: Unknown table 'rec' in field list +DROP PROCEDURE p1; +# Totally confusing name mixture +CREATE TABLE rec (rec INT); +INSERT INTO rec VALUES (10); +CREATE PROCEDURE p1 AS +BEGIN +FOR rec IN (SELECT rec FROM rec) +LOOP +SELECT rec.rec; +END LOOP; +END; +$$ +CALL p1; +rec.rec +10 +DROP PROCEDURE p1; +DROP TABLE rec; +# Make sure that duplicate column names are not allowed +CREATE PROCEDURE p1 AS +BEGIN +FOR rec IN (SELECT 'a' AS a, 'A' as a) +LOOP +NULL; +END LOOP; +END; +$$ +CALL p1; +ERROR 42S21: Duplicate column name 'a' +DROP PROCEDURE p1; +# A complete working example +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10,'b0'); +INSERT INTO t1 VALUES (11,'b1'); +INSERT INTO t1 VALUES (12,'b2'); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; +CREATE PROCEDURE p1 AS +BEGIN +FOR rec IN (SELECT a, b FROM t1) +LOOP +SELECT rec.a, rec.b; +INSERT INTO t2 VALUES (rec.a, rec.b); +rec.a:= rec.a + 1000; +rec.b:= 'b'|| rec.b; +INSERT INTO t3 VALUES (rec.a, rec.b); +END LOOP; +END; +$$ +CALL p1(); +rec.a rec.b +10 b0 +rec.a rec.b +11 b1 +rec.a rec.b +12 b2 +SELECT * FROM t2; +a b +10 b0 +11 b1 +12 b2 +SELECT * FROM t3; +a b +1010 bb0 +1011 bb1 +1012 bb2 +DROP PROCEDURE p1; +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; +# A combination of explicit and implicit cursors +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10,'b1'); +INSERT INTO t1 VALUES (11,'b2'); +INSERT INTO t1 VALUES (12,'b3'); +CREATE PROCEDURE p1 AS +BEGIN +FOR rec1 IN (SELECT a, b FROM t1) +LOOP +DECLARE +CURSOR cur2 IS SELECT a+1000 AS a, 'bb'||b AS b FROM t1 WHERE a=rec1.a AND b=rec1.b; +BEGIN +SELECT rec1.a, rec1.b; +FOR rec2 IN cur2 +LOOP +SELECT rec2.a, rec2.b; +END LOOP; +END; +END LOOP; +FOR rec1 IN (SELECT a,b FROM t1) +LOOP +FOR rec2 IN (SELECT a+2000 AS a,'bbb'||b AS b FROM t1 WHERE a=rec1.a AND b=rec1.b) +LOOP +SELECT rec2.a, rec2.b; +END LOOP; +END LOOP; +END; +$$ +CALL p1(); +rec1.a rec1.b +10 b1 +rec2.a rec2.b +1010 bbb1 +rec1.a rec1.b +11 b2 +rec2.a rec2.b +1011 bbb2 +rec1.a rec1.b +12 b3 +rec2.a rec2.b +1012 bbb3 +rec2.a rec2.b +2010 bbbb1 +rec2.a rec2.b +2011 bbbb2 +rec2.a rec2.b +2012 bbbb3 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-15941 Explicit cursor FOR loop does not close the cursor +# +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +v INT; +BEGIN +FOR rec IN cur +LOOP +NULL; +END LOOP; +FETCH cur INTO v; +END; +$$ +ERROR 24000: Cursor is not open +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +v INT; +BEGIN +<<label>> +FOR rec IN cur +LOOP +NULL; +END LOOP label; +FETCH cur INTO v; +END; +$$ +ERROR 24000: Cursor is not open +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN +OPEN cur; +FOR rec IN cur +LOOP +NULL; +END LOOP; +END; +$$ +ERROR 24000: Cursor is already open +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN +FOR rec IN cur +LOOP +SELECT rec.a; +END LOOP; +SELECT cur%ISOPEN; +FOR rec IN cur +LOOP +SELECT rec.a; +END LOOP; +SELECT cur%ISOPEN; +END; +$$ +rec.a +1 +cur%ISOPEN +0 +rec.a +1 +cur%ISOPEN +0 +DECLARE +CURSOR cur IS SELECT 1 AS a FROM DUAL; +BEGIN +<<label1>> +FOR rec IN cur +LOOP +SELECT rec.a; +END LOOP label1; +SELECT cur%ISOPEN; +<<label2>> +FOR rec IN cur +LOOP +SELECT rec.a; +END LOOP; +SELECT cur%ISOPEN; +END; +$$ +rec.a +1 +cur%ISOPEN +0 +rec.a +1 +cur%ISOPEN +0 +# +# MDEV-14139 Anchored data types for variables +# +DECLARE +CURSOR c1 IS SELECT 10 AS a, 'bbb' AS b, TIME'10:20:30' AS c; +row1 c1%ROWTYPE; +a_row1 row1%TYPE; +aa_row1 a_row1%TYPE; +BEGIN +CREATE TABLE t2 AS SELECT a_row1.a AS a, a_row1.b AS b, a_row1.c AS c; +SHOW CREATE TABLE t2; +DROP TABLE t2; +CREATE TABLE t2 AS SELECT aa_row1.a AS a, aa_row1.b AS b, aa_row1.c AS c; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +Table Create Table +t2 CREATE TABLE "t2" ( + "a" int(11) DEFAULT NULL, + "b" varchar(3) DEFAULT NULL, + "c" time DEFAULT NULL +) +Table Create Table +t2 CREATE TABLE "t2" ( + "a" int(11) DEFAULT NULL, + "b" varchar(3) DEFAULT NULL, + "c" time DEFAULT NULL +) +# +# MDEV-14388 Server crashes in handle_select / val_uint in ORACLE mode +# +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (0),(1),(2),(3); +CREATE FUNCTION f1() RETURN INT is +BEGIN +FOR v1 in (SELECT id FROM t1) +LOOP +NULL; +END LOOP; +RETURN 1; +END; +$$ +SELECT f1(); +f1() +1 +DROP FUNCTION f1; +DROP TABLE t1; +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE FUNCTION f1() RETURN INT IS +CURSOR cur IS SELECT id FROM t1; +rec cur%ROWTYPE; +BEGIN +RETURN 1; +END; +$$ +SELECT f1(); +f1() +1 +DROP FUNCTION f1; +DROP TABLE t1; +# +# MDEV-17278 CURSOR FOR LOOP - ERROR: unexpected end of stream, read 0 bytes (SERVER CRASH) +# +CREATE TABLE t1 (id2 int, id int, en1 enum('aaa','a','b','c')); +INSERT INTO t1 VALUES(1,1,'aaa'),(2,2,'a'),(3,3,'b'),(4,4,'c'); +CREATE PROCEDURE p1() +AS +BEGIN +FOR rec IN (SELECT en1 FROM t1) +LOOP +SELECT rec.en1; +END LOOP; +END; +$$ +CALL p1(); +rec.en1 +aaa +rec.en1 +a +rec.en1 +b +rec.en1 +c +DROP PROCEDURE p1; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor.result b/mysql-test/suite/compat/oracle/r/sp-cursor.result new file mode 100644 index 00000000..aa9c5de8 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-cursor.result @@ -0,0 +1,1022 @@ +SET sql_mode=ORACLE; +# +# MDEV-10582 sql_mode=ORACLE: explicit cursor attributes %ISOPEN, %ROWCOUNT, %FOUND, %NOTFOUND +# +# +# Cursor attributes outside of an SP context +# +SELECT c%ISOPEN; +ERROR 42000: Undefined CURSOR: c +SELECT c%FOUND; +ERROR 42000: Undefined CURSOR: c +SELECT c%NOTFOUND; +ERROR 42000: Undefined CURSOR: c +SELECT c%ROWCOUNT; +ERROR 42000: Undefined CURSOR: c +# +# Undefinite cursor attributes +# +CREATE PROCEDURE p1 +AS +BEGIN +SELECT c%ISOPEN; +END; +$$ +ERROR 42000: Undefined CURSOR: c +CREATE PROCEDURE p1 +AS +BEGIN +SELECT c%ROWCOUNT; +END; +$$ +ERROR 42000: Undefined CURSOR: c +CREATE PROCEDURE p1 +AS +BEGIN +SELECT c%FOUND; +END; +$$ +ERROR 42000: Undefined CURSOR: c +CREATE PROCEDURE p1 +AS +BEGIN +SELECT c%NOTFOUND; +END; +$$ +ERROR 42000: Undefined CURSOR: c +# +# Not opened cursor attributes %FOUND, %NOTFOUND, %ROWCOUNT +# +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT 1 AS c FROM DUAL; +BEGIN +SELECT c%ROWCOUNT; +END; +$$ +CALL p1; +ERROR 24000: Cursor is not open +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT 1 AS c FROM DUAL; +BEGIN +SELECT c%FOUND; +END; +$$ +CALL p1; +ERROR 24000: Cursor is not open +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT 1 AS c FROM DUAL; +BEGIN +SELECT c%NOTFOUND; +END; +$$ +CALL p1; +ERROR 24000: Cursor is not open +DROP PROCEDURE p1; +# +# Not opened cursor attributes %FOUND, %NOTFOUND, %ROWCOUNT with INVALID_CURSOR exception +# +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT 1 AS c FROM DUAL; +BEGIN +SELECT c%ROWCOUNT; +EXCEPTION +WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg; +END; +$$ +CALL p1; +c%ROWCOUNT +msg +INVALID_CURSOR caught +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT 1 AS c FROM DUAL; +BEGIN +SELECT c%FOUND; +EXCEPTION +WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg; +END; +$$ +CALL p1; +c%FOUND +msg +INVALID_CURSOR caught +DROP PROCEDURE p1; +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT 1 AS c FROM DUAL; +BEGIN +SELECT c%NOTFOUND; +EXCEPTION +WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg; +END; +$$ +CALL p1; +c%NOTFOUND +msg +INVALID_CURSOR caught +DROP PROCEDURE p1; +# +# print() +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT * FROM t1 ORDER BY a; +BEGIN +EXPLAIN EXTENDED SELECT c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +END; +$$ +CALL p1(); +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 "c"%ISOPEN AS "c%ISOPEN","c"%ROWCOUNT AS "c%ROWCOUNT","c"%FOUND AS "c%FOUND","c"%NOTFOUND AS "c%NOTFOUND" +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Declared data type of the attributes +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +CREATE PROCEDURE p1 +AS +CURSOR c IS SELECT * FROM t1 ORDER BY a; +BEGIN +OPEN c; +CREATE TABLE t2 AS SELECT c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +SHOW CREATE TABLE t2; +DROP TABLE t2; +CLOSE c; +END; +$$ +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "c%ISOPEN" int(1) NOT NULL, + "c%ROWCOUNT" bigint(21) DEFAULT NULL, + "c%FOUND" int(1) DEFAULT NULL, + "c%NOTFOUND" int(1) DEFAULT NULL +) +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Core functionality +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (20); +INSERT INTO t1 VALUES (30); +CREATE PROCEDURE p1 +AS +a INT:=0; +CURSOR c IS SELECT * FROM t1 ORDER BY a; +BEGIN +SELECT a, c%ISOPEN; +OPEN c; +/* +After OPEN and before FETCH: +- %ROWCOUNT returns 0 +- %FOUND and %NOTFOUND return NULL +*/ +SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +FETCH c INTO a; +SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +FETCH c INTO a; +SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +FETCH c INTO a; +SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +FETCH c INTO a; +SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +CLOSE c; +SELECT a, c%ISOPEN; +/* +After reopen and before FETCH: +- %ROWCOUNT returns 0 +- %FOUND and %NOTFOUND return NULL +*/ +OPEN c; +SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +FETCH c INTO a; +SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; +CLOSE c; +END; +$$ +CALL p1(); +a c%ISOPEN +0 0 +a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND +0 1 0 NULL NULL +a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND +10 1 1 1 0 +a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND +20 1 2 1 0 +a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND +30 1 3 1 0 +a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND +30 1 3 0 1 +a c%ISOPEN +30 0 +a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND +30 1 0 NULL NULL +a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND +10 1 1 1 0 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# %NOTFOUND as a loop exit condition +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (20); +INSERT INTO t1 VALUES (30); +CREATE PROCEDURE p1 +AS +a INT:=0; +CURSOR c IS SELECT * FROM t1 ORDER BY a; +BEGIN +OPEN c; +LOOP +FETCH c INTO a; +EXIT WHEN c%NOTFOUND; +SELECT a; +END LOOP; +CLOSE c; +END; +$$ +CALL p1(); +a +10 +a +20 +a +30 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# %FOUND as a loop exit condition +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (20); +INSERT INTO t1 VALUES (30); +CREATE PROCEDURE p1 +AS +a INT:=0; +CURSOR c IS SELECT * FROM t1 ORDER BY a; +BEGIN +OPEN c; +LOOP +FETCH c INTO a; +EXIT WHEN NOT c%FOUND; +SELECT a; +END LOOP; +CLOSE c; +END; +$$ +CALL p1(); +a +10 +a +20 +a +30 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# End of MDEV-10582 sql_mode=ORACLE: explicit cursor attributes %ISOPEN, %ROWCOUNT, %FOUND, %NOTFOUND +# +# +# MDEV-10597 Cursors with parameters +# +# +# OPEN with a wrong number of parameters +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1(a_a INT,a_b VARCHAR) +AS +v_a INT; +v_b VARCHAR(10); +CURSOR c (p_a INT, p_b VARCHAR) IS SELECT * FROM t1 WHERE a=p_a; +BEGIN +OPEN c(a_a); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +DBMS_OUTPUT.PUT_LINE('Fetched a record a='||TO_CHAR(v_a)||' b='||v_b); +END LOOP; +CLOSE c; +END; +$$ +ERROR 42000: Incorrect parameter count to cursor 'c' +DROP TABLE t1; +# +# Cursor parameters are not visible outside of the cursor +# +CREATE PROCEDURE p1(a_a INT) +AS +v_a INT; +CURSOR c (p_a INT) IS SELECT a FROM t1 WHERE a=p_a; +BEGIN +OPEN c(a_a); +p_a:=10; +END; +$$ +ERROR HY000: Unknown system variable 'p_a' +CREATE PROCEDURE p1(a_a INT) +AS +v_a INT; +CURSOR c (p_a INT) IS SELECT a FROM t1 WHERE a=p_a; +BEGIN +p_a:=10; +OPEN c(a_a); +END; +$$ +ERROR HY000: Unknown system variable 'p_a' +# +# Cursor parameter shadowing a local variable +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +CREATE PROCEDURE p1(a INT) +AS +v_a INT:=NULL; +p_a INT:=NULL; +CURSOR c (p_a VARCHAR2) IS SELECT a FROM t1 WHERE p_a IS NOT NULL; +BEGIN +OPEN c(a); +FETCH c INTO v_a; +IF c%NOTFOUND THEN +BEGIN +SELECT 'No records found' AS msg; +RETURN; +END; +END IF; +CLOSE c; +SELECT 'Fetched a record a='||v_a AS msg; +INSERT INTO t1 VALUES (v_a); +END; +$$ +CALL p1(1); +msg +Fetched a record a=1 +SELECT * FROM t1; +a +1 +1 +CALL p1(NULL); +msg +No records found +SELECT * FROM t1; +a +1 +1 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Parameters in SELECT list +# +CREATE PROCEDURE p1(a_a INT, a_b VARCHAR) +AS +v_a INT; +v_b VARCHAR(10); +CURSOR c (p_a INT, p_b VARCHAR) IS SELECT p_a,p_b FROM DUAL; +BEGIN +FOR i IN 0..1 +LOOP +OPEN c(a_a + i,a_b); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +SELECT 'Fetched a record a=' || v_a || ' b=' || v_b AS msg; +END LOOP; +CLOSE c; +END LOOP; +END; +$$ +CALL p1(1,'b1'); +msg +Fetched a record a=1 b=b1 +msg +Fetched a record a=2 b=b1 +DROP PROCEDURE p1; +# +# Parameters in SELECT list + UNION +# +CREATE PROCEDURE p1(a_a INT, a_b VARCHAR) +AS +v_a INT; +v_b VARCHAR(10); +CURSOR c (p_a INT, p_b VARCHAR) IS +SELECT p_a,p_b FROM DUAL +UNION ALL +SELECT p_a+1,p_b||'b' FROM DUAL; +BEGIN +OPEN c(a_a,a_b); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +SELECT 'Fetched a record a=' || v_a || ' b=' || v_b AS msg; +END LOOP; +CLOSE c; +END; +$$ +CALL p1(1,'b1'); +msg +Fetched a record a=1 b=b1 +msg +Fetched a record a=2 b=b1b +DROP PROCEDURE p1; +# +# Parameters in SELECT list + type conversion + warnings +# +CREATE PROCEDURE p1(a_a VARCHAR) +AS +v_a INT; +CURSOR c (p_a INT) IS SELECT p_a FROM DUAL; +BEGIN +OPEN c(a_a); +LOOP +FETCH c INTO v_a; +EXIT WHEN c%NOTFOUND; +SELECT 'Fetched a record a=' || v_a AS msg; +END LOOP; +CLOSE c; +END; +$$ +CALL p1('1b'); +msg +Fetched a record a=1 +Warnings: +Warning 1265 Data truncated for column 'p_a' at row 0 +CALL p1('b1'); +msg +Fetched a record a=0 +Warnings: +Warning 1366 Incorrect integer value: 'b1' for column ``.``.`p_a` at row 0 +DROP PROCEDURE p1; +# +# One parameter in SELECT list + subselect +# +CREATE PROCEDURE p1(a_a VARCHAR) +AS +v_a VARCHAR(10); +CURSOR c (p_a VARCHAR) IS +SELECT p_a FROM DUAL UNION SELECT REVERSE(p_a) FROM DUAL; +BEGIN +OPEN c((SELECT a_a)); +LOOP +FETCH c INTO v_a; +EXIT WHEN c%NOTFOUND; +SELECT v_a; +END LOOP; +CLOSE c; +END; +$$ +CALL p1('ab'); +v_a +ab +v_a +ba +DROP PROCEDURE p1; +# +# Two parameters in SELECT list + subselect +# +SET sql_mode=ORACLE; +CREATE PROCEDURE p1() +AS +v_a VARCHAR(10); +v_b VARCHAR(20); +CURSOR c (p_a VARCHAR, p_b VARCHAR) IS +SELECT p_a, p_b FROM DUAL +UNION +SELECT p_b, p_a FROM DUAL; +BEGIN +OPEN c((SELECT 'aaa'),(SELECT 'bbb')); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +SELECT v_a, v_b; +END LOOP; +CLOSE c; +END; +$$ +CALL p1(); +v_a v_b +aaa bbb +v_a v_b +bbb aaa +DROP PROCEDURE p1; +# +# Two parameters in SELECT list + two parameters in WHERE + subselects +# +SET sql_mode=ORACLE; +CREATE PROCEDURE p1(a_a VARCHAR, a_b VARCHAR) +AS +v_a VARCHAR(10); +v_b VARCHAR(20); +CURSOR c (value_a VARCHAR, value_b VARCHAR, +pattern_a VARCHAR, pattern_b VARCHAR) IS +SELECT value_a, value_b FROM DUAL WHERE value_a LIKE pattern_a +UNION +SELECT value_b, value_a FROM DUAL WHERE value_b LIKE pattern_b; +BEGIN +OPEN c((SELECT 'aaa'),(SELECT 'bbb'),(SELECT a_a),(SELECT a_b)); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +SELECT v_a, v_b; +END LOOP; +CLOSE c; +END; +$$ +CALL p1('%','%'); +v_a v_b +aaa bbb +v_a v_b +bbb aaa +CALL p1('aaa','xxx'); +v_a v_b +aaa bbb +CALL p1('xxx','bbb'); +v_a v_b +bbb aaa +CALL p1('xxx','xxx'); +DROP PROCEDURE p1; +# +# Parameters in SELECT list + stored function +# +CREATE FUNCTION f1 (a VARCHAR) RETURN VARCHAR +AS +BEGIN +RETURN a || 'y'; +END; +$$ +CREATE PROCEDURE p1(a_a VARCHAR) +AS +v_a VARCHAR(10); +v_b VARCHAR(10); +CURSOR c (p_sel_a VARCHAR, p_cmp_a VARCHAR) IS +SELECT p_sel_a, p_cmp_a FROM DUAL; +BEGIN +OPEN c(f1(a_a), f1(a_a)); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +SELECT v_a; +END LOOP; +CLOSE c; +END; +$$ +CALL p1('x'); +v_a +xy +CALL p1(f1(COALESCE(NULL, f1('x')))); +v_a +xyyy +DROP PROCEDURE p1; +DROP FUNCTION f1; +# +# One parameter in WHERE clause +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TABLE t2 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (1,'11'); +INSERT INTO t1 VALUES (1,'12'); +INSERT INTO t1 VALUES (2,'21'); +INSERT INTO t1 VALUES (2,'22'); +INSERT INTO t1 VALUES (3,'31'); +INSERT INTO t1 VALUES (3,'32'); +CREATE PROCEDURE p1(a_a INT) +AS +v_a INT; +v_b VARCHAR(10); +CURSOR c (p_a INT) IS SELECT a,b FROM t1 WHERE a=p_a; +BEGIN +OPEN c(a_a); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +INSERT INTO t2 VALUES (v_a,v_b); +END LOOP; +CLOSE c; +END; +$$ +CALL p1(1); +SELECT * FROM t2; +a b +1 11 +1 12 +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +# +# Two parameters in WHERE clause +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TABLE t2 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (1,'11'); +INSERT INTO t1 VALUES (1,'12'); +INSERT INTO t1 VALUES (2,'21'); +INSERT INTO t1 VALUES (2,'22'); +INSERT INTO t1 VALUES (3,'31'); +INSERT INTO t1 VALUES (3,'32'); +CREATE PROCEDURE p1(a_a INT, a_b VARCHAR) +AS +v_a INT; +v_b VARCHAR(10); +CURSOR c (p_a INT, p_b VARCHAR) IS SELECT a,b FROM t1 WHERE a=p_a AND b=p_b; +BEGIN +OPEN c(a_a, a_b); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +INSERT INTO t2 VALUES (v_a,v_b); +END LOOP; +CLOSE c; +END; +$$ +CALL p1(1,'11'); +SELECT * FROM t2; +a b +1 11 +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +# +# Parameters in WHERE and HAVING clauses +# +CREATE TABLE t1 (name VARCHAR(10), value INT); +INSERT INTO t1 VALUES ('but',1); +INSERT INTO t1 VALUES ('but',1); +INSERT INTO t1 VALUES ('but',1); +INSERT INTO t1 VALUES ('bin',1); +INSERT INTO t1 VALUES ('bin',1); +INSERT INTO t1 VALUES ('bot',1); +CREATE PROCEDURE p1 (arg_name_limit VARCHAR, arg_total_limit INT) +AS +v_name VARCHAR(10); +v_total INT; +-- +0 is needed to work around the bug MDEV-11081 +CURSOR c(p_v INT) IS +SELECT name, SUM(value + p_v) + 0 AS total FROM t1 +WHERE name LIKE arg_name_limit +GROUP BY name HAVING total>=arg_total_limit; +BEGIN +FOR i IN 0..1 +LOOP +OPEN c(i); +LOOP +FETCH c INTO v_name, v_total; +EXIT WHEN c%NOTFOUND; +SELECT v_name, v_total; +END LOOP; +CLOSE c; +END LOOP; +END; +$$ +CALL p1('%', 2); +v_name v_total +bin 2 +v_name v_total +but 3 +v_name v_total +bin 4 +v_name v_total +bot 2 +v_name v_total +but 6 +CALL p1('b_t', 0); +v_name v_total +bot 1 +v_name v_total +but 3 +v_name v_total +bot 2 +v_name v_total +but 6 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# One parameter in LIMIT clause +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (1,'b1'); +INSERT INTO t1 VALUES (2,'b2'); +INSERT INTO t1 VALUES (3,'b3'); +INSERT INTO t1 VALUES (4,'b4'); +INSERT INTO t1 VALUES (5,'b5'); +INSERT INTO t1 VALUES (6,'b6'); +CREATE PROCEDURE p1(a_a INT) +AS +v_a INT; +v_b VARCHAR(10); +CURSOR c (p_a INT) IS SELECT a,b FROM t1 ORDER BY a LIMIT p_a; +BEGIN +CREATE TABLE t2 (a INT, b VARCHAR(10)); +OPEN c(a_a); +LOOP +FETCH c INTO v_a, v_b; +EXIT WHEN c%NOTFOUND; +INSERT INTO t2 VALUES (v_a,v_b); +END LOOP; +CLOSE c; +SELECT * FROM t2; +DROP TABLE t2; +END; +$$ +CALL p1(1); +a b +1 b1 +CALL p1(3); +a b +1 b1 +2 b2 +3 b3 +CALL p1(6); +a b +1 b1 +2 b2 +3 b3 +4 b4 +5 b5 +6 b6 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# End of MDEV-10597 Cursors with parameters +# +# +# MDEV-12209 sql_mode=ORACLE: Syntax error in a OPEN cursor with parameters makes the server crash +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (1,'A'); +CREATE PROCEDURE p1(a INT,b VARCHAR) +AS +CURSOR c (p_a INT, p_b VARCHAR) IS SELECT * FROM t1 WHERE a=p_a; +BEGIN +OPEN c(a+, b); +LOOP +FETCH c INTO a, b; +EXIT WHEN c%NOTFOUND; +SELECT a, b; +END LOOP; +CLOSE c; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' b); +LOOP +FETCH c INTO a, b; +EXIT WHEN c%NOTFOUND; +SELECT a, b; +END LOOP; +CLO...' at line 5 +DROP TABLE t1; +# +# MDEV-10577 sql_mode=ORACLE: %TYPE in variable declarations +# +CREATE TABLE t1 (a INT, b VARCHAR(10),c DATETIME(3)); +INSERT INTO t1 VALUES (1,'b1','2001-01-01 10:20:30.123'); +INSERT INTO t1 VALUES (2,'b2','2001-01-02 10:20:30.123'); +CREATE TABLE t2 LIKE t1; +CREATE PROCEDURE p1() +AS +v_a t1.a%TYPE; +v_b t1.b%TYPE; +v_c t1.c%TYPE; +CURSOR c IS SELECT a,b,c FROM t1; +BEGIN +OPEN c; +LOOP +FETCH c INTO v_a, v_b, v_c; +EXIT WHEN c%NOTFOUND; +INSERT INTO t2 (a,b,c) VALUES (v_a, v_b, v_c); +END LOOP; +CLOSE c; +END; +$$ +CALL p1(); +SELECT * FROM t2; +a b c +1 b1 2001-01-01 10:20:30.123 +2 b2 2001-01-02 10:20:30.123 +DROP TABLE t2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-12007 Allow ROW variables as a cursor FETCH target +# +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +INSERT INTO t1 VALUES (20,'b20'); +INSERT INTO t1 VALUES (30,'b30'); +CREATE PROCEDURE p1 AS +rec ROW(a INT, b VARCHAR(32)); +CURSOR c IS SELECT a,b FROM t1; +BEGIN +OPEN c; +LOOP +FETCH c INTO rec; +EXIT WHEN c%NOTFOUND; +SELECT ('rec=(' || rec.a ||','|| rec.b||')') AS c; +END LOOP; +CLOSE c; +END; +$$ +CALL p1(); +c +rec=(10,b10) +c +rec=(20,b20) +c +rec=(30,b30) +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-12441 Variables declared after cursors with parameters lose values +# +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x1 INT:=101; +BEGIN +OPEN cur(10,11); +CLOSE cur; +SELECT x0, x1; +END; +$$ +CALL p1(); +x0 x1 +100 101 +DROP PROCEDURE p1; +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x1 t1.a%TYPE:=101; +BEGIN +OPEN cur(10,11); +CLOSE cur; +SELECT x0, x1; +END; +$$ +CALL p1(); +x0 x1 +100 101 +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2; +x1 ROW(a INT,b INT):=ROW(101,102); +BEGIN +OPEN cur(10,11); +CLOSE cur; +SELECT x0, x1.a, x1.b; +END; +$$ +CALL p1(); +x0 x1.a x1.b +100 101 102 +DROP PROCEDURE p1; +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10,'Tbl-t1.b0'); +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur(cp1 INT, cp2 INT) IS SELECT a,b FROM t1; +x1 t1%ROWTYPE:=ROW(101,'Var-x1.b0'); +BEGIN +SELECT x0, x1.a, x1.b; +OPEN cur(10,11); +FETCH cur INTO x1; +CLOSE cur; +SELECT x0, x1.a, x1.b; +END; +$$ +CALL p1(); +x0 x1.a x1.b +100 101 Var-x1.b0 +x0 x1.a x1.b +100 10 Tbl-t1.b0 +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10,'Tbl-t1.b0'); +CREATE PROCEDURE p1() AS +x0 INT:=100; +CURSOR cur(cp1 INT, cp2 INT) IS SELECT a,b FROM t1; +x1 cur%ROWTYPE:=ROW(101,'Var-x1.b0'); +BEGIN +SELECT x0, x1.a, x1.b; +OPEN cur(10,11); +FETCH cur INTO x1; +CLOSE cur; +SELECT x0, x1.a, x1.b; +END; +$$ +CALL p1(); +x0 x1.a x1.b +100 101 Var-x1.b0 +x0 x1.a x1.b +100 10 Tbl-t1.b0 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-12854 Synchronize CREATE..SELECT data type and result set metadata data type for INT functions +# +DECLARE +CURSOR c IS SELECT 1 AS c FROM DUAL; +BEGIN +OPEN c; +SELECT +c%ISOPEN, +c%NOTFOUND, +c%FOUND, +c%ROWCOUNT; +CLOSE c; +END; +$$ +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def c%ISOPEN 3 1 1 N 32897 0 63 +def c%NOTFOUND 3 1 0 Y 32896 0 63 +def c%FOUND 3 1 0 Y 32896 0 63 +def c%ROWCOUNT 8 21 1 Y 32896 0 63 +c%ISOPEN c%NOTFOUND c%FOUND c%ROWCOUNT +1 NULL NULL 0 +# +# MDEV-17387 MariaDB Server giving wrong error while executing select query from procedure +# +CREATE TABLE t1 +( +JOBN varchar(18) NOT NULL, +pk int(11) NOT NULL, +PRIMARY KEY (pk), +KEY (JOBN) +); +CREATE PROCEDURE p1 +AS +lS NUMBER(10) :=0; +CURSOR cBPD IS SELECT * FROM t1 WHERE JOBN='x'; +BEGIN +FOR lbpd IN cBPD LOOP +lS:=lS+1; +END LOOP; +EXCEPTION +WHEN OTHERS THEN +BEGIN +SELECT SQLERRM; +END; +END; +$$ +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Start of 10.8 tests +# +# +# MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION +# +DECLARE +va INT; +CURSOR cur (a IN INT) IS SELECT a FROM dual; +BEGIN +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +va +1 +DECLARE +va INT; +CURSOR cur (a OUT INT) IS SELECT a FROM dual; +BEGIN +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter' +DECLARE +va INT; +CURSOR cur (a INOUT INT) IS SELECT a FROM dual; +BEGIN +OPEN cur(1); +FETCH cur INTO va; +CLOSE cur; +SELECT va; +END; +$$ +ERROR 42000: This version of MariaDB doesn't yet support 'OUT/INOUT cursor parameter' +# +# End of 10.8 tests +# diff --git a/mysql-test/suite/compat/oracle/r/sp-expr.result b/mysql-test/suite/compat/oracle/r/sp-expr.result new file mode 100644 index 00000000..bb0c1a5c --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-expr.result @@ -0,0 +1,158 @@ +SET sql_mode=ORACLE; +# +# Start of 10.3 tests +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +BEGIN +CASE ((1) IN (SELECT a FROM t1)) WHEN 1 THEN SELECT 1; +ELSE SELECT NULL; +END CASE; +END; +$$ +1 +1 +BEGIN +CASE (EXISTS (SELECT a FROM t1)) WHEN 1 THEN SELECT 1; +ELSE SELECT NULL; +END CASE; +END; +$$ +1 +1 +BEGIN +IF ((1) IN (SELECT a FROM t1)) THEN SELECT 1; +ELSE SELECT NULL; +END IF; +END; +$$ +1 +1 +BEGIN +IF (EXISTS (SELECT a FROM t1)) THEN SELECT 1; +ELSE SELECT NULL; +END IF; +END; +$$ +1 +1 +BEGIN +WHILE ((1234) IN (SELECT * FROM t1)) LOOP +SELECT 1; +END LOOP; +END; +$$ +BEGIN +WHILE (EXISTS (SELECT * FROM t1 WHERE a=1234)) LOOP +SELECT 1; +END LOOP; +END; +$$ +BEGIN +REPEAT +SELECT 1; +UNTIL (1 IN (SELECT * FROM t1)) +END REPEAT; +END; +$$ +1 +1 +BEGIN +REPEAT +SELECT 1; +UNTIL EXISTS (SELECT * FROM t1 WHERE a=1) +END REPEAT; +END; +$$ +1 +1 +BEGIN +FOR i IN 0..(1 IN (SELECT * FROM t1)) +LOOP +SELECT i; +END LOOP; +END; +$$ +i +0 +i +1 +BEGIN +FOR i IN 0..EXISTS (SELECT * FROM t1 WHERE a=1) +LOOP +SELECT i; +END LOOP; +END; +$$ +i +0 +i +1 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +DECLARE +a INT DEFAULT ((10) IN (SELECT * FROM t1)); +BEGIN +SELECT a; +END; +$$ +a +1 +DECLARE +a INT DEFAULT EXISTS (SELECT * FROM t1); +BEGIN +SELECT a; +END; +$$ +a +1 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +CREATE FUNCTION f1() RETURN INT AS +BEGIN +RETURN ((1) IN (SELECT * FROM t1)); +END; +$$ +CREATE FUNCTION f2() RETURN INT AS +BEGIN +RETURN EXISTS (SELECT * FROM t1 WHERE a=1); +END; +$$ +SELECT f1(); +f1() +1 +SELECT f2(); +f2() +1 +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +DECLARE +va INT; +CURSOR cur(amin INT) IS SELECT a FROM t1 WHERE a>amin ORDER BY a; +BEGIN +OPEN cur(1 IN (SELECT * FROM t1)); +FETCH cur INTO va; +SELECT va; +CLOSE cur; +END; +$$ +va +2 +DECLARE +va INT; +CURSOR cur(amin INT) IS SELECT a FROM t1 WHERE a>amin ORDER BY a; +BEGIN +OPEN cur(EXISTS (SELECT * FROM t1)); +FETCH cur INTO va; +SELECT va; +CLOSE cur; +END; +$$ +va +2 +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/sp-goto-debug.result b/mysql-test/suite/compat/oracle/r/sp-goto-debug.result new file mode 100644 index 00000000..3660bfa2 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-goto-debug.result @@ -0,0 +1,236 @@ +SET sql_mode=ORACLE; +# +# MDEV-20667 Server crash on pop_cursor +# +CREATE PROCEDURE p1() IS +BEGIN +IF 1=2 THEN +BEGIN +DECLARE +CURSOR cur1 IS SELECT a FROM t1 ; +BEGIN +GOTO iac_err; +END; +END; +END IF; +IF 1=1 THEN +GOTO iac_err; +END IF; +<< iac_err >> +RETURN; +END// +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump_if_not 5(5) 1 = 2 +1 cpush cur1@0 +2 jump 3 +3 cpop 1 +4 jump 7 +5 jump_if_not 7(7) 1 = 1 +6 jump 7 +7 preturn +DROP PROCEDURE p1; +CREATE PROCEDURE p1() IS +BEGIN +IF 1=2 THEN +BEGIN +DECLARE +CURSOR cur1 IS SELECT a FROM t1 ; +BEGIN +GOTO iac_err; +END; +END; +END IF; +IF 1=1 THEN +GOTO iac_err; +END IF; +<< iac_err >> +RETURN ; +END// +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump_if_not 5(5) 1 = 2 +1 cpush cur1@0 +2 jump 3 +3 cpop 1 +4 jump 7 +5 jump_if_not 7(7) 1 = 1 +6 jump 7 +7 preturn +DROP PROCEDURE p1; +CREATE PROCEDURE p1() IS +BEGIN +IF 1=2 THEN +BEGIN +DECLARE +CURSOR cur1 IS SELECT a FROM t1 ; +BEGIN +GOTO iac_err; +END; +END; +END IF; +GOTO iac_err; +<< iac_err >> +RETURN ; +END// +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump_if_not 5(5) 1 = 2 +1 cpush cur1@0 +2 jump 3 +3 cpop 1 +4 jump 5 +5 preturn +DROP PROCEDURE p1; +CREATE PROCEDURE p1() IS +BEGIN +IF 1=1 THEN +DECLARE +CURSOR cur2 IS SELECT 'cur2' FROM DUAL; +BEGIN +SELECT 'cur2'; +IF 1=1 THEN +DECLARE +CURSOR cur3 IS SELECT 'cur3' FROM DUAL; +BEGIN +SELECT 'cur3'; +IF 1=1 THEN +DECLARE +CURSOR cur4 IS SELECT 'cur4' FROM DUAL; +BEGIN +SELECT 'cur4'; +GOTO ret; +END; +END IF; +GOTO ret; +END; +END IF; +GOTO ret; +END; +END IF; +<<ret>> +RETURN; +END; +// +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump_if_not 15(15) 1 = 1 +1 cpush cur2@0 +2 stmt 0 "SELECT 'cur2'" +3 jump_if_not 13(13) 1 = 1 +4 cpush cur3@1 +5 stmt 0 "SELECT 'cur3'" +6 jump_if_not 11(11) 1 = 1 +7 cpush cur4@2 +8 stmt 0 "SELECT 'cur4'" +9 cpop 3 +10 jump 15 +11 cpop 2 +12 jump 15 +13 cpop 1 +14 jump 15 +15 preturn +DROP PROCEDURE p1; +CREATE PROCEDURE p1(lab VARCHAR(32)) IS +BEGIN +IF 1=1 THEN +DECLARE +CURSOR cur2 IS SELECT 'cur2' FROM DUAL; +BEGIN +IF 1=1 THEN +DECLARE +CURSOR cur3 IS SELECT 'cur3' FROM DUAL; +BEGIN +IF 1=1 THEN +DECLARE +CURSOR cur4 IS SELECT 'cur4' FROM DUAL; +BEGIN +IF lab = 'cur4' THEN +SELECT 'goto from cur4' AS comment; +GOTO ret; +END IF; +END; +END IF; +IF lab = 'cur3' THEN +SELECT 'goto from cur3' AS comment; +GOTO ret; +END IF; +END; +END IF; +IF lab = 'cur2' THEN +SELECT 'goto from cur2' AS comment; +GOTO ret; +END IF; +END; +END IF; +<<ret>> +RETURN; +END; +// +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump_if_not 21(21) 1 = 1 +1 cpush cur2@0 +2 jump_if_not 16(16) 1 = 1 +3 cpush cur3@1 +4 jump_if_not 11(11) 1 = 1 +5 cpush cur4@2 +6 jump_if_not 10(10) lab@0 = 'cur4' +7 stmt 0 "SELECT 'goto from cur4' AS comment" +8 cpop 3 +9 jump 21 +10 cpop 1 +11 jump_if_not 15(15) lab@0 = 'cur3' +12 stmt 0 "SELECT 'goto from cur3' AS comment" +13 cpop 2 +14 jump 21 +15 cpop 1 +16 jump_if_not 20(20) lab@0 = 'cur2' +17 stmt 0 "SELECT 'goto from cur2' AS comment" +18 cpop 1 +19 jump 21 +20 cpop 1 +21 preturn +CALL p1(''); +CALL p1('cur2'); +comment +goto from cur2 +CALL p1('cur3'); +comment +goto from cur3 +CALL p1('cur4'); +comment +goto from cur4 +DROP PROCEDURE p1; +CREATE PROCEDURE p1() IS +BEGIN +IF 1=2 THEN +BEGIN +DECLARE +CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; +BEGIN +GOTO iac_err; +END; +END; +END IF; +IF 1=1 THEN +GOTO iac_err; +END IF; +<<iac_err >> +RETURN; +END// +SHOW PROCEDURE CODE p1; +Pos Instruction +0 jump_if_not 9(9) 1 = 2 +1 hpush_jump 4 0 CONTINUE +2 stmt 31 "SET @x2 = 1" +3 hreturn 0 +4 hpop 1 +5 jump 11 +6 jump 11 +7 hpop 1 +8 jump 9 +9 jump_if_not 11(11) 1 = 1 +10 jump 11 +11 preturn +DROP PROCEDURE p1; diff --git a/mysql-test/suite/compat/oracle/r/sp-goto.result b/mysql-test/suite/compat/oracle/r/sp-goto.result new file mode 100644 index 00000000..badda507 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-goto.result @@ -0,0 +1,913 @@ +set sql_mode=oracle; +# +# MDEV-10697 sql_mode=ORACLE: GOTO statement +# +# matrice of tests in procedure +# |-------------------------------------------------------- +# | | Same | Outside | to sub | No | +# | | block | one block | block | matching | +# | | | | | label | +# |-------------------------------------------------------- +# | Forward jump | F1 | F3 | F5 | F7 | +# |-------------------------------------------------------- +# | Backward jump | F2 | F4 | F6 | F8 | +# |-------------------------------------------------------- +# Jump from handler to outside handling code block : F9 +# Jump from handler to handling code block : F10 (forbidden) +# Jump inside handler : F21 +# Jump between handler : F22 (forbidden) +# Jump from cascaded block with handler : F11 +# Duplicate label in same block : F12 (forbidden) +# Duplicate label in different block : F13 +# Jump outside unlabeled block : F14 +# Jump inside/outside labeled block : F15 +# Jump from if / else : F16 +# Jump with cursors : F17 +# Jump outside case : F18 +# Jump inside/outside case block : F19 +# Jump outside labeled loop : F20 +# Jump (continue) labeled loop : F23 +# Two consecutive label : P24 +# Two consecutive label (backward and forward jump) : P25 +# Two consecutive label, continue to wrong label : P26 +# Consecutive goto label and block label : P27 +# Test in function +# backward jump : func1 +# forward jump : func2 +# Test in trigger +# forward jump : trg1 +# +# Forward jump in same block +# +CREATE or replace procedure f1(p2 IN OUT VARCHAR) +AS +BEGIN +p2:='a'; +goto lab1; +<<lab1>> +goto lab2; +p2:='b'; +<<lab2>> +return ; +END; +$$ +call f1(@wp1); +select 'f1',@wp1; +f1 @wp1 +f1 a +DROP PROCEDURE f1; +# +# Backward jump in same block +# +CREATE or replace procedure f2(p2 IN OUT VARCHAR) +AS +BEGIN +p2:='a'; +<<lab1>> +if (p2='b') then +return ; +end if; +p2:='b'; +goto lab1; +END; +$$ +call f2(@wp1); +select 'f2',@wp1; +f2 @wp1 +f2 b +DROP PROCEDURE f2; +# +# Forward jump outside one block +# +CREATE or replace procedure f3(p2 IN OUT VARCHAR) +AS +BEGIN +p2:='a'; +if (p2='a') then +goto lab1; +end if; +p2:='c'; +<<lab1>> +return ; +END; +$$ +call f3(@wp1); +select 'f3',@wp1; +f3 @wp1 +f3 a +DROP PROCEDURE f3; +# +# Backward jump outside one block +# +CREATE or replace procedure f4(p2 IN OUT VARCHAR) +AS +BEGIN +p2:='a'; +<<lab1>> +if (p2='a') then +p2:=p2||'b'; +goto lab1; +end if; +if (p2='ab') then +p2:=p2||'c'; +end if; +return ; +END; +$$ +call f4(@wp1); +select 'f4',@wp1; +f4 @wp1 +f4 abc +DROP PROCEDURE f4; +# +# Forward jump inside sub block +CREATE or replace procedure f5(p2 IN OUT VARCHAR) +AS +BEGIN +p2:='a'; +goto lab5 ; +if (p2='a') then +<<lab5>> +p2:=p2||'b'; +end if; +return ; +END; +$$ +ERROR 42000: GOTO with no matching label: lab5 +# +# Backward jump inside sub block +CREATE or replace procedure f6(p2 IN OUT VARCHAR) +AS +BEGIN +p2:='a'; +if (p2='a') then +<<lab6>> +p2:=p2||'b'; +return ; +end if; +goto lab6 ; +END; +$$ +ERROR 42000: GOTO with no matching label: lab6 +# +# Backward jump - missing label +CREATE or replace procedure f7(p2 IN OUT VARCHAR) +AS +BEGIN +<<lab>> +goto lab7 ; +return ; +END; +$$ +ERROR 42000: GOTO with no matching label: lab7 +# +# Forward jump - missing label +CREATE or replace procedure f8(p2 IN OUT VARCHAR) +AS +BEGIN +goto lab8 ; +<<lab>> +return ; +END; +$$ +ERROR 42000: GOTO with no matching label: lab8 +# +# Jump from handler to procedure code +# +CREATE or replace procedure f9(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +<<lab9>> +if lim=-1 then +res:=res||' -- goto end limit -1 --'; +goto lab9_end; +end if; +begin +SELECT a INTO a FROM information_schema.tables LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN +begin +res:=res||'--- too_many_rows cought ---'; +lim:=0; +goto lab9; +end; +WHEN NO_DATA_FOUND THEN +begin +res:=res||'--- no_data_found cought ---'; +lim:=-1; +goto lab9; +end; +end; +res:=res||'error'; +<<lab9_end>> +return ; +END; +$$ +SET @res=''; +CALL f9(2, @res); +SELECT 'f9',@res; +f9 @res +f9 --- too_many_rows cought ------ no_data_found cought --- -- goto end limit -1 -- +CALL f9(0, @res); +SELECT 'f9',@res; +f9 @res +f9 --- no_data_found cought --- -- goto end limit -1 -- +DROP PROCEDURE f9; +# +# Jump from handler to handling bloc +CREATE or replace procedure f10(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +begin +<<lab10>> +SELECT a INTO a FROM information_schema.tables LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN +begin +res:='--- too_many_rows cought ---'; +goto lab10; +end; +WHEN NO_DATA_FOUND THEN res:='--- no_data_found cought ---'; +end; +return ; +END; +$$ +ERROR 42000: GOTO with no matching label: lab10 +# +# Jump from cascaded block with handler +# +CREATE or replace procedure f11(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +<<lab11a>> +begin +SELECT a INTO a FROM information_schema.tables LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN +begin +res:=res||'--- too_many_rows cought 1 ---'; +goto lab11b; +end; +WHEN NO_DATA_FOUND THEN +begin +res:=res||'--- no_data_found cought 1 ---'; +lim:=2; +SELECT a INTO a FROM information_schema.tables LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN +begin +res:=res||'--- too_many_rows cought 2 ---'; +goto lab11a; +end; +WHEN NO_DATA_FOUND THEN res:='--- no_data_found cought 2 ---'; +end; +end; +set res:=res||' error '; +<<lab11b>> +return ; +END; +$$ +SET @res=''; +CALL f11(0, @res); +SELECT 'f11',@res; +f11 @res +f11 --- no_data_found cought 1 ------ too_many_rows cought 2 ------ too_many_rows cought 1 --- +DROP PROCEDURE f11; +# +# Jump inside handler +# +CREATE or replace procedure f21(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +begin +SELECT a INTO a FROM information_schema.tables LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN +begin +<<retry>> +lim:=lim-1; +loop +begin +SELECT a INTO a FROM information_schema.tables LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN +begin +lim:=lim-1; +goto retry; +end; +end; +exit ; +end loop; +end; +end; +res:=lim; +return ; +END; +$$ +SET @res=''; +CALL f21(10, @res); +SELECT 'f21',@res; +f21 @res +f21 1 +drop procedure f21; +# +# Jump beetween handler +CREATE or replace procedure f22(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +res:='ok'; +begin +SELECT a INTO a FROM information_schema.tables LIMIT lim; +EXCEPTION +WHEN TOO_MANY_ROWS THEN +goto nodata ; +WHEN NO_DATA_FOUND THEN +begin +<<nodata>> +res:='error'; +end; +end; +return ; +END; +$$ +ERROR 42000: GOTO with no matching label: nodata +# +# Duplicate label in same bloc +CREATE or replace procedure f12(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +<<lab12>> +res:='error'; +<<lab12>> +return ; +END; +$$ +ERROR 42000: Redefining label lab12 +# +# Duplicate label in different block +# +CREATE or replace procedure f13(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +a:=0; +<<lab13>> +a:=a+1; +begin +<<lab13>> +a:=a+1; +if (a<10) then +goto lab13; +end if; +end; +res:=a; +if (a=10) then +goto lab13; +end if; +return ; +END; +$$ +SET @res=''; +CALL f13(0, @res); +SELECT 'f13',@res; +f13 @res +f13 12 +DROP PROCEDURE f13; +# +# Jump outside unlabeled block +# +CREATE or replace procedure f14(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +a:=0; +loop +a:=a+1; +if (a<10) then +continue; +end if; +if (a>=lim) then +goto lab14; +end if; +if (a>=20) then +exit; +end if; +end loop; +<<lab14>> +res:=a; +return ; +END; +$$ +SET @res=''; +CALL f14(15, @res); +SELECT 'f14',@res; +f14 @res +f14 15 +CALL f14(8, @res); +SELECT 'f14',@res; +f14 @res +f14 10 +CALL f14(25, @res); +SELECT 'f14',@res; +f14 @res +f14 20 +DROP PROCEDURE f14; +# +# Jump inside/outside labeled block +# +CREATE or replace procedure f15(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +a:=0; +<<looplabel>> loop +<<beginlooplabel>> +a:=a+1; +if (a<10) then +continue looplabel; +end if; +if (a>=lim) then +goto lab15; +end if; +if (a>=20) then +exit looplabel; +end if; +goto beginlooplabel; +end loop; +<<lab15>> +res:=a; +return ; +END; +$$ +SET @res=''; +CALL f15(15, @res); +SELECT 'f15',@res; +f15 @res +f15 15 +CALL f15(8, @res); +SELECT 'f15',@res; +f15 @res +f15 10 +CALL f15(25, @res); +SELECT 'f15',@res; +f15 @res +f15 20 +DROP PROCEDURE f15; +# +# Jump from if / else +# +CREATE or replace procedure f16(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +if (lim<10) then +goto lab16_1; +else +goto lab16_2; +end if; +<<lab16_1>> +res:='if lab16_1'; +goto lab16_3; +<<lab16_2>> +res:='else lab16_2'; +goto lab16_3; +res:='error lab16_3'; +<<lab16_3>> +return ; +END; +$$ +SET @res=''; +CALL f16(15, @res); +SELECT 'f16',@res; +f16 @res +f16 else lab16_2 +CALL f16(8, @res); +SELECT 'f16',@res; +f16 @res +f16 if lab16_1 +DROP PROCEDURE f16; +# +# Jump with cursors +# +CREATE or replace procedure f17(lim INT, res OUT VARCHAR) +AS +v_a INT; +v_b VARCHAR(10); +CURSOR cur1 IS SELECT 1 FROM dual where 1=2; +BEGIN +OPEN cur1; +LOOP +FETCH cur1 INTO v_a; +EXIT WHEN cur1%NOTFOUND; +END LOOP; +CLOSE cur1; +<<lab17>> +lim:=lim-1; +begin +declare +CURSOR cur1 IS SELECT 1 FROM dual; +CURSOR cur2 IS SELECT 1 FROM dual where 1=2; +begin +LOOP +OPEN cur1; +FETCH cur1 INTO v_a; +EXIT WHEN cur1%NOTFOUND; +res:=res||'-'||lim ; +close cur1; +if (lim>0) then +goto lab17; +else +goto lab17_end; +end if; +END LOOP; +end; +<<lab17_end>> +null; +end; +END; +$$ +SET @res=''; +CALL f17(5, @res); +SELECT 'f17',@res; +f17 @res +f17 -4-3-2-1-0 +DROP PROCEDURE f17; +# +# Jump outside case +# +CREATE or replace procedure f18(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +case lim +when 1 then +res:='case branch 18_1'; +goto lab18_1; +res:='error'; +when 2 then +res:='case branch 18_2'; +goto lab18_2; +res:='error'; +else +res:='default branch 18'; +end case; +<<lab18_1>> +null; +<<lab18_2>> +return ; +END; +$$ +SET @res=''; +CALL f18(0, @res); +SELECT 'f18',@res; +f18 @res +f18 default branch 18 +CALL f18(1, @res); +SELECT 'f18',@res; +f18 @res +f18 case branch 18_1 +CALL f18(2, @res); +SELECT 'f18',@res; +f18 @res +f18 case branch 18_2 +DROP PROCEDURE f18; +# +# Jump inside/outside case block +# +CREATE or replace procedure f19(lim INT, res OUT VARCHAR) +AS +a INT; +BEGIN +a:=1; +case lim +when 1 then +<<lab19_0>> +a:=a+1; +if (a<10) then +goto lab19_0; +else +goto lab19_1; +end if; +res:='case branch 19_1'; +else +res:='default branch 18'; +end case; +goto lab19_end; +<<lab19_1>> +res:=a; +<<lab19_end>> +return ; +END; +$$ +SET @res=''; +CALL f19(1, @res); +SELECT 'f19',@res; +f19 @res +f19 10 +DROP PROCEDURE f19; +# +# Jump outside labeled loop +# +CREATE OR REPLACE PROCEDURE f20(res OUT VARCHAR) +AS +a INT := 1; +BEGIN +<<lab>> +FOR i IN a..10 LOOP +IF i = 5 THEN +a:= a+1; +goto lab; +END IF; +END LOOP; +res:=a; +END; +$$ +CALL f20(@res); +SELECT 'f20',@res; +f20 @res +f20 6 +DROP PROCEDURE f20; +# +# Jump (continue) labeled loop +# +CREATE OR REPLACE PROCEDURE f23(res OUT VARCHAR) +AS +a INT := 1; +BEGIN +<<lab>> +FOR i IN a..10 LOOP +IF i = 5 THEN +a:= a+1; +continue lab; +END IF; +END LOOP; +res:=a; +END; +$$ +CALL f23(@res); +SELECT 'f23',@res; +f23 @res +f23 2 +DROP PROCEDURE f23; +# +# Two consecutive label (backward jump) +# +CREATE OR REPLACE PROCEDURE p24(action IN INT, res OUT varchar) AS +a integer; +BEGIN +<<lab1>> +<<lab2>> +if (action = 1) then +res:=res||' '||action; +action:=2; +goto lab1; +end if; +if (action = 2) then +res:=res||' '||action; +action:=3; +goto lab2; +end if; +END; +$$ +call p24(1,@res); +select 'p24',@res; +p24 @res +p24 1 2 +DROP PROCEDURE p24; +# +# Two consecutive label (backward and forward jump) +# +CREATE OR REPLACE PROCEDURE p25(action IN INT, res OUT varchar) AS +a integer; +BEGIN +if (action = 1) then +res:=res||' '||action; +action:=2; +goto lab2; +end if; +goto lab_end; +<<lab1>> +<<lab2>> +res:=res||' '||action; +if (action = 2) then +res:=res||' '||action; +action:=3; +goto lab1; +end if; +<<lab_end>> +null; +END; +$$ +call p25(1,@res); +select 'p25',@res; +p25 @res +p25 1 2 2 3 +DROP PROCEDURE p25; +# +# Two consecutive label, continue to wrong label +CREATE OR REPLACE PROCEDURE p26(action IN INT, res OUT varchar) AS +BEGIN +<<lab1>> +<<lab2>> +FOR i IN 1..10 LOOP +continue lab1; +END LOOP; +END; +$$ +ERROR 42000: CONTINUE with no matching label: lab1 +# +# Consecutive goto label and block label +# +CREATE OR REPLACE PROCEDURE p27(action IN INT, res OUT varchar) AS +BEGIN +res:=''; +<<lab1>> +<<lab2>> +FOR i IN 1..10 LOOP +if (action = 1) then +res:=res||' '||action||'-'||i; +action:=2; +continue lab2; +end if; +if (action = 2) then +res:=res||' '||action||'-'||i; +action:='3'; +goto lab2; +end if; +if (action = 3) then +res:=res||' '||action||'-'||i; +action:='4'; +goto lab1; +end if; +if (action = 4) then +res:=res||' '||action||'-'||i; +exit lab2; +end if; +END LOOP; +END; +$$ +call p27(1,@res); +select 'p27',@res; +p27 @res +p27 1-1 2-2 3-1 4-1 +DROP PROCEDURE p27; +# ---------------------- +# -- TEST IN FUNCTION -- +# ---------------------- +# +# FUNCTION : Backward jump +# +CREATE or replace function func1() +return varchar +AS +p2 varchar(10); +BEGIN +p2:='a'; +<<lab1>> +if (p2='a') then +p2:=p2||'b'; +goto lab1; +end if; +if (p2='ab') then +p2:=p2||'c'; +end if; +return p2; +END; +$$ +select 'func1',func1(); +func1 func1() +func1 abc +DROP function func1; +# +# FUNCTION : forward jump +# +CREATE or replace function func2() +return varchar +AS +p2 varchar(10); +BEGIN +p2:='a'; +if (p2='a') then +goto lab1; +end if; +p2:='b'; +<<lab1>> +return p2; +END; +$$ +select 'func2',func2(); +func2 func2() +func2 a +DROP function func2; +# --------------------- +# -- TEST IN TRIGGER -- +# --------------------- +# +# TRIGGER : forward jump +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW +BEGIN +IF :NEW.a IS NULL +THEN +:NEW.a:= 15; +goto end_trg; +END IF; +:NEW.a:= 10; +<<end_trg>> +null; +END; +$$ +insert into t1 values (1); +insert into t1 values (null); +SELECT * FROM t1; +a +10 +15 +DROP TRIGGER trg1; +DROP TABLE t1; +# +# MDEV-20667 Server crash on pop_cursor +# +CREATE TABLE t1 (a VARCHAR(6)); +CREATE PROCEDURE p1() IS +BEGIN +IF 1=2 THEN +BEGIN +DECLARE +CURSOR cur1 IS SELECT a FROM t1 ; +BEGIN +GOTO iac_err; +END; +END; +END IF; +IF 1=1 THEN +GOTO iac_err; +END IF; +<< iac_err >> +RETURN; +END// +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE PROCEDURE p1() IS +BEGIN +IF 1=2 THEN +BEGIN +DECLARE +CURSOR cur1 IS SELECT a FROM t1 ; +BEGIN +GOTO iac_err; +END; +END; +END IF; +IF 1=1 THEN +GOTO iac_err; +END IF; +<< iac_err >> +RETURN ; +END// +CALL p1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() IS +BEGIN +IF 1=2 THEN +BEGIN +DECLARE +CURSOR cur1 IS SELECT a FROM t1 ; +BEGIN +GOTO iac_err; +END; +END; +END IF; +GOTO iac_err; +<< iac_err >> +RETURN ; +END// +CALL p1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() IS +BEGIN +IF 1=2 THEN +BEGIN +DECLARE +CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; +BEGIN +GOTO iac_err; +END; +END; +END IF; +IF 1=1 THEN +GOTO iac_err; +END IF; +<<iac_err >> +RETURN; +END// +CALL p1; +DROP PROCEDURE p1; diff --git a/mysql-test/suite/compat/oracle/r/sp-inout.result b/mysql-test/suite/compat/oracle/r/sp-inout.result new file mode 100644 index 00000000..fa6f5076 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-inout.result @@ -0,0 +1,2571 @@ +# +# MDEV-10654 IN, OUT, INOUT parameters in CREATE FUNCTION +# +SET sql_mode=ORACLE; +# +# CREATE PACKAGE with procedure and function with IN, OUT, INOUT qualifiers +# And SHOW CREATE PACKAGE +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c INOUT INT, d OUT INT); +FUNCTION func_sub(d OUT INT, a IN INT, b IN INT, c INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c INOUT INT, d OUT INT) +AS +res INT; +BEGIN +res := func_sub(d, a, b, c); +d := d + c + res; +END; +FUNCTION func_sub(d OUT INT, a IN INT, b IN INT, c INOUT INT) RETURN INT +AS +BEGIN +c := c + 6; +d := 10; +RETURN a - b; +END; +END; +$$ +SHOW CREATE PACKAGE pkg2; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg2 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PACKAGE "pkg2" AS +PROCEDURE proc_main(a IN INT, b IN INT, c INOUT INT, d OUT INT); +FUNCTION func_sub(d OUT INT, a IN INT, b IN INT, c INOUT INT) RETURN INT; +END latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE PACKAGE BODY pkg2; +Package body sql_mode Create Package Body character_set_client collation_connection Database Collation +pkg2 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PACKAGE BODY "pkg2" AS +PROCEDURE proc_main(a IN INT, b IN INT, c INOUT INT, d OUT INT) +AS +res INT; +BEGIN +res := func_sub(d, a, b, c); +d := d + c + res; +END; +FUNCTION func_sub(d OUT INT, a IN INT, b IN INT, c INOUT INT) RETURN INT +AS +BEGIN +c := c + 6; +d := 10; +RETURN a - b; +END; +END latin1 latin1_swedish_ci latin1_swedish_ci +DROP PACKAGE pkg2; +# +# CREATE FUNCTION with IN, OUT, INOUT qualifiers +# SHOW CREATE FUNCTION +# +CREATE OR REPLACE FUNCTION add_func(a IN INT, b IN INT, c OUT INT, d INOUT INT) RETURN INT +AS +BEGIN +c := 100; +d := d + 1; +RETURN a + b; +END; +$$ +SHOW CREATE FUNCTION add_func; +Function sql_mode Create Function character_set_client collation_connection Database Collation +add_func PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "add_func"(a IN INT, b IN INT, c OUT INT, d INOUT INT) RETURN int(11) +AS +BEGIN +c := 100; +d := d + 1; +RETURN a + b; +END latin1 latin1_swedish_ci latin1_swedish_ci +DROP FUNCTION add_func; +# +# CREATE PROCEDURE with IN, OUT, INOUT qualifiers +# SHOW CREATE PROCEDURE +# +CREATE OR REPLACE PROCEDURE add_proc(a IN INT, b IN INT, c INOUT INT, d OUT INT) +AS +BEGIN +d := a + b + c + d; +END; +$$ +SHOW CREATE PROCEDURE add_proc; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +add_proc PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PROCEDURE "add_proc"(a IN INT, b IN INT, c INOUT INT, d OUT INT) +AS +BEGIN +d := a + b + c + d; +END latin1 latin1_swedish_ci latin1_swedish_ci +DROP PROCEDURE add_proc; +# +# Call function from SELECT query +# SELECT > FUNCTION(IN) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION add_func2 (a IN INT, b IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION add_func2(a IN INT, b IN INT) RETURN INT +AS +BEGIN +RETURN a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +select pkg2.add_func2(@a, @b); +pkg2.add_func2(@a, @b) +5 +DROP PACKAGE pkg2; +# +# Call function from SELECT query +# SELECT > FUNCTION(OUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION add_func3 (a IN INT, b IN INT, c OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION add_func3(a IN INT, b IN INT, c OUT INT) RETURN INT +AS +BEGIN +c := 100; +RETURN a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @c = 0; +select pkg2.add_func3(@a, @b, @c); +ERROR HY000: OUT or INOUT argument 3 for function pkg2.add_func3 is not allowed here +DROP PACKAGE pkg2; +# +# Call function from SELECT query +# SELECT > FUNCTION(INOUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION add_func4 (a IN INT, b IN INT, c OUT INT, d INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION add_func4(a IN INT, b IN INT, c OUT INT, d INOUT INT) RETURN INT +AS +BEGIN +c := 100; +d := d + 1; +RETURN a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @c = 0; +set @d = 9; +select pkg2.add_func4(@a, @b, @c, @d); +ERROR HY000: OUT or INOUT argument 3 for function pkg2.add_func4 is not allowed here +DROP PACKAGE pkg2; +# +# Call from procedure +# PROCEDURE(OUT) > FUNCTION(IN) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE add_proc2 (a IN INT, b IN INT, c OUT INT); +FUNCTION add_func2 (a IN INT, b IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE add_proc2(a IN INT, b IN INT, c OUT INT) +AS +BEGIN +c := add_func2(a, b); +END; +FUNCTION add_func2(a IN INT, b IN INT) RETURN INT +AS +BEGIN +RETURN a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @c = 0; +call pkg2.add_proc2(@a, @b, @c); +select @c; +@c +5 +DROP PACKAGE pkg2; +# +# Call from procedure +# PROCEDURE(OUT) > FUNCTION(OUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE add_proc3 (a IN INT, b IN INT, c OUT INT); +FUNCTION add_func3 (a IN INT, b IN INT, c OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE add_proc3(a IN INT, b IN INT, c OUT INT) +AS +res INT; +BEGIN +res := add_func3(a, b, c); +END; +FUNCTION add_func3(a IN INT, b IN INT, c OUT INT) RETURN INT +AS +BEGIN +c := 100; +RETURN a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @c = 0; +call pkg2.add_proc3(@a, @b, @c); +select @c; +@c +100 +DROP PACKAGE pkg2; +# +# Call from procedure +# PROCEDURE(OUT) > FUNCTION(INOUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE add_proc4 (a IN INT, b IN INT, c OUT INT); +FUNCTION add_func4 (a IN INT, b IN INT, c OUT INT, d INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE add_proc4(a IN INT, b IN INT, res OUT INT) +AS +c INT; +d INT; +BEGIN +d := 30; +res := add_func4(a, b, c, d); +res := c + d; +END; +FUNCTION add_func4(a IN INT, b IN INT, c OUT INT, d INOUT INT) RETURN INT +AS +BEGIN +c := 100; +d := d + 1; +RETURN a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @res = 0; +call pkg2.add_proc4(@a, @b, @res); +select @res; +@res +131 +DROP PACKAGE pkg2; +# +# Call from procedure +# PROCEDURE(OUT) > PROCEDURE(OUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE test_proc1 (a IN INT, b IN INT, c OUT INT); +PROCEDURE add_proc (a IN INT, b IN INT, c OUT INT); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE test_proc1(a IN INT, b IN INT, c OUT INT) +AS +BEGIN +call pkg2.add_proc(a, b, c); +END; +PROCEDURE add_proc(a IN INT, b IN INT, c OUT INT) +AS +BEGIN +c := a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @c = 0; +call pkg2.test_proc1(@a, @b, @c); +select @c; +@c +5 +DROP PACKAGE pkg2; +# +# Argument's order change +# PROCEDURE(a IN, b IN, c OUT) > FUNCTION(b IN, a IN, c OUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c OUT INT); +FUNCTION func_sub(b IN INT, a IN INT, c OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c OUT INT) +AS +res INT; +BEGIN +res := func_sub(b, a, c); +END; +FUNCTION func_sub(b IN INT, a IN INT, c OUT INT) RETURN INT +AS +res INT; +BEGIN +c := a - b; +res := a; +RETURN res; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @c = 0; +call pkg2.proc_main(@a, @b, @c); +select @c; +@c +-1 +DROP PACKAGE pkg2; +# +# Argument's order change +# PROCEDURE(a IN, b IN, c OUT) > FUNCTION(c OUT, b IN, a IN) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c OUT INT); +FUNCTION func_sub(c OUT INT, b IN INT, a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c OUT INT) +AS +res INT; +BEGIN +res := func_sub(c, b, a); +END; +FUNCTION func_sub(c OUT INT, b IN INT, a IN INT) RETURN INT +AS +res INT; +BEGIN +c := a - b; +res := a; +RETURN res; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @c = 0; +call pkg2.proc_main(@a, @b, @c); +select @c; +@c +-1 +DROP PACKAGE pkg2; +# +# Argument's order change +# PROCEDURE(a IN, b IN, c INOUT, d OUT) > FUNCTION(d OUT, a IN, b IN, c INOUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c INOUT INT, d OUT INT); +FUNCTION func_sub(d OUT INT, a IN INT, b IN INT, c INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c INOUT INT, d OUT INT) +AS +res INT; +BEGIN +res := func_sub(d, a, b, c); +d := d + c + res; +END; +FUNCTION func_sub(d OUT INT, a IN INT, b IN INT, c INOUT INT) RETURN INT +AS +BEGIN +c := c + 6; +d := 10; +RETURN a - b; +END; +END; +$$ +set @a = 15; +set @b = 5; +set @c = 4; +set @d= 0; +call pkg2.proc_main(@a, @b, @c, @d); +select @d; +@d +30 +DROP PACKAGE pkg2; +# +# Argument's order change +# PROCEDURE(a IN INT, b IN INT, c INOUT INT, d OUT INT) > FUNCTION1(c INOUT INT, b IN INT) > FUNCTION2(d OUT INT, a IN INT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c INOUT INT, d OUT INT); +FUNCTION func_sub1(c INOUT INT, b IN INT) RETURN INT; +FUNCTION func_sub2(d OUT INT, a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b IN INT, c INOUT INT, d OUT INT) +AS +res1 INT; +res2 INT; +BEGIN +res1 := func_sub1(c, b); +res2 := func_sub2(d, a); +d := d + c; +END; +FUNCTION func_sub1(c INOUT INT, b IN INT) RETURN INT +AS +BEGIN +c := c + b; +RETURN 0; +END; +FUNCTION func_sub2(d OUT INT, a IN INT) RETURN INT +AS +BEGIN +d := 5 + a; +RETURN 0; +END; +END; +$$ +set @a = 15; +set @b = 6; +set @c = 4; +set @d= 0; +call pkg2.proc_main(@a, @b, @c, @d); +select @d; +@d +30 +DROP PACKAGE pkg2; +# +# Argument's order change +# FUNCTION1(a IN, b IN) > FUNCTION2(b IN, c OUT, a IN) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT, b IN INT) RETURN INT; +FUNCTION func_sub(b IN INT, c OUT INT, a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT, b IN INT) RETURN INT +AS +c INT; +res INT; +BEGIN +res := func_sub(b, c, a); +RETURN res + c; +END; +FUNCTION func_sub(b IN INT, c OUT INT, a IN INT) RETURN INT +AS +BEGIN +c := 100; +RETURN a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +select pkg2.func_main(@a, @b); +pkg2.func_main(@a, @b) +105 +DROP PACKAGE pkg2; +# +# Call procedure inside function +# FUNCTION1(a IN, b IN) > PROCEDURE(a IN, b IN, c OUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(b IN INT, a IN INT) RETURN INT; +PROCEDURE proc_sub(a IN INT, b IN INT, c OUT INT); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(b IN INT, a IN INT) RETURN INT +AS +c INT; +BEGIN +call proc_sub(a, b, c); +RETURN c; +END; +PROCEDURE proc_sub(a IN INT, b IN INT, c OUT INT) +AS +BEGIN +c := a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +select pkg2.func_main(@a, @b); +pkg2.func_main(@a, @b) +5 +DROP PACKAGE pkg2; +# +# Call procedure inside function +# FUNCTION1(a IN, b IN) > PROCEDURE(a IN, b INOUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(b IN INT, a IN INT) RETURN INT; +PROCEDURE proc_sub(a IN INT, b INOUT INT); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(b IN INT, a IN INT) RETURN INT +AS +BEGIN +call proc_sub(a, b); +RETURN b; +END; +PROCEDURE proc_sub(a IN INT, b INOUT INT) +AS +BEGIN +b := a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +select pkg2.func_main(@a, @b); +pkg2.func_main(@a, @b) +5 +DROP PACKAGE pkg2; +# +# Call procedure inside function +# FUNCTION1(a IN, b IN, c OUT) > PROCEDURE(a IN, b IN, c OUT) +# +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(b IN INT, a IN INT, c OUT INT) RETURN INT; +PROCEDURE proc_sub(a IN INT, b IN INT, c OUT INT); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(b IN INT, a IN INT, c OUT INT) RETURN INT +AS +res INT; +BEGIN +call proc_sub(a, b, c); +RETURN 0; +END; +PROCEDURE proc_sub(a IN INT, b IN INT, c OUT INT) +AS +BEGIN +c := a + b; +END; +END; +$$ +set @a = 2; +set @b = 3; +set @c = 0; +select pkg2.func_main(@a, @b, @c); +ERROR HY000: OUT or INOUT argument 3 for function pkg2.func_main is not allowed here +DROP PACKAGE pkg2; +# +# Call function from UPDATE query +# UPDATE <table> SET <column> = FUNCTION(a IN) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a IN INT) RETURN INT +AS +BEGIN +RETURN a * 10; +END; +END; +$$ +set @a = 5; +UPDATE Persons SET Age = pkg2.func(@a) WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# Call function from UPDATE query +# UPDATE <table> SET <column> = FUNCTION(a OUT) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a OUT INT) RETURN INT +AS +BEGIN +a := 5; +RETURN 80; +END; +END; +$$ +set @a = 0; +UPDATE Persons SET Age = pkg2.func(@a) WHERE ID = 1; +ERROR HY000: OUT or INOUT argument 1 for function pkg2.func is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# Call function from INSERT query +# INSERT INTO <table> SELECT <val1>, <val2>, FUNCTION(a IN) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a IN INT) RETURN INT +AS +BEGIN +RETURN a * 10; +END; +END; +$$ +set @a = 4; +INSERT INTO Persons SELECT 4, 'DDD', PKG2.func(@a); +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# Call function from INSERT query +# INSERT INTO <table> SELECT <val1>, <val2>, FUNCTION(a OUT) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a OUT INT) RETURN INT +AS +BEGIN +a := 45; +RETURN 40; +END; +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +set @a = 0; +INSERT INTO Persons SELECT 5, 'EEE', PKG2.func(@a); +ERROR HY000: OUT or INOUT argument 1 for function PKG2.func is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# Call function from DELETE query +# DELETE FROM <table> WHERE <column> = FUNCTION(a IN) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a IN INT) RETURN INT +AS +BEGIN +RETURN a; +END; +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +set @a = 4; +DELETE FROM Persons WHERE ID = PKG2.func(@a); +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# Call function from DELETE query +# DELETE FROM <table> WHERE <column> = FUNCTION(a OUT) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a OUT INT) RETURN INT +AS +BEGIN +a := 40; +RETURN 4; +END; +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +set @a = 0; +DELETE FROM Persons WHERE ID = PKG2.func(@a); +ERROR HY000: OUT or INOUT argument 1 for function PKG2.func is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# SELECT query inside function +# FUNCTION(a IN) > SELECT … FROM <table> +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT +AS +c INT; +BEGIN +SELECT AGE INTO c FROM Persons WHERE ID = a; +RETURN c; +END; +END; +$$ +set @a = 3; +select pkg2.func_main(@a); +pkg2.func_main(@a) +30 +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# SELECT query inside function +# FUNCTION(a OUT) > SELECT … FROM <table> +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a OUT INT) RETURN INT +AS +BEGIN +SELECT AGE INTO a FROM Persons WHERE ID = 3; +RETURN 0; +END; +END; +$$ +set @a = 0; +select pkg2.func_main(@a); +ERROR HY000: OUT or INOUT argument 1 for function pkg2.func_main is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# SELECT query inside function +# FUNCTION(a INOUT) > SELECT … FROM <table> +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a INOUT INT) RETURN INT +AS +BEGIN +SELECT AGE INTO a FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +set @a = 1; +select pkg2.func_main(@a); +ERROR HY000: OUT or INOUT argument 1 for function pkg2.func_main is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# SELECT query inside function +# FUNCTION(a IN) > FUNCTION(a IN, b OUT) > SELECT … FROM <table> +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT +AS +b INT; +res INT; +BEGIN +res := func_sub(a, b); +RETURN b; +END; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT +AS +BEGIN +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +set @a = 2; +select pkg2.func_main(@a); +pkg2.func_main(@a) +20 +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# UPDATE query inside function +# FUNCTION(a IN) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT +AS +c INT; +BEGIN +UPDATE Persons SET AGE = 50 WHERE ID = a; +SELECT AGE INTO c FROM Persons WHERE ID = a; +RETURN c; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +set @a = 5; +select pkg2.func_main(@a); +pkg2.func_main(@a) +50 +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 50 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# UPDATE query inside function +# FUNCTION(a IN, b OUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT, b OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT, b OUT INT) RETURN INT +AS +BEGIN +UPDATE Persons SET AGE = 60 WHERE ID = a; +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +set @a = 5; +set @b = 0; +select pkg2.func_main(@a, @b); +ERROR HY000: OUT or INOUT argument 2 for function pkg2.func_main is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# UPDATE query inside function +# FUNCTION(a IN, b INOUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT, b INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT, b INOUT INT) RETURN INT +AS +BEGIN +UPDATE Persons SET AGE = 60 WHERE ID = a; +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +set @a = 5; +set @b = 0; +select pkg2.func_main(@a, @b); +ERROR HY000: OUT or INOUT argument 2 for function pkg2.func_main is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# UPDATE query inside function +# FUNCTION(a IN) > FUNCTION(a IN, b OUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 80); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT +AS +b INT; +res INT; +BEGIN +res := func_sub(a, b); +RETURN b; +END; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT +AS +BEGIN +UPDATE Persons SET AGE = 10 WHERE ID = a; +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 80 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +set @a = 1; +select pkg2.func_main(@a); +pkg2.func_main(@a) +10 +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# INSERT query inside function +# FUNCTION(a IN) > INSERT INTO <table> VALUES … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 50); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT +AS +b INT; +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 60); +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN b; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 50 +set @a = 6; +select pkg2.func_main(@a); +pkg2.func_main(@a) +60 +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 50 +6 FFF 60 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# INSERT query inside function +# FUNCTION(a IN, b OUT) > INSERT INTO <table> VALUES … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 50); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT, b OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT, b OUT INT) RETURN INT +AS +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 60); +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 50 +set @a = 6; +set @b = 0; +select pkg2.func_main(@a, @b); +ERROR HY000: OUT or INOUT argument 2 for function pkg2.func_main is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# INSERT query inside function +# FUNCTION(a IN, b INOUT) > INSERT INTO <table> VALUES … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT, b INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT, b INOUT INT) RETURN INT +AS +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 60); +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +set @a = 6; +set @b = 0; +select pkg2.func_main(@a, @b); +ERROR HY000: OUT or INOUT argument 2 for function pkg2.func_main is not allowed here +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# INSERT query inside function +# FUNCTION(a IN) > FUNCTION(a IN, b OUT) > INSERT INTO <table> VALUES … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'EEE', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func_main(a IN INT) RETURN INT +AS +b INT; +res INT; +BEGIN +res := func_sub(a, b); +RETURN b; +END; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT +AS +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 60); +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +set @a = 6; +select pkg2.func_main(@a); +pkg2.func_main(@a) +60 +select * from Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 EEE 40 +6 FFF 60 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(IN) > SELECT FROM <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +BEGIN +b := func_sub(a); +END; +FUNCTION func_sub(a IN INT) RETURN INT +AS +b INT; +BEGIN +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN b; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +set @a = 2; +set @b = 0; +call pkg2.proc_main(@a, @b); +select @b; +@b +20 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(OUT) > SELECT FROM <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +res INT; +BEGIN +res := func_sub(a, b); +END; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT +AS +BEGIN +SELECT AGE INTO b FROM Persons WHERE ID = a; +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +set @a = 1; +set @b = 0; +call pkg2.proc_main(@a, @b); +select @b; +@b +50 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(INOUT) > SELECT FROM <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT, b INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +c INT; +res INT; +BEGIN +c := 5; +res := func_sub(a, c); +b := c; +END; +FUNCTION func_sub(a IN INT, c INOUT INT) RETURN INT +AS +res INT; +BEGIN +SELECT AGE INTO res FROM Persons WHERE ID = a; +c := c * 100; +RETURN res; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +set @a = 2; +set @b = 0; +call pkg2.proc_main(@a, @b); +select @b; +@b +500 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(IN) > INSESRT INTO <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +BEGIN +b := func_sub(a); +END; +FUNCTION func_sub(a IN INT) RETURN INT +AS +BEGIN +INSERT INTO Persons VALUE (a, 'FFF', 50); +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +set @a = 5; +set @b = 0; +call pkg2.proc_main(@a, @b); +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(OUT) > INSESRT INTO <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +res INT; +BEGIN +res := func_sub(a, b); +END; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT +AS +BEGIN +INSERT INTO Persons VALUE (a, 'GGG', 60); +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +set @a = 6; +set @b = 0; +call pkg2.proc_main(@a, @b); +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +6 GGG 60 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(INOUT) > INSESRT INTO <table> … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); +INSERT INTO Persons VALUES (6, 'GGG', 60); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT, b INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +c INT; +res INT; +BEGIN +c := 5; +res := func_sub(a, c); +b := c; +END; +FUNCTION func_sub(a IN INT, c INOUT INT) RETURN INT +AS +res INT; +BEGIN +INSERT INTO Persons VALUE (a, 'HHH', 70); +c := c * 100; +RETURN res; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +6 GGG 60 +set @a = 7; +set @b = 0; +call pkg2.proc_main(@a, @b); +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +6 GGG 60 +7 HHH 70 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(IN) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 50); +INSERT INTO Persons VALUES (6, 'GGG', 60); +INSERT INTO Persons VALUES (7, 'HHH', 70); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +BEGIN +b := func_sub(a); +END; +FUNCTION func_sub(a IN INT) RETURN INT +AS +BEGIN +UPDATE Persons SET AGE = 100 WHERE ID = a; +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 50 +6 GGG 60 +7 HHH 70 +set @a = 5; +set @b = 0; +call pkg2.proc_main(@a, @b); +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 60 +7 HHH 70 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 100); +INSERT INTO Persons VALUES (6, 'GGG', 60); +INSERT INTO Persons VALUES (7, 'HHH', 70); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +res INT; +BEGIN +res := func_sub(a, b); +END; +FUNCTION func_sub(a IN INT, b OUT INT) RETURN INT +AS +BEGIN +UPDATE Persons SET AGE = 100 WHERE ID = a; +b := 1; +RETURN 0; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 60 +7 HHH 70 +set @a = 6; +set @b = 0; +call pkg2.proc_main(@a, @b); +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 100 +7 HHH 70 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# PROCEDURE > FUNCTION > SQL query +# PROCEDURE(OUT) > FUNCTION(INOUT) > UPDATE <table> SET … +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +INSERT INTO Persons VALUES (4, 'DDD', 40); +INSERT INTO Persons VALUES (5, 'FFF', 100); +INSERT INTO Persons VALUES (6, 'GGG', 100); +INSERT INTO Persons VALUES (7, 'HHH', 70); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT); +FUNCTION func_sub(a IN INT, b INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc_main(a IN INT, b OUT INT) +AS +c INT; +res INT; +BEGIN +c := 5; +res := func_sub(a, c); +b := c; +END; +FUNCTION func_sub(a IN INT, c INOUT INT) RETURN INT +AS +res INT; +BEGIN +UPDATE Persons SET AGE = 100 WHERE ID = a; +c := c * 100; +RETURN res; +END; +END; +$$ +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 100 +7 HHH 70 +set @a = 7; +set @b = 0; +call pkg2.proc_main(@a, @b); +select * from Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +4 DDD 40 +5 FFF 100 +6 GGG 100 +7 HHH 100 +DROP TABLE Persons; +DROP PACKAGE pkg2; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 20 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 20 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(IN) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a IN INT) RETURN INT +AS +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +DECLARE +a INT; +res INT; +BEGIN +a := 10; +res := 0; +res := pkg2.func(a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 30 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 30 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(OUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 40); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a OUT INT) RETURN INT +AS +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +a := 100; +RETURN 0; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +DECLARE +a INT; +res INT; +BEGIN +a := 10; +res := 0; +res := pkg2.func(a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 40 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > FUNCTION(INOUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 50); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +FUNCTION func(a INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +FUNCTION func(a INOUT INT) RETURN INT +AS +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +a := 100; +RETURN 0; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +DECLARE +a INT; +res INT; +BEGIN +a := 10; +res := 0; +res := pkg2.func(a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 60 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 60 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(IN) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc(a IN INT); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc(a IN INT) +AS +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +call pkg2.proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 30 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 30 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc(a OUT INT); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc(a OUT INT) +AS +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +call pkg2.proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(INOUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc(a INOUT INT); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc(a INOUT INT) +AS +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +a := 100; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +set @a = 2; +call pkg2.proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 50 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 50 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(IN) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc(a OUT INT); +FUNCTION func(a IN INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc(a OUT INT) +AS +res INT; +BEGIN +a := 100; +res := func(a); +END; +FUNCTION func(a IN INT) RETURN INT +AS +BEGIN +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +call pkg2.proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 60 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 60 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc(a OUT INT); +FUNCTION func(a OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc(a OUT INT) +AS +res INT; +BEGIN +a := 100; +res := func(a); +END; +FUNCTION func(a OUT INT) RETURN INT +AS +BEGIN +a := 200; +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +call pkg2.proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 80 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 80 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(INOUT) > UPDATE TABLE2 +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc(a OUT INT); +FUNCTION func(a INOUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc(a OUT INT) +AS +res INT; +BEGIN +a := 100; +res := func(a); +END; +FUNCTION func(a INOUT INT) RETURN INT +AS +BEGIN +a := 200; +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +call pkg2.proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 90 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 90 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +1 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Trigger +# TRIGGER AFTER UPDATE ON TABLE1 > PROCEDURE(OUT) > FUNCTION(OUT) > UPDATE TABLE2 with OUT argument (to check if OUT is returning by reference) +# +CREATE TABLE Persons ( +ID int, +Name varchar(255), +Age int +); +INSERT INTO Persons VALUES (1, 'AAA', 10); +INSERT INTO Persons VALUES (2, 'BBB', 20); +INSERT INTO Persons VALUES (3, 'CCC', 30); +CREATE TABLE PersonsLog ( +UpdateCount int +); +INSERT INTO PersonsLog VALUES (0); +CREATE OR REPLACE PACKAGE pkg2 +AS +PROCEDURE proc(a OUT INT); +FUNCTION func(a OUT INT) RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg2 +AS +PROCEDURE proc(a OUT INT) +AS +res INT; +BEGIN +res := func(a); +UPDATE PersonsLog SET UpdateCount = a; +END; +FUNCTION func(a OUT INT) RETURN INT +AS +BEGIN +a := 111; +UPDATE PersonsLog SET UpdateCount = UpdateCount+1; +RETURN 0; +END; +END; +$$ +CREATE OR REPLACE TRIGGER my_trigger +AFTER UPDATE ON Persons +FOR EACH ROW +BEGIN +call pkg2.proc(@a); +END; +$$ +SELECT * FROM Persons; +ID Name Age +1 AAA 10 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +0 +UPDATE Persons SET Age = 80 WHERE ID = 1; +SELECT * FROM Persons; +ID Name Age +1 AAA 80 +2 BBB 20 +3 CCC 30 +SELECT * FROM PersonsLog; +UpdateCount +111 +DROP TRIGGER my_trigger; +DROP PACKAGE pkg2; +DROP TABLE Persons; +DROP TABLE PersonsLog; +# +# Package BODY variables as OUT parameters +# +CREATE PACKAGE pkg1 AS +FUNCTION f1(b IN OUT INT) RETURN INT; +FUNCTION show_private_variables() RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +pa INT:= 0; +pb INT:= 10; +FUNCTION f1(b IN OUT INT) RETURN INT AS +BEGIN +b:= b + 100; +RETURN 500+b-100; +END; +FUNCTION show_private_variables() RETURN TEXT AS +BEGIN +RETURN 'Private variables: pa=' || pa || ' pb=' || pb; +END; +BEGIN +SET pa=f1(pb); +END; +$$ +SELECT pkg1.show_private_variables(); +pkg1.show_private_variables() +Private variables: pa=510 pb=110 +DROP PACKAGE pkg1; diff --git a/mysql-test/suite/compat/oracle/r/sp-memory-leak.result b/mysql-test/suite/compat/oracle/r/sp-memory-leak.result new file mode 100644 index 00000000..109a9f84 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-memory-leak.result @@ -0,0 +1,27 @@ +# +# Start of 10.5 tests +# +# +# MDEV-26186 280 Bytes lost in mysys/array.c, mysys/hash.c, sql/sp.cc, sql/sp.cc, sql/item_create.cc, sql/item_create.cc, sql/sql_yacc.yy:10748 when using oracle sql_mode +# +SET sql_mode= 'oracle'; +BEGIN CONTINUE WHEN f0(); +ERROR 42000: CONTINUE with no matching label: +SET sql_mode= 'oracle'; +BEGIN CONTINUE label WHEN f0(); +ERROR 42000: CONTINUE with no matching label: label +SET sql_mode= 'oracle'; +BEGIN EXIT WHEN f0(); +ERROR 42000: EXIT with no matching label: +SET sql_mode= 'oracle'; +BEGIN EXIT label WHEN f0(); +ERROR 42000: EXIT with no matching label: label +SET sql_mode= 'oracle'; +WHILE f(8)<1 DO SELECT 1;; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DO SELECT 1' at line 1 +SET sql_mode= 'oracle'; +BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f0(); +ERROR 42000: RETURN is only allowed in a FUNCTION +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/compat/oracle/r/sp-package-code.result b/mysql-test/suite/compat/oracle/r/sp-package-code.result new file mode 100644 index 00000000..0dea72db --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-code.result @@ -0,0 +1,245 @@ +SET sql_mode=ORACLE; +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +PROCEDURE p2show; +PROCEDURE p2public; +FUNCTION f2public RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +a INT:=10; +PROCEDURE p1 AS +b INT:=20; +BEGIN +b:=a; +b:=a+1; +a:=b; +a:=b+1; +a:=a+1; +SET @a:=@a+2; +SELECT f1() FROM DUAL; +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN a; +END; +PROCEDURE p2private AS +BEGIN +SELECT 'This is p2private'; +END; +PROCEDURE p2public AS +BEGIN +SELECT 'This is p2public'; +END; +FUNCTION f2private RETURN TEXT AS +BEGIN +RETURN 'This is f2private'; +END; +FUNCTION f2public RETURN TEXT AS +BEGIN +RETURN 'This is f2public'; +END; +PROCEDURE p2show AS +BEGIN +SHOW FUNCTION CODE f2public; +SHOW FUNCTION CODE f2private; +SHOW PROCEDURE CODE p2public; +SHOW PROCEDURE CODE p2private; +SHOW PROCEDURE CODE p2show; +END; +BEGIN +a:=a+1; +DECLARE +b INT; +BEGIN +b:=a; +b:=a+1; +a:=b; +a:=b+1; +END; +END; +$$ +SHOW PROCEDURE CODE pkg1.p1; +Pos Instruction +0 set b@0 20 +1 set b@0 PACKAGE_BODY.a@0 +2 set b@0 PACKAGE_BODY.a@0 + 1 +3 set PACKAGE_BODY.a@0 b@0 +4 set PACKAGE_BODY.a@0 b@0 + 1 +5 set PACKAGE_BODY.a@0 PACKAGE_BODY.a@0 + 1 +6 stmt 31 "SET @a:=@a+2" +7 stmt 0 "SELECT f1() FROM DUAL" +SHOW FUNCTION CODE pkg1.f1; +Pos Instruction +0 freturn int PACKAGE_BODY.a@0 +SHOW PACKAGE BODY CODE pkg1; +Pos Instruction +0 set a@0 10 +1 set a@0 a@0 + 1 +2 set b@1 NULL +3 set b@1 a@0 +4 set b@1 a@0 + 1 +5 set a@0 b@1 +6 set a@0 b@1 + 1 +7 jump 11 +CALL pkg1.p2show; +Pos Instruction +0 freturn blob 'This is f2public' +Pos Instruction +0 freturn blob 'This is f2private' +Pos Instruction +0 stmt 0 "SELECT 'This is p2public'" +Pos Instruction +0 stmt 0 "SELECT 'This is p2private'" +Pos Instruction +0 stmt 110 "SHOW FUNCTION CODE f2public" +1 stmt 110 "SHOW FUNCTION CODE f2private" +2 stmt 109 "SHOW PROCEDURE CODE p2public" +3 stmt 109 "SHOW PROCEDURE CODE p2private" +4 stmt 109 "SHOW PROCEDURE CODE p2show" +DROP PACKAGE pkg1; +CREATE TABLE t1 (a INT); +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +a t1.a%TYPE:=10; +PROCEDURE p1 AS +b t1.a%TYPE:=20; +BEGIN +b:=a; +b:=a+1; +b:=b+1; +a:=b; +a:=b+1; +a:=a+1; +END; +BEGIN +a:=a+1; +DECLARE +b t1.a%TYPE; +BEGIN +b:=a; +b:=a+1; +a:=b; +a:=b+1; +END; +END; +$$ +SHOW PROCEDURE CODE pkg1.p1; +Pos Instruction +0 set b@0 20 +1 set b@0 PACKAGE_BODY.a@0 +2 set b@0 PACKAGE_BODY.a@0 + 1 +3 set b@0 b@0 + 1 +4 set PACKAGE_BODY.a@0 b@0 +5 set PACKAGE_BODY.a@0 b@0 + 1 +6 set PACKAGE_BODY.a@0 PACKAGE_BODY.a@0 + 1 +SHOW PACKAGE BODY CODE pkg1; +Pos Instruction +0 set a@0 10 +1 set a@0 a@0 + 1 +2 set b@1 NULL +3 set b@1 a@0 +4 set b@1 a@0 + 1 +5 set a@0 b@1 +6 set a@0 b@1 + 1 +7 jump 11 +DROP PACKAGE pkg1; +DROP TABLE t1; +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +a ROW(a INT,b TEXT):=ROW(10,'x10'); +PROCEDURE p1 AS +b ROW(a INT,b TEXT):=ROW(20,'x20'); +BEGIN +b:=a; +a:=b; +b.a:=a.a+1; +a.a:=b.a+1; +a.a:=a.a+1; +END; +BEGIN +a.a:=a.a+1; +DECLARE +b ROW(a INT,b TEXT):=ROW(30,'x30'); +BEGIN +b:=a; +b.a:=a.a+1; +a:=b; +a.a:=b.a+1; +END; +END; +$$ +SHOW PROCEDURE CODE pkg1.p1; +Pos Instruction +0 set b@0 (20,'x20') +1 set b@0 PACKAGE_BODY.a@0 +2 set PACKAGE_BODY.a@0 b@0 +3 set b.a@0[0] PACKAGE_BODY.a.a@0[0] + 1 +4 set PACKAGE_BODY.a.a@0[0] b.a@0[0] + 1 +5 set PACKAGE_BODY.a.a@0[0] PACKAGE_BODY.a.a@0[0] + 1 +SHOW PACKAGE BODY CODE pkg1; +Pos Instruction +0 set a@0 (10,'x10') +1 set a.a@0[0] a.a@0[0] + 1 +2 set b@1 (30,'x30') +3 set b@1 a@0 +4 set b.a@1[0] a.a@0[0] + 1 +5 set a@0 b@1 +6 set a.a@0[0] b.a@1[0] + 1 +7 jump 11 +DROP PACKAGE pkg1; +CREATE TABLE t1 (a INT, b TEXT); +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +a t1%ROWTYPE:=ROW(10,'x10'); +PROCEDURE p1 AS +b t1%ROWTYPE:=ROW(20,'x20'); +BEGIN +b:=a; +a:=b; +b.a:=a.a+1; +a.a:=b.a+1; +a.a:=a.a+1; +END; +BEGIN +a.a:=a.a+1; +DECLARE +b t1%ROWTYPE:=ROW(30,'x30'); +BEGIN +b:=a; +b.a:=a.a+1; +a:=b; +a.a:=b.a+1; +END; +END; +$$ +SHOW PROCEDURE CODE pkg1.p1; +Pos Instruction +0 set b@0 (20,'x20') +1 set b@0 PACKAGE_BODY.a@0 +2 set PACKAGE_BODY.a@0 b@0 +3 set b.a@0["a"] PACKAGE_BODY.a.a@0["a"] + 1 +4 set PACKAGE_BODY.a.a@0["a"] b.a@0["a"] + 1 +5 set PACKAGE_BODY.a.a@0["a"] PACKAGE_BODY.a.a@0["a"] + 1 +SHOW PACKAGE BODY CODE pkg1; +Pos Instruction +0 set a@0 (10,'x10') +1 set a.a@0["a"] a.a@0["a"] + 1 +2 set b@1 (30,'x30') +3 set b@1 a@0 +4 set b.a@1["a"] a.a@0["a"] + 1 +5 set a@0 b@1 +6 set a.a@0["a"] b.a@1["a"] + 1 +7 jump 11 +DROP PACKAGE pkg1; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-db.result b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-db.result new file mode 100644 index 00000000..95f45c25 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-db.result @@ -0,0 +1,43 @@ +# +# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine +# +SET @object_type='db'; +# +# Start of sp-package-concurrent-dml.inc +# +SET sql_mode=ORACLE; +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p2 AS +BEGIN +SELECT 'This is p2' AS msg; +END; +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1' AS msg; +DO GET_LOCK('mdev15070',120); +CALL p2(); +DO RELEASE_LOCK('mdev15070'); +END; +END; +$$ +connect con2,localhost,root; +connection con2; +DO GET_LOCK('mdev15070', 120); +connection default; +CALL pkg1.p1; +connection con2; +CREATE DATABASE test1; +CREATE FUNCTION test1.f1() RETURNS INT RETURN 10; +DROP DATABASE test1; +DO RELEASE_LOCK('mdev15070'); +disconnect con2; +connection default; +msg +This is p1 +msg +This is p2 +DROP PACKAGE IF EXISTS pkg1; diff --git a/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-package.result b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-package.result new file mode 100644 index 00000000..eb7d38a8 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-package.result @@ -0,0 +1,96 @@ +# +# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine +# +SET @object_type='package_replace_pkg1'; +# +# Start of sp-package-concurrent-dml.inc +# +SET sql_mode=ORACLE; +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p2 AS +BEGIN +SELECT 'This is p2' AS msg; +END; +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1' AS msg; +DO GET_LOCK('mdev15070',120); +CALL p2(); +DO RELEASE_LOCK('mdev15070'); +END; +END; +$$ +connect con2,localhost,root; +connection con2; +DO GET_LOCK('mdev15070', 120); +connection default; +CALL pkg1.p1; +connection con2; +SET sql_mode=ORACLE; +CREATE OR REPLACE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +DROP PACKAGE pkg1; +DO RELEASE_LOCK('mdev15070'); +disconnect con2; +connection default; +msg +This is p1 +msg +This is p2 +DROP PACKAGE IF EXISTS pkg1; +Warnings: +Note 1305 PACKAGE test.pkg1 does not exist +SET @object_type='package_body_replace_pkg1'; +# +# Start of sp-package-concurrent-dml.inc +# +SET sql_mode=ORACLE; +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p2 AS +BEGIN +SELECT 'This is p2' AS msg; +END; +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1' AS msg; +DO GET_LOCK('mdev15070',120); +CALL p2(); +DO RELEASE_LOCK('mdev15070'); +END; +END; +$$ +connect con2,localhost,root; +connection con2; +DO GET_LOCK('mdev15070', 120); +connection default; +CALL pkg1.p1; +connection con2; +SET sql_mode=ORACLE; +CREATE OR REPLACE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1 version 2' AS msg; +END; +END; +$$ +DROP PACKAGE pkg1; +DO RELEASE_LOCK('mdev15070'); +disconnect con2; +connection default; +msg +This is p1 +msg +This is p2 +DROP PACKAGE IF EXISTS pkg1; +Warnings: +Note 1305 PACKAGE test.pkg1 does not exist diff --git a/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-trigger.result b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-trigger.result new file mode 100644 index 00000000..8181714f --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-trigger.result @@ -0,0 +1,44 @@ +# +# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine +# +SET @object_type='trigger'; +# +# Start of sp-package-concurrent-dml.inc +# +SET sql_mode=ORACLE; +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p2 AS +BEGIN +SELECT 'This is p2' AS msg; +END; +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1' AS msg; +DO GET_LOCK('mdev15070',120); +CALL p2(); +DO RELEASE_LOCK('mdev15070'); +END; +END; +$$ +connect con2,localhost,root; +connection con2; +DO GET_LOCK('mdev15070', 120); +connection default; +CALL pkg1.p1; +connection con2; +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=1; +DROP TRIGGER tr1; +DROP TABLE t1; +DO RELEASE_LOCK('mdev15070'); +disconnect con2; +connection default; +msg +This is p1 +msg +This is p2 +DROP PACKAGE IF EXISTS pkg1; diff --git a/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-view.result b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-view.result new file mode 100644 index 00000000..b0ceec60 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-concurrent-dml-view.result @@ -0,0 +1,42 @@ +# +# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine +# +SET @object_type='view'; +# +# Start of sp-package-concurrent-dml.inc +# +SET sql_mode=ORACLE; +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p2 AS +BEGIN +SELECT 'This is p2' AS msg; +END; +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1' AS msg; +DO GET_LOCK('mdev15070',120); +CALL p2(); +DO RELEASE_LOCK('mdev15070'); +END; +END; +$$ +connect con2,localhost,root; +connection con2; +DO GET_LOCK('mdev15070', 120); +connection default; +CALL pkg1.p1; +connection con2; +CREATE VIEW v1 AS SELECT 1 AS c; +DROP VIEW v1; +DO RELEASE_LOCK('mdev15070'); +disconnect con2; +connection default; +msg +This is p1 +msg +This is p2 +DROP PACKAGE IF EXISTS pkg1; diff --git a/mysql-test/suite/compat/oracle/r/sp-package-i_s.result b/mysql-test/suite/compat/oracle/r/sp-package-i_s.result new file mode 100644 index 00000000..2f4201f7 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-i_s.result @@ -0,0 +1,75 @@ +# +# Start of 10.5 tests +# +# +# MDEV-30662 SQL/PL package body does not appear in I_S.ROUTINES.ROUTINE_DEFINITION +# +SET sql_mode=ORACLE; +CREATE OR REPLACE PACKAGE pkg1 AS +FUNCTION f1() RETURN INT; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +FUNCTION f1() RETURN INT AS +BEGIN +RETURN 1; +END; +END; +$$ +SELECT routine_name, routine_type, routine_definition +FROM information_schema.routines +WHERE routine_type LIKE 'PACKAGE%' +ORDER BY routine_type; +routine_name pkg1 +routine_type PACKAGE +routine_definition AS +FUNCTION f1() RETURN INT; +END +routine_name pkg1 +routine_type PACKAGE BODY +routine_definition AS +FUNCTION f1() RETURN INT AS +BEGIN +RETURN 1; +END; +END +DROP PACKAGE pkg1; +SET sql_mode=ORACLE; +CREATE OR REPLACE PACKAGE pkg1 AS +FUNCTION f1() RETURN INT; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +FUNCTION f1() RETURN INT AS +BEGIN +RETURN 1; +END; +BEGIN +SET @a=10; +SET @a=f1(); +END; +$$ +SELECT routine_name, routine_type, routine_definition +FROM information_schema.routines +WHERE routine_type LIKE 'PACKAGE%' +ORDER BY routine_type; +routine_name pkg1 +routine_type PACKAGE +routine_definition AS +FUNCTION f1() RETURN INT; +END +routine_name pkg1 +routine_type PACKAGE BODY +routine_definition AS +FUNCTION f1() RETURN INT AS +BEGIN +RETURN 1; +END; +BEGIN +SET @a=10; +SET @a=f1(); +END +DROP PACKAGE pkg1; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/compat/oracle/r/sp-package-innodb.result b/mysql-test/suite/compat/oracle/r/sp-package-innodb.result new file mode 100644 index 00000000..0ac357df --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-innodb.result @@ -0,0 +1,77 @@ +SET default_storage_engine=InnoDB; +SET sql_mode=ORACLE; +CREATE TABLE t1 (a INT, routine TEXT); +SELECT ENGINE FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; +ENGINE +InnoDB +INSERT INTO t1 VALUES (10,'none'); +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +a INT; +PROCEDURE p1 AS +BEGIN +a:=a+1; +INSERT INTO t1 VALUES (a,'p1'); +END; +BEGIN +SELECT MAX(t1.a) FROM t1 INTO a; +a:=a+1; +INSERT INTO t1 VALUES (a,'pkg1 initialization'); +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL pkg1.p1; +SELECT * FROM t1 ORDER BY a; +a routine +10 none +11 pkg1 initialization +12 p1 +DELETE FROM t1; +# sp-cache-invalidate +START TRANSACTION; +CALL pkg1.p1; +SELECT * FROM t1 ORDER BY a; +a routine +NULL pkg1 initialization +NULL p1 +ROLLBACK; +SELECT * FROM t1 ORDER BY a; +a routine +DELETE FROM t1; +# sp-cache-invalidate +INSERT INTO t1 VALUES (20,'none'); +START TRANSACTION; +CALL pkg1.p1; +SELECT * FROM t1 ORDER BY a; +a routine +20 none +21 pkg1 initialization +22 p1 +COMMIT; +SELECT * FROM t1 ORDER BY a; +a routine +20 none +21 pkg1 initialization +22 p1 +DELETE FROM t1; +# sp-cache-invalidate +INSERT INTO t1 VALUES (20,'none'); +START TRANSACTION; +CALL pkg1.p1; +SELECT * FROM t1 ORDER BY a; +a routine +20 none +21 pkg1 initialization +22 p1 +ROLLBACK; +SELECT * FROM t1 ORDER BY a; +a routine +20 none +DELETE FROM t1; +DROP PACKAGE pkg1; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/sp-package-mdl.result b/mysql-test/suite/compat/oracle/r/sp-package-mdl.result new file mode 100644 index 00000000..bb46341f --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-mdl.result @@ -0,0 +1,80 @@ +SET sql_mode=ORACLE; +DO GET_LOCK('lock',300); +connect conn1,localhost,root,,; +SET sql_mode=ORACLE; +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS +BEGIN +DO GET_LOCK('lock',300); +END; +FUNCTION f1 RETURN INT AS +BEGIN +CALL p1; +RETURN 1; +END; +END; +$$ +SELECT pkg1.f1(); +connection default; +connect conn2,localhost,root,,; +SET sql_mode=ORACLE; +DROP PACKAGE pkg1; +connection default; +SELECT ID-CONNECTION_ID() AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME +FROM INFORMATION_SCHEMA.PROCESSLIST +LEFT JOIN INFORMATION_SCHEMA.METADATA_LOCK_INFO +ON (ID=THREAD_ID) +ORDER BY ID,TABLE_NAME,LOCK_MODE,LOCK_TYPE; +CONN 0 +INFO SELECT ID-CONNECTION_ID() AS CONN,INFO,STATE,LOCK_MODE,LOCK_TYPE,TABLE_NAME +FROM INFORMATION_SCHEMA.PROCESSLIST +LEFT JOIN INFORMATION_SCHEMA.METADATA_LOCK_INFO +ON (ID=THREAD_ID) +ORDER BY ID,TABLE_NAME,LOCK_MODE,LOCK_TYPE +STATE Filling schema table +LOCK_MODE MDL_SHARED_NO_WRITE +LOCK_TYPE User lock +TABLE_NAME +CONN 1 +INFO DO GET_LOCK('lock',300) +STATE User lock +LOCK_MODE MDL_SHARED +LOCK_TYPE Stored package body metadata lock +TABLE_NAME pkg1 +CONN 1 +INFO DO GET_LOCK('lock',300) +STATE User lock +LOCK_MODE MDL_SHARED +LOCK_TYPE Stored function metadata lock +TABLE_NAME pkg1.f1 +CONN 1 +INFO DO GET_LOCK('lock',300) +STATE User lock +LOCK_MODE MDL_SHARED +LOCK_TYPE Stored procedure metadata lock +TABLE_NAME pkg1.p1 +CONN 2 +INFO DROP PACKAGE pkg1 +STATE Waiting for stored package body metadata lock +LOCK_MODE MDL_BACKUP_DDL +LOCK_TYPE Backup lock +TABLE_NAME +CONN 2 +INFO DROP PACKAGE pkg1 +STATE Waiting for stored package body metadata lock +LOCK_MODE MDL_INTENTION_EXCLUSIVE +LOCK_TYPE Schema metadata lock +TABLE_NAME +DO RELEASE_LOCK('lock'); +connection conn1; +pkg1.f1() +1 +disconnect conn1; +connection conn2; +disconnect conn2; +connection default; diff --git a/mysql-test/suite/compat/oracle/r/sp-package-mysqldump.result b/mysql-test/suite/compat/oracle/r/sp-package-mysqldump.result new file mode 100644 index 00000000..24211c63 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-mysqldump.result @@ -0,0 +1,261 @@ +SET sql_mode=ORACLE; +CREATE PROCEDURE p1 AS +BEGIN +SELECT pkg1.f1(); -- a standalone routine calls a package routine +END; +$$ +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS +BEGIN +CALL test.p1; -- a package routine calls a standalone routine +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +END; +$$ +CALL p1; +pkg1.f1() +10 +CALL pkg1.p1; +pkg1.f1() +10 +SELECT pkg1.f1(); +pkg1.f1() +10 +CREATE PACKAGE pkg2 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `p1` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +BEGIN +SELECT pkg1.f1(); -- a standalone routine calls a package routine +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT' */ ; +/*!50003 DROP PACKAGE IF EXISTS `pkg1` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER="root"@"localhost" PACKAGE "pkg1" AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT' */ ; +/*!50003 DROP PACKAGE IF EXISTS `pkg2` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER="root"@"localhost" PACKAGE "pkg2" AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT' */ ; +/*!50003 DROP PACKAGE BODY IF EXISTS `pkg1` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +DELIMITER ;; +CREATE DEFINER="root"@"localhost" PACKAGE BODY "pkg1" AS +PROCEDURE p1 AS +BEGIN +CALL test.p1; -- a package routine calls a standalone routine +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +<?xml version="1.0"?> +<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +<database name="test"> + <routines> + <routine Procedure="p1" sql_mode="PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> +<![CDATA[ +CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +BEGIN +SELECT pkg1.f1(); -- a standalone routine calls a package routine +END +]]> + </routine> + <routine Package="pkg1" sql_mode="PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> +<![CDATA[ +CREATE DEFINER="root"@"localhost" PACKAGE "pkg1" AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END +]]> + </routine> + <routine Package="pkg2" sql_mode="PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> +<![CDATA[ +CREATE DEFINER="root"@"localhost" PACKAGE "pkg2" AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END +]]> + </routine> + <routine Package_body="pkg1" sql_mode="PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> +<![CDATA[ +CREATE DEFINER="root"@"localhost" PACKAGE BODY "pkg1" AS +PROCEDURE p1 AS +BEGIN +CALL test.p1; -- a package routine calls a standalone routine +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +END +]]> + </routine> + </routines> +</database> +</mysqldump> +DROP PACKAGE pkg1; +DROP PACKAGE pkg2; +DROP PROCEDURE p1; +SHOW PACKAGE STATUS; +Db test +Name pkg1 +Type PACKAGE +Definer root@localhost +Modified 0000-00-00 00:00:00 +Created 0000-00-00 00:00:00 +Security_type DEFINER +Comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +Db test +Name pkg2 +Type PACKAGE +Definer root@localhost +Modified 0000-00-00 00:00:00 +Created 0000-00-00 00:00:00 +Security_type DEFINER +Comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +SHOW PACKAGE BODY STATUS; +Db test +Name pkg1 +Type PACKAGE BODY +Definer root@localhost +Modified 0000-00-00 00:00:00 +Created 0000-00-00 00:00:00 +Security_type DEFINER +Comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +SHOW CREATE PACKAGE pkg1; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PACKAGE "pkg1" AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE PACKAGE pkg2; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg2 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PACKAGE "pkg2" AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE PACKAGE BODY pkg1; +Package body sql_mode Create Package Body character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PACKAGE BODY "pkg1" AS +PROCEDURE p1 AS +BEGIN +CALL test.p1; +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END; +END latin1 latin1_swedish_ci latin1_swedish_ci +CALL p1; +pkg1.f1() +10 +CALL pkg1.p1; +pkg1.f1() +10 +SELECT pkg1.f1(); +pkg1.f1() +10 +DROP PACKAGE pkg1; +DROP PACKAGE pkg2; +DROP PROCEDURE p1; +# removing the dump file diff --git a/mysql-test/suite/compat/oracle/r/sp-package-security.result b/mysql-test/suite/compat/oracle/r/sp-package-security.result new file mode 100644 index 00000000..c08b78cb --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package-security.result @@ -0,0 +1,322 @@ +SET sql_mode=ORACLE; +CREATE DATABASE db1; +CREATE USER u1@localhost IDENTIFIED BY ''; +GRANT SELECT ON db1.* TO u1@localhost; +connect conn1,localhost,u1,,db1; +SELECT CURRENT_USER; +CURRENT_USER +u1@localhost +SET sql_mode=ORACLE; +# +# User u1 cannot drop PROCEDURE, PACKAGE, PACKAGE BODY by default +# +DROP PROCEDURE p1; +ERROR 42000: alter routine command denied to user 'u1'@'localhost' for routine 'db1.p1' +DROP PACKAGE pkg1; +ERROR 42000: alter routine command denied to user 'u1'@'localhost' for routine 'db1.pkg1' +DROP PACKAGE BODY pkg1; +ERROR 42000: alter routine command denied to user 'u1'@'localhost' for routine 'db1.pkg1' +# +# User u1 cannot create PROCEDURE, PACKAGE, PACKAGE BODY by default +# +CREATE PROCEDURE p1 AS +BEGIN +NULL; +END; +$$ +ERROR 42000: Access denied for user 'u1'@'localhost' to database 'db1' +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +ERROR 42000: Access denied for user 'u1'@'localhost' to database 'db1' +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS BEGIN NULL; END; +END; +$$ +ERROR 42000: PACKAGE db1.pkg1 does not exist +# +# Now create a PACKAGE by root +# +connection default; +USE db1; +CREATE PROCEDURE p1root AS +BEGIN +SELECT 1; +END; +$$ +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END; +$$ +SHOW CREATE PACKAGE pkg1; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PACKAGE "pkg1" AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END latin1 latin1_swedish_ci latin1_swedish_ci +# +# u1 cannot SHOW yet: +# - the standalone procedure earlier created by root +# - the package specifications earlier create by root +# +connection conn1; +SHOW CREATE PROCEDURE p1root; +ERROR 42000: PROCEDURE p1root does not exist +SHOW CREATE PACKAGE pkg1; +ERROR 42000: PACKAGE pkg1 does not exist +# +# User u1 still cannot create a PACKAGE BODY +# +connection conn1; +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS BEGIN NULL; END; +FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is f1'; END; +END; +$$ +ERROR 42000: Access denied for user 'u1'@'localhost' to database 'db1' +# +# Now grant EXECUTE: +# - on the standalone procedure earlier created by root +# - on the package specification earlier created by root +# +connection default; +GRANT EXECUTE ON PROCEDURE db1.p1root TO u1@localhost; +GRANT EXECUTE ON PACKAGE db1.pkg1 TO u1@localhost; +# +# Now u1 can do SHOW for: +# - the standalone procedure earlier created by root +# - the package specification earlier created by root +# +disconnect conn1; +connect conn1,localhost,u1,,db1; +SET sql_mode=ORACLE; +SHOW CREATE PROCEDURE db1.p1root; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +p1root PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE PACKAGE db1.pkg1; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci +# +# Now revoke EXECUTE and grant CREATE ROUTINE instead +# +connection default; +REVOKE EXECUTE ON PROCEDURE db1.p1root FROM u1@localhost; +REVOKE EXECUTE ON PACKAGE db1.pkg1 FROM u1@localhost; +GRANT CREATE ROUTINE ON db1.* TO u1@localhost; +# +# Reconnect u1 to make new grants have effect +# +disconnect conn1; +connect conn1,localhost,u1,,db1; +SET sql_mode=ORACLE; +# +# Now u1 can SHOW: +# - standalone routines earlier created by root +# - package specifications earlier created by root +# +SHOW CREATE PROCEDURE p1root; +Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation +p1root PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE PACKAGE pkg1; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci +# +# Now u1 can CREATE, DROP and EXECUTE its own standalone procedures +# +CREATE PROCEDURE p1 AS +BEGIN +NULL; +END; +$$ +SHOW GRANTS; +Grants for u1@localhost +GRANT USAGE ON *.* TO "u1"@"localhost" +GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" +GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE "db1"."p1" TO "u1"@"localhost" +CALL p1; +DROP PROCEDURE p1; +SHOW GRANTS; +Grants for u1@localhost +GRANT USAGE ON *.* TO "u1"@"localhost" +GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" +# +# Now u1 can also CREATE, DROP its own package specifications +# +CREATE PACKAGE pkg2 AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END; +$$ +SHOW CREATE PACKAGE pkg2; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg2 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="u1"@"localhost" PACKAGE "pkg2" AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END latin1 latin1_swedish_ci latin1_swedish_ci +SHOW GRANTS; +Grants for u1@localhost +GRANT USAGE ON *.* TO "u1"@"localhost" +GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" +GRANT EXECUTE, ALTER ROUTINE ON PACKAGE "db1"."pkg2" TO "u1"@"localhost" +DROP PACKAGE pkg2; +SHOW GRANTS; +Grants for u1@localhost +GRANT USAGE ON *.* TO "u1"@"localhost" +GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" +# +# Now u1 can also CREATE, DROP package bodies and EXECUTE package body routines +# +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS BEGIN SELECT 'This is pkg1.p1' AS `comment`; END; +FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is pkg1.f1'; END; +END; +$$ +SHOW CREATE PACKAGE pkg1; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE PACKAGE BODY pkg1; +Package body sql_mode Create Package Body character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="u1"@"localhost" PACKAGE BODY "pkg1" AS +PROCEDURE p1 AS BEGIN SELECT 'This is pkg1.p1' AS `comment`; END; +FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is pkg1.f1'; END; +END latin1 latin1_swedish_ci latin1_swedish_ci +SHOW GRANTS; +Grants for u1@localhost +GRANT USAGE ON *.* TO "u1"@"localhost" +GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" +GRANT EXECUTE, ALTER ROUTINE ON PACKAGE BODY "db1"."pkg1" TO "u1"@"localhost" +CALL pkg1.p1; +comment +This is pkg1.p1 +SELECT pkg1.f1(); +pkg1.f1() +This is pkg1.f1 +DROP PACKAGE BODY pkg1; +SHOW GRANTS; +Grants for u1@localhost +GRANT USAGE ON *.* TO "u1"@"localhost" +GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" +# +# Now create a PACKAGE BODY by root. +# u1 does not have EXECUTE access by default. +# +connection default; +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS BEGIN SELECT 'This is pkg1.p1' AS `comment`; END; +FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is pkg1.f1'; END; +END; +$$ +connection conn1; +SHOW CREATE PACKAGE pkg1; +Package sql_mode Create Package character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE PACKAGE BODY pkg1; +Package body sql_mode Create Package Body character_set_client collation_connection Database Collation +pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci +CALL pkg1.p1; +ERROR 42000: execute command denied to user 'u1'@'localhost' for routine 'db1.pkg1' +SELECT pkg1.f1(); +ERROR 42000: execute command denied to user 'u1'@'localhost' for routine 'db1.pkg1' +# +# Now grant EXECUTE to u1 on the PACKAGE BODY created by root +# +connection default; +GRANT EXECUTE ON PACKAGE BODY db1.pkg1 TO u1@localhost; +disconnect conn1; +connect conn1,localhost,u1,,db1; +SELECT CURRENT_USER; +CURRENT_USER +u1@localhost +SET sql_mode=ORACLE; +SHOW GRANTS; +Grants for u1@localhost +GRANT USAGE ON *.* TO "u1"@"localhost" +GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" +GRANT EXECUTE ON PACKAGE BODY "db1"."pkg1" TO "u1"@"localhost" +CALL pkg1.p1; +comment +This is pkg1.p1 +SELECT pkg1.f1(); +pkg1.f1() +This is pkg1.f1 +connection default; +DROP PACKAGE BODY pkg1; +# +# u1 still cannot DROP the package specification earlier created by root. +# +connection conn1; +DROP PACKAGE pkg1; +ERROR 42000: alter routine command denied to user 'u1'@'localhost' for routine 'db1.pkg1' +# +# Grant ALTER ROUTINE to u1 +# +connection default; +GRANT ALTER ROUTINE ON db1.* TO u1@localhost; +# +# Now u1 can DROP: +# - the standalone procedure earlier created by root +# - the package specification earlier created by root +# +disconnect conn1; +connect conn1,localhost,u1,,db1; +SET sql_mode=ORACLE; +DROP PACKAGE pkg1; +DROP PROCEDURE p1root; +disconnect conn1; +connection default; +DROP USER u1@localhost; +DROP DATABASE db1; +USE test; +# +# Creator=root, definer=xxx +# +CREATE USER xxx@localhost; +CREATE DEFINER=xxx@localhost PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE DEFINER=xxx@localhost PACKAGE BODY p1 AS +PROCEDURE p1 AS +BEGIN +SELECT SESSION_USER(), CURRENT_USER(), 'p1.p1' AS msg; +END; +BEGIN +SELECT SESSION_USER(), CURRENT_USER(), 'package body p1' AS msg; +END; +$$ +CALL p1.p1; +ERROR 42000: execute command denied to user 'xxx'@'localhost' for routine 'test.p1' +GRANT EXECUTE ON PACKAGE BODY test.p1 TO xxx@localhost; +CALL p1.p1; +SESSION_USER() CURRENT_USER() msg +root@localhost xxx@localhost package body p1 +SESSION_USER() CURRENT_USER() msg +root@localhost xxx@localhost p1.p1 +DROP PACKAGE p1; +DROP USER xxx@localhost; +# +# Creator=root, definer=xxx, SQL SECURITY INVOKER +# +CREATE USER xxx@localhost; +CREATE DEFINER=xxx@localhost PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE DEFINER=xxx@localhost PACKAGE BODY p1 SQL SECURITY INVOKER AS +PROCEDURE p1 AS +BEGIN +SELECT SESSION_USER(), CURRENT_USER(), 'p1.p1' AS msg; +END; +BEGIN +SELECT SESSION_USER(), CURRENT_USER(), 'package body p1' AS msg; +END; +$$ +CALL p1.p1; +SESSION_USER() CURRENT_USER() msg +root@localhost root@localhost package body p1 +SESSION_USER() CURRENT_USER() msg +root@localhost root@localhost p1.p1 +DROP PACKAGE p1; +DROP USER xxx@localhost; diff --git a/mysql-test/suite/compat/oracle/r/sp-package.result b/mysql-test/suite/compat/oracle/r/sp-package.result new file mode 100644 index 00000000..ee17c048 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-package.result @@ -0,0 +1,3375 @@ +SET sql_mode=ORACLE; +# +# Creating a body of a non-existing package +# +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +END; +$$ +ERROR 42000: PACKAGE test.test2 does not exist +# +# Dropping a non-existing package +# +DROP PACKAGE test2; +ERROR 42000: PACKAGE test.test2 does not exist +DROP PACKAGE IF EXISTS test2; +Warnings: +Note 1305 PACKAGE test.test2 does not exist +DROP PACKAGE BODY test2; +ERROR 42000: PACKAGE BODY test.test2 does not exist +# +# Bad combinations of OR REPLACE and IF EXISTS +# +CREATE OR REPLACE PACKAGE IF NOT EXISTS pkg AS +PROCEDURE p1; +END; +$$ +ERROR HY000: Incorrect usage of OR REPLACE and IF NOT EXISTS +CREATE OR REPLACE PACKAGE BODY IF NOT EXISTS pkg AS +PROCEDURE p1 AS BEGIN NULL; END; +END; +$$ +ERROR HY000: Incorrect usage of OR REPLACE and IF NOT EXISTS +# +# PACKAGE and PS +# +PREPARE stmt FROM 'CREATE PACKAGE test2 AS FUNCTION f1 RETURN INT; END test2'; +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +END; +$$ +PREPARE stmt FROM 'CREATE PACKAGE BODY test2 AS' + ' FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END;' + 'END test2'; +DROP PACKAGE test2; +# +# Package and READ ONLY transactions +# +SET SESSION TRANSACTION READ ONLY; +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END +$$ +ERROR 25006: Cannot execute statement in a READ ONLY transaction +SET SESSION TRANSACTION READ WRITE; +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +FUNCTION f2 RETURN INT; +END; +$$ +SET SESSION TRANSACTION READ ONLY +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +FUNCTION f2 RETURN INT AS BEGIN RETURN f1(); END; +PROCEDURE p1 AS +BEGIN +SELECT f2(); +END; +END; +$$ +ERROR 25006: Cannot execute statement in a READ ONLY transaction +SET SESSION TRANSACTION READ WRITE; +DROP PACKAGE test2; +SET SESSION TRANSACTION READ ONLY; +DROP PACKAGE test2; +ERROR 25006: Cannot execute statement in a READ ONLY transaction +DROP PACKAGE BODY test2; +ERROR 25006: Cannot execute statement in a READ ONLY transaction +SET SESSION TRANSACTION READ WRITE; +# +# Syntax error inside a CREATE PACKAGE, inside a routine definition +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +FUNCTION f2 RETURN INT; +FUNCTION f3; +FUNCTION f4 RETURN INT; +END +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '; +FUNCTION f4 RETURN INT; +END' at line 4 +# +# Syntax error inside a CREATE PACKAGE, outside of a routine definition +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +FUNCTION f2 RETURN INT; +FUNCTION f3 RETURN INT AS BEGIN RETURN 10; END; +FUNCTION f4 RETURN INT; +END +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'AS BEGIN RETURN 10; END; +FUNCTION f4 RETURN INT; +END' at line 4 +# +# Syntax error inside a CREATE PACKAGE BODY, inside a routine definition +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +FUNCTION f2 RETURN INT; +END; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +FUNCTION f2 RETURN INT SA BEGIN RETURN 10; END; -- Notice "SA" vs "AS" +END +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SA BEGIN RETURN 10; END; -- Notice "SA" vs "AS" +END' at line 3 +DROP PACKAGE test2; +# +# Syntax error inside a CREATE PACKAGE BODY, outside a routine definition +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +FUNCTION f2 RETURN INT; +END; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +SOME SYNTAX ERROR; +FUNCTION f2 RETURN INT AS BEGIN RETURN 10; END; +END +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SOME SYNTAX ERROR; +FUNCTION f2 RETURN INT AS BEGIN RETURN 10; END; +END' at line 3 +DROP PACKAGE test2; +# +# Syntax error inside a CREATE PACKAGE BODY executable section +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +BEGIN +SOME SYNTAX ERROR; +END +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SYNTAX ERROR; +END' at line 4 +DROP PACKAGE test2; +# +# CREATE PROCEDURE inside a package PROCEDURE is not allowed +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS +BEGIN +CREATE PROCEDURE p1 AS BEGIN NULL; END; +END; +END; +$$ +ERROR 2F003: Can't create a PROCEDURE from within another stored routine +DROP PACKAGE test2; +# +# CREATE PACKAGE inside a package PROCEDURE is not allowed +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS +BEGIN +CREATE PACKAGE p1 AS PROCEDURE p1; END; +END; +END; +$$ +ERROR 2F003: Can't create a PACKAGE from within another stored routine +DROP PACKAGE test2; +# +# CREATE PROCEDURE inside a package executable section is not allowed +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS BEGIN NULL; END; +BEGIN +CREATE PROCEDURE p1 AS BEGIN NULL; END; +END; +$$ +ERROR 2F003: Can't create a PROCEDURE from within another stored routine +DROP PACKAGE test2; +# +# CREATE FUNCTION inside a package executable section is not allowed +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS BEGIN NULL; END; +BEGIN +CREATE FUNCTION f1 RETURN INT AS BEGIN RETURN 0; END; +END; +$$ +ERROR 2F003: Can't create a FUNCTION from within another stored routine +DROP PACKAGE test2; +# +# CREATE PACKAGE inside a package executable section is not allowed +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS BEGIN NULL; END; +BEGIN +CREATE PACKAGE p1 AS PROCEDURE p1; END; +END; +$$ +ERROR 2F003: Can't create a PACKAGE from within another stored routine +DROP PACKAGE test2; +# +# Broken CREATE PACKAGE at CREATE PACKAGE BODY time +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +END; +$$ +UPDATE mysql.proc SET `body`='garbage' + WHERE db='test' AND name='test2' AND type='PACKAGE'; +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT +AS BEGIN +RETURN f2(); +END; +END; +$$ +ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +show warnings; +Level Code Message +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'garbage' at line 1 +Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +DROP PACKAGE test2; +# +# Broken CREATE PACKAGE at a package function call time +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT +AS BEGIN +RETURN f2(); +END; +END; +$$ +SELECT test2.f1(); +ERROR 42000: FUNCTION test.f2 does not exist +UPDATE mysql.proc SET `body`='garbage' + WHERE db='test' AND name='test2' AND type='PACKAGE'; +# sp-cache-invalidate +SELECT test2.f1(); +ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +show warnings; +Level Code Message +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'garbage' at line 1 +Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +SELECT test2.f1(); +ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +show warnings; +Level Code Message +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'garbage' at line 1 +Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +SELECT test2.f1(); +ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +show warnings; +Level Code Message +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'garbage' at line 1 +Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +DROP PACKAGE test2; +# +# Broken CREATE PACKAGE at a package procedure call time +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 +AS BEGIN +CALL p2; +END; +END; +$$ +CALL test2.f1(); +ERROR 42000: PROCEDURE test2.f1 does not exist +UPDATE mysql.proc SET `body`='garbage' + WHERE db='test' AND name='test2' AND type='PACKAGE'; +# sp-cache-invalidate +CALL test2.p1(); +ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +show warnings; +Level Code Message +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'garbage' at line 1 +Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +CALL test2.p1(); +ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +show warnings; +Level Code Message +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'garbage' at line 1 +Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +CALL test2.p1(); +ERROR HY000: Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +show warnings; +Level Code Message +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'garbage' at line 1 +Error 1457 Failed to load routine test.test2 (internal code -6). For more details, run SHOW WARNINGS +DROP PACKAGE test2; +# +# Bad routine names +# +CREATE PACKAGE p1 AS +PROCEDURE pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp1; +END; +$$ +ERROR 42000: Identifier name 'pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp1' is too long +CREATE PACKAGE p1 AS +FUNCTION fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1 +RETURN INT; +END; +$$ +ERROR 42000: Identifier name 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1' is too long +CREATE PACKAGE p1 AS +PROCEDURE "p1 "; +END; +$$ +ERROR 42000: Incorrect routine name 'p1 ' +CREATE PACKAGE p1 AS +FUNCTION "f1 " RETURN INT; +END; +$$ +ERROR 42000: Incorrect routine name 'f1 ' +CREATE PACKAGE p1 AS +PROCEDURE "p1.p1"; +END; +$$ +ERROR 42000: Incorrect routine name 'p1.p1' +CREATE PACKAGE p1 AS +FUNCTION "f1.f1" RETURN INT; +END; +$$ +ERROR 42000: Incorrect routine name 'f1.f1' +# +# Duplicate PROCEDURE in CREATE PACKAGE +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +PROCEDURE p1; +END; +$$ +ERROR 42000: PROCEDURE test2.p1 already exists +CREATE PACKAGE test2 AS +PROCEDURE p1; +PROCEDURE P1; +END; +$$ +ERROR 42000: PROCEDURE test2.P1 already exists +# +# Duplicate FUNCTION in CREATE PACKAGE +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +FUNCTION f1 RETURN INT; +END; +$$ +ERROR 42000: FUNCTION test2.f1 already exists +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +FUNCTION F1 RETURN INT; +END; +$$ +ERROR 42000: FUNCTION test2.F1 already exists +# +# Duplicate PROCEDURE in CREATE PACKAGE BODY +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS BEGIN NULL; END; +PROCEDURE p1 AS BEGIN NULL; END; +END; +$$ +ERROR 42000: PROCEDURE test2.p1 already exists +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS BEGIN NULL; END; +PROCEDURE P1 AS BEGIN NULL; END; +END; +$$ +ERROR 42000: PROCEDURE test2.P1 already exists +DROP PACKAGE test2; +# +# Duplicate FUNCTION in CREATE PACKAGE BODY +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 0; END; +FUNCTION f1 RETURN INT AS BEGIN RETURN 0; END; +END; +$$ +ERROR 42000: FUNCTION test2.f1 already exists +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 0; END; +FUNCTION F1 RETURN INT AS BEGIN RETURN 0; END; +END; +$$ +ERROR 42000: FUNCTION test2.F1 already exists +DROP PACKAGE test2; +# +# Routines declared in CREATE PACKAGE missing in CREATE PACKAGE BODY +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p2 AS BEGIN NULL; END; +END; +$$ +ERROR HY000: Subroutine 'test.test2.p1' is declared in the package specification but is not defined in the package body +DROP PACKAGE test2; +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f2 RETURN INT AS BEGIN RETURN 10; END; +END; +$$ +ERROR HY000: Subroutine 'test.test2.f1' is declared in the package specification but is not defined in the package body +DROP PACKAGE test2; +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION p1 RETURN INT AS BEGIN RETURN 10; END; +END; +$$ +ERROR HY000: Subroutine 'test.test2.p1' is declared in the package specification but is not defined in the package body +DROP PACKAGE test2; +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1(a INT) AS BEGIN NULL; END; -- Notice different prototype +END; +$$ +ERROR HY000: Subroutine 'test.test2.p1' is declared in the package specification but is not defined in the package body +DROP PACKAGE test2; +# +# Forward declarations in CREATE PACKAGE BODY with missing implementations +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS BEGIN NULL; END; +PROCEDURE p2; +END; +$$ +ERROR HY000: Subroutine 'test.test2.p2' has a forward declaration but is not defined +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1 AS BEGIN NULL; END; +END; +$$ +ERROR HY000: Subroutine 'test.test2.f1' has a forward declaration but is not defined +DROP PACKAGE test2; +# +# Creating a new package +# +CREATE PACKAGE test2 COMMENT 'package-test2-comment' AS +FUNCTION f1 RETURN INT DETERMINISTIC; +FUNCTION f2(a INT) RETURN INT; +FUNCTION concat RETURN INT; +PROCEDURE p1; +PROCEDURE p2(a INT); +END +$$ +Warnings: +Note 1585 This function 'concat' has the same name as a native function +SELECT * FROM mysql.proc WHERE db='test' AND name='test2'; +db test +name test2 +type PACKAGE +specific_name test2 +language SQL +sql_data_access CONTAINS_SQL +is_deterministic NO +security_type DEFINER +param_list +returns +body AS +FUNCTION f1 RETURN INT DETERMINISTIC; +FUNCTION f2(a INT) RETURN INT; +FUNCTION concat RETURN INT; +PROCEDURE p1; +PROCEDURE p2(a INT); +END +definer root@localhost +created # +modified # +sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +comment package-test2-comment +character_set_client latin1 +collation_connection latin1_swedish_ci +db_collation latin1_swedish_ci +body_utf8 AS +FUNCTION f1 RETURN INT DETERMINISTIC; +FUNCTION f2(a INT) RETURN INT; +FUNCTION concat RETURN INT; +PROCEDURE p1; +PROCEDURE p2(a INT); +END +aggregate NONE +SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='test' AND ROUTINE_NAME='test2'; +SPECIFIC_NAME test2 +ROUTINE_CATALOG def +ROUTINE_SCHEMA test +ROUTINE_NAME test2 +ROUTINE_TYPE PACKAGE +DATA_TYPE +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER NULL +ROUTINE_BODY SQL +ROUTINE_DEFINITION AS +FUNCTION f1 RETURN INT DETERMINISTIC; +FUNCTION f2(a INT) RETURN INT; +FUNCTION concat RETURN INT; +PROCEDURE p1; +PROCEDURE p2(a INT); +END +EXTERNAL_NAME NULL +EXTERNAL_LANGUAGE NULL +PARAMETER_STYLE SQL +IS_DETERMINISTIC NO +SQL_DATA_ACCESS CONTAINS SQL +SQL_PATH NULL +SECURITY_TYPE DEFINER +CREATED # +LAST_ALTERED # +SQL_MODE PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +ROUTINE_COMMENT package-test2-comment +DEFINER root@localhost +CHARACTER_SET_CLIENT latin1 +COLLATION_CONNECTION latin1_swedish_ci +DATABASE_COLLATION latin1_swedish_ci +CREATE PACKAGE IF NOT EXISTS test2 AS +FUNCTION f1 RETURN INT; +END test2 +$$ +Warnings: +Note 1304 PACKAGE test2 already exists +CREATE PACKAGE BODY test2 COMMENT 'package-body-test2-comment' AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +FUNCTION f2(a INT) RETURN INT AS BEGIN RETURN f1()+a; END; +FUNCTION concat RETURN INT AS BEGIN RETURN 1; END; +PROCEDURE p1 AS +BEGIN +SELECT f2(0); +END; +PROCEDURE p2(a INT) AS +BEGIN +SELECT f2(a); +END; +END; +$$ +Warnings: +Note 1585 This function 'concat' has the same name as a native function +Note 1585 This function 'concat' has the same name as a native function +CREATE PACKAGE BODY IF NOT EXISTS test2 AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 20; END; +FUNCTION f2(a INT) RETURN INT AS BEGIN RETURN f1()+a; END; +FUNCTION concat RETURN INT AS BEGIN RETURN 1; END; +PROCEDURE p1 AS +BEGIN +SELECT f2(0); +END; +PROCEDURE p2(a INT) AS +BEGIN +SELECT f2(a); +END; +END; +$$ +Warnings: +Note 1585 This function 'concat' has the same name as a native function +Note 1585 This function 'concat' has the same name as a native function +Note 1304 PACKAGE BODY test2 already exists +SELECT test2.f1(); +test2.f1() +10 +SELECT test2.f2(1); +test2.f2(1) +11 +CALL test2.p1(); +f2(0) +10 +CALL test2.p2(1); +f2(a) +11 +SELECT * FROM mysql.proc WHERE db='test' AND name LIKE 'test2.%'; +SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='test' AND ROUTINE_NAME='test2'; +SPECIFIC_NAME test2 +ROUTINE_CATALOG def +ROUTINE_SCHEMA test +ROUTINE_NAME test2 +ROUTINE_TYPE PACKAGE +DATA_TYPE +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER NULL +ROUTINE_BODY SQL +ROUTINE_DEFINITION AS +FUNCTION f1 RETURN INT DETERMINISTIC; +FUNCTION f2(a INT) RETURN INT; +FUNCTION concat RETURN INT; +PROCEDURE p1; +PROCEDURE p2(a INT); +END +EXTERNAL_NAME NULL +EXTERNAL_LANGUAGE NULL +PARAMETER_STYLE SQL +IS_DETERMINISTIC NO +SQL_DATA_ACCESS CONTAINS SQL +SQL_PATH NULL +SECURITY_TYPE DEFINER +CREATED # +LAST_ALTERED # +SQL_MODE PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +ROUTINE_COMMENT package-test2-comment +DEFINER root@localhost +CHARACTER_SET_CLIENT latin1 +COLLATION_CONNECTION latin1_swedish_ci +DATABASE_COLLATION latin1_swedish_ci +SPECIFIC_NAME test2 +ROUTINE_CATALOG def +ROUTINE_SCHEMA test +ROUTINE_NAME test2 +ROUTINE_TYPE PACKAGE BODY +DATA_TYPE +CHARACTER_MAXIMUM_LENGTH NULL +CHARACTER_OCTET_LENGTH NULL +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME NULL +COLLATION_NAME NULL +DTD_IDENTIFIER NULL +ROUTINE_BODY SQL +ROUTINE_DEFINITION AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +FUNCTION f2(a INT) RETURN INT AS BEGIN RETURN f1()+a; END; +FUNCTION concat RETURN INT AS BEGIN RETURN 1; END; +PROCEDURE p1 AS +BEGIN +SELECT f2(0); +END; +PROCEDURE p2(a INT) AS +BEGIN +SELECT f2(a); +END; +END +EXTERNAL_NAME NULL +EXTERNAL_LANGUAGE NULL +PARAMETER_STYLE SQL +IS_DETERMINISTIC NO +SQL_DATA_ACCESS CONTAINS SQL +SQL_PATH NULL +SECURITY_TYPE DEFINER +CREATED # +LAST_ALTERED # +SQL_MODE PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +ROUTINE_COMMENT package-body-test2-comment +DEFINER root@localhost +CHARACTER_SET_CLIENT latin1 +COLLATION_CONNECTION latin1_swedish_ci +DATABASE_COLLATION latin1_swedish_ci +SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='test' AND ROUTINE_NAME LIKE 'test2.%'; +SHOW PACKAGE STATUS; +Db test +Name test2 +Type PACKAGE +Definer root@localhost +Modified 0000-00-00 00:00:00 +Created 0000-00-00 00:00:00 +Security_type DEFINER +Comment package-test2-comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +SHOW PACKAGE BODY STATUS; +Db test +Name test2 +Type PACKAGE BODY +Definer root@localhost +Modified 0000-00-00 00:00:00 +Created 0000-00-00 00:00:00 +Security_type DEFINER +Comment package-body-test2-comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +SHOW CREATE PACKAGE test2; +Package test2 +sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +Create Package CREATE DEFINER="root"@"localhost" PACKAGE "test2" COMMENT 'package-test2-comment' + AS +FUNCTION f1 RETURN INT DETERMINISTIC; +FUNCTION f2(a INT) RETURN INT; +FUNCTION concat RETURN INT; +PROCEDURE p1; +PROCEDURE p2(a INT); +END +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +Warnings: +Level Note +Code 1585 +Message This function 'concat' has the same name as a native function +SHOW CREATE PACKAGE BODY test2; +Package body test2 +sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +Create Package Body CREATE DEFINER="root"@"localhost" PACKAGE BODY "test2" COMMENT 'package-body-test2-comment' + AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +FUNCTION f2(a INT) RETURN INT AS BEGIN RETURN f1()+a; END; +FUNCTION concat RETURN INT AS BEGIN RETURN 1; END; +PROCEDURE p1 AS +BEGIN +SELECT f2(0); +END; +PROCEDURE p2(a INT) AS +BEGIN +SELECT f2(a); +END; +END +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +Warnings: +Level Note +Code 1585 +Message This function 'concat' has the same name as a native function +DROP PACKAGE BODY test2; +SELECT test2.f1(); +ERROR 42000: FUNCTION test.test2.f1 does not exist +SELECT test2.f2(); +ERROR 42000: FUNCTION test.test2.f2 does not exist +CALL test2.p1(); +ERROR 42000: PROCEDURE test.test2.p1 does not exist +DROP PACKAGE BODY IF EXISTS test2; +Warnings: +Note 1305 PACKAGE BODY test.test2 does not exist +DROP PACKAGE BODY test2; +ERROR 42000: PACKAGE BODY test.test2 does not exist +DROP PACKAGE test2; +# +# Creating a new package in a remote database +# +CREATE DATABASE test2; +CREATE PACKAGE test2.test2 COMMENT 'package-test2-comment' AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END +$$ +CREATE PACKAGE BODY test2.test2 COMMENT 'package-body-test2-comment' AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +PROCEDURE p1 AS BEGIN SELECT f1(); END; +END; +$$ +SHOW PACKAGE STATUS; +Db test2 +Name test2 +Type PACKAGE +Definer root@localhost +Modified 0000-00-00 00:00:00 +Created 0000-00-00 00:00:00 +Security_type DEFINER +Comment package-test2-comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +SHOW PACKAGE BODY STATUS; +Db test2 +Name test2 +Type PACKAGE BODY +Definer root@localhost +Modified 0000-00-00 00:00:00 +Created 0000-00-00 00:00:00 +Security_type DEFINER +Comment package-body-test2-comment +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +USE test2; +SELECT test2.f1(); +test2.f1() +10 +CALL test2.p1(); +f1() +10 +USE test; +DROP PACKAGE BODY test2.test2; +DROP PACKAGE test2.test2; +DROP DATABASE test2; +# +# Only public routines are available outside +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +-- Public routines +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN 'This is test2.f1'; +END; +PROCEDURE p1 AS +BEGIN +SELECT 'This is test2.p1'; +END; +-- Private routines +FUNCTION f2 RETURN TEXT AS +BEGIN +RETURN 'This is test2.f2'; +END; +PROCEDURE p2 AS +BEGIN +SELECT 'This is test2.p2'; +END; +END; +$$ +SELECT test2.f1(); +test2.f1() +This is test2.f1 +CALL test2.p1(); +This is test2.p1 +This is test2.p1 +SELECT test2.f2(); +ERROR 42000: FUNCTION test2.f2 does not exist +CALL test2.p2(); +ERROR 42000: PROCEDURE test2.p2 does not exist +DROP PACKAGE test2; +# +# PACKAGE BODY with forward declarations +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +-- Forward declarations +FUNCTION f2private RETURN TEXT; +PROCEDURE p2private; +-- Public routines +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN f2private(); +END; +PROCEDURE p1 AS +BEGIN +CALL p2private; +END; +-- Definitions for the forward declarations +FUNCTION f2private RETURN TEXT AS +BEGIN +RETURN 'This is f2private'; +END; +PROCEDURE p2private AS +BEGIN +SELECT 'This is p2private'; +END; +END; +$$ +SELECT test2.f1(); +test2.f1() +This is f2private +CALL test2.p1(); +This is p2private +This is p2private +DROP PACKAGE test2; +# +# Calling private routines with forward declarations, +# using qualified notation, e.g. "CALL pkg.proc" +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +-- Forward declarations +FUNCTION f2private RETURN TEXT; +PROCEDURE p2private; +-- Public routines +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN test2.f2private(); +END; +PROCEDURE p1 AS +BEGIN +CALL test2.p2private; +END; +-- Definitions for the forward declarations +FUNCTION f2private RETURN TEXT AS +BEGIN +RETURN 'This is f2private'; +END; +PROCEDURE p2private AS +BEGIN +SELECT 'This is p2private' AS msg; +END; +END; +$$ +SELECT test2.f1(); +test2.f1() +This is f2private +CALL test2.p1(); +msg +This is p2private +DROP PACKAGE test2; +# +# Calling private routines, using qualified notation, e.g. "pkg.proc" +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +-- Private routines +FUNCTION f2private RETURN TEXT AS +BEGIN +RETURN 'This is f2private'; +END; +PROCEDURE p2private AS +BEGIN +SELECT 'This is p2private' AS msg; +END; +-- Public routines +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN test2.f2private(); +END; +PROCEDURE p1 AS +BEGIN +CALL test2.p2private; +END; +END; +$$ +SELECT test2.f1(); +test2.f1() +This is f2private +CALL test2.p1(); +msg +This is p2private +DROP PACKAGE test2; +# +# Calling private routines from the package initialization section, +# using qualified notation, e.g. "pkg.proc" +# +CREATE PACKAGE test2 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY test2 AS +-- Private routines +FUNCTION f2private RETURN TEXT AS +BEGIN +RETURN 'This is f2private'; +END; +PROCEDURE p2private AS +BEGIN +SELECT 'This is p2private' AS msg; +END; +-- Public routines +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1' AS msg; +END; +BEGIN +SELECT test2.f2private(); +CALL test2.p2private(); +END; +$$ +CALL test2.p1(); +test2.f2private() +This is f2private +msg +This is p2private +msg +This is p1 +DROP PACKAGE test2; +# +# Testing OR REPLACE +# +CREATE OR REPLACE PACKAGE pkg AS +FUNCTION f0 RETURN INT; +END; +$$ +CREATE OR REPLACE PACKAGE pkg AS +FUNCTION f1 RETURN INT; +END; +$$ +SELECT name, type, `body` FROM mysql.proc WHERE name LIKE 'pkg%' ORDER BY type; +name type body +pkg PACKAGE AS +FUNCTION f1 RETURN INT; +END +CREATE OR REPLACE PACKAGE BODY pkg AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +END; +$$ +SELECT name, type, `body` FROM mysql.proc WHERE name LIKE 'pkg%' ORDER BY type; +name type body +pkg PACKAGE AS +FUNCTION f1 RETURN INT; +END +pkg PACKAGE BODY AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 10; END; +END +SELECT pkg.f1(); +pkg.f1() +10 +CREATE OR REPLACE PACKAGE BODY pkg AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 20; END; +END; +$$ +SELECT name, type, `body` FROM mysql.proc WHERE name LIKE 'pkg%' ORDER BY type; +name type body +pkg PACKAGE AS +FUNCTION f1 RETURN INT; +END +pkg PACKAGE BODY AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 20; END; +END +SELECT pkg.f1(); +pkg.f1() +20 +CREATE OR REPLACE PACKAGE pkg AS +FUNCTION f1 RETURN BIGINT; +END; +$$ +SELECT name, type, `body` FROM mysql.proc WHERE name LIKE 'pkg%' ORDER BY type; +name type body +pkg PACKAGE AS +FUNCTION f1 RETURN BIGINT; +END +SELECT pkg.f1(); +ERROR 42000: FUNCTION test.pkg.f1 does not exist +CREATE OR REPLACE PACKAGE BODY pkg AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 30; END; +END; +$$ +SELECT name, type, `body` FROM mysql.proc WHERE name LIKE 'pkg%' ORDER BY type; +name type body +pkg PACKAGE AS +FUNCTION f1 RETURN BIGINT; +END +pkg PACKAGE BODY AS +FUNCTION f1 RETURN INT AS BEGIN RETURN 30; END; +END +SELECT pkg.f1(); +pkg.f1() +30 +DROP PACKAGE pkg; +# +# Package routines accessing tables +# +CREATE TABLE t1 (a INT); +CREATE PACKAGE test2 AS +PROCEDURE p1(a INT); +END; +$$ +CREATE PACKAGE BODY test2 AS +PROCEDURE p1(a INT) AS +BEGIN +INSERT INTO t1 VALUES (10); +END; +END; +$$ +CALL test2.p1(10); +SELECT * FROM t1; +a +10 +DROP PACKAGE test2; +DROP TABLE t1; +# +# CREATE PACKAGE: Optional package name after the "END" keyword +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END test2.test2 +$$ +ERROR HY000: END identifier 'test2.test2' does not match 'test.test2' +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END test3 +$$ +ERROR HY000: END identifier 'test3' does not match 'test2' +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END test2 +$$ +DROP PACKAGE test2; +# +# MDEV-12089 sql_mode=ORACLE: Understand optional routine name after the END keyword +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN INT; +PROCEDURE p1; +END test2; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END f1.f1; +END test2; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.f1; +END test2' at line 5 +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END f2; +END test2; +$$ +ERROR HY000: END identifier 'f2' does not match 'f1' +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS +BEGIN +NULL; +END p1.p1; +END test2; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.p1; +END test2' at line 5 +CREATE PACKAGE BODY test2 AS +PROCEDURE p1 AS +BEGIN +NULL; +END p2; +END test2; +$$ +ERROR HY000: END identifier 'p2' does not match 'p1' +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END f1; +PROCEDURE p1 AS +BEGIN +NULL; +END p1; +END test2; +$$ +DROP PACKAGE test2; +# +# Package and package routine name and end name are case insensitive +# +CREATE PACKAGE test2 AS +FUNCTION f1 RETURN TEXT; +PROCEDURE p1; +END TEST2; +$$ +CREATE PACKAGE BODY test2 AS +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN 'This is f1'; +END F1; +PROCEDURE P1 AS +BEGIN +SELECT 'This is p1' AS msg; +END p1; +END TEST2; +$$ +SELECT TEST2.F1(); +TEST2.F1() +This is f1 +SELECT test2.f1(); +test2.f1() +This is f1 +CALL TEST2.p1(); +msg +This is p1 +CALL test2.P1(); +msg +This is p1 +DROP PACKAGE BODY TEST2; +DROP PACKAGE TEST2; +# +# Testing various qualified/non-qualified db/package SP call chains +# +CREATE FUNCTION f3() RETURN TEXT AS +BEGIN +SET @track= @track || ' ' || 'test.f3()'; +RETURN ''; +END; +$$ +CREATE PROCEDURE p3() AS +BEGIN +SET @track= @track || ' ' || 'test.p3()'; +END; +$$ +CREATE FUNCTION ff2(task TEXT) RETURN TEXT AS +step TEXT := REGEXP_SUBSTR(task,'^[^ ]*'); +tail TEXT := REGEXP_REPLACE(task,'^[^ ]*[ ]*(.*)','\\1'); +rc TEXT; +BEGIN +SET @track= @track || ' ' || 'test.ff2()'; +CASE step +WHEN '' THEN NULL; +WHEN 'p3' THEN CALL p3(); +WHEN 'f3' THEN rc:= f3(); +WHEN 'pack.p2' THEN CALL pack.p2(tail); +WHEN 'pack.f2' THEN rc:= pack.f2(tail); +WHEN 'pack.p3' THEN CALL pack.p3(); +WHEN 'pack.f3' THEN rc:= pack.f3(); +WHEN 'test.p3' THEN CALL test.p3(); +WHEN 'test.f3' THEN rc:= test.f3(); +WHEN 'test.pp2' THEN CALL test.pp2(tail); +WHEN 'test.ff2' THEN rc:= test.ff2(tail); +ELSE SET @track= @track || ' ' || step || ' [unknown step]'; +END CASE; +RETURN ''; +END; +$$ +CREATE PROCEDURE pp2(task TEXT) AS +step TEXT := REGEXP_SUBSTR(task,'^[^ ]*'); +tail TEXT := REGEXP_REPLACE(task,'^[^ ]*[ ]*(.*)','\\1'); +rc TEXT; +BEGIN +SET @track= @track || ' ' || 'test.pp2()'; +CASE step +WHEN '' THEN NULL; +WHEN 'p3' THEN CALL p3(); +WHEN 'f3' THEN rc:= f3(); +WHEN 'pack.p2' THEN CALL pack.p2(tail); +WHEN 'pack.f2' THEN rc:= pack.f2(tail); +WHEN 'pack.p3' THEN CALL pack.p3(); +WHEN 'pack.f3' THEN rc:= pack.f3(); +WHEN 'test.p3' THEN CALL test.p3(); +WHEN 'test.f3' THEN rc:= test.f3(); +WHEN 'test.pp2' THEN CALL test.pp2(tail); +WHEN 'test.ff2' THEN rc:= test.ff2(tail); +ELSE SET @track= @track || ' ' || step || ' [unknown step]'; +END CASE; +END; +$$ +CREATE PACKAGE pack AS +PROCEDURE p1(task TEXT); +PROCEDURE p2(task TEXT); +FUNCTION f1(task TEXT) RETURN TEXT; +FUNCTION f2(step2 TEXT) RETURN TEXT; +FUNCTION f3 RETURN TEXT; +PROCEDURE p3; +END; +$$ +CREATE PACKAGE BODY pack AS +PROCEDURE p1(task TEXT) AS +step TEXT := REGEXP_SUBSTR(task,'^[^ ]*'); +tail TEXT := REGEXP_REPLACE(task,'^[^ ]*[ ]*(.*)','\\1'); +rc TEXT; +BEGIN +SET @track= 'test.pack.p1()'; +CASE step +WHEN '' THEN NULL; +WHEN 'p2' THEN CALL p2(tail); +WHEN 'f2' THEN rc:= f2(tail); +WHEN 'p3' THEN CALL p3(); +WHEN 'f3' THEN rc:= f3(); +WHEN 'px' THEN CALL px(); +WHEN 'fx' THEN rc:= fx(); +WHEN 'pp2' THEN CALL pp2(tail); +WHEN 'ff2' THEN rc:= ff2(tail); +WHEN 'pack.p2' THEN CALL pack.p2(tail); +WHEN 'pack.f2' THEN rc:= pack.f2(tail); +WHEN 'pack.p3' THEN CALL pack.p3(); +WHEN 'pack.f3' THEN rc:= pack.f3(); +WHEN 'pack.px' THEN CALL pack.px(); +WHEN 'pack.fx' THEN rc:= pack.fx(); +WHEN 'test.p3' THEN CALL test.p3(); +WHEN 'test.f3' THEN rc:= test.f3(); +WHEN 'test.pp2' THEN CALL test.pp2(tail); +WHEN 'test.ff2' THEN rc:= test.ff2(tail); +ELSE SET @track= @track || ' ' || step || ' [unknown step]'; +END CASE; +SELECT @track; +END; +FUNCTION f1(task TEXT) RETURN TEXT AS +step TEXT := REGEXP_SUBSTR(task,'^[^ ]*'); +tail TEXT := REGEXP_REPLACE(task,'^[^ ]*[ ]*(.*)','\\1'); +rc TEXT; +BEGIN +SET @track= 'test.pack.f1()'; +CASE step +WHEN '' THEN NULL; +WHEN 'p2' THEN CALL p2(tail); +WHEN 'f2' THEN rc:= f2(tail); +WHEN 'p3' THEN CALL p3(); +WHEN 'f3' THEN rc:= f3(); +WHEN 'px' THEN CALL px(); +WHEN 'fx' THEN rc:= fx(); +WHEN 'pp2' THEN CALL pp2(tail); +WHEN 'ff2' THEN rc:= ff2(tail); +WHEN 'pack.p2' THEN CALL pack.p2(tail); +WHEN 'pack.f2' THEN rc:= pack.f2(tail); +WHEN 'pack.p3' THEN CALL pack.p3(); +WHEN 'pack.f3' THEN rc:= pack.f3(); +WHEN 'pack.px' THEN CALL pack.px(); +WHEN 'pack.fx' THEN rc:= pack.fx(); +WHEN 'test.p3' THEN CALL test.p3(); +WHEN 'test.f3' THEN rc:= test.f3(); +WHEN 'test.pp2' THEN CALL test.pp2(tail); +WHEN 'test.ff2' THEN rc:= test.ff2(tail); +ELSE SET @track= @track || ' ' || step || ' [unknown step]'; +END CASE; +SIGNAL SQLSTATE '01000' SET MESSAGE_TEXT=@track; +RETURN ''; +END; +PROCEDURE p2(task TEXT) AS +step TEXT := REGEXP_SUBSTR(task,'^[^ ]*'); +tail TEXT := REGEXP_REPLACE(task,'^[^ ]*[ ]*(.*)','\\1'); +rc TEXT; +BEGIN +SET @track= @track || ' ' || 'test.pack.p2()'; +CASE step +WHEN '' THEN NULL; +WHEN 'p2' THEN CALL p2(tail); +WHEN 'f2' THEN rc:= f2(tail); +WHEN 'p3' THEN CALL p3(); +WHEN 'f3' THEN rc:= f3(); +WHEN 'px' THEN CALL px(); +WHEN 'fx' THEN rc:= fx(); +WHEN 'pp2' THEN CALL pp2(tail); +WHEN 'ff2' THEN rc:= ff2(tail); +WHEN 'pack.p2' THEN CALL pack.p2(tail); +WHEN 'pack.f2' THEN rc:= pack.f2(tail); +WHEN 'pack.p3' THEN CALL pack.p3(); +WHEN 'pack.f3' THEN rc:= pack.f3(); +WHEN 'pack.px' THEN CALL pack.px(); +WHEN 'pack.fx' THEN rc:= pack.fx(); +WHEN 'test.p3' THEN CALL test.p3(); +WHEN 'test.f3' THEN rc:= test.f3(); +WHEN 'test.pp2' THEN CALL test.pp2(tail); +WHEN 'test.ff2' THEN rc:= test.ff2(tail); +ELSE SET @track= @track || ' ' || step || ' [unknown step]'; +END CASE; +END; +FUNCTION f2(task TEXT) RETURN TEXT AS +step TEXT := REGEXP_SUBSTR(task,'^[^ ]*'); +tail TEXT := REGEXP_REPLACE(task,'^[^ ]*[ ]*(.*)','\\1'); +rc TEXT; +BEGIN +SET @track= @track || ' ' || 'test.pack.f2()'; +CASE step +WHEN '' THEN NULL; +WHEN 'p2' THEN CALL p2(tail); +WHEN 'f2' THEN rc:= f2(tail); +WHEN 'p3' THEN CALL p3(); +WHEN 'f3' THEN rc:= f3(); +WHEN 'px' THEN CALL px(); +WHEN 'fx' THEN rc:= fx(); +WHEN 'pp2' THEN CALL pp2(tail); +WHEN 'ff2' THEN rc:= ff2(tail); +WHEN 'pack.p2' THEN CALL pack.p2(tail); +WHEN 'pack.f2' THEN rc:= pack.f2(tail); +WHEN 'pack.p3' THEN CALL pack.p3(); +WHEN 'pack.f3' THEN rc:= pack.f3(); +WHEN 'pack.px' THEN CALL pack.px(); +WHEN 'pack.fx' THEN rc:= pack.fx(); +WHEN 'test.p3' THEN CALL test.p3(); +WHEN 'test.f3' THEN rc:= test.f3(); +WHEN 'test.pp2' THEN CALL test.pp2(tail); +WHEN 'test.ff2' THEN rc:= test.ff2(tail); +ELSE SET @track= @track || ' ' || step || ' [unknown step]'; +END CASE; +RETURN ''; +END; +PROCEDURE p3 AS +BEGIN +SET @track= @track || ' ' || 'test.pack.p3()'; +END; +FUNCTION f3 RETURN TEXT AS +BEGIN +SET @track= @track || ' ' || 'test.pack.f3()'; +RETURN ''; +END; +END pack; +$$ +SET max_sp_recursion_depth=10; +# pack.routine -> * +CALL pack.p1('p2'); +@track +test.pack.p1() test.pack.p2() +CALL pack.p1('f2'); +@track +test.pack.p1() test.pack.f2() +CALL pack.p1('px'); +ERROR 42000: PROCEDURE test.px does not exist +CALL pack.p1('fx'); +ERROR 42000: FUNCTION test.fx does not exist +CALL pack.p1('pp2'); +@track +test.pack.p1() test.pp2() +CALL pack.p1('ff2'); +@track +test.pack.p1() test.ff2() +CALL pack.p1('pack.p2'); +@track +test.pack.p1() test.pack.p2() +CALL pack.p1('pack.f2'); +@track +test.pack.p1() test.pack.f2() +CALL pack.p1('pack.px'); +ERROR 42000: PROCEDURE pack.px does not exist +CALL pack.p1('pack.fx'); +ERROR 42000: FUNCTION pack.fx does not exist +CALL pack.p1('test.pp2'); +@track +test.pack.p1() test.pp2() +CALL pack.p1('test.ff2'); +@track +test.pack.p1() test.ff2() +DO pack.f1('p2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() +DO pack.f1('f2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() +DO pack.p1('px'); +ERROR 42000: FUNCTION pack.p1 does not exist +DO pack.p1('fx'); +ERROR 42000: FUNCTION pack.p1 does not exist +DO pack.f1('pp2'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() +DO pack.f1('ff2'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() +DO pack.f1('pack.p2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() +DO pack.f1('pack.f2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() +SELECT pack.f1('pack.px'); +ERROR 42000: PROCEDURE pack.px does not exist +SELECT pack.f1('pack.fx'); +ERROR 42000: FUNCTION pack.fx does not exist +DO pack.f1('test.pp2'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() +DO pack.f1('test.ff2'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() +# +# Qualified_package_routine -> Non_qualified_package_routine +# +# pack.routine -> [pack.]routine -> pack.routine +CALL pack.p1('p2 pack.p3'); +@track +test.pack.p1() test.pack.p2() test.pack.p3() +CALL pack.p1('p2 pack.f3'); +@track +test.pack.p1() test.pack.p2() test.pack.f3() +CALL pack.p1('f2 pack.p3'); +@track +test.pack.p1() test.pack.f2() test.pack.p3() +CALL pack.p1('f2 pack.f3'); +@track +test.pack.p1() test.pack.f2() test.pack.f3() +DO pack.f1('p2 pack.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pack.p3() +DO pack.f1('p2 pack.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pack.f3() +DO pack.f1('f2 pack.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pack.p3() +DO pack.f1('f2 pack.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pack.f3() +# pack.routine -> [pack.]routine -> [pack]routine +CALL pack.p1('p2 p3'); +@track +test.pack.p1() test.pack.p2() test.pack.p3() +CALL pack.p1('p2 f3'); +@track +test.pack.p1() test.pack.p2() test.pack.f3() +CALL pack.p1('f2 p3'); +@track +test.pack.p1() test.pack.f2() test.pack.p3() +CALL pack.p1('f2 f3'); +@track +test.pack.p1() test.pack.f2() test.pack.f3() +DO pack.f1('p2 p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pack.p3() +DO pack.f1('p2 f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pack.f3() +DO pack.f1('f2 p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pack.p3() +DO pack.f1('f2 f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pack.f3() +# pack.routine -> [pack.]routine -> test.routine +CALL pack.p1('p2 test.p3'); +@track +test.pack.p1() test.pack.p2() test.p3() +CALL pack.p1('p2 test.f3'); +@track +test.pack.p1() test.pack.p2() test.f3() +CALL pack.p1('f2 test.p3'); +@track +test.pack.p1() test.pack.f2() test.p3() +CALL pack.p1('f2 test.f3'); +@track +test.pack.p1() test.pack.f2() test.f3() +DO pack.f1('p2 test.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.p3() +DO pack.f1('p2 test.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.f3() +DO pack.f1('f2 test.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.p3() +DO pack.f1('f2 test.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.f3() +# pack.routine -> [pack.]routine -> [test.]routine +CALL pack.p1('p2 pp2'); +@track +test.pack.p1() test.pack.p2() test.pp2() +CALL pack.p1('p2 ff2'); +@track +test.pack.p1() test.pack.p2() test.ff2() +CALL pack.p1('f2 pp2'); +@track +test.pack.p1() test.pack.f2() test.pp2() +CALL pack.p1('f2 ff2'); +@track +test.pack.p1() test.pack.f2() test.ff2() +DO pack.f1('p2 pp2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pp2() +DO pack.f1('p2 ff2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.ff2() +DO pack.f1('f2 pp2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pp2() +DO pack.f1('f2 ff2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.ff2() +# +# Qualified_package_routine -> Non_qualified_database_routine +# +# pack.routine -> [test.]routine -> pack.routine +CALL pack.p1('pp2 pack.p3'); +@track +test.pack.p1() test.pp2() test.pack.p3() +CALL pack.p1('pp2 pack.f3'); +@track +test.pack.p1() test.pp2() test.pack.f3() +CALL pack.p1('ff2 pack.p3'); +@track +test.pack.p1() test.ff2() test.pack.p3() +CALL pack.p1('ff2 pack.f3'); +@track +test.pack.p1() test.ff2() test.pack.f3() +DO pack.f1('pp2 pack.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.pack.p3() +DO pack.f1('pp2 pack.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.pack.f3() +DO pack.f1('ff2 pack.p3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.pack.p3() +DO pack.f1('ff2 pack.f3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.pack.f3() +# pack.routine -> [test.]routine -> test.routine +CALL pack.p1('pp2 test.p3'); +@track +test.pack.p1() test.pp2() test.p3() +CALL pack.p1('pp2 test.f3'); +@track +test.pack.p1() test.pp2() test.f3() +CALL pack.p1('ff2 test.p3'); +@track +test.pack.p1() test.ff2() test.p3() +CALL pack.p1('ff2 test.f3'); +@track +test.pack.p1() test.ff2() test.f3() +DO pack.f1('pp2 test.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.p3() +DO pack.f1('pp2 test.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.f3() +DO pack.f1('ff2 test.p3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.p3() +DO pack.f1('ff2 test.f3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.f3() +# pack.routine -> [test.]routine -> [test.]routine +CALL pack.p1('pp2 p3'); +@track +test.pack.p1() test.pp2() test.p3() +CALL pack.p1('pp2 f3'); +@track +test.pack.p1() test.pp2() test.f3() +CALL pack.p1('ff2 p3'); +@track +test.pack.p1() test.ff2() test.p3() +CALL pack.p1('ff2 f3'); +@track +test.pack.p1() test.ff2() test.f3() +DO pack.f1('pp2 p3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.p3() +DO pack.f1('pp2 f3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.f3() +DO pack.f1('ff2 p3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.p3() +DO pack.f1('ff2 f3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.f3() +# +# Qualified_package_routine -> Qualified_package_routine +# +# pack.routine -> pack.routine -> pack.routine +CALL pack.p1('pack.p2 pack.p3'); +@track +test.pack.p1() test.pack.p2() test.pack.p3() +CALL pack.p1('pack.p2 pack.f3'); +@track +test.pack.p1() test.pack.p2() test.pack.f3() +CALL pack.p1('pack.f2 pack.p3'); +@track +test.pack.p1() test.pack.f2() test.pack.p3() +CALL pack.p1('pack.f2 pack.f3'); +@track +test.pack.p1() test.pack.f2() test.pack.f3() +DO pack.f1('pack.p2 pack.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pack.p3() +DO pack.f1('pack.p2 pack.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pack.f3() +DO pack.f1('pack.f2 pack.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pack.p3() +DO pack.f1('pack.f2 pack.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pack.f3() +# pack.routine -> pack.routine -> [pack.]routine +CALL pack.p1('pack.p2 p3'); +@track +test.pack.p1() test.pack.p2() test.pack.p3() +CALL pack.p1('pack.p2 f3'); +@track +test.pack.p1() test.pack.p2() test.pack.f3() +CALL pack.p1('pack.f2 p3'); +@track +test.pack.p1() test.pack.f2() test.pack.p3() +CALL pack.p1('pack.f2 f3'); +@track +test.pack.p1() test.pack.f2() test.pack.f3() +DO pack.f1('pack.p2 p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pack.p3() +DO pack.f1('pack.p2 f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pack.f3() +DO pack.f1('pack.f2 p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pack.p3() +DO pack.f1('pack.f2 f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pack.f3() +# pack.routine -> pack.routine -> test.routine +CALL pack.p1('pack.p2 test.p3'); +@track +test.pack.p1() test.pack.p2() test.p3() +CALL pack.p1('pack.p2 test.f3'); +@track +test.pack.p1() test.pack.p2() test.f3() +CALL pack.p1('pack.f2 test.p3'); +@track +test.pack.p1() test.pack.f2() test.p3() +CALL pack.p1('pack.f2 test.f3'); +@track +test.pack.p1() test.pack.f2() test.f3() +DO pack.f1('pack.p2 test.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.p3() +DO pack.f1('pack.p2 test.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.f3() +DO pack.f1('pack.f2 test.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.p3() +DO pack.f1('pack.f2 test.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.f3() +# pack.routine -> pack.routine -> [test.]routine +CALL pack.p1('pack.p2 pp2'); +@track +test.pack.p1() test.pack.p2() test.pp2() +CALL pack.p1('pack.p2 ff2'); +@track +test.pack.p1() test.pack.p2() test.ff2() +CALL pack.p1('pack.f2 pp2'); +@track +test.pack.p1() test.pack.f2() test.pp2() +CALL pack.p1('pack.f2 ff2'); +@track +test.pack.p1() test.pack.f2() test.ff2() +DO pack.f1('pack.p2 pp2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.pp2() +DO pack.f1('pack.p2 ff2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.p2() test.ff2() +DO pack.f1('pack.f2 pp2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.pp2() +DO pack.f1('pack.f2 ff2'); +Warnings: +Warning 1642 test.pack.f1() test.pack.f2() test.ff2() +# +# Qualified_package_routine -> Qualified_database_routine +# +pack.routine -> test.routine -> pack.routine +CALL pack.p1('test.pp2 pack.p3'); +@track +test.pack.p1() test.pp2() test.pack.p3() +CALL pack.p1('test.pp2 pack.f3'); +@track +test.pack.p1() test.pp2() test.pack.f3() +CALL pack.p1('test.ff2 pack.p3'); +@track +test.pack.p1() test.ff2() test.pack.p3() +CALL pack.p1('test.ff2 pack.f3'); +@track +test.pack.p1() test.ff2() test.pack.f3() +DO pack.f1('test.pp2 pack.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.pack.p3() +DO pack.f1('test.pp2 pack.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.pack.f3() +DO pack.f1('test.ff2 pack.p3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.pack.p3() +DO pack.f1('test.ff2 pack.f3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.pack.f3() +pack.routine -> test.routine -> test.routine +CALL pack.p1('test.pp2 test.p3'); +@track +test.pack.p1() test.pp2() test.p3() +CALL pack.p1('test.pp2 test.f3'); +@track +test.pack.p1() test.pp2() test.f3() +CALL pack.p1('test.ff2 test.p3'); +@track +test.pack.p1() test.ff2() test.p3() +CALL pack.p1('test.ff2 test.f3'); +@track +test.pack.p1() test.ff2() test.f3() +DO pack.f1('test.pp2 test.p3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.p3() +DO pack.f1('test.pp2 test.f3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.f3() +DO pack.f1('test.ff2 test.p3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.p3() +DO pack.f1('test.ff2 test.f3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.f3() +pack.routine -> test.routine -> [test.]routine +CALL pack.p1('test.pp2 p3'); +@track +test.pack.p1() test.pp2() test.p3() +CALL pack.p1('test.pp2 f3'); +@track +test.pack.p1() test.pp2() test.f3() +CALL pack.p1('test.ff2 p3'); +@track +test.pack.p1() test.ff2() test.p3() +CALL pack.p1('test.ff2 f3'); +@track +test.pack.p1() test.ff2() test.f3() +DO pack.f1('test.pp2 p3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.p3() +DO pack.f1('test.pp2 f3'); +Warnings: +Warning 1642 test.pack.f1() test.pp2() test.f3() +DO pack.f1('test.ff2 p3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.p3() +DO pack.f1('test.ff2 f3'); +Warnings: +Warning 1642 test.pack.f1() test.ff2() test.f3() +# Longer chains +CALL pack.p1('p2 f2 p2 test.pp2 test.ff2 pack.p3'); +@track +test.pack.p1() test.pack.p2() test.pack.f2() test.pack.p2() test.pp2() test.ff2() test.pack.p3() +CALL pack.p1('p2 test.pp2 pack.p2 pack.f2 test.ff2 pack.p3'); +@track +test.pack.p1() test.pack.p2() test.pp2() test.pack.p2() test.pack.f2() test.ff2() test.pack.p3() +DROP PACKAGE pack; +DROP FUNCTION f3; +DROP PROCEDURE p3; +DROP FUNCTION ff2; +DROP PROCEDURE pp2; +# +# Calling a standalone function from a non-current database, +# which calls a package routine from the same non-current database. +# +CREATE PROCEDURE p1 AS +BEGIN +CALL pkg1.p1; +END; +$$ +CREATE PACKAGE pkg1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +PROCEDURE p1 AS +BEGIN +SELECT database(); +END; +END; +$$ +CALL p1; +database() +test +CREATE DATABASE test2; +USE test2; +CALL test.p1; +database() +test +DROP DATABASE test2; +CALL test.p1; +database() +test +USE test; +DROP PACKAGE pkg1; +DROP PROCEDURE p1; +# +# Creating a package with a different DEFINER +# +CREATE USER xxx@localhost; +CREATE DEFINER=xxx@localhost PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE DEFINER=xxx@localhost PACKAGE BODY p1 AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END; +$$ +SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type; +definer name security_type type +xxx@localhost p1 DEFINER PACKAGE +xxx@localhost p1 DEFINER PACKAGE BODY +DROP PACKAGE p1; +DROP USER xxx@localhost; +# +# Creating a package with a different DEFINER, with SQL SECURITY INVOKER +# +CREATE USER xxx@localhost; +CREATE DEFINER=xxx@localhost PACKAGE p1 SQL SECURITY INVOKER AS +PROCEDURE p1; +END; +$$ +CREATE DEFINER=xxx@localhost PACKAGE BODY p1 SQL SECURITY INVOKER AS +PROCEDURE p1 AS +BEGIN +NULL; +END; +END; +$$ +SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type; +definer name security_type type +xxx@localhost p1 INVOKER PACKAGE +xxx@localhost p1 INVOKER PACKAGE BODY +DROP PACKAGE p1; +DROP USER xxx@localhost; +# +# A package with an initialization section +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +PROCEDURE p1 AS BEGIN SET @a=@a+1; SELECT @a; END; +FUNCTION f1 RETURN INT AS BEGIN SET @a=@a+1; RETURN @a; END; +BEGIN +SET @a:=10; +END; +$$ +CALL p1.p1(); +@a +11 +CALL p1.p1(); +@a +12 +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +11 +CALL p1.p1(); +@a +12 +SELECT p1.f1(); +p1.f1() +13 +CALL p1.p1(); +@a +14 +DROP PACKAGE p1; +# +# A package with an initialization section calling +# routines from the same package, and standalone routines. +# +CREATE PROCEDURE init20 AS +BEGIN +SET @msg= @msg || '[init20]'; +END; +$$ +CREATE PACKAGE p1 AS +PROCEDURE init1; +PROCEDURE init2; +FUNCTION init3 RETURN INT; +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY p1 AS +PROCEDURE init1 AS +BEGIN +SET @msg= @msg || '[p1.init1]'; +END; +PROCEDURE init2 AS +BEGIN +SET @msg= @msg || '[p1.init2]'; +END; +FUNCTION init3 RETURN INT AS +BEGIN +SET @msg= @msg || '[p1.init3]'; +RETURN 0; +END; +PROCEDURE p1 AS +BEGIN +SET @msg= @msg || '[p1.p1]'; +SELECT @msg; +END; +FUNCTION f1 RETURN TEXT AS +BEGIN +SET @msg= @msg || '[p1.f1]'; +RETURN @msg; +END; +BEGIN +SET @msg= ''; +init1(); +init2(); +DO init3(); +init20(); +END; +$$ +CALL p1.p1(); +@msg +[p1.init1][p1.init2][p1.init3][init20][p1.p1] +CALL p1.p1(); +@msg +[p1.init1][p1.init2][p1.init3][init20][p1.p1][p1.p1] +SELECT p1.f1(); +p1.f1() +[p1.init1][p1.init2][p1.init3][init20][p1.p1][p1.p1][p1.f1] +SELECT p1.f1(); +p1.f1() +[p1.init1][p1.init2][p1.init3][init20][p1.p1][p1.p1][p1.f1][p1.f1] +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +[p1.init1][p1.init2][p1.init3][init20][p1.f1] +CALL p1.p1(); +@msg +[p1.init1][p1.init2][p1.init3][init20][p1.f1][p1.p1] +SELECT p1.f1(); +p1.f1() +[p1.init1][p1.init2][p1.init3][init20][p1.f1][p1.p1][p1.f1] +CALL p1.p1(); +@msg +[p1.init1][p1.init2][p1.init3][init20][p1.f1][p1.p1][p1.f1][p1.p1] +DROP PACKAGE p1; +DROP PROCEDURE init20; +# +# EXECUTE IMMEDIATE in the package initialization section +# +SET @a=1000; +CREATE TABLE t1 AS SELECT 10 AS a; +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +PROCEDURE p1 AS BEGIN SET @a=@a+1; SELECT @a; END; +FUNCTION f1 RETURN INT AS BEGIN SET @a=@a+1; RETURN @a; END; +BEGIN +EXECUTE IMMEDIATE 'SELECT MAX(a) FROM t1 INTO @a'; +END; +$$ +CALL p1.p1(); +@a +11 +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1.p1(); +@a +12 +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +ERROR 0A000: Dynamic SQL is not allowed in stored function or trigger +DROP PACKAGE p1; +DROP TABLE t1; +# +# A package with an initialization section, loading table data into a user variable +# +SET @a=1000; +CREATE TABLE t1 AS SELECT 10 AS a; +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +PROCEDURE p1 AS BEGIN SET @a=@a+1; SELECT @a; END; +FUNCTION f1 RETURN INT AS BEGIN SET @a=@a+1; RETURN @a; END; +BEGIN +SELECT MAX(a) FROM t1 INTO @a; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1.p1(); +@a +11 +CALL p1.p1(); +@a +12 +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +11 +DROP PACKAGE p1; +DROP TABLE t1; +# +# A package with an initialization section producing an error +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY p1 AS +PROCEDURE p1 AS BEGIN SELECT 'This is p1' AS msg; END; +FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is f1'; END; +BEGIN +SELECT 1 FROM t1 INTO @a; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1.p1(); +ERROR 42S02: Table 'test.t1' doesn't exist +SELECT p1.f1(); +ERROR 42S02: Table 'test.t1' doesn't exist +# sp-cache-invalidate +SELECT p1.f1(); +ERROR 42S02: Table 'test.t1' doesn't exist +CALL p1.p1(); +ERROR 42S02: Table 'test.t1' doesn't exist +SELECT p1.f1(); +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE TABLE t1 (a INT) AS SELECT 1; +CALL p1.p1(); +msg +This is p1 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +This is f1 +# sp-cache-invalidate +CALL p1.p1(); +msg +This is p1 +DROP TABLE t1; +DROP PACKAGE p1; +# +# A package with SF-unsafe statements in the initialization section +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY p1 AS +PROCEDURE p1 AS BEGIN SELECT 'This is p1' AS msg; END; +FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is f1'; END; +BEGIN +CREATE TABLE IF NOT EXISTS t1 (a INT); +DROP TABLE IF EXISTS t1; +END; +$$ +CALL p1.p1(); +msg +This is p1 +SELECT p1.f1(); +p1.f1() +This is f1 +# sp-cache-invalidate +SELECT p1.f1(); +ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger +CALL p1.p1(); +msg +This is p1 +SELECT p1.f1(); +p1.f1() +This is f1 +DROP PACKAGE p1; +# +# MDEV-13139 Package-wide variables in CREATE PACKAGE +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +a INT; +a INT; +PROCEDURE p1 AS +BEGIN +CREATE VIEW v1 AS SELECT a; +END; +END; +$$ +ERROR 42000: Duplicate variable: a +CREATE PACKAGE BODY p1 AS +a INT; +PROCEDURE p1 AS +BEGIN +NULL; +END; +b INT; -- Variables cannot go after routine definitions +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'b INT; -- Variables cannot go after routine definitions +END' at line 7 +CREATE PACKAGE BODY p1 AS +a INT; +PROCEDURE p1 AS +BEGIN +CREATE VIEW v1 AS SELECT a; +END; +END; +$$ +ERROR HY000: View's SELECT contains a variable or parameter +CREATE PACKAGE BODY p1 AS +a INT:=NULL; +PROCEDURE p1 AS +BEGIN +SELECT a; +a:=COALESCE(a,0)+100; +SET a=a+1; +END; +FUNCTION f1 RETURN INT AS +BEGIN +RETURN a; +END; +END; +$$ +CALL p1.p1; +a +NULL +CALL p1.p1; +a +101 +CALL p1.p1; +a +202 +SELECT p1.f1(); +p1.f1() +303 +DROP PACKAGE p1; +# +# One package variable with a default value +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +a INT:=10; +PROCEDURE p1 AS BEGIN a:=a+1; SELECT a; END; +FUNCTION f1 RETURN INT AS BEGIN a:=a+1; RETURN a; END; +END; +$$ +CALL p1.p1(); +a +11 +CALL p1.p1(); +a +12 +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +11 +CALL p1.p1(); +a +12 +SELECT p1.f1(); +p1.f1() +13 +CALL p1.p1(); +a +14 +DROP PACKAGE p1; +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +a ROW (a INT, b TEXT):=ROW(10,'bbb'); +PROCEDURE p1 AS +BEGIN +a.a:= a.a+1; +a.b:= a.b || 'B'; +SELECT a.a, a.b; +END; +FUNCTION f1 RETURN INT AS BEGIN a.a:= a.a+1; RETURN a.a; END; +END; +$$ +CALL p1.p1(); +a.a a.b +11 bbbB +CALL p1.p1(); +a.a a.b +12 bbbBB +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +11 +CALL p1.p1(); +a.a a.b +12 bbbB +SELECT p1.f1(); +p1.f1() +13 +CALL p1.p1(); +a.a a.b +14 bbbBB +DROP PACKAGE p1; +CREATE TABLE t1 (a INT); +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +a t1.a%TYPE:=10; +PROCEDURE p1 AS BEGIN a:=a+1; SELECT a; END; +FUNCTION f1 RETURN INT AS BEGIN a:=a+1; RETURN a; END; +END; +$$ +CALL p1.p1(); +a +11 +CALL p1.p1(); +a +12 +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +11 +CALL p1.p1(); +a +12 +SELECT p1.f1(); +p1.f1() +13 +CALL p1.p1(); +a +14 +DROP PACKAGE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT, b TEXT); +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +a t1%ROWTYPE:=ROW(10,'bbb'); +PROCEDURE p1 AS +BEGIN +a.a:= a.a+1; +a.b:= a.b || 'B'; +SELECT a.a, a.b; +END; +FUNCTION f1 RETURN INT AS BEGIN a.a:= a.a+1; RETURN a.a; END; +END; +$$ +CALL p1.p1(); +a.a a.b +11 bbbB +CALL p1.p1(); +a.a a.b +12 bbbBB +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +11 +CALL p1.p1(); +a.a a.b +12 bbbB +SELECT p1.f1(); +p1.f1() +13 +CALL p1.p1(); +a.a a.b +14 bbbBB +DROP PACKAGE p1; +DROP TABLE t1; +# +# One package variable, set in the package initialization section +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +a INT; +PROCEDURE p1 AS BEGIN a:=a+1; SELECT a; END; +FUNCTION f1 RETURN INT AS BEGIN a:=a+1; RETURN a; END; +BEGIN +a:=10; +END; +$$ +CALL p1.p1(); +a +11 +CALL p1.p1(); +a +12 +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +11 +CALL p1.p1(); +a +12 +SELECT p1.f1(); +p1.f1() +13 +CALL p1.p1(); +a +14 +DROP PACKAGE p1; +# +# A package with an initialization section, +# loading table data into a package variable +# +CREATE TABLE t1 AS SELECT 10 AS a; +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN INT; +END; +$$ +CREATE PACKAGE BODY p1 AS +a INT; +PROCEDURE p1 AS BEGIN SET a=a+1; SELECT a; END; +FUNCTION f1 RETURN INT AS BEGIN SET a=a+1; RETURN a; END; +BEGIN +a:=(SELECT MAX(t1.a) FROM t1); +END; +$$ +CALL p1.p1(); +a +11 +CALL p1.p1(); +a +12 +SELECT p1.f1(); +p1.f1() +13 +SELECT p1.f1(); +p1.f1() +14 +# sp-cache-invalidate +SELECT p1.f1(); +p1.f1() +11 +DROP PACKAGE p1; +DROP TABLE t1; +# +# Package variables and XPath +# +CREATE PACKAGE p1 AS +FUNCTION f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY p1 AS +i INT:=0; +xml TEXT:= '<a><b>b1</b><b>b2</b><b>b3</b></a>'; +FUNCTION f1 RETURN TEXT AS +BEGIN +SET i=i+1; +RETURN ExtractValue(xml, '/a/b[$i]'); +END; +END; +$$ +SELECT p1.f1(); +p1.f1() +b1 +SELECT p1.f1(); +p1.f1() +b2 +SELECT p1.f1(); +p1.f1() +b3 +DROP PACKAGE p1; +# +# Package variables as OUT routine parameter +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +a INT; +b INT; +c INT:=10; +PROCEDURE p2(a OUT INT) AS +BEGIN +a:=c; +c:=c+1; +END; +PROCEDURE p1 AS +BEGIN +CALL p2(b); +SELECT a,b; +END; +BEGIN +CALL p2(a); +END; +$$ +CALL p1.p1; +a b +10 11 +DROP PACKAGE p1; +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +a ROW(a INT, b TEXT); +b ROW(a INT, b TEXT); +c ROW(a INT, b TEXT):=ROW(1,'b'); +PROCEDURE p2(x OUT ROW(a INT,b TEXT)) AS +BEGIN +x:=c; +x.a:=c.a+100; +x.b:=c.b||'X'; +c.a:=c.a+1; +c.b:=c.b||'B'; +END; +PROCEDURE p1 AS +BEGIN +CALL p2(b); +SELECT a.a,a.b,b.a,b.b; +END; +BEGIN +CALL p2(a); +END; +$$ +CALL p1.p1; +a.a a.b b.a b.b +101 bX 102 bBX +DROP PACKAGE p1; +CREATE TABLE t1 (a INT,b TEXT); +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +a t1%ROWTYPE; +b t1%ROWTYPE; +c t1%ROWTYPE:=ROW(1,'b'); +PROCEDURE p2(x OUT t1%ROWTYPE) AS +BEGIN +x:=c; +x.a:=c.a+100; +x.b:=c.b||'X'; +c.a:=c.a+1; +c.b:=c.b||'B'; +END; +PROCEDURE p1 AS +BEGIN +CALL p2(b); +SELECT a.a,a.b,b.a,b.b; +END; +BEGIN +CALL p2(a); +END; +$$ +CALL p1.p1; +a.a a.b b.a b.b +101 bX 102 bBX +DROP PACKAGE p1; +DROP TABLE t1; +# +# Package variable fields as OUT routine parameters +# +CREATE TABLE t1 (a INT,b TEXT); +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +a t1%ROWTYPE; +x t1%ROWTYPE:=ROW(10,'b'); +PROCEDURE p2(a OUT INT,b OUT TEXT) AS +BEGIN +a:=x.a; +b:=x.b; +x.a:=x.a+1; +x.b:=x.b||'B'; +END; +PROCEDURE p1 AS +BEGIN +CALL p2(a.a, a.b); +SELECT a.a,a.b; +END; +BEGIN +CALL p2(a.a, a.b); +SELECT a.a, a.b; +END; +$$ +CALL p1.p1; +a.a a.b +10 b +a.a a.b +11 bB +DROP PACKAGE p1; +DROP TABLE t1; +# +# Package variables as SELECT INTO targets +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +a INT; +b INT; +PROCEDURE p1 AS +BEGIN +SELECT 2 INTO b; +SELECT a,b; +END; +BEGIN +SELECT 1 INTO a; +END; +$$ +CALL p1.p1; +a b +1 2 +DROP PACKAGE p1; +CREATE TABLE t1 (a INT, b TEXT); +INSERT INTO t1 VALUES (10,'b'); +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +a t1%ROWTYPE; +b t1%ROWTYPE; +PROCEDURE p1 AS +BEGIN +SELECT * FROM t1 INTO a; +SELECT a.a,a.b; +END; +BEGIN +SELECT * FROM t1 INTO b; +SELECT b.a, b.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1.p1; +b.a b.b +10 b +a.a a.b +10 b +DROP PACKAGE p1; +DROP TABLE t1; +# +# Package variable fields as SELECT INTO targets +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +END; +$$ +CREATE PACKAGE BODY p1 AS +a ROW(a INT, b TEXT); +b ROW(a INT, b TEXT); +PROCEDURE p1 AS +BEGIN +SELECT 20,'x2' INTO b.a,b.b; +SELECT a.a,a.b,b.a,b.b; +END; +BEGIN +SELECT 10,'x1' INTO a.a,a.b; +END; +$$ +CALL p1.p1; +a.a a.b b.a b.b +10 x1 20 x2 +DROP PACKAGE p1; +# +# Recursive package procedure calls +# Makes sure that the non-top sp_head instances created by +# sp_clone_and_link_routine() correctly reproduce the package context: +# package variables, package routines. +# +CREATE PACKAGE p1 AS +PROCEDURE p1(c INT); +END p1; +$$ +CREATE PACKAGE BODY p1 AS +pv1 INT:=10; +FUNCTION f1 RETURN INT AS BEGIN RETURN pv1+100; END; +PROCEDURE p1(c INT) AS +BEGIN +SELECT c, pv1, f1(); +IF c>0 THEN +pv1:=pv1+1; +CALL p1(c-1); +END IF; +END; +END; +$$ +SET max_sp_recursion_depth=5; +CALL p1.p1(5); +c pv1 f1() +5 10 110 +c pv1 f1() +4 11 111 +c pv1 f1() +3 12 112 +c pv1 f1() +2 13 113 +c pv1 f1() +1 14 114 +c pv1 f1() +0 15 115 +SET max_sp_recursion_depth=0; +CALL p1.p1(0); +c pv1 f1() +0 15 115 +CALL p1.p1(1); +c pv1 f1() +1 15 115 +ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p1.p1 +DROP PACKAGE p1; +# +# Non-reserved keywords as package body variable names +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +END p1; +$$ +CREATE PACKAGE BODY p1 AS +ascii INT:=10; +action INT:=20; +PROCEDURE p1 AS +BEGIN +SELECT ascii, action; +END; +BEGIN +ascii := ascii + 1; +action := action + 1; +END; +$$ +CALL p1.p1; +ascii action +11 21 +DROP PACKAGE p1; +# +# Package routines calling routines of another package +# +CREATE PACKAGE p1 AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE p2 AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY p1 AS +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1.p1' AS msg; +END; +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN 'This is p1.f1'; +END; +END; +$$ +CREATE PACKAGE BODY p2 AS +PROCEDURE p1 AS +BEGIN +CALL p1.p1; +END; +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN p1.f1(); +END; +END; +$$ +CALL p1.p1; +msg +This is p1.p1 +CALL p2.p1; +msg +This is p1.p1 +SELECT p1.f1(), p2.f1(); +p1.f1() p2.f1() +This is p1.f1 This is p1.f1 +DROP PACKAGE p2; +DROP PACKAGE p1; +# +# Package names with dot characters +# +CREATE PACKAGE "p1.p1" AS +PROCEDURE p1; +FUNCTION f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY "p1.p1" AS +PROCEDURE p1 AS +BEGIN +SELECT 'This is p1' AS msg; +END; +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN 'This is f1'; +END; +END; +$$ +CALL "p1.p1"."p1"; +msg +This is p1 +SELECT "p1.p1"."f1"(); +"p1.p1"."f1"() +This is f1 +DROP PACKAGE "p1.p1"; +# +# MDEV-15070 Crash when doing a CREATE VIEW inside a package routine +# +SET sql_mode=ORACLE; +CREATE OR REPLACE PACKAGE pkg1 AS +PROCEDURE p00(); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg1 AS +PROCEDURE p01() AS +BEGIN +SELECT 'This is p01' AS msg; +END; +PROCEDURE p00() AS +BEGIN +CREATE OR REPLACE VIEW v1 AS SELECT 1; +DROP VIEW v1; +CALL p01(); +END; +END; +$$ +CALL pkg1.p00; +msg +This is p01 +DROP PACKAGE pkg1; +CREATE OR REPLACE TABLE t1 (a INT); +CREATE OR REPLACE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a=1; +CREATE OR REPLACE PACKAGE pkg1 AS +PROCEDURE p00(); +END; +$$ +CREATE OR REPLACE PACKAGE BODY pkg1 AS +PROCEDURE p01() AS +BEGIN +SELECT 'This is p01' AS msg; +END; +PROCEDURE p00() AS +BEGIN +DROP TRIGGER tr1; +CALL p01(); +END; +END; +$$ +CALL pkg1.p00; +msg +This is p01 +DROP PACKAGE pkg1; +DROP TABLE t1; +# +# MDEV-17387 MariaDB Server giving wrong error while executing select query from procedure +# +CREATE TABLE t1 ( +CTR varchar(2) NOT NULL, +COR varchar(3) NOT NULL, +DATE datetime NOT NULL, +CHAN varchar(4) NOT NULL, +CNO varchar(20) NOT NULL, +JOBN varchar(18) NOT NULL, +C1 varchar(30) DEFAULT NULL, +C2 varchar(30) DEFAULT NULL, +TIME datetime DEFAULT NULL, +AMT decimal(12,2) DEFAULT NULL, +DT datetime NOT NULL, +pk int(11) NOT NULL, +PRIMARY KEY (pk), +KEY Indx1 (JOBN) +); +CREATE PACKAGE xyz IS +PROCEDURE xyz123(ctr IN VARCHAR2,Jn IN VARCHAR2,R OUT VARCHAR2); +END; +$$ +CREATE OR REPLACE PACKAGE BODY xyz IS +PROCEDURE xyz123( +ctr IN VARCHAR2, +Jn IN VARCHAR2, +R OUT VARCHAR2) +AS +lS NUMBER(10) :=0; +CURSOR cBPD IS +SELECT CTR, COR, DATE, CHAN, CNO, C1, C2, TIME, AMT +FROM t1 WHERE JOBN=Jn; +BEGIN +FOR lbpd IN cBPD +LOOP +lS:=lS+1; +END LOOP; +EXCEPTION +WHEN OTHERS THEN +BEGIN +SELECT SQLERRM; +END; +END; +END $$ +CALL xyz.xyz123(17,18,@R); +DROP PACKAGE xyz; +DROP TABLE t1; +# +# MDEV-28166 sql_mode=ORACLE: fully qualified package function calls do not work: db.pkg.func() +# +SELECT `db `.pkg.func(); +ERROR 42000: Incorrect database name 'db ' +SELECT db.`pkg `.func(); +ERROR 42000: Incorrect routine name 'pkg ' +SELECT db.pkg.`func `(); +ERROR 42000: Incorrect routine name 'func ' +CREATE DATABASE db1; +USE db1; +CREATE PACKAGE pkg1 AS +FUNCTION f1 RETURN TEXT; +FUNCTION f2_db1_pkg1_f1 RETURN TEXT; +FUNCTION f2_pkg1_f1 RETURN TEXT; +FUNCTION f2_f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY pkg1 +AS +FUNCTION f1 RETURN TEXT IS +BEGIN +RETURN 'This is db1.pkg1.f1'; +END; +FUNCTION f2_db1_pkg1_f1 RETURN TEXT IS +BEGIN +RETURN db1.pkg1.f1(); +END; +FUNCTION f2_pkg1_f1 RETURN TEXT IS +BEGIN +RETURN pkg1.f1(); +END; +FUNCTION f2_f1 RETURN TEXT IS +BEGIN +RETURN f1(); +END; +END; +$$ +USE db1; +SELECT pkg1.f2_db1_pkg1_f1(); +pkg1.f2_db1_pkg1_f1() +This is db1.pkg1.f1 +SELECT pkg1.f2_pkg1_f1(); +pkg1.f2_pkg1_f1() +This is db1.pkg1.f1 +SELECT pkg1.f2_f1(); +pkg1.f2_f1() +This is db1.pkg1.f1 +SELECT db1.pkg1.f2_db1_pkg1_f1(); +db1.pkg1.f2_db1_pkg1_f1() +This is db1.pkg1.f1 +SELECT db1.pkg1.f2_pkg1_f1(); +db1.pkg1.f2_pkg1_f1() +This is db1.pkg1.f1 +SELECT db1.pkg1.f2_f1(); +db1.pkg1.f2_f1() +This is db1.pkg1.f1 +USE test; +SELECT db1.pkg1.f2_db1_pkg1_f1(); +db1.pkg1.f2_db1_pkg1_f1() +This is db1.pkg1.f1 +SELECT db1.pkg1.f2_pkg1_f1(); +db1.pkg1.f2_pkg1_f1() +This is db1.pkg1.f1 +SELECT db1.pkg1.f2_f1(); +db1.pkg1.f2_f1() +This is db1.pkg1.f1 +DROP DATABASE db1; +CREATE DATABASE db1; +CREATE DATABASE db2; +CREATE PACKAGE db1.pkg1 AS +FUNCTION f1 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY db1.pkg1 AS +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN 'This is db1.pkg1.f1'; +END; +END; +$$ +CREATE PACKAGE db2.pkg1 AS +FUNCTION f1 RETURN TEXT; +FUNCTION var1 RETURN TEXT; +FUNCTION var2 RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY db2.pkg1 AS +m_var1 TEXT; +m_var2 TEXT; +FUNCTION f1 RETURN TEXT AS +BEGIN +RETURN 'This is db2.pkg1.f1'; +END; +FUNCTION var1 RETURN TEXT AS +BEGIN +RETURN m_var1; +END; +FUNCTION var2 RETURN TEXT AS +BEGIN +RETURN m_var2; +END; +BEGIN +m_var1:= db1.pkg1.f1(); +m_var2:= db2.pkg1.f1(); +END; +$$ +SELECT db2.pkg1.var1(), db2.pkg1.var2(); +db2.pkg1.var1() db2.pkg1.var2() +This is db1.pkg1.f1 This is db2.pkg1.f1 +DROP DATABASE db1; +DROP DATABASE db2; +CREATE PACKAGE pkg1 AS +FUNCTION f1(a TEXT) RETURN TEXT; +END; +$$ +CREATE PACKAGE BODY pkg1 AS +FUNCTION f1(a TEXT) RETURN TEXT AS +BEGIN +RETURN a; +END; +END; +$$ +SELECT test.pkg1.f1('xxx'); +test.pkg1.f1('xxx') +xxx +SELECT test.pkg1.f1('xxx' AS a); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'AS a)' at line 1 +DROP PACKAGE pkg1; +# +# MDEV-19328 sql_mode=ORACLE: Package function in VIEW +# +SET sql_mode=ORACLE; +CREATE PACKAGE test1 AS +FUNCTION f_test RETURN number; +END test1; +$$ +CREATE PACKAGE BODY test1 +AS +FUNCTION f_test RETURN NUMBER IS +BEGIN +RETURN 1; +END; +END test1; +$$ +SET sql_mode=ORACLE; +CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test(); +SELECT * FROM v_test; +c1 +1 +SHOW CREATE VIEW v_test; +View v_test +Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"() +character_set_client latin1 +collation_connection latin1_swedish_ci +SET sql_mode=DEFAULT; +SELECT * FROM v_test; +c1 +1 +SHOW CREATE VIEW v_test; +View v_test +Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`() +character_set_client latin1 +collation_connection latin1_swedish_ci +DROP VIEW v_test; +SET sql_mode=DEFAULT; +CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test1.f_test(); +ERROR 42000: FUNCTION test1.f_test does not exist +SET sql_mode=ORACLE; +CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test(); +SELECT * FROM v_test; +c1 +1 +SHOW CREATE VIEW v_test; +View v_test +Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"() +character_set_client latin1 +collation_connection latin1_swedish_ci +SET sql_mode=DEFAULT; +SELECT * FROM v_test; +c1 +1 +SHOW CREATE VIEW v_test; +View v_test +Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`() +character_set_client latin1 +collation_connection latin1_swedish_ci +DROP VIEW v_test; +SET sql_mode=DEFAULT; +CREATE VIEW v_test AS SELECT 1 AS c1 FROM DUAL WHERE 1=test.test1.f_test(); +SELECT * FROM v_test; +c1 +1 +SHOW CREATE VIEW v_test; +View v_test +Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_test` AS select 1 AS `c1` from DUAL where 1 = `test`.`test1`.`f_test`() +character_set_client latin1 +collation_connection latin1_swedish_ci +SET sql_mode=ORACLE; +SELECT * FROM v_test; +c1 +1 +SHOW CREATE VIEW v_test; +View v_test +Create View CREATE VIEW "v_test" AS select 1 AS "c1" from DUAL where 1 = "test"."test1"."f_test"() +character_set_client latin1 +collation_connection latin1_swedish_ci +DROP VIEW v_test; +SET sql_mode=ORACLE; +DROP PACKAGE test1; +# +# MDEV-19804 sql_mode=ORACLE: call procedure in packages +# +CALL `db1 `.pkg.p; +ERROR 42000: Incorrect database name 'db1 ' +CALL db1.`pkg `.p; +ERROR 42000: Incorrect routine name 'pkg ' +CALL db1.pkg.`p `; +ERROR 42000: Incorrect routine name 'p ' +SET sql_mode=ORACLE; +CREATE PACKAGE pkg1 as +PROCEDURE p1(); +END; +$$ +CREATE PACKAGE BODY pkg1 as +PROCEDURE p1() as +BEGIN +SELECT 'test-function' AS c1; +END; +END; +$$ +CALL pkg1.p1; +c1 +test-function +CALL test.pkg1.p1; +c1 +test-function +SET sql_mode=DEFAULT; +CALL test.pkg1.p1; +c1 +test-function +SET sql_mode=ORACLE; +BEGIN +CALL pkg1.p1; +CALL test.pkg1.p1; +END +$$ +c1 +test-function +c1 +test-function +BEGIN +pkg1.p1; +test.pkg1.p1; +END +$$ +c1 +test-function +c1 +test-function +DROP PACKAGE pkg1; +CREATE DATABASE db1; +CREATE PACKAGE db1.pkg1 AS +PROCEDURE p1(a OUT TEXT); +END; +$$ +CREATE PACKAGE BODY db1.pkg1 AS +PROCEDURE p1(a OUT TEXT) AS +BEGIN +a:= 'This is db1.pkg1.p1'; +END; +END; +$$ +CREATE DATABASE db2; +CREATE PACKAGE db2.pkg1 AS +FUNCTION var1 RETURN TEXT; +PROCEDURE p1(a OUT TEXT); +PROCEDURE p2_db1_pkg1_p1; +END; +$$ +CREATE PACKAGE BODY db2.pkg1 AS +m_var1 TEXT; +FUNCTION var1 RETURN TEXT AS +BEGIN +RETURN m_var1; +END; +PROCEDURE p1(a OUT TEXT) AS +BEGIN +a:= 'This is db2.pkg1.p1'; +END; +PROCEDURE p2_db1_pkg1_p1 AS +a TEXT; +BEGIN +db1.pkg1.p1(a); +SELECT a; +END; +BEGIN +db1.pkg1.p1(m_var1); +END; +$$ +SELECT db2.pkg1.var1(); +db2.pkg1.var1() +This is db1.pkg1.p1 +CALL db2.pkg1.p2_db1_pkg1_p1; +a +This is db1.pkg1.p1 +DROP DATABASE db1; +DROP DATABASE db2; +# +# MDEV-29370 Functions in packages are slow and seems to ignore deterministic +# +SET SQL_MODE=ORACLE; +CREATE TABLE t1 (c1 CHAR(1)); +CREATE FUNCTION f1_deterministic() +RETURN CHAR(1) +DETERMINISTIC +IS +BEGIN +RETURN 'X'; +END; +// +CREATE FUNCTION f2_not_deterministic() +RETURN CHAR(1) +IS +BEGIN +RETURN 'X'; +END; +// +CREATE PACKAGE pkg1 +IS +PROCEDURE t1_populate(numrows INTEGER); +FUNCTION f3_deterministic() RETURN CHAR(1) DETERMINISTIC; +FUNCTION f4_not_deterministic() RETURN CHAR(1); +END; +// +CREATE PACKAGE BODY pkg1 +IS +PROCEDURE t1_populate(numrounds INTEGER) +IS +i INTEGER; +BEGIN +INSERT INTO t1 VALUES('Y'); +FOR i IN 1..numrounds LOOP +INSERT INTO t1 SELECT * FROM t1; +END LOOP; +END; +FUNCTION f3_deterministic() RETURN CHAR(1) DETERMINISTIC COMMENT 'xxx' + IS +BEGIN +RETURN 'X'; +END; +FUNCTION f4_not_deterministic() RETURN CHAR(1) +IS +BEGIN +RETURN 'X'; +END; +END; +// +CALL pkg1.t1_populate(3); +EXPLAIN EXTENDED SELECT 'Deterministic function', COUNT(*) FROM t1 WHERE c1 = f1_deterministic(); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where +Warnings: +Note 1003 select 'Deterministic function' AS "Deterministic function",count(0) AS "COUNT(*)" from "test"."t1" where "test"."t1"."c1" = <cache>("f1_deterministic"()) +EXPLAIN EXTENDED SELECT 'Non-deterministic function', COUNT(*) FROM t1 WHERE c1 = f2_not_deterministic(); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where +Warnings: +Note 1003 select 'Non-deterministic function' AS "Non-deterministic function",count(0) AS "COUNT(*)" from "test"."t1" where "test"."t1"."c1" = "f2_not_deterministic"() +EXPLAIN EXTENDED SELECT 'Deterministic package function', COUNT(*) FROM t1 WHERE c1 = pkg1.f3_deterministic(); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where +Warnings: +Note 1003 select 'Deterministic package function' AS "Deterministic package function",count(0) AS "COUNT(*)" from "test"."t1" where "test"."t1"."c1" = <cache>("test"."pkg1"."f3_deterministic"()) +EXPLAIN EXTENDED SELECT 'Non-deterministic package function', COUNT(*) FROM t1 WHERE c1 = pkg1.f4_not_deterministic(); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where +Warnings: +Note 1003 select 'Non-deterministic package function' AS "Non-deterministic package function",count(0) AS "COUNT(*)" from "test"."t1" where "test"."t1"."c1" = "test"."pkg1"."f4_not_deterministic"() +DROP TABLE t1; +DROP FUNCTION f1_deterministic; +DROP FUNCTION f2_not_deterministic; +DROP PACKAGE pkg1; diff --git a/mysql-test/suite/compat/oracle/r/sp-param.result b/mysql-test/suite/compat/oracle/r/sp-param.result new file mode 100644 index 00000000..bb415bd7 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-param.result @@ -0,0 +1,423 @@ +SET sql_mode=ORACLE; +# +# MDEV-10596 Allow VARCHAR and VARCHAR2 without length as a data type of routine parameters and in RETURN clause +# +CREATE FUNCTION f1(param CHAR) RETURN CHAR AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param CHAR) RETURN varchar(2000) CHARSET latin1 COLLATE latin1_swedish_ci +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',2000)));; +LENGTH(f1(REPEAT('a',2000))) +2000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',2000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(2000) DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param NCHAR) RETURN NCHAR AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param NCHAR) RETURN varchar(2000) CHARSET utf8mb3 COLLATE utf8mb3_general_ci +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',2000)));; +LENGTH(f1(REPEAT('a',2000))) +2000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',2000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(2000) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param BINARY) RETURN BINARY AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param BINARY) RETURN varbinary(2000) +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',2000)));; +LENGTH(f1(REPEAT('a',2000))) +2000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',2000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(2000) DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param VARCHAR) RETURN VARCHAR AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARCHAR) RETURN varchar(4000) CHARSET latin1 COLLATE latin1_swedish_ci +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(4000) DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARCHAR2) RETURN varchar(4000) CHARSET latin1 COLLATE latin1_swedish_ci +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(4000) DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param NVARCHAR) RETURN NVARCHAR AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param NVARCHAR) RETURN varchar(4000) CHARSET utf8mb3 COLLATE utf8mb3_general_ci +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(4000) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param VARBINARY) RETURN VARBINARY AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param VARBINARY) RETURN varbinary(4000) +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(4000) DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; +CREATE FUNCTION f1(param RAW) RETURN RAW AS BEGIN RETURN param; END;; +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function character_set_client collation_connection Database Collation +f1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" FUNCTION "f1"(param RAW) RETURN varbinary(4000) +AS BEGIN RETURN param; END latin1 latin1_swedish_ci latin1_swedish_ci +SELECT LENGTH(f1(REPEAT('a',4000)));; +LENGTH(f1(REPEAT('a',4000))) +4000 +CREATE TABLE t1 AS SELECT f1(REPEAT('a',4000)) AS a;; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(4000) DEFAULT NULL +) +DROP TABLE t1; +DROP FUNCTION f1; + +MDEV-13919 sql_mode=ORACLE: Derive length of VARCHAR SP parameters with no length from actual parameters + +set sql_mode= 'oracle,strict_trans_tables'; +CREATE OR REPLACE PROCEDURE p1(pinout INOUT varchar, pin IN varchar) +AS +BEGIN +pinout:=pin; +END; +/ +call p1(@w,'0123456789') +/ +declare w varchar(10); +begin +call p1(w,'0123456789'); +end; +/ +declare w varchar(5); +begin +call p1(w,'0123456789'); +end; +/ +ERROR 22001: Data too long for column 'pinout' at row 0 +declare w varchar(20); +begin +w:='aaa'; +call p1(w,'0123456789'); +end; +/ +declare w varchar(8); +begin +w:='aaa'; +call p1(w,'0123456789'); +end; +/ +ERROR 22001: Data too long for column 'pinout' at row 0 +declare str varchar(6000); +pout varchar(6000); +begin +str:=lpad('x',6000,'y'); +call p1(pout,str); +select length(pout); +end; +/ +length(pout) +6000 +declare str varchar(6000); +pout varchar(4000); +begin +str:=lpad('x',6000,'y'); +call p1(pout,str); +select length(pout); +end; +/ +ERROR 22001: Data too long for column 'pinout' at row 0 +declare str varchar(40000); +pout varchar(60000); +begin +str:=lpad('x',40000,'y'); +call p1(pout,str); +select length(pout); +end; +/ +length(pout) +40000 +declare str text(80000); +pout text(80000); +begin +str:=lpad('x',80000,'y'); +call p1(pout,str); +select length(pout); +end; +/ +ERROR 22001: Data too long for column 'pin' at row 0 +declare str text(80000); +pout text(80000); +begin +str:=lpad('x',60000,'y'); +call p1(pout,str); +select length(pout); +end; +/ +length(pout) +60000 +drop procedure p1 +/ +SET sql_mode=ORACLE; +CREATE PROCEDURE p1(pinout INOUT varchar, pin IN varchar) +AS +BEGIN +pinout:=pin; +END; +/ +CREATE PROCEDURE p2(len INT) +AS +pinout VARCHAR(10); +pin VARCHAR(30); +BEGIN +pin:= REPEAT('x', len); +p1(pinout, pin); +SELECT LENGTH(pinout); +END; +/ +CALL p2(10); +LENGTH(pinout) +10 +CALL p2(11); +LENGTH(pinout) +10 +Warnings: +Warning 1265 Data truncated for column 'pinout' at row 0 +DROP PROCEDURE p1; +DROP PROCEDURE p2; +SET sql_mode=ORACLE; +CREATE FUNCTION f1(pin VARCHAR, padlen INT) RETURN TEXT +AS +BEGIN +pin:=LPAD(pin, padlen); +RETURN pin; +END; +/ +CREATE PROCEDURE p2(padlen INT) AS +str TEXT :='x'; +BEGIN +SELECT LENGTH(f1(str,padlen)); +END; +/ +CALL p2(65535); +LENGTH(f1(str,padlen)) +65532 +Warnings: +Warning 1265 Data truncated for column 'pin' at row 0 +CALL p2(65536); +LENGTH(f1(str,padlen)) +65532 +Warnings: +Warning 1265 Data truncated for column 'pin' at row 0 +DROP PROCEDURE p2; +DROP FUNCTION f1; +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +CREATE PROCEDURE p1(pinout INOUT VARCHAR CHARACTER SET utf8, +pin IN VARCHAR CHARACTER SET utf8) +AS +BEGIN +pinout:=pin; +END; +/ +CREATE PROCEDURE p2(padlen INT) AS +str VARCHAR(40000) CHARACTER SET latin1; +pout VARCHAR(60000) CHARACTER SET latin1; +BEGIN +str:=lpad('x',padlen,'y'); +p1(pout,str); +SELECT length(pout); +END; +/ +CALL p2(21844); +length(pout) +21844 +CALL p2(21845); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(21846); +ERROR 22001: Data too long for column 'pin' at row 0 +DROP PROCEDURE p2; +DROP PROCEDURE p1; +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +CREATE PROCEDURE p1(pinout INOUT VARCHAR CHARACTER SET utf8, +pin IN VARCHAR CHARACTER SET utf8) +AS +BEGIN +pinout:=pin; +END; +/ +CREATE PROCEDURE p2(padlen INT) AS +str TEXT CHARACTER SET utf8; +pout TEXT CHARACTER SET utf8; +BEGIN +str:=lpad('x',padlen,'y'); +p1(pout,str); +SELECT length(pout); +END; +/ +CALL p2(21844); +length(pout) +21844 +CALL p2(21845); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(21846); +ERROR 22001: Data too long for column 'pin' at row 0 +DROP PROCEDURE p2; +DROP PROCEDURE p1; +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +CREATE FUNCTION f1(pin VARCHAR CHARACTER SET latin1, padlen INT) RETURN TEXT +AS +BEGIN +pin:=LPAD(pin, padlen); +RETURN pin; +END; +/ +CREATE PROCEDURE p2(padlen INT) AS +str TEXT CHARACTER SET latin1 :='x'; +BEGIN +SELECT LENGTH(f1(str,padlen)); +END; +/ +CALL p2(65532); +LENGTH(f1(str,padlen)) +65532 +CALL p2(65533); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(65534); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(65535); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(65536); +ERROR 22001: Data too long for column 'pin' at row 0 +DROP PROCEDURE p2; +DROP FUNCTION f1; +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +CREATE FUNCTION f1(pin VARCHAR CHARACTER SET utf8, padlen INT) RETURN TEXT +AS +BEGIN +pin:=LPAD(pin, padlen); +RETURN pin; +END; +/ +CREATE PROCEDURE p2(padlen INT) AS +str TEXT CHARACTER SET utf8 := 'x'; +BEGIN +SELECT LENGTH(f1(str,padlen)); +END; +/ +CALL p2(21844); +LENGTH(f1(str,padlen)) +21844 +CALL p2(21845); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(21846); +ERROR 22001: Data too long for column 'pin' at row 0 +DROP PROCEDURE p2; +DROP FUNCTION f1; +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +CREATE FUNCTION f1(pin VARCHAR CHARACTER SET utf8, padlen INT) RETURN TEXT +AS +BEGIN +pin:=LPAD(pin, padlen); +RETURN pin; +END; +/ +CREATE PROCEDURE p2(padlen INT) AS +str TEXT CHARACTER SET latin1 := 'x'; +BEGIN +SELECT LENGTH(f1(str,padlen)); +END; +/ +CALL p2(21844); +LENGTH(f1(str,padlen)) +21844 +CALL p2(21845); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(21846); +ERROR 22001: Data too long for column 'pin' at row 0 +DROP PROCEDURE p2; +DROP FUNCTION f1; +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +CREATE FUNCTION f1(pin VARCHAR CHARACTER SET latin1, padlen INT) RETURN TEXT +AS +BEGIN +pin:=LPAD(pin, padlen); +RETURN pin; +END; +/ +CREATE PROCEDURE p2(padlen INT) AS +str TEXT CHARACTER SET utf8 := 'x'; +BEGIN +SELECT LENGTH(f1(str,padlen)); +END; +/ +CALL p2(65532); +LENGTH(f1(str,padlen)) +65532 +CALL p2(65533); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(65534); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(65535); +ERROR 22001: Data too long for column 'pin' at row 0 +CALL p2(65536); +ERROR 22001: Data too long for column 'pin' at row 0 +DROP PROCEDURE p2; +DROP FUNCTION f1; diff --git a/mysql-test/suite/compat/oracle/r/sp-row.result b/mysql-test/suite/compat/oracle/r/sp-row.result new file mode 100644 index 00000000..0b23f303 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-row.result @@ -0,0 +1,3129 @@ +SET sql_mode=ORACLE; +# +# MDEV-10914 ROW data type for stored routine variables +# +# +# ROW of ROWs is not supported yet +# +CREATE PROCEDURE p1() +AS +a ROW(a ROW(a INT)); +BEGIN +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ROW(a INT)); +BEGIN +END' at line 3 +# +# Returning the entire ROW parameter from a function +# +CREATE FUNCTION f1(a ROW(a INT, b INT)) RETURN INT +AS +BEGIN +RETURN a; +END; +$$ +SELECT f1(ROW(10,20)); +ERROR HY000: Cannot cast 'row' as 'int' in assignment of `f1(ROW(10,20))` +DROP FUNCTION f1; +# +# ROW as an SP parameter +# +CREATE FUNCTION f1(a ROW(a INT,b INT)) RETURN INT +AS +BEGIN +RETURN a.b; +END; +$$ +CREATE PROCEDURE p1() +AS +a ROW(a INT,b INT):=(11,21); +BEGIN +SELECT f1(a); +END; +$$ +SELECT f1(ROW(10,20)); +f1(ROW(10,20)) +20 +SELECT f1(10); +ERROR 21000: Operand should contain 2 column(s) +SELECT f1(ROW(10,20,30)); +ERROR 21000: Operand should contain 2 column(s) +CALL p1(); +f1(a) +21 +DROP PROCEDURE p1; +DROP FUNCTION f1; +CREATE PROCEDURE p1(a ROW(a INT,b INT)) +AS +BEGIN +SELECT a.a, a.b; +END; +$$ +CALL p1(ROW(10,20)); +a.a a.b +10 20 +CALL p1(10); +ERROR 21000: Operand should contain 2 column(s) +CALL p1(ROW(10,20,30)); +ERROR 21000: Operand should contain 2 column(s) +DROP PROCEDURE p1; +# +# ROW as an SP OUT parameter +# +CREATE PROCEDURE p1(a OUT ROW(a INT,b INT)) +AS +BEGIN +a.a:=10; +a.b:=20; +END; +$$ +CREATE PROCEDURE p2 +AS +a ROW(a INT,b INT):=(11,21); +BEGIN +CALL p1(a); +SELECT a.a,a.b; +END; +$$ +CALL p2(); +a.a a.b +10 20 +DROP PROCEDURE p2; +DROP PROCEDURE p1; +# +# ROW as an SP return value is not supported yet +# +CREATE FUNCTION p1() RETURN ROW(a INT) +AS +BEGIN +RETURN NULL; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ROW(a INT) +AS +BEGIN +RETURN NULL; +END' at line 1 +# +# Diplicate row field +# +CREATE PROCEDURE p1() +AS +a ROW (a INT, a DOUBLE); +BEGIN +SELECT a.a; +END; +$$ +ERROR 42S21: Duplicate column name 'a' +# +# Bad scalar default value +# +CREATE PROCEDURE p1() +AS +a ROW (a INT, b DOUBLE):= 1; +BEGIN +SELECT a.a; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP PROCEDURE p1; +# +# Bad ROW default value with a wrong number of fields +# +CREATE PROCEDURE p1() +AS +a ROW (a INT, b DOUBLE):= ROW(1,2,3); +BEGIN +SELECT a.a; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP PROCEDURE p1; +# +# Scalar variable vs table alias cause no ambiguity +# +CREATE PROCEDURE p1() +AS +a INT; +BEGIN +-- a.x is a table column here (not a row variable field) +SELECT a.x FROM a; +SELECT a.x FROM t1 a; +END; +$$ +DROP PROCEDURE p1; +# +# Using the entire ROW variable in select list +# +CREATE PROCEDURE p1() +AS +a ROW (a INT); +BEGIN +SELECT a; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 1 column(s) +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +a ROW (a INT,b INT); +BEGIN +SELECT a; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 1 column(s) +DROP PROCEDURE p1; +# +# Using the entire ROW variable in functions +# +CREATE PROCEDURE p1() +AS +a ROW (a INT); +BEGIN +SELECT COALESCE(a); +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 1 column(s) +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +a ROW (a INT,b INT); +BEGIN +SELECT COALESCE(a); +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 1 column(s) +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +a ROW (a INT); +BEGIN +SELECT a+1; +END; +$$ +CALL p1(); +ERROR HY000: Illegal parameter data types row and int for operation '+' +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +a ROW (a INT,b INT); +BEGIN +SELECT a+1; +END; +$$ +CALL p1(); +ERROR HY000: Illegal parameter data types row and int for operation '+' +DROP PROCEDURE p1; +# +# Comparing the entire ROW to a scalar value +# +CREATE PROCEDURE p1() +AS +a ROW (a INT,b INT); +BEGIN +SELECT a=1; +END; +$$ +CALL p1(); +ERROR HY000: Illegal parameter data types row and int for operation '=' +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +a ROW (a INT,b INT); +BEGIN +SELECT 1=a; +END; +$$ +CALL p1(); +ERROR HY000: Illegal parameter data types int and row for operation '=' +DROP PROCEDURE p1; +# +# Passing the entire ROW to a stored function +# +CREATE FUNCTION f1(a INT) RETURN INT +AS +BEGIN +RETURN a; +END; +$$ +CREATE PROCEDURE p1() +AS +a ROW (a INT,b INT); +BEGIN +SELECT f1(a); +END; +$$ +CALL p1(); +ERROR HY000: Cannot cast 'row' as 'int' in assignment of `a` +DROP PROCEDURE p1; +DROP FUNCTION f1; +CREATE FUNCTION f1(a INT) RETURN INT +AS +BEGIN +RETURN a; +END; +$$ +CREATE PROCEDURE p1() +AS +a ROW (a INT); +BEGIN +SELECT f1(a); +END; +$$ +CALL p1(); +ERROR HY000: Cannot cast 'row' as 'int' in assignment of `a` +DROP PROCEDURE p1; +DROP FUNCTION f1; +# +# Assigning a scalar value to a ROW variable with 1 column +# +CREATE OR REPLACE PROCEDURE p1 +AS +rec ROW(a INT); +BEGIN +rec:=1; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 1 column(s) +DROP PROCEDURE p1; +# +# Assigning a scalar value to a ROW variable with 2 columns +# +CREATE OR REPLACE PROCEDURE p1 +AS +rec ROW(a INT,b INT); +BEGIN +rec:=1; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP PROCEDURE p1; +# +# Assigning a ROW value to a ROW variable with different number of columns +# +CREATE OR REPLACE PROCEDURE p1 +AS +rec ROW(a INT,b INT); +BEGIN +rec:=ROW(1,2,3); +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP PROCEDURE p1; +# +# Returning the entire ROW from a function is not supported yet +# This syntax would be needed: SELECT f1().x FROM DUAL; +# +CREATE FUNCTION f1(a INT) RETURN INT +AS +rec ROW(a INT); +BEGIN +RETURN rec; +END; +$$ +SELECT f1(10); +ERROR HY000: Cannot cast 'row' as 'int' in assignment of `f1(10)` +DROP FUNCTION f1; +# +# Using the entire ROW in SELECT..CREATE +# +CREATE PROCEDURE p1 +AS +rec ROW(a INT,b INT); +BEGIN +CREATE TABLE t1 AS SELECT rec; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 1 column(s) +DROP PROCEDURE p1; +# +# Using the entire ROW in LIMIT +# +CREATE PROCEDURE p1() +AS +rec ROW(a INT); +BEGIN +rec.a:= '10'; +SELECT * FROM t1 LIMIT rec; +END; +$$ +ERROR HY000: A variable of a non-integer based type in LIMIT clause +# +# Setting ROW fields using a SET command +# +CREATE OR REPLACE PROCEDURE p1 +AS +rec ROW(a INT,b DOUBLE,c VARCHAR(10)); +a INT; +BEGIN +SET @a= 10, rec.a=10, rec.b=20, rec.c= 'test', a= 5; +SELECT rec.a, rec.b, rec.c, a; +END; +$$ +CALL p1(); +rec.a rec.b rec.c a +10 20 test 5 +DROP PROCEDURE p1; +# +# Assigning a ROW variable from a ROW value +# +CREATE PROCEDURE p1 +AS +rec ROW(a INT,b INT); +BEGIN +rec:=ROW(1,2); +SELECT rec.a, rec.b; +END; +$$ +CALL p1(); +rec.a rec.b +1 2 +DROP PROCEDURE p1; +# +# Assigning a ROW variable from another ROW value +# +CREATE PROCEDURE p1 +AS +rec1 ROW(a INT,b INT); +rec2 ROW(a INT,b INT); +BEGIN +rec1:=ROW(1,2); +rec2:=rec1; +SELECT rec2.a, rec2.b; +END; +$$ +CALL p1(); +rec2.a rec2.b +1 2 +DROP PROCEDURE p1; +# +# Comparing a ROW variable to a ROW() function +# +CREATE OR REPLACE PROCEDURE p1 +AS +rec ROW(a INT,b INT); +BEGIN +rec.a:= 1; +rec.b:= 2; +SELECT rec=(0,0), rec=ROW(0,0), (0,0)=rec, ROW(0,0)=rec; +SELECT rec=(1,2), rec=ROW(1,2), (1,2)=rec, ROW(1,2)=rec; +SELECT rec=(NULL,0), rec=ROW(NULL,0); +SELECT rec=(NULL,2), rec=ROW(NULL,2); +SELECT rec<>(0,0), rec<>ROW(0,0); +SELECT rec<>(1,2), rec<>ROW(1,2); +SELECT rec<>(NULL,0), rec<>ROW(NULL,0); +SELECT rec<>(NULL,2), rec<>ROW(NULL,2); +SELECT rec IN ((0,0)), rec IN (ROW(0,0)); +SELECT rec IN ((1,2)), rec IN (ROW(1,2)); +SELECT rec IN ((0,NULL),(1,2)); +SELECT rec NOT IN ((0,NULL),(1,1)); +SELECT rec NOT IN ((1,NULL),(1,1)); +END; +$$ +CALL p1(); +rec=(0,0) rec=ROW(0,0) (0,0)=rec ROW(0,0)=rec +0 0 0 0 +rec=(1,2) rec=ROW(1,2) (1,2)=rec ROW(1,2)=rec +1 1 1 1 +rec=(NULL,0) rec=ROW(NULL,0) +0 0 +rec=(NULL,2) rec=ROW(NULL,2) +NULL NULL +rec<>(0,0) rec<>ROW(0,0) +1 1 +rec<>(1,2) rec<>ROW(1,2) +0 0 +rec<>(NULL,0) rec<>ROW(NULL,0) +1 1 +rec<>(NULL,2) rec<>ROW(NULL,2) +NULL NULL +rec IN ((0,0)) rec IN (ROW(0,0)) +0 0 +rec IN ((1,2)) rec IN (ROW(1,2)) +1 1 +rec IN ((0,NULL),(1,2)) +1 +rec NOT IN ((0,NULL),(1,1)) +1 +rec NOT IN ((1,NULL),(1,1)) +NULL +DROP PROCEDURE p1; +# +# Comparing a ROW variable to another ROW variable +# +CREATE OR REPLACE PROCEDURE p1 +AS +rec1,rec2,rec3 ROW(a INT,b INT); +BEGIN +rec1.a:= 1; +rec1.b:= 2; +rec2.a:= 11; +rec2.b:= 12; +rec3.a:= 11; +rec3.b:= 12; +SELECT rec1=rec2, rec2=rec1, rec2=rec3, rec3=rec2; +END; +$$ +CALL p1(); +rec1=rec2 rec2=rec1 rec2=rec3 rec3=rec2 +0 0 1 1 +DROP PROCEDURE p1; +# +# Referencing a non-existing row variable +# +CREATE PROCEDURE p1() +AS +BEGIN +SET a.b=1; +END; +$$ +ERROR HY000: Unknown structured system variable or ROW routine variable 'a' +CREATE PROCEDURE p1() +AS +BEGIN +a.b:=1; +END; +$$ +ERROR HY000: Unknown structured system variable or ROW routine variable 'a' +# +# Referencing a non-existing row field +# +CREATE PROCEDURE p1() +AS +a ROW(a INT,b INT); +BEGIN +SELECT a.c FROM t1; +END; +$$ +ERROR HY000: Row variable 'a' does not have a field 'c' +# +# ROW and scalar variables with the same name shadowing each other +# +CREATE PROCEDURE p1() +AS +a ROW(a INT); +BEGIN +a.a:=100; +DECLARE +a INT:= 200; +BEGIN +SELECT a; +DECLARE +a ROW(a INT); +BEGIN +a.a:=300; +SELECT a.a; +END; +SELECT a; +END; +SELECT a.a; +END; +$$ +CALL p1(); +a +200 +a.a +300 +a +200 +a.a +100 +DROP PROCEDURE p1; +# +# ROW with good default values +# +CREATE PROCEDURE p1() +AS +a ROW(a INT,b INT):= (10,20); +b ROW(a INT,b INT):= (11,21); +c ROW(a INT,b INT):= a; +BEGIN +SELECT a.a, a.b, b.a, b.b, c.a, c.b FROM DUAL; +END; +$$ +CALL p1; +a.a a.b b.a b.b c.a c.b +10 20 11 21 10 20 +DROP PROCEDURE p1; +# +# ROW in WHERE clause +# +CREATE TABLE t1 (a INT,b INT); +INSERT INTO t1 VALUES (10,20); +CREATE PROCEDURE p1() +AS +rec ROW(a INT,b INT):=ROW(10,20); +BEGIN +SELECT * FROM t1 WHERE rec=ROW(a,b); +SELECT * FROM t1 WHERE ROW(a,b)=rec; +SELECT * FROM t1 WHERE rec=ROW(10,20); +SELECT * FROM t1 WHERE ROW(10,20)=rec; +END; +$$ +CALL p1(); +a b +10 20 +a b +10 20 +a b +10 20 +a b +10 20 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# ROW fields in WHERE clause +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1() +AS +rec ROW(a INT); +BEGIN +rec.a:= 10; +SELECT * FROM t1 WHERE a=rec.a; +END; +$$ +CALL p1(); +a +10 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# ROW fields in HAVING clause +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1() +AS +rec ROW(a INT); +BEGIN +rec.a:= 10; +SELECT * FROM t1 HAVING a=rec.a; +SELECT * FROM t1 HAVING MIN(a)=rec.a; +END; +$$ +CALL p1(); +a +10 +a +10 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# ROW fields in LIMIT clause +# +CREATE TABLE t1 (a INT); +SELECT 1 FROM t1 LIMIT t1.a; +ERROR 42000: Undeclared variable: t1 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1() +AS +rec ROW(a INT); +BEGIN +rec.a:= 10; +SELECT * FROM t1 LIMIT rec.a; +END; +$$ +CALL p1(); +a +10 +20 +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +rec ROW(a VARCHAR(10)); +BEGIN +rec.a:= '10'; +SELECT * FROM t1 LIMIT rec.a; +END; +$$ +ERROR HY000: A variable of a non-integer based type in LIMIT clause +# +# ROW fields in select list +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10),(20); +CREATE PROCEDURE p1() +AS +t1 ROW(a INT); +BEGIN +t1.a:= 10; +SELECT t1.a, 'This is the variable t1.a value, rather than the column t1.a' AS comm FROM t1; +SELECT t1.a, t2.a, t1.a+t2.a FROM t1 t2; +END; +$$ +CALL p1(); +t1.a comm +10 This is the variable t1.a value, rather than the column t1.a +10 This is the variable t1.a value, rather than the column t1.a +t1.a a t1.a+t2.a +10 10 20 +10 20 30 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# ROW fields as insert values +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec ROW(a INT, b VARCHAR(10)); +BEGIN +rec.a:= 10; +rec.b:= 'test'; +INSERT INTO t1 VALUES (rec.a, rec.b); +END; +$$ +CALL p1(); +SELECT * FROM t1; +a b +10 test +DROP TABLE t1; +DROP PROCEDURE p1; +# +# ROW fields as SP out parameters +# +CREATE PROCEDURE p1(a OUT INT, b OUT VARCHAR) +AS +BEGIN +a:= 10; +b:= 'test'; +END; +$$ +CREATE PROCEDURE p2 +AS +rec ROW(a INT, b VARCHAR(10)); +BEGIN +CALL p1(rec.a, rec.b); +SELECT rec.a, rec.b; +END; +$$ +CALL p2; +rec.a rec.b +10 test +DROP PROCEDURE p1; +DROP PROCEDURE p2; +# +# ROW fields as dynamic SQL out parameters +# +CREATE PROCEDURE p1(a OUT INT, b OUT VARCHAR) +AS +BEGIN +a:= 20; +b:= 'test-dynamic-sql'; +END; +$$ +CREATE PROCEDURE p2 +AS +rec ROW(a INT, b VARCHAR(30)); +BEGIN +EXECUTE IMMEDIATE 'CALL p1(?,?)' USING rec.a, rec.b; +SELECT rec.a, rec.b; +END; +$$ +CALL p2; +rec.a rec.b +20 test-dynamic-sql +DROP PROCEDURE p1; +DROP PROCEDURE p2; +# +# ROW fields as SELECT..INTO targets +# +CREATE PROCEDURE p1 +AS +rec ROW(a INT, b VARCHAR(10)); +BEGIN +SELECT 10,'test' INTO rec.a,rec.b; +SELECT rec.a, rec.b; +END; +$$ +CALL p1; +rec.a rec.b +10 test +DROP PROCEDURE p1; +# +# Implicit default NULL handling +# +CREATE PROCEDURE p1 +AS +rec ROW(a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,0), e TIME, f DATETIME); +BEGIN +SELECT rec.a, rec.b, rec.c, rec.d, rec.e, rec.f FROM DUAL; +END; +$$ +CALL p1(); +rec.a rec.b rec.c rec.d rec.e rec.f +NULL NULL NULL NULL NULL NULL +DROP PROCEDURE p1; +# +# NULL handling +# +CREATE PROCEDURE p1 +AS +rec1 ROW(a INT, b VARCHAR(10)):=(NULL,NULL); +rec2 ROW(a INT, b VARCHAR(10)):=rec1; +BEGIN +SELECT rec1.a, rec1.b, rec2.a, rec2.b; +rec1:= (10,20); +rec2:= rec1; +SELECT rec1.a, rec1.b, rec2.a, rec2.b; +rec1:= (NULL,20); +rec2:= rec1; +SELECT rec1.a, rec1.b, rec2.a, rec2.b; +rec1:= (10,NULL); +rec2:= rec1; +SELECT rec1.a, rec1.b, rec2.a, rec2.b; +rec1:= (NULL,NULL); +rec2:= rec1; +SELECT rec1.a, rec1.b, rec2.a, rec2.b; +END; +$$ +CALL p1; +rec1.a rec1.b rec2.a rec2.b +NULL NULL NULL NULL +rec1.a rec1.b rec2.a rec2.b +10 20 10 20 +rec1.a rec1.b rec2.a rec2.b +NULL 20 NULL 20 +rec1.a rec1.b rec2.a rec2.b +10 NULL 10 NULL +rec1.a rec1.b rec2.a rec2.b +NULL NULL NULL NULL +DROP PROCEDURE p1; +# +# Testing multiple ROW variable declarations +# This makes sure that fill_field_definitions() is called only once +# per a ROW field, so create length is not converted to internal length +# multiple times. +# +CREATE PROCEDURE p1 +AS +rec1, rec2, rec3 ROW(a VARCHAR(10) CHARACTER SET utf8); +BEGIN +CREATE TABLE t1 AS SELECT rec1.a, rec2.a, rec3.a; +END; +$$ +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "rec1.a" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "rec2.a" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "rec3.a" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# INT +# +CREATE PROCEDURE p1() AS var INT; rec ROW(var INT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(1); rec ROW(var INT(1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(2); rec ROW(var INT(2)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(3); rec ROW(var INT(3)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(4); rec ROW(var INT(4)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(5); rec ROW(var INT(5)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(6); rec ROW(var INT(6)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(7); rec ROW(var INT(7)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(8); rec ROW(var INT(8)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(9); rec ROW(var INT(9)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(10); rec ROW(var INT(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(11); rec ROW(var INT(11)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(11) DEFAULT NULL, + "rec.var" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(12); rec ROW(var INT(12)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(12) DEFAULT NULL, + "rec.var" int(12) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(13); rec ROW(var INT(13)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(13) DEFAULT NULL, + "rec.var" int(13) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(14); rec ROW(var INT(14)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(14) DEFAULT NULL, + "rec.var" int(14) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(20); rec ROW(var INT(20)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(20) DEFAULT NULL, + "rec.var" int(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var INT(21); rec ROW(var INT(21)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" int(21) DEFAULT NULL, + "rec.var" int(21) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# TINYINT +# +CREATE PROCEDURE p1() AS var TINYINT; rec ROW(var TINYINT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(4) DEFAULT NULL, + "rec.var" tinyint(4) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(1); rec ROW(var TINYINT(1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(4) DEFAULT NULL, + "rec.var" tinyint(4) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(2); rec ROW(var TINYINT(2)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(4) DEFAULT NULL, + "rec.var" tinyint(4) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(3); rec ROW(var TINYINT(3)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(4) DEFAULT NULL, + "rec.var" tinyint(4) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(4); rec ROW(var TINYINT(4)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(4) DEFAULT NULL, + "rec.var" tinyint(4) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(5); rec ROW(var TINYINT(5)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(5) DEFAULT NULL, + "rec.var" tinyint(5) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(6); rec ROW(var TINYINT(6)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(6) DEFAULT NULL, + "rec.var" tinyint(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(7); rec ROW(var TINYINT(7)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(7) DEFAULT NULL, + "rec.var" tinyint(7) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(8); rec ROW(var TINYINT(8)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(8) DEFAULT NULL, + "rec.var" tinyint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(9); rec ROW(var TINYINT(9)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(9) DEFAULT NULL, + "rec.var" tinyint(9) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(10); rec ROW(var TINYINT(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(10) DEFAULT NULL, + "rec.var" tinyint(10) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(11); rec ROW(var TINYINT(11)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(11) DEFAULT NULL, + "rec.var" tinyint(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(12); rec ROW(var TINYINT(12)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(12) DEFAULT NULL, + "rec.var" tinyint(12) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(13); rec ROW(var TINYINT(13)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(13) DEFAULT NULL, + "rec.var" tinyint(13) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(14); rec ROW(var TINYINT(14)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(14) DEFAULT NULL, + "rec.var" tinyint(14) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(20); rec ROW(var TINYINT(20)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(20) DEFAULT NULL, + "rec.var" tinyint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYINT(21); rec ROW(var TINYINT(21)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinyint(21) DEFAULT NULL, + "rec.var" tinyint(21) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# SMALLINT +# +CREATE PROCEDURE p1() AS var SMALLINT; rec ROW(var SMALLINT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(6) DEFAULT NULL, + "rec.var" smallint(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(1); rec ROW(var SMALLINT(1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(6) DEFAULT NULL, + "rec.var" smallint(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(2); rec ROW(var SMALLINT(2)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(6) DEFAULT NULL, + "rec.var" smallint(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(3); rec ROW(var SMALLINT(3)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(6) DEFAULT NULL, + "rec.var" smallint(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(4); rec ROW(var SMALLINT(4)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(6) DEFAULT NULL, + "rec.var" smallint(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(5); rec ROW(var SMALLINT(5)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(6) DEFAULT NULL, + "rec.var" smallint(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(6); rec ROW(var SMALLINT(6)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(6) DEFAULT NULL, + "rec.var" smallint(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(7); rec ROW(var SMALLINT(7)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(7) DEFAULT NULL, + "rec.var" smallint(7) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(8); rec ROW(var SMALLINT(8)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(8) DEFAULT NULL, + "rec.var" smallint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(9); rec ROW(var SMALLINT(9)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(9) DEFAULT NULL, + "rec.var" smallint(9) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(10); rec ROW(var SMALLINT(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(10) DEFAULT NULL, + "rec.var" smallint(10) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(11); rec ROW(var SMALLINT(11)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(11) DEFAULT NULL, + "rec.var" smallint(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(12); rec ROW(var SMALLINT(12)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(12) DEFAULT NULL, + "rec.var" smallint(12) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(13); rec ROW(var SMALLINT(13)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(13) DEFAULT NULL, + "rec.var" smallint(13) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(14); rec ROW(var SMALLINT(14)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(14) DEFAULT NULL, + "rec.var" smallint(14) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(20); rec ROW(var SMALLINT(20)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(20) DEFAULT NULL, + "rec.var" smallint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var SMALLINT(21); rec ROW(var SMALLINT(21)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" smallint(21) DEFAULT NULL, + "rec.var" smallint(21) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# MEDIUMINT +# +CREATE PROCEDURE p1() AS var MEDIUMINT; rec ROW(var MEDIUMINT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(9) DEFAULT NULL, + "rec.var" mediumint(9) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(1); rec ROW(var MEDIUMINT(1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(2); rec ROW(var MEDIUMINT(2)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(3); rec ROW(var MEDIUMINT(3)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(4); rec ROW(var MEDIUMINT(4)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(5); rec ROW(var MEDIUMINT(5)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(6); rec ROW(var MEDIUMINT(6)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(7); rec ROW(var MEDIUMINT(7)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(8); rec ROW(var MEDIUMINT(8)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(8) DEFAULT NULL, + "rec.var" mediumint(8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(9); rec ROW(var MEDIUMINT(9)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(9) DEFAULT NULL, + "rec.var" mediumint(9) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(10); rec ROW(var MEDIUMINT(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(10) DEFAULT NULL, + "rec.var" mediumint(10) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(11); rec ROW(var MEDIUMINT(11)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(11) DEFAULT NULL, + "rec.var" mediumint(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(12); rec ROW(var MEDIUMINT(12)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(12) DEFAULT NULL, + "rec.var" mediumint(12) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(13); rec ROW(var MEDIUMINT(13)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(13) DEFAULT NULL, + "rec.var" mediumint(13) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(14); rec ROW(var MEDIUMINT(14)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(14) DEFAULT NULL, + "rec.var" mediumint(14) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(20); rec ROW(var MEDIUMINT(20)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(20) DEFAULT NULL, + "rec.var" mediumint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMINT(21); rec ROW(var MEDIUMINT(21)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumint(21) DEFAULT NULL, + "rec.var" mediumint(21) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# BIGINT +# +CREATE PROCEDURE p1() AS var BIGINT; rec ROW(var BIGINT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(1); rec ROW(var BIGINT(1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(2); rec ROW(var BIGINT(2)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(3); rec ROW(var BIGINT(3)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(4); rec ROW(var BIGINT(4)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(5); rec ROW(var BIGINT(5)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(6); rec ROW(var BIGINT(6)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(7); rec ROW(var BIGINT(7)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(8); rec ROW(var BIGINT(8)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(9); rec ROW(var BIGINT(9)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(10); rec ROW(var BIGINT(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(11); rec ROW(var BIGINT(11)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(12); rec ROW(var BIGINT(12)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(13); rec ROW(var BIGINT(13)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(14); rec ROW(var BIGINT(14)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(20); rec ROW(var BIGINT(20)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(20) DEFAULT NULL, + "rec.var" bigint(20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BIGINT(21); rec ROW(var BIGINT(21)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" bigint(21) DEFAULT NULL, + "rec.var" bigint(21) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# DOUBLE +# +CREATE PROCEDURE p1() AS var DOUBLE; rec ROW(var DOUBLE); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double DEFAULT NULL, + "rec.var" double DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,1); rec ROW(var DOUBLE(30,1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,1) DEFAULT NULL, + "rec.var" double(30,1) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,2); rec ROW(var DOUBLE(30,2)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,2) DEFAULT NULL, + "rec.var" double(30,2) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,3); rec ROW(var DOUBLE(30,3)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,3) DEFAULT NULL, + "rec.var" double(30,3) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,4); rec ROW(var DOUBLE(30,4)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,4) DEFAULT NULL, + "rec.var" double(30,4) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,5); rec ROW(var DOUBLE(30,5)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,5) DEFAULT NULL, + "rec.var" double(30,5) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,6); rec ROW(var DOUBLE(30,6)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,6) DEFAULT NULL, + "rec.var" double(30,6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,7); rec ROW(var DOUBLE(30,7)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,7) DEFAULT NULL, + "rec.var" double(30,7) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,8); rec ROW(var DOUBLE(30,8)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,8) DEFAULT NULL, + "rec.var" double(30,8) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,9); rec ROW(var DOUBLE(30,9)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,9) DEFAULT NULL, + "rec.var" double(30,9) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,10); rec ROW(var DOUBLE(30,10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,10) DEFAULT NULL, + "rec.var" double(30,10) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,11); rec ROW(var DOUBLE(30,11)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,11) DEFAULT NULL, + "rec.var" double(30,11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,12); rec ROW(var DOUBLE(30,12)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,12) DEFAULT NULL, + "rec.var" double(30,12) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,13); rec ROW(var DOUBLE(30,13)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,13) DEFAULT NULL, + "rec.var" double(30,13) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,14); rec ROW(var DOUBLE(30,14)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,14) DEFAULT NULL, + "rec.var" double(30,14) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,20); rec ROW(var DOUBLE(30,20)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,20) DEFAULT NULL, + "rec.var" double(30,20) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DOUBLE(30,21); rec ROW(var DOUBLE(30,21)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" double(30,21) DEFAULT NULL, + "rec.var" double(30,21) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# VARCHAR +# +CREATE PROCEDURE p1() AS var CHAR; rec ROW(var CHAR); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" char(1) DEFAULT NULL, + "rec.var" char(1) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BINARY; rec ROW(var BINARY); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" binary(1) DEFAULT NULL, + "rec.var" binary(1) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var CHAR(1); rec ROW(var CHAR(1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" char(1) DEFAULT NULL, + "rec.var" char(1) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var CHAR(10); rec ROW(var CHAR(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" char(10) DEFAULT NULL, + "rec.var" char(10) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var NCHAR(10); rec ROW(var NCHAR(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "rec.var" char(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var BINARY(10); rec ROW(var BINARY(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" binary(10) DEFAULT NULL, + "rec.var" binary(10) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var VARBINARY(10); rec ROW(var VARBINARY(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" varbinary(10) DEFAULT NULL, + "rec.var" varbinary(10) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var VARCHAR(10); rec ROW(var VARCHAR(10)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" varchar(10) DEFAULT NULL, + "rec.var" varchar(10) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var VARCHAR(10) CHARACTER SET utf8; rec ROW(var VARCHAR(10) CHARACTER SET utf8); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "rec.var" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_bin; rec ROW(var VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_bin); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL, + "rec.var" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# TIME +# +CREATE PROCEDURE p1() AS var TIME; rec ROW(var TIME); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" time DEFAULT NULL, + "rec.var" time DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TIME(1); rec ROW(var TIME(1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" time(1) DEFAULT NULL, + "rec.var" time(1) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TIME(2); rec ROW(var TIME(2)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" time(2) DEFAULT NULL, + "rec.var" time(2) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TIME(3); rec ROW(var TIME(3)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" time(3) DEFAULT NULL, + "rec.var" time(3) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TIME(4); rec ROW(var TIME(4)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" time(4) DEFAULT NULL, + "rec.var" time(4) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TIME(5); rec ROW(var TIME(5)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" time(5) DEFAULT NULL, + "rec.var" time(5) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TIME(6); rec ROW(var TIME(6)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" time(6) DEFAULT NULL, + "rec.var" time(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# DATETIME +# +CREATE PROCEDURE p1() AS var DATETIME; rec ROW(var DATETIME); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" datetime DEFAULT NULL, + "rec.var" datetime DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DATETIME(1); rec ROW(var DATETIME(1)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" datetime(1) DEFAULT NULL, + "rec.var" datetime(1) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DATETIME(2); rec ROW(var DATETIME(2)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" datetime(2) DEFAULT NULL, + "rec.var" datetime(2) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DATETIME(3); rec ROW(var DATETIME(3)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" datetime(3) DEFAULT NULL, + "rec.var" datetime(3) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DATETIME(4); rec ROW(var DATETIME(4)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" datetime(4) DEFAULT NULL, + "rec.var" datetime(4) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DATETIME(5); rec ROW(var DATETIME(5)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" datetime(5) DEFAULT NULL, + "rec.var" datetime(5) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var DATETIME(6); rec ROW(var DATETIME(6)); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" datetime(6) DEFAULT NULL, + "rec.var" datetime(6) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# LOB +# +CREATE PROCEDURE p1() AS var TEXT; rec ROW(var TEXT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" text DEFAULT NULL, + "rec.var" text DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYTEXT; rec ROW(var TINYTEXT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinytext DEFAULT NULL, + "rec.var" tinytext DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMTEXT; rec ROW(var MEDIUMTEXT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumtext DEFAULT NULL, + "rec.var" mediumtext DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var LONGTEXT; rec ROW(var LONGTEXT); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" longtext DEFAULT NULL, + "rec.var" longtext DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TEXT CHARACTER SET utf8; rec ROW(var TEXT CHARACTER SET utf8); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "rec.var" text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var TINYTEXT CHARACTER SET utf8; rec ROW(var TINYTEXT CHARACTER SET utf8); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" tinytext CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "rec.var" tinytext CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var MEDIUMTEXT CHARACTER SET utf8; rec ROW(var MEDIUMTEXT CHARACTER SET utf8); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" mediumtext CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "rec.var" mediumtext CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE PROCEDURE p1() AS var LONGTEXT CHARACTER SET utf8; rec ROW(var LONGTEXT CHARACTER SET utf8); BEGIN CREATE TABLE t1 AS SELECT var,rec.var FROM DUAL;END; +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "var" longtext CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "rec.var" longtext CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# End of MDEV-10914 ROW data type for stored routine variables +# +# +# MDEV-12133 sql_mode=ORACLE: table%ROWTYPE in variable declarations +# +# +# Referring to a table in a non-existing database +# +CREATE PROCEDURE p1() +AS +rec test2.t1%ROWTYPE; +BEGIN +NULL; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test2.t1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CALL p1(); +ERROR 42S02: Table 'test2.t1' doesn't exist +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Referring to a table in the current database +# +CREATE PROCEDURE p1() +AS +rec t1%ROWTYPE; +BEGIN +CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "rec.a" int(11) DEFAULT NULL, + "rec.b" varchar(10) DEFAULT NULL, + "rec.c" double DEFAULT NULL, + "rec.d" decimal(10,0) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Referring to a table in an explicitly specified database +# +CREATE PROCEDURE p1() +AS +rec test.t1%ROWTYPE; +BEGIN +CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "rec.a" int(11) DEFAULT NULL, + "rec.b" varchar(10) DEFAULT NULL, + "rec.c" double DEFAULT NULL, + "rec.d" decimal(10,0) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Referring to a view in the current database +# +CREATE PROCEDURE p1() +AS +rec v1%ROWTYPE; +BEGIN +CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.v1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CREATE VIEW v1 AS SELECT * FROM t1; +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "rec.a" int(11) DEFAULT NULL, + "rec.b" varchar(10) DEFAULT NULL, + "rec.c" double DEFAULT NULL, + "rec.d" decimal(10,0) DEFAULT NULL +) +DROP VIEW v1; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Referring to a view in an explicitly specified database +# +CREATE PROCEDURE p1() +AS +rec test.v1%ROWTYPE; +BEGIN +CREATE TABLE t2 AS SELECT rec.a, rec.b, rec.c, rec.d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.v1' doesn't exist +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10)); +CREATE VIEW v1 AS SELECT * FROM t1; +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "rec.a" int(11) DEFAULT NULL, + "rec.b" varchar(10) DEFAULT NULL, + "rec.c" double DEFAULT NULL, + "rec.d" decimal(10,0) DEFAULT NULL +) +DROP VIEW v1; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Checking that all table%ROWTYPE fields are NULL by default +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE; +BEGIN +SELECT rec1.a, rec1.b, rec1.c, rec1.d; +END; +$$ +CALL p1(); +rec1.a rec1.b rec1.c rec1.d +NULL NULL NULL NULL +DROP TABLE t1; +DROP PROCEDURE p1; +# +# A table%ROWTYPE variable with a ROW expression as a default +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE DEFAULT ROW(10,'bbb'); +BEGIN +SELECT rec1.a, rec1.b; +END; +$$ +CALL p1(); +rec1.a rec1.b +10 bbb +DROP TABLE t1; +DROP PROCEDURE p1; +# +# A table%ROWTYPE variable with an incompatible ROW expression as a default +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE DEFAULT ROW(10,'bbb','ccc'); +BEGIN +SELECT rec1.a, rec1.b; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# A table%ROWTYPE variable with a ROW variable as a default +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 ROW(a INT, b VARCHAR(10)):= ROW(10,'bbb'); +rec2 t1%ROWTYPE DEFAULT rec1; +BEGIN +SELECT rec2.a, rec2.b; +END; +$$ +CALL p1(); +rec2.a rec2.b +10 bbb +DROP TABLE t1; +DROP PROCEDURE p1; +# +# A ROW variable using a table%ROWTYPE variable as a default +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE := ROW(10,'bbb'); +rec2 ROW(a INT, b VARCHAR(10)):= rec1; +BEGIN +SELECT rec2.a, rec2.b; +END; +$$ +CALL p1(); +rec2.a rec2.b +10 bbb +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning table%ROWTYPE variables with a different column count +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE); +CREATE TABLE t2 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE; +rec2 t2%ROWTYPE; +BEGIN +rec2:=rec1; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE; +rec2 t2%ROWTYPE; +BEGIN +rec1:=rec2; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 3 column(s) +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning compatible table%ROWTYPE variables (equal number of fields) +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TABLE t2 (x INT, y VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE; +rec2 t2%ROWTYPE; +BEGIN +rec1.a:= 10; +rec1.b:= 'bbb'; +rec2:=rec1; +SELECT rec2.x, rec2.y; +END; +$$ +CALL p1(); +rec2.x rec2.y +10 bbb +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning between incompatible table%ROWTYPE and explicit ROW variables +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE; +rec2 ROW(x INT,y INT,z INT); +BEGIN +rec2.x:= 10; +rec2.y:= 20; +rec2.z:= 30; +rec1:= rec2; +END; +$$ +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning between compatible table%ROWTYPE and explicit ROW variables +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE; +rec2 ROW(x INT,y INT); +BEGIN +rec2.x:= 10; +rec2.y:= 20; +rec1:= rec2; +SELECT rec1.a, rec1.b; +rec1.a:= 11; +rec1.b:= 21; +rec2:= rec1; +SELECT rec2.x, rec2.y; +END; +$$ +CALL p1(); +rec1.a rec1.b +10 20 +rec2.x rec2.y +11 21 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Assigning table%ROWTYPE from a ROW expression +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE; +BEGIN +rec1:= ROW(10,20); +SELECT rec1.a, rec1.b; +END; +$$ +CALL p1(); +rec1.a rec1.b +10 20 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a table%ROWTYPE variable with a wrong field count +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); +CREATE TABLE t2 (a INT, b VARCHAR(10)); +INSERT INTO t1 VALUES (10,'bb1',111.111e2, 12.31); +CREATE PROCEDURE p1() +AS +rec2 t2%ROWTYPE; +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec2; +CLOSE cur1; +END; +$$ +CALL p1(); +ERROR HY000: Incorrect number of FETCH variables +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a table%ROWTYPE variable +# +CREATE TABLE t1 (a INT, b VARCHAR(10), c DOUBLE, d DECIMAL(10,2)); +CREATE TABLE t2 LIKE t1; +INSERT INTO t1 VALUES (10,'bb1',111.111e2, 12.31); +INSERT INTO t1 VALUES (20,'bb2',222.222e2, 12.32); +INSERT INTO t1 VALUES (30,'bb3',333.333e2, 12.33); +CREATE PROCEDURE p1() +AS +rec t1%ROWTYPE; +CURSOR cur IS SELECT * FROM t1; +BEGIN +OPEN cur; +LOOP +FETCH cur INTO rec; +EXIT WHEN cur%NOTFOUND; +SELECT rec.a, rec.b, rec.c, rec.d; +INSERT INTO t2 VALUES (rec.a, rec.b, rec.c, rec.d); +END LOOP; +CLOSE cur; +END; +$$ +CALL p1(); +rec.a rec.b rec.c rec.d +10 bb1 11111.1 12.31 +rec.a rec.b rec.c rec.d +20 bb2 22222.2 12.32 +rec.a rec.b rec.c rec.d +30 bb3 33333.3 12.33 +SELECT * FROM t2; +a b c d +10 bb1 11111.1 12.31 +20 bb2 22222.2 12.32 +30 bb3 33333.3 12.33 +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a table%ROWTYPE variable with different column names +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TABLE t2 (x INT, y VARCHAR(10)); +INSERT INTO t1 VALUES (10,'bbb'); +CREATE PROCEDURE p1() +AS +rec2 t2%ROWTYPE; +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec2; +SELECT rec2.x, rec2.y; +CLOSE cur1; +END; +$$ +CALL p1(); +rec2.x rec2.y +10 bbb +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# Fetching a cursor into a table%ROWTYPE variable, with truncation +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TABLE t2 (a INT, b INT); +INSERT INTO t1 VALUES (10,'11x'); +CREATE PROCEDURE p1() +AS +rec2 t2%ROWTYPE; +CURSOR cur1 IS SELECT * FROM t1; +BEGIN +OPEN cur1; +FETCH cur1 INTO rec2; +SELECT rec2.a, rec2.b; +CLOSE cur1; +END; +$$ +CALL p1(); +rec2.a rec2.b +10 11 +Warnings: +Warning 1265 Data truncated for column 'b' at row 1 +DROP TABLE t2; +DROP TABLE t1; +DROP PROCEDURE p1; +# +# table%ROWTYPE variables are not allowed in LIMIT +# +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,2); +CREATE PROCEDURE p1() +AS +rec1 t1%ROWTYPE:=(1,2); +BEGIN +SELECT * FROM t1 LIMIT rec1.a; +END; +$$ +ERROR HY000: A variable of a non-integer based type in LIMIT clause +DROP TABLE t1; +# +# table%ROWTYPE variable fields as OUT parameters +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1(a OUT INT,b OUT VARCHAR(10)) +AS +BEGIN +a:=10; +b:='bb'; +END; +$$ +CREATE PROCEDURE p2() +AS +rec1 t1%ROWTYPE; +BEGIN +CALL p1(rec1.a, rec1.b); +SELECT rec1.a, rec1.b; +END; +$$ +CALL p2(); +rec1.a rec1.b +10 bb +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Passing the entire table%ROWTYPE variable +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1(a ROW(a INT, b VARCHAR(10))) +AS +BEGIN +SELECT a.a, a.b; +END; +$$ +CREATE PROCEDURE p2() +AS +rec1 t1%ROWTYPE:= ROW(10,'bb'); +BEGIN +CALL p1(rec1); +END; +$$ +CALL p2(); +a.a a.b +10 bb +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Passing the entire table%ROWTYPE variable as an OUT parameter +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1(a OUT ROW(a INT, b VARCHAR(10))) +AS +BEGIN +a:= ROW(10,'bb'); +END; +$$ +CREATE PROCEDURE p2() +AS +rec1 t1%ROWTYPE; +BEGIN +CALL p1(rec1); +SELECT rec1.a, rec1.b; +END; +$$ +CALL p2(); +rec1.a rec1.b +10 bb +DROP PROCEDURE p2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Assigning a table%ROWTYPE field to an OUT parameter +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1 (res IN OUT INTEGER) +AS +rec1 t1%ROWTYPE:=ROW(10,'b0'); +BEGIN +res:=rec1.a; +END; +$$ +CALL p1(@res); +SELECT @res; +@res +10 +SET @res=NULL; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing Item_splocal_row_field_by_name::print +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1 +AS +rec t1%ROWTYPE:=ROW(10,'bb'); +BEGIN +EXPLAIN EXTENDED SELECT rec.a, rec.b; +END; +$$ +CALL p1(); +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 rec.a@0["a"] AS "rec.a",rec.b@0["b"] AS "rec.b" +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Non-existing field +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1 +AS +rec t1%ROWTYPE; +BEGIN +SELECT rec.c; +END; +$$ +CALL p1(); +ERROR HY000: Row variable 'rec' does not have a field 'c' +ALTER TABLE t1 ADD c INT; +CALL p1(); +rec.c +NULL +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing that field names are case insensitive +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE PROCEDURE p1 +AS +rec t1%ROWTYPE:=ROW(10,'bb'); +BEGIN +SELECT rec.A, rec.B; +END; +$$ +CALL p1(); +rec.A rec.B +10 bb +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing that table%ROWTYPE uses temporary tables vs shadowed real tables +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +CREATE TEMPORARY TABLE t1 (x INT, y VARCHAR(10)); +CREATE PROCEDURE p1 +AS +rec t1%ROWTYPE:=ROW(10,'bb'); +BEGIN +SELECT rec.A, rec.B; +END; +$$ +CALL p1(); +ERROR HY000: Row variable 'rec' does not have a field 'A' +DROP TEMPORARY TABLE t1; +CALL p1(); +rec.A rec.B +10 bb +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Testing that the structure of table%ROWTYPE variables is determined at the very beginning and is not changed after ALTER +# +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +BEGIN +ALTER TABLE t1 ADD c INT; +DECLARE +rec t1%ROWTYPE; -- this will not have column "c" + BEGIN +rec.c:=10; +END; +END; +$$ +CALL p1(); +ERROR HY000: Row variable 'rec' does not have a field 'c' +DROP TABLE t1; +DROP PROCEDURE p1; +# +# MDEV-12291 Allow ROW variables as SELECT INTO targets +# +# ROW variable with a wrong column count +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +rec1 ROW(a INT, b VARCHAR(32), c DOUBLE); +BEGIN +SELECT * FROM t1 INTO rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +ERROR 21000: The used SELECT statements have a different number of columns +DROP TABLE t1; +DROP PROCEDURE p1; +# Multiple ROW variables +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +rec1 ROW(a INT, b VARCHAR(32)); +BEGIN +SELECT * FROM t1 INTO rec1, rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP TABLE t1; +DROP PROCEDURE p1; +# ROW variables working example +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +rec1 ROW(a INT, b VARCHAR(32)); +BEGIN +SELECT * FROM t1 INTO rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +rec1.a rec1.b +10 b10 +DROP TABLE t1; +DROP PROCEDURE p1; +# table%ROWTYPE variable with a wrong column count +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +rec1 t1%ROWTYPE; +BEGIN +SELECT 10,'a','b' FROM t1 INTO rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +ERROR 21000: The used SELECT statements have a different number of columns +DROP TABLE t1; +DROP PROCEDURE p1; +# Multiple table%ROWTYPE variables +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +rec1 t1%ROWTYPE; +BEGIN +SELECT 10,'a' FROM t1 INTO rec1, rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP TABLE t1; +DROP PROCEDURE p1; +# table%ROWTYPE working example +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +rec1 t1%ROWTYPE; +BEGIN +SELECT * FROM t1 INTO rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +rec1.a rec1.b +10 b10 +DROP TABLE t1; +DROP PROCEDURE p1; +# cursor%ROWTYPE variable with a wrong column count +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +CURSOR cur1 IS SELECT 10, 'b0', 'c0'; +rec1 cur1%ROWTYPE; +BEGIN +SELECT * FROM t1 INTO rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +ERROR 21000: The used SELECT statements have a different number of columns +DROP TABLE t1; +DROP PROCEDURE p1; +# Multiple cursor%ROWTYPE variables +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +CURSOR cur1 IS SELECT * FROM t1; +rec1 cur1%ROWTYPE; +BEGIN +SELECT * FROM t1 INTO rec1, rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +ERROR 21000: Operand should contain 2 column(s) +DROP TABLE t1; +DROP PROCEDURE p1; +# cursor%ROWTYPE working example +CREATE TABLE t1 (a INT, b VARCHAR(32)); +INSERT INTO t1 VALUES (10,'b10'); +CREATE PROCEDURE p1 AS +CURSOR cur1 IS SELECT * FROM t1; +rec1 cur1%ROWTYPE; +BEGIN +SELECT * FROM t1 INTO rec1; +SELECT rec1.a, rec1.b; +END; +$$ +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +CALL p1(); +rec1.a rec1.b +10 b10 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# MDEV-12347 Valgrind reports invalid read errors in Item_field_row::element_index_by_name +# +CREATE TABLE t1 (a INT, b ENUM('b0','b1','b12','b3')); +CREATE PROCEDURE p1 AS +BEGIN +DECLARE +rec t1%ROWTYPE; +BEGIN +rec.b:='b0'; +SELECT rec.b; +END; +END; +$$ +CALL p1(); +rec.b +b0 +DROP TABLE t1; +DROP PROCEDURE p1; +CREATE TABLE t1 (a INT, b SET('b0','b1','b12','b3')); +CREATE PROCEDURE p1 AS +BEGIN +DECLARE +rec t1%ROWTYPE; +BEGIN +rec.b:='b0'; +SELECT rec.b; +END; +END; +$$ +CALL p1(); +rec.b +b0 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# MDEV-13273 Confusion between table alias and ROW type variable +# +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (0,0); +CREATE PROCEDURE p1 +AS +a INT; +b INT; +BEGIN +-- a.c1 is a table column +SELECT a.c1 INTO b +FROM t1 a +WHERE a.c2 = 0; +SELECT b; +END; +$$ +CALL p1; +b +0 +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (0,0); +CREATE PROCEDURE p1 +AS +a ROW (c1 INT, c2 INT) := ROW(101,102); +b INT; +BEGIN +-- a.c1 is a ROW variable field +SELECT a.c1 INTO b +FROM t1 a +WHERE a.c2 = 102; +SELECT b; +END; +$$ +CALL p1; +b +101 +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (0,0); +CREATE PROCEDURE p1 +AS +a t1%ROWTYPE := ROW (10,20); +b INT; +BEGIN +-- a.c1 is a ROW variable field +SELECT a.c1 INTO b +FROM t1 a +WHERE a.c2 = 20; +SELECT b; +END; +$$ +CALL p1; +b +10 +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (c1 INT, c2 INT); +INSERT INTO t1 VALUES (0,0); +CREATE PROCEDURE p1 +AS +CURSOR cur1 IS SELECT * FROM t1; +a cur1%ROWTYPE := ROW (10,20); +b INT; +BEGIN +-- a.c1 is a ROW variable field +SELECT a.c1 INTO b +FROM t1 a +WHERE a.c2 = 20; +SELECT b; +END; +$$ +CALL p1; +b +10 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# MDEV-13527 Crash when EXPLAIN SELECT .. INTO row_sp_variable.field +# +DECLARE +a ROW(a INT); +BEGIN +EXPLAIN SELECT 1 INTO a.a; +END; +$$ +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +# +# MDEV-14139 Anchored data types for variables +# +DECLARE +row1 ROW(int11 INT,text1 TEXT); +a_row1 row1%TYPE; +aa_row1 a_row1%TYPE; +BEGIN +CREATE TABLE t1 AS SELECT a_row1.int11 AS int11, a_row1.text1 AS text1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 AS SELECT aa_row1.int11 AS int11, aa_row1.text1 AS text1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +END; +$$ +Table Create Table +t1 CREATE TABLE "t1" ( + "int11" int(11) DEFAULT NULL, + "text1" text DEFAULT NULL +) +Table Create Table +t1 CREATE TABLE "t1" ( + "int11" int(11) DEFAULT NULL, + "text1" text DEFAULT NULL +) diff --git a/mysql-test/suite/compat/oracle/r/sp-security.result b/mysql-test/suite/compat/oracle/r/sp-security.result new file mode 100644 index 00000000..db29a17a --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp-security.result @@ -0,0 +1,288 @@ +SET sql_mode=ORACLE; +# +# MDEV-10577 sql_mode=ORACLE: %TYPE in variable declarations +# +# +# Initiation: +# - creating database db1 +# - creating user user1 with access rights to db1 +# +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT, b VARCHAR(10)); +CREATE USER user1; +GRANT ALL PRIVILEGES ON test.* TO user1; +connect conn1,localhost,user1,,test; +SET sql_mode=ORACLE; +SELECT database(); +database() +test +SELECT user(); +user() +user1@localhost +# +# Making sure that user1 does not have privileges to db1.t1 +# +SHOW CREATE TABLE db1.t1; +ERROR 42000: SHOW command denied to user 'user1'@'localhost' for table `db1`.`t1` +SHOW FIELDS IN db1.t1; +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table `db1`.`t1` +# +# Trigger: using %TYPE with a table we don't have access to +# +CREATE TABLE test.t1 (a INT, b INT); +INSERT INTO test.t1 (a,b) VALUES (10,20); +SELECT * FROM t1; +a b +10 20 +CREATE TRIGGER test.tr1 BEFORE INSERT ON test.t1 FOR EACH ROW +BEGIN +DECLARE b db1.t1.b%TYPE := 20; +BEGIN +:NEW.b := 10; +END; +END +$$ +INSERT INTO t1 (a) VALUES (10); +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table `db1`.`t1` +SELECT * FROM t1; +a b +10 20 +DROP TRIGGER tr1; +DROP TABLE t1; +# +# Stored procedure: Using %TYPE for with a table that we don't have access to +# DEFINER user1, SQL SECURITY DEFAULT +# +CREATE PROCEDURE p1() +AS +a db1.t1.a%TYPE := 10; +BEGIN +SELECT a; +END; +$$ +CALL p1; +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table `db1`.`t1` +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +a db1.t1%ROWTYPE; +BEGIN +SELECT a.a; +END; +$$ +CALL p1; +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table `db1`.`t1` +DROP PROCEDURE p1; +# +# Stored procedure: Using %TYPE for with a table that we don't have access to +# DEFINER root, SQL SECURITY INVOKER +# +connection default; +CREATE PROCEDURE p1() +SQL SECURITY INVOKER +AS +a db1.t1.a%TYPE := 10; +BEGIN +SELECT a; +END; +$$ +connection conn1; +CALL p1; +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table `db1`.`t1` +DROP PROCEDURE p1; +connection default; +CREATE PROCEDURE p1() +SQL SECURITY INVOKER +AS +a db1.t1%ROWTYPE; +BEGIN +SELECT a.a; +END; +$$ +connection conn1; +CALL p1; +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table `db1`.`t1` +DROP PROCEDURE p1; +# +# Stored procedure: Using %TYPE for with a table that we don't have access to +# DEFINER root, SQL SECURITY DEFINER +# +connection default; +CREATE PROCEDURE p1() +SQL SECURITY DEFINER +AS +a db1.t1.a%TYPE := 10; +BEGIN +SELECT a; +END; +$$ +connection conn1; +CALL p1; +a +10 +DROP PROCEDURE p1; +connection default; +CREATE PROCEDURE p1() +SQL SECURITY DEFINER +AS +a db1.t1%ROWTYPE; +BEGIN +a.a:= 10; +SELECT a.a; +END; +$$ +connection conn1; +CALL p1; +a.a +10 +DROP PROCEDURE p1; +# +# Stored function: Using %TYPE for with a table that we don't have access to +# DEFINER user1, SQL SECURITY DEFAULT +# +CREATE TABLE t1 (a INT); +CREATE FUNCTION f1() RETURN INT +AS +a db1.t1.a%TYPE:=0; +BEGIN +RETURN OCTET_LENGTH(a); +END; +$$ +SELECT f1(); +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table `db1`.`t1` +DROP FUNCTION f1; +DROP TABLE t1; +# +# Stored function: Using %TYPE for with a table that we don't have access to +# DEFINER root, SQL SECURITY INVOKER +# +connection default; +CREATE TABLE t1 (a INT); +CREATE FUNCTION f1() RETURN INT +SQL SECURITY INVOKER +AS +a db1.t1.a%TYPE:=0; +BEGIN +RETURN OCTET_LENGTH(a); +END; +$$ +connection conn1; +SELECT f1(); +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table `db1`.`t1` +DROP FUNCTION f1; +DROP TABLE t1; +# +# Stored function: Using %TYPE for with a table that we don't have access to +# DEFINER root, SQL SECURITY DEFINER +# +connection default; +CREATE TABLE t1 (a INT); +CREATE FUNCTION f1() RETURN INT +SQL SECURITY DEFINER +AS +a db1.t1.a%TYPE:=0; +BEGIN +RETURN OCTET_LENGTH(a); +END; +$$ +connection conn1; +SELECT f1(); +f1() +1 +DROP FUNCTION f1; +DROP TABLE t1; +connection default; +GRANT SELECT (a) ON db1.t1 TO user1; +connection conn1; +# +# Making sure that user1 has access to db1.t1.a, but not to db1.t1.b +# +SHOW CREATE TABLE db1.t1; +ERROR 42000: SHOW command denied to user 'user1'@'localhost' for table `db1`.`t1` +SHOW FIELDS IN db1.t1; +Field Type Null Key Default Extra +a int(11) YES NULL +# +# Trigger: Per-column privileges +# +CREATE TABLE test.t1 (a INT, b INT); +INSERT INTO test.t1 (a,b) VALUES (10,20); +SELECT * FROM t1; +a b +10 20 +CREATE TRIGGER test.tr1 BEFORE INSERT ON test.t1 FOR EACH ROW +BEGIN +DECLARE a db1.t1.a%TYPE := 20; +BEGIN +:NEW.b := 10; +END; +END +$$ +INSERT INTO t1 (a) VALUES (10); +SELECT * FROM t1; +a b +10 20 +10 10 +DROP TRIGGER tr1; +CREATE TRIGGER test.tr1 BEFORE INSERT ON test.t1 FOR EACH ROW +BEGIN +DECLARE b db1.t1.b%TYPE := 20; +BEGIN +:NEW.b := 10; +END; +END +$$ +INSERT INTO t1 (a) VALUES (10); +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for column 'b' in table 't1' +SELECT * FROM t1; +a b +10 20 +10 10 +DROP TRIGGER tr1; +DROP TABLE t1; +# +# Stored procedure: Per-column privileges +# DEFINER user1, SQL SECURITY DEFAULT +# +CREATE PROCEDURE p1() +AS +a db1.t1.a%TYPE := 10; +BEGIN +SELECT a; +END; +$$ +CALL p1; +a +10 +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +b db1.t1.b%TYPE := 10; +BEGIN +SELECT b; +END; +$$ +CALL p1; +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for column 'b' in table 't1' +DROP PROCEDURE p1; +CREATE PROCEDURE p1() +AS +b db1.t1%ROWTYPE; +BEGIN +b.b:=10; +SELECT b.b; +END; +$$ +CALL p1; +ERROR 42000: SELECT command denied to user 'user1'@'localhost' for column 'b' in table 't1' +DROP PROCEDURE p1; +# +# Clean up +# +disconnect conn1; +connection default; +DROP USER user1; +DROP DATABASE db1; +# +# End of MDEV-10577 sql_mode=ORACLE: %TYPE in variable declarations +# diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result new file mode 100644 index 00000000..409ea3b8 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/sp.result @@ -0,0 +1,2577 @@ +SET sql_mode=ORACLE; +# Testing routines with no parameters +CREATE FUNCTION f1 RETURN INT +AS +BEGIN +RETURN 10; +END; +/ +SHOW CREATE FUNCTION f1; +Function f1 +sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +Create Function CREATE DEFINER="root"@"localhost" FUNCTION "f1"() RETURN int(11) +AS +BEGIN +RETURN 10; +END +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +SELECT f1(); +f1() +10 +DROP FUNCTION f1; +CREATE PROCEDURE p1 +AS +BEGIN +SET @a=10; +END; +/ +SHOW CREATE PROCEDURE p1; +Procedure p1 +sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT +Create Procedure CREATE DEFINER="root"@"localhost" PROCEDURE "p1"() +AS +BEGIN +SET @a=10; +END +character_set_client latin1 +collation_connection latin1_swedish_ci +Database Collation latin1_swedish_ci +SET @a=0; +CALL p1(); +SELECT @a; +@a +10 +DROP PROCEDURE p1; +# Testing ":=" to set the default value of a variable +CREATE FUNCTION f1 () RETURN NUMBER(10) AS +a NUMBER(10) := 10; +BEGIN +DECLARE +b NUMBER(10) DEFAULT 3; +BEGIN +RETURN a+b; +END; +END; +/ +SELECT f1(); +f1() +13 +DROP FUNCTION f1; +# Testing labels +CREATE FUNCTION f1 (a INT) RETURN CLOB AS +BEGIN +<<label1>> +BEGIN +IF a = 1 THEN +LEAVE label1; +END IF; +RETURN 'IS NOT 1'; +END label1; +RETURN 'IS 1'; +END; +/ +SELECT f1(1); +f1(1) +IS 1 +SELECT f1(2); +f1(2) +IS NOT 1 +DROP FUNCTION f1; +CREATE FUNCTION f1 (a INT) RETURN INT IS +BEGIN +<<label1>> +LOOP +IF a = 2 THEN +LEAVE label1; +END IF; +SET a= a-1; +END LOOP; +RETURN a; +END; +/ +SELECT f1(4); +f1(4) +2 +DROP FUNCTION f1; +CREATE FUNCTION f1 (a INT) RETURN INT AS +BEGIN +<<label1>> +WHILE a>0 LOOP +IF a = 2 THEN +LEAVE label1; +END IF; +SET a= a-1; +END LOOP label1; +RETURN a; +END; +/ +SELECT f1(4); +f1(4) +2 +DROP FUNCTION f1; +CREATE FUNCTION f1 (a INT) RETURN INT AS +BEGIN +<<label1>> +REPEAT +IF a = 2 THEN +LEAVE label1; +END IF; +SET a= a-1; +UNTIL a=0 END REPEAT; +RETURN a; +END; +/ +SELECT f1(4); +f1(4) +2 +DROP FUNCTION f1; +# Testing IN/OUT/INOUT +CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10)) AS +BEGIN +SET p1='p1new'; +SET p2='p2new'; +END; +/ +SET @p1='p1', @p2='p2'; +CALL p1(@p1, @p2); +SELECT @p1, @p2; +@p1 @p2 +p1 p2new +DROP PROCEDURE p1; +# Testing Oracle-style assigment +CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10)) AS +BEGIN +p1:= 'p1new'; +END; +/ +SET @p1='p1'; +CALL p1(@p1); +SELECT @p1; +@p1 +p1new +DROP PROCEDURE p1; +# Testing that NULL is a valid statement +CREATE PROCEDURE p1(a INT) AS +BEGIN +NULL; +END; +/ +DROP PROCEDURE p1; +CREATE PROCEDURE p1(a INT) AS +a INT:=10; +BEGIN +IF a=10 THEN NULL; ELSE NULL; END IF; +END; +/ +DROP PROCEDURE p1; +# Keywords that are OK for table names, but not for SP variables +CREATE TABLE function (function int); +INSERT INTO function SET function=10; +SELECT function.function FROM function; +function +10 +DROP TABLE function; +# Testing that (some) keyword_sp are allowed in Oracle-style assignments +CREATE PROCEDURE p1 (action OUT INT) AS BEGIN action:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (clob OUT INT) AS BEGIN clob:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (enum OUT INT) AS BEGIN enum:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (via OUT INT) AS BEGIN via:=10; END;/ +DROP PROCEDURE p1/ +# Testing keyword_directly_assignable +CREATE PROCEDURE p1 (ascii OUT INT) AS BEGIN ascii:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (backup OUT INT) AS BEGIN backup:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (binlog OUT INT) AS BEGIN binlog:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (byte OUT INT) AS BEGIN byte:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (cache OUT INT) AS BEGIN cache:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (checksum OUT INT) AS BEGIN checksum:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (checkpoint OUT INT) AS BEGIN checkpoint:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (column_add OUT INT) AS BEGIN column_add:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (column_check OUT INT) AS BEGIN column_check:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (column_create OUT INT) AS BEGIN column_create:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (column_delete OUT INT) AS BEGIN column_delete:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (column_get OUT INT) AS BEGIN column_get:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (deallocate OUT INT) AS BEGIN deallocate:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (examined OUT INT) AS BEGIN examined:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (execute OUT INT) AS BEGIN execute:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (flush OUT INT) AS BEGIN flush:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (format OUT INT) AS BEGIN format:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (get OUT INT) AS BEGIN get:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (help OUT INT) AS BEGIN help:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (host OUT INT) AS BEGIN host:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (install OUT INT) AS BEGIN install:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (option OUT INT) AS BEGIN option:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (options OUT INT) AS BEGIN options:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (owner OUT INT) AS BEGIN owner:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (parser OUT INT) AS BEGIN parser:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (port OUT INT) AS BEGIN port:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (prepare OUT INT) AS BEGIN prepare:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (remove OUT INT) AS BEGIN remove:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (reset OUT INT) AS BEGIN reset:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (restore OUT INT) AS BEGIN restore:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (security OUT INT) AS BEGIN security:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (server OUT INT) AS BEGIN server:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (signed OUT INT) AS BEGIN signed:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (socket OUT INT) AS BEGIN socket:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (slave OUT INT) AS BEGIN slave:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (slaves OUT INT) AS BEGIN slaves:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (soname OUT INT) AS BEGIN soname:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (start OUT INT) AS BEGIN start:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (stop OUT INT) AS BEGIN stop:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (stored OUT INT) AS BEGIN stored:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (unicode OUT INT) AS BEGIN unicode:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (uninstall OUT INT) AS BEGIN uninstall:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (upgrade OUT INT) AS BEGIN upgrade:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (wrapper OUT INT) AS BEGIN wrapper:=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (xa OUT INT) AS BEGIN xa:=10; END;/ +DROP PROCEDURE p1/ +# Testing that keyword_directly_not_assignable does not work in := +CREATE PROCEDURE p1 (commit OUT INT) AS BEGIN commit:=10; END;/ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':=10; END' at line 1 +CREATE PROCEDURE p1 (rollback OUT INT) AS BEGIN rollback:=10; END;/ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':=10; END' at line 1 +CREATE PROCEDURE p1 (shutdown OUT INT) AS BEGIN shutdown:=10; END;/ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':=10; END' at line 1 +CREATE PROCEDURE p1 (exception OUT INT) AS BEGIN exception:=10; END;/ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':=10; END' at line 1 +# Testing that keyword_directly_not_assignable works in SET statements. +CREATE PROCEDURE p1 (contains OUT INT) AS BEGIN SET contains=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (language OUT INT) AS BEGIN SET language=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (no OUT INT) AS BEGIN SET no=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (charset OUT INT) AS BEGIN SET charset=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (do OUT INT) AS BEGIN SET do=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (repair OUT INT) AS BEGIN SET repair=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (handler OUT INT) AS BEGIN SET handler=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (open OUT INT) AS BEGIN SET open=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (close OUT INT) AS BEGIN SET close=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (savepoint OUT INT) AS BEGIN SET savepoint=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (truncate OUT INT) AS BEGIN SET truncate=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (begin OUT INT) AS BEGIN SET begin=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (end OUT INT) AS BEGIN SET end=10; END;/ +DROP PROCEDURE p1/ +CREATE PROCEDURE p1 (exception OUT INT) AS BEGIN SET exception=10; END;/ +DROP PROCEDURE p1/ +# Testing that keyword_directly_not_assignable works in table/column names +CREATE TABLE contains (contains INT); +DROP TABLE contains; +CREATE TABLE language (language INT); +DROP TABLE language; +CREATE TABLE no (no INT); +DROP TABLE no; +CREATE TABLE charset (charset INT); +DROP TABLE charset; +CREATE TABLE do (do INT); +DROP TABLE do; +CREATE TABLE repair (repair INT); +DROP TABLE repair; +CREATE TABLE handler (handler INT); +DROP TABLE handler; +CREATE TABLE open (open INT); +DROP TABLE open; +CREATE TABLE close (close INT); +DROP TABLE close; +CREATE TABLE savepoint (savepoint INT); +DROP TABLE savepoint; +CREATE TABLE truncate (truncate INT); +DROP TABLE truncate; +CREATE TABLE begin (begin INT); +DROP TABLE begin; +CREATE TABLE end (end INT); +DROP TABLE end; +CREATE TABLE exception (exception INT); +DROP TABLE exception; +# Testing ELSIF +CREATE FUNCTION f1(a INT) RETURN CLOB +AS +BEGIN +IF a=1 THEN RETURN 'a is 1'; +ELSIF a=2 THEN RETURN 'a is 2'; +ELSE RETURN 'a is unknown'; +END IF; +END; +/ +SELECT f1(2) FROM DUAL; +f1(2) +a is 2 +DROP FUNCTION f1; +# Testing top-level declarations +CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10)) +AS +p2 VARCHAR(10); +BEGIN +p2:='p1new'; +p1:=p2; +END; +/ +SET @p1='p1'; +CALL p1(@p1); +SELECT @p1; +@p1 +p1new +DROP PROCEDURE p1; +CREATE FUNCTION f1 (p1 VARCHAR2(10)) RETURN VARCHAR(20) +AS +p2 VARCHAR(10); +BEGIN +p2:='new'; +RETURN CONCAT(p1, p2); +END; +/ +SET @p1='p1'; +SELECT f1(@p1); +f1(@p1) +p1new +DROP FUNCTION f1; +# Testing non-top declarations +CREATE PROCEDURE p1 (p1 OUT VARCHAR2(10)) +AS +BEGIN +DECLARE +p2 VARCHAR(10); +BEGIN +p2:='p1new'; +p1:=p2; +END; +DECLARE +t1 VARCHAR(10); +t2 VARCHAR(10); +BEGIN +END; +END; +/ +SET @p1='p1'; +CALL p1(@p1); +SELECT @p1; +@p1 +p1new +DROP PROCEDURE p1; +CREATE FUNCTION f1 (p1 VARCHAR2(10)) RETURN VARCHAR(20) +AS +BEGIN +DECLARE +p2 VARCHAR(10); +BEGIN +p2:='new'; +RETURN CONCAT(p1, p2); +END; +DECLARE +t1 VARCHAR(10); +t2 VARCHAR(10); +BEGIN +END; +END; +/ +SET @p1='p1'; +SELECT f1(@p1); +f1(@p1) +p1new +DROP FUNCTION f1; +# Testing exceptions +CREATE TABLE t1 (c1 INT); +CREATE PROCEDURE sp1 (p1 IN VARCHAR2(20), p2 OUT VARCHAR2(30)) +IS +v1 INT; +BEGIN +SELECT c1 INTO v1 FROM t1; +p2 := p1; +EXCEPTION +WHEN NOT FOUND THEN +BEGIN +p2 := 'def'; +END; +END; +/ +CALL sp1('abc', @a); +SELECT @a; +@a +def +DROP PROCEDURE sp1; +DROP TABLE t1; +CREATE PROCEDURE sp1 (v IN OUT INT, error IN INT) +IS +BEGIN +SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=error, MESSAGE_TEXT='User defined error!'; +v:= 223; +EXCEPTION +WHEN 30001 THEN +BEGIN +v:= 113; +END; +END; +/ +SET @v=10; +CALL sp1(@v, 30001); +CALL sp1(@v, 30002); +ERROR 45000: User defined error! +SELECT @v; +@v +113 +DROP PROCEDURE sp1; +CREATE PROCEDURE sp1 (v IN OUT INT, error IN INT) +IS +BEGIN +BEGIN +BEGIN +SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=error, MESSAGE_TEXT='User defined error!'; +v:= 223; +EXCEPTION +WHEN 30001 THEN +BEGIN +v:= 113; +END; +END; +END; +END; +/ +SET @v=10; +CALL sp1(@v, 30001); +SELECT @v; +@v +113 +SET @v=10; +CALL sp1(@v, 30002); +ERROR 45000: User defined error! +SELECT @v; +@v +10 +DROP PROCEDURE sp1; +# +# Testing EXIT statement +# +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +EXIT; +END; +/ +ERROR 42000: EXIT with no matching label: +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +<<lable1>> +BEGIN +<<label2>> +LOOP +EXIT label1; +END LOOP; +END; +END; +/ +ERROR 42000: EXIT with no matching label: label1 +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +LOOP +LOOP +i:= i + 1; +IF i >= 5 THEN +EXIT; +END IF; +END LOOP; +i:= i + 100; +EXIT; +END LOOP; +RETURN i; +END; +/ +SELECT f1() FROM DUAL; +f1() +105 +DROP FUNCTION f1; +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +<<label1>> +LOOP +<<label2>> +LOOP +i:= i + 1; +IF i >= 5 THEN +EXIT label2; +END IF; +END LOOP; +i:= i + 100; +EXIT; +END LOOP; +RETURN i; +END; +/ +SELECT f1() FROM DUAL; +f1() +105 +DROP FUNCTION f1; +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +<<label1>> +LOOP +<<label2>> +LOOP +i:= i + 1; +IF i >= 5 THEN +EXIT label1; +END IF; +END LOOP; +i:= i + 100; +EXIT; +END LOOP; +RETURN i; +END; +/ +SELECT f1() FROM DUAL; +f1() +5 +DROP FUNCTION f1; +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +LOOP +i:= i + 1; +EXIT WHEN i >=5; +END LOOP; +RETURN i; +END; +/ +SELECT f1() FROM DUAL; +f1() +5 +DROP FUNCTION f1; +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +<<label1>> +LOOP +<<label2>> +LOOP +i:= i + 1; +EXIT label2 WHEN i >= 5; +END LOOP; +i:= i + 100; +EXIT; +END LOOP; +RETURN i; +END; +/ +SELECT f1() FROM DUAL; +f1() +105 +DROP FUNCTION f1; +CREATE FUNCTION f1 RETURN INT +IS +i INT := 0; +BEGIN +<<label1>> +LOOP +<<label2>> +LOOP +i:= i + 1; +EXIT label1 WHEN i >= 5; +END LOOP; +i:= i + 100; +EXIT; +END LOOP; +RETURN i; +END; +/ +SELECT f1() FROM DUAL; +f1() +5 +DROP FUNCTION f1; +# Testing CURSOR declaration +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +CREATE FUNCTION f1 RETURN INT +AS +v_a INT:=10; +CURSOR c IS SELECT a FROM t1; +BEGIN +OPEN c; +FETCH c INTO v_a; +CLOSE c; +RETURN v_a; +EXCEPTION +WHEN OTHERS THEN RETURN -1; +END; +/ +SELECT f1() FROM DUAL; +f1() +1 +DROP FUNCTION f1; +DROP TABLE t1; +# Testing RETURN in procedures +CREATE PROCEDURE p1 (a IN OUT INT) +AS +BEGIN +RETURN 10; +END; +/ +ERROR 42000: RETURN is only allowed in a FUNCTION +CREATE FUNCTION f1 (a INT) RETURN INT +AS +BEGIN +RETURN; +END; +/ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '; +END' at line 4 +CREATE PROCEDURE p1 (a IN OUT INT) +AS +BEGIN +IF a < 10 THEN +BEGIN +a:= a - 1; +RETURN; +END; +END IF; +a:= a + 1; +EXCEPTION +WHEN OTHERS THEN RETURN; +END; +/ +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +11 +SET @v=9; +CALL p1(@v); +SELECT @v; +@v +8 +DROP PROCEDURE p1; +CREATE PROCEDURE p1 (a IN OUT INT) +AS +BEGIN +DROP TABLE t1_non_existent; +EXCEPTION +WHEN OTHERS THEN +BEGIN +a:= 100; +RETURN; +END; +END; +/ +SET @v=10; +CALL p1(@v); +SELECT @v; +@v +100 +DROP PROCEDURE p1; +# Testing WHILE loop +CREATE PROCEDURE p1 (a IN OUT INT) +AS +i INT:= 1; +j INT:= 3; +BEGIN +WHILE i<=j +LOOP +a:= a + i; +i:= i + 1; +END LOOP; +END; +/ +SET @v=0; +CALL p1(@v); +SELECT @v; +@v +6 +DROP PROCEDURE p1; +CREATE PROCEDURE p1 (a IN OUT INT) +AS +i INT:= 1; +j INT:= 3; +BEGIN +<<label>> +WHILE i<=j +LOOP +a:= a + i; +i:= i + 1; +END LOOP label; +END; +/ +SET @v=0; +CALL p1(@v); +SELECT @v; +@v +6 +DROP PROCEDURE p1; +# Testing the FOR loop statement +CREATE TABLE t1 (a INT); +FOR i IN 1..3 +LOOP +INSERT INTO t1 VALUES (i); +END LOOP; +/ +SELECT * FROM t1; +a +1 +2 +3 +DROP TABLE t1; +CREATE FUNCTION f1 (lower_bound INT, upper_bound INT, lim INT) RETURN INT +AS +total INT := 0; +BEGIN +FOR i IN lower_bound . . upper_bound +LOOP +NULL +END LOOP; +RETURN total; +END; +/ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '. upper_bound +LOOP +NULL +END LOOP; +RETURN total; +END' at line 5 +CREATE FUNCTION f1 (lower_bound INT, upper_bound INT, lim INT) RETURN INT +AS +total INT := 0; +BEGIN +FOR i IN lower_bound .. upper_bound +LOOP +total:= total + i; +IF i = lim THEN +EXIT; +END IF; +-- Bounds are calculated only once. +-- The below assignments have no effect on the loop condition +lower_bound:= 900; +upper_bound:= 1000; +END LOOP; +RETURN total; +END; +/ +SELECT f1(1, 3, 100) FROM DUAL; +f1(1, 3, 100) +6 +SELECT f1(1, 3, 2) FROM DUAL; +f1(1, 3, 2) +3 +DROP FUNCTION f1; +CREATE FUNCTION f1 RETURN INT +AS +total INT := 0; +BEGIN +FOR i IN 1 .. 5 +LOOP +total:= total + 1000; +FOR j IN 1 .. 5 +LOOP +total:= total + 1; +IF j = 3 THEN +EXIT; -- End the internal loop +END IF; +END LOOP; +END LOOP; +RETURN total; +END; +/ +SELECT f1() FROM DUAL; +f1() +5015 +DROP FUNCTION f1; +CREATE FUNCTION f1 (a INT, b INT) RETURN INT +AS +total INT := 0; +BEGIN +FOR i IN REVERSE 1..a +LOOP +total:= total + i; +IF i = b THEN +EXIT; +END IF; +END LOOP; +RETURN total; +END +/ +SELECT f1(3, 100) FROM DUAL; +f1(3, 100) +6 +SELECT f1(3, 2) FROM DUAL; +f1(3, 2) +5 +DROP FUNCTION f1; +# Testing labeled FOR LOOP statement +CREATE FUNCTION f1 (a INT, limita INT, b INT, limitb INT) RETURN INT +AS +total INT := 0; +BEGIN +<<la>> +FOR ia IN 1 .. a +LOOP +total:= total + 1000; +<<lb>> +FOR ib IN 1 .. b +LOOP +total:= total + 1; +EXIT lb WHEN ib = limitb; +EXIT la WHEN ia = limita; +END LOOP lb; +END LOOP la; +RETURN total; +END; +/ +SELECT f1(1, 1, 1, 1) FROM DUAL; +f1(1, 1, 1, 1) +1001 +SELECT f1(1, 2, 1, 2) FROM DUAL; +f1(1, 2, 1, 2) +1001 +SELECT f1(2, 1, 2, 1) FROM DUAL; +f1(2, 1, 2, 1) +2002 +SELECT f1(2, 1, 2, 2) FROM DUAL; +f1(2, 1, 2, 2) +1001 +SELECT f1(2, 2, 2, 2) FROM DUAL; +f1(2, 2, 2, 2) +2003 +SELECT f1(2, 3, 2, 3) FROM DUAL; +f1(2, 3, 2, 3) +2004 +DROP FUNCTION f1; +# Testing labeled ITERATE in a labeled FOR LOOP statement +CREATE FUNCTION f1 (a INT, b INT, blim INT) RETURN INT +AS +total INT := 0; +BEGIN +<<la>> +FOR ia IN 1 .. a +LOOP +total:= total + 1000; +DECLARE +ib INT:= 1; +BEGIN +WHILE ib <= b +LOOP +IF ib > blim THEN +ITERATE la; +END IF; +ib:= ib + 1; +total:= total + 1; +END LOOP; +END; +END LOOP la; +RETURN total; +END; +/ +SELECT f1(3,3,0), f1(3,3,1), f1(3,3,2), f1(3,3,3), f1(3,3,4) FROM DUAL; +f1(3,3,0) f1(3,3,1) f1(3,3,2) f1(3,3,3) f1(3,3,4) +3000 3003 3006 3009 3009 +DROP FUNCTION f1; +# Testing CONTINUE statement +CREATE FUNCTION f1(a INT) RETURN INT +AS +total INT:= 0; +BEGIN +FOR i IN 1 .. a +LOOP +IF i=5 THEN +CONTINUE; +END IF; +total:= total + 1; +END LOOP; +RETURN total; +END; +/ +SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; +f1(3) f1(4) f1(5) f1(6) +3 4 4 5 +DROP FUNCTION f1; +CREATE FUNCTION f1(a INT) RETURN INT +AS +total INT:= 0; +BEGIN +<<lj>> +FOR j IN 1 .. 2 +LOOP +FOR i IN 1 .. a +LOOP +IF i=5 THEN +CONTINUE lj; +END IF; +total:= total + 1; +END LOOP; +END LOOP; +RETURN total; +END; +/ +SELECT f1(3), f1(4), f1(5) FROM DUAL; +f1(3) f1(4) f1(5) +6 8 8 +DROP FUNCTION f1; +CREATE FUNCTION f1(a INT) RETURN INT +AS +total INT:= 0; +BEGIN +<<lj>> +FOR j IN 1 .. 2 +LOOP +FOR i IN 1 .. a +LOOP +CONTINUE lj WHEN i=5; +total:= total + 1; +END LOOP; +END LOOP; +RETURN total; +END; +/ +SELECT f1(3), f1(4), f1(5) FROM DUAL; +f1(3) f1(4) f1(5) +6 8 8 +DROP FUNCTION f1; +CREATE FUNCTION f1(a INT) RETURN INT +AS +total INT:= 0; +i INT:= 1; +BEGIN +WHILE i <= a +LOOP +i:= i + 1; +IF i=6 THEN +CONTINUE; +END IF; +total:= total + 1; +END LOOP; +RETURN total; +END; +/ +SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL; +f1(3) f1(4) f1(5) f1(6) +3 4 4 5 +DROP FUNCTION f1; +# +# Testing behaviour of unknown identifiers in EXIT and CONTINUE statements +# +CREATE PROCEDURE p1 +AS +BEGIN +LOOP +EXIT WHEN unknown_ident IS NULL; +END LOOP; +END$$ +ERROR 42000: Undeclared variable: unknown_ident +CREATE PROCEDURE p1 +AS +BEGIN +<<label>> +LOOP +EXIT label WHEN unknown_ident IS NULL; +END LOOP; +END$$ +ERROR 42000: Undeclared variable: unknown_ident +CREATE PROCEDURE p1 +AS +BEGIN +LOOP +CONTINUE WHEN unknown_ident IS NULL; +END LOOP; +END$$ +ERROR 42000: Undeclared variable: unknown_ident +CREATE PROCEDURE p1 +AS +BEGIN +<<label>> +LOOP +CONTINUE label WHEN unknown_ident IS NULL; +END LOOP; +END$$ +ERROR 42000: Undeclared variable: unknown_ident +# +# MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT +# +EXPLAIN EXTENDED SELECT sql%rowcount; +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 SQL%ROWCOUNT AS "sql%rowcount" +CREATE TABLE t1 AS SELECT SQL%ROWCOUNT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "SQL%ROWCOUNT" bigint(21) NOT NULL +) +DROP TABLE t1; +# +# UPDATE +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1 +AS +BEGIN +UPDATE t1 SET a=30; +SELECT SQL%ROWCOUNT; +END; +$$ +CALL p1(); +SQL%ROWCOUNT +0 +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (20); +CREATE PROCEDURE p1 +AS +BEGIN +UPDATE t1 SET a=30; +SELECT SQL%ROWCOUNT; +END; +$$ +CALL p1(); +SQL%ROWCOUNT +2 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# DELETE +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1 +AS +BEGIN +DELETE FROM t1; +SELECT SQL%ROWCOUNT; +END; +$$ +CALL p1(); +SQL%ROWCOUNT +0 +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (20); +CREATE PROCEDURE p1 +AS +BEGIN +DELETE FROM t1; +SELECT SQL%ROWCOUNT; +END; +$$ +CALL p1(); +SQL%ROWCOUNT +2 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# SELECT ... INTO var FROM ... - one row found +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (20); +CREATE PROCEDURE p1 +AS +va INT; +BEGIN +SELECT a INTO va FROM t1 LIMIT 1; +SELECT SQL%ROWCOUNT; +END; +$$ +CALL p1(); +SQL%ROWCOUNT +1 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# SELECT ... INTO var FROM ... - no rows found +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1 +AS +va INT; +BEGIN +SELECT a INTO va FROM t1; +SELECT SQL%ROWCOUNT; +END; +$$ +CALL p1(); +SQL%ROWCOUNT +0 +Warnings: +Warning 1329 No data - zero rows fetched, selected, or processed +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1 +AS +va INT; +BEGIN +SELECT a INTO va FROM t1; +SELECT SQL%ROWCOUNT; +EXCEPTION +WHEN NO_DATA_FOUND THEN SELECT SQL%ROWCOUNT||' (EXCEPTION)'; +END; +$$ +CALL p1(); +SQL%ROWCOUNT||' (EXCEPTION)' +0 (EXCEPTION) +DROP PROCEDURE p1; +DROP TABLE t1; +# +# SELECT ... INTO var FROM ... - multiple rows found +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (20); +CREATE PROCEDURE p1 +AS +va INT:=1; +BEGIN +SELECT a INTO va FROM t1; +SELECT SQL%ROWCOUNT; +EXCEPTION +WHEN TOO_MANY_ROWS THEN SELECT SQL%ROWCOUNT||' (EXCEPTION) va='||va; +END; +$$ +CALL p1(); +SQL%ROWCOUNT||' (EXCEPTION) va='||va +1 (EXCEPTION) va=10 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# INSERT INTO t2 SELECT ... +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (20); +CREATE PROCEDURE p1 +AS +BEGIN +INSERT INTO t2 SELECT * FROM t1; +SELECT SQL%ROWCOUNT; +END; +$$ +CALL p1(); +SQL%ROWCOUNT +2 +DROP PROCEDURE p1; +DROP TABLE t1, t2; +# +# End of MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT +# +# +# MDEV-10577 sql_mode=ORACLE: %TYPE in variable declarations +# +# +# Missing table +# +CREATE PROCEDURE p1 +AS +a t1.a%TYPE; +BEGIN +NULL; +END; +$$ +CALL p1(); +ERROR 42S02: Table 'test.t1' doesn't exist +DROP PROCEDURE p1; +# +# Missing column +# +CREATE TABLE t1 (b INT); +CREATE PROCEDURE p1 +AS +a t1.a%TYPE; +BEGIN +NULL; +END; +$$ +CALL p1(); +ERROR 42S22: Unknown column 'a' in 't1' +DROP PROCEDURE p1; +DROP TABLE t1; +# +# One %TYPE variable +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p1 +AS +a t1.a%TYPE; +BEGIN +a:= 123; +SELECT a; +END; +$$ +CALL p1(); +a +123 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Two %TYPE variables, with a truncation warning on assignment +# +CREATE TABLE t1 (a TINYINT, b INT); +CREATE PROCEDURE p1 +AS +a t1.a%TYPE; +b t1.b%TYPE; +BEGIN +a:= 200; +b:= 200; +SELECT a, b; +END; +$$ +CALL p1(); +a b +127 200 +Warnings: +Warning 1264 Out of range value for column 'a' at row 0 +DROP PROCEDURE p1; +DROP TABLE t1; +# +# %TYPE variables for fields with various attributes +# +CREATE TABLE t1 ( +id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, +a TINYINT NOT NULL, +b INT NOT NULL, +ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, +UNIQUE(a) +); +CREATE PROCEDURE p1 +AS +id t1.id%TYPE; +a t1.a%TYPE; +b t1.b%TYPE; +ts t1.ts%TYPE; +BEGIN +SELECT id, a, b, ts; +CREATE TABLE t2 AS SELECT id, a, b, ts; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +id a b ts +NULL NULL NULL NULL +Table Create Table +t2 CREATE TABLE "t2" ( + "id" int(11) DEFAULT NULL, + "a" tinyint(4) DEFAULT NULL, + "b" int(11) DEFAULT NULL, + "ts" timestamp NULL DEFAULT NULL +) +DROP PROCEDURE p1; +DROP TABLE t1; +# +# %TYPE + virtual columns +# +CREATE TABLE t1 ( +a INT NOT NULL, +b VARCHAR(32), +c INT AS (a + 10) VIRTUAL, +d VARCHAR(5) AS (left(b,5)) PERSISTENT +); +CREATE PROCEDURE p1 +AS +c t1.c%TYPE; +d t1.d%TYPE; +BEGIN +SELECT c, d; +CREATE TABLE t2 AS SELECT c, d; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +c d +NULL NULL +Table Create Table +t2 CREATE TABLE "t2" ( + "c" int(11) DEFAULT NULL, + "d" varchar(5) DEFAULT NULL +) +DROP PROCEDURE p1; +DROP TABLE t1; +# +# %TYPE + the ZEROFILL attribute +# +CREATE TABLE t1 ( +dz DECIMAL(10,3) ZEROFILL +); +CREATE PROCEDURE p1 +AS +dzr t1.dz%TYPE := 10; +dzt DECIMAL(10,3) ZEROFILL := 10; +BEGIN +SELECT dzr, dzt; +CREATE TABLE t2 AS SELECT dzr,dzt; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +dzr dzt +0000010.000 0000010.000 +Table Create Table +t2 CREATE TABLE "t2" ( + "dzr" decimal(10,3) unsigned DEFAULT NULL, + "dzt" decimal(10,3) unsigned DEFAULT NULL +) +DROP PROCEDURE p1; +DROP TABLE t1; +# +# Temporary tables shadow real tables for %TYPE purposes +# +CREATE TABLE t1 (a VARCHAR(10)); +INSERT INTO t1 VALUES ('t1'); +CREATE TEMPORARY TABLE t1 (a INT); +INSERT INTO t1 VALUES (10); +SELECT * FROM t1; +a +10 +CREATE PROCEDURE p1 +AS +a t1.a%TYPE:=11; +BEGIN +CREATE TABLE t2 AS SELECT a; +END; +$$ +# +# Should use INT(11) as %TYPE, as in the temporary table +# +CALL p1(); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" int(11) DEFAULT NULL +) +SELECT * FROM t2; +a +11 +DROP TABLE t2; +SELECT * FROM t1; +a +10 +DROP TEMPORARY TABLE t1; +SELECT * FROM t1; +a +t1 +# +# Should use VARCHAR(10) as %TYPE, as in the real table +# +CALL p1(); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" varchar(10) DEFAULT NULL +) +SELECT * FROM t2; +a +11 +DROP TABLE t2; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# t1.a%TYPE searches for "t1" in the current database +# +CREATE TABLE t1 (a VARCHAR(10)); +CREATE DATABASE test1; +CREATE TABLE test1.t1 (a INT); +CREATE PROCEDURE p1 +AS +a t1.a%TYPE:=11; +BEGIN +CREATE TABLE test.t2 AS SELECT a; +END; +$$ +# +# This interprets t1.a%TYPE as VARCHAR(10), as in test.t1.a +# +USE test; +CALL test.p1(); +SHOW CREATE TABLE test.t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" varchar(10) DEFAULT NULL +) +DROP TABLE test.t2; +# +# This interprets t1.a%TYPE as INT, as in test1.t1.a +# +USE test1; +CALL test.p1(); +SHOW CREATE TABLE test.t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" int(11) DEFAULT NULL +) +DROP TABLE test.t2; +# +# Error if there is no an active database +# +DROP DATABASE test1; +CALL test.p1(); +ERROR 3D000: No database selected +USE test; +DROP PROCEDURE p1; +DROP TABLE t1; +# +# A reference to a table in a non-existing database +# +CREATE PROCEDURE p1 +AS +a test1.t1.a%TYPE; +BEGIN +CREATE TABLE t1 AS SELECT a; +END; +$$ +CALL p1; +ERROR 42S02: Table 'test1.t1' doesn't exist +DROP PROCEDURE p1; +# +# A reference to a table in a different database +# +CREATE TABLE t1(a INT); +CREATE DATABASE test1; +CREATE TABLE test1.t1 (a VARCHAR(10)); +CREATE PROCEDURE p1 +AS +a t1.a%TYPE; +b test1.t1.a%TYPE; +BEGIN +CREATE TABLE t2 AS SELECT a,b; +END; +$$ +CALL p1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" int(11) DEFAULT NULL, + "b" varchar(10) DEFAULT NULL +) +DROP PROCEDURE p1; +DROP TABLE t2; +DROP DATABASE test1; +DROP TABLE t1; +# +# Using a table before it appears in a %TYPE declaration + multiple %TYPE declarations +# +CREATE TABLE t1 (a INT, b VARCHAR(10)); +INSERT INTO t1 (a,b) VALUES (10,'b10'); +CREATE PROCEDURE p1 +AS +BEGIN +INSERT INTO t1 (a,b) VALUES (11, 'b11'); +SELECT * FROM t1; +DECLARE +va t1.a%TYPE:= 30; +vb t1.b%TYPE:= 'b30'; +BEGIN +INSERT INTO t1 (a,b) VALUES (12,'b12'); +SELECT * FROM t1; +INSERT INTO t1 (a,b) VALUES (va, vb); +SELECT * FROM t1; +END; +DECLARE +va t1.a%TYPE:= 40; +vb t1.b%TYPE:= 'b40'; +BEGIN +INSERT INTO t1 (a,b) VALUES (va,vb); +SELECT * FROM t1; +END; +END; +$$ +CALL p1; +a b +10 b10 +11 b11 +a b +10 b10 +11 b11 +12 b12 +a b +10 b10 +11 b11 +12 b12 +30 b30 +a b +10 b10 +11 b11 +12 b12 +30 b30 +40 b40 +DROP TABLE t1; +DROP PROCEDURE p1; +# +# %TYPE variables + TABLE vs VIEW +# +CREATE TABLE t1 ( +bit6 BIT(6), +bit7 BIT(7), +bit8 BIT(8), +i1 TINYINT, +i2 SMALLINT, +i3 MEDIUMINT, +i4 INT, +i8 BIGINT, +ff FLOAT, +fd DOUBLE, +cc CHAR(10), +cv VARCHAR(10), +cvu VARCHAR(10) CHARACTER SET utf8, +t1 TINYTEXT, +t2 TEXT, +t3 MEDIUMTEXT, +t4 LONGTEXT, +enum1 ENUM('a','b','c'), +set1 SET('a','b','c'), +blob1 TINYBLOB, +blob2 BLOB, +blob3 MEDIUMBLOB, +blob4 LONGBLOB, +yy YEAR, +dd DATE, +tm0 TIME, +tm3 TIME(3), +tm6 TIME(6), +dt0 DATETIME, +dt3 DATETIME(3), +dt6 DATETIME(6), +ts0 TIMESTAMP, +ts3 TIMESTAMP(3), +ts6 TIMESTAMP(6), +dc100 DECIMAL(10,0), +dc103 DECIMAL(10,3), +dc209 DECIMAL(20,9) +); +CREATE PROCEDURE p1(command enum('create','select')) +AS +bit6 t1.bit6%TYPE := 0x30; +bit7 t1.bit7%TYPE := 0x41; +bit8 t1.bit8%TYPE := 0x7E; +i1 t1.i1%TYPE := 11; +i2 t1.i2%TYPE := 12; +i3 t1.i3%TYPE := 13; +i4 t1.i4%TYPE := 14; +i8 t1.i8%TYPE := 18; +ff t1.ff%TYPE := 21; +fd t1.fd%TYPE := 22; +cc t1.cc%TYPE := 'char'; +cv t1.cv%TYPE := 'varchar'; +cvu t1.cvu%TYPE := 'varcharu8'; +t1 t1.t1%TYPE := 'text1'; +t2 t1.t2%TYPE := 'text2'; +t3 t1.t3%TYPE := 'text3'; +t4 t1.t4%TYPE := 'text4'; +enum1 t1.enum1%TYPE := 'b'; +set1 t1.set1%TYPE := 'a,c'; +blob1 t1.blob1%TYPE := 'blob1'; +blob2 t1.blob2%TYPE := 'blob2'; +blob3 t1.blob3%TYPE := 'blob3'; +blob4 t1.blob4%TYPE := 'blob4'; +yy t1.yy%TYPE := 2001; +dd t1.dd%TYPE := '2001-01-01'; +tm0 t1.tm0%TYPE := '00:00:01'; +tm3 t1.tm3%TYPE := '00:00:03.333'; +tm6 t1.tm6%TYPE := '00:00:06.666666'; +dt0 t1.dt0%TYPE := '2001-01-01 00:00:01'; +dt3 t1.dt3%TYPE := '2001-01-03 00:00:01.333'; +dt6 t1.dt6%TYPE := '2001-01-06 00:00:01.666666'; +ts0 t1.ts0%TYPE := '2002-01-01 00:00:01'; +ts3 t1.ts3%TYPE := '2002-01-03 00:00:01.333'; +ts6 t1.ts6%TYPE := '2002-01-06 00:00:01.666666'; +dc100 t1.dc100%TYPE := 10; +dc103 t1.dc103%TYPE := 10.123; +dc209 t1.dc209%TYPE := 10.123456789; +BEGIN +CASE +WHEN command='create' THEN +CREATE TABLE t2 AS SELECT +bit6, bit7, bit8, +i1,i2,i3,i4,i8, +ff,fd, dc100, dc103, dc209, +cc,cv,cvu, +t1,t2,t3,t4, +enum1, set1, +blob1, blob2, blob3, blob4, +dd, yy, +tm0, tm3, tm6, +dt0, dt3, dt6, +ts0, ts3, ts6; +WHEN command='select' THEN +SELECT +bit6, bit7, bit8, +i1,i2,i3,i4,i8, +ff,fd, dc100, dc103, dc209, +cc,cv,cvu, +t1,t2,t3,t4, +enum1, set1, +blob1, blob2, blob3, blob4, +dd, yy, +tm0, tm3, tm6, +dt0, dt3, dt6, +ts0, ts3, ts6; +END CASE; +END; +$$ +# +# TABLE +# +CALL p1('create'); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "bit6" bit(6) DEFAULT NULL, + "bit7" bit(7) DEFAULT NULL, + "bit8" bit(8) DEFAULT NULL, + "i1" tinyint(4) DEFAULT NULL, + "i2" smallint(6) DEFAULT NULL, + "i3" mediumint(9) DEFAULT NULL, + "i4" int(11) DEFAULT NULL, + "i8" bigint(20) DEFAULT NULL, + "ff" float DEFAULT NULL, + "fd" double DEFAULT NULL, + "dc100" decimal(10,0) DEFAULT NULL, + "dc103" decimal(10,3) DEFAULT NULL, + "dc209" decimal(20,9) DEFAULT NULL, + "cc" char(10) DEFAULT NULL, + "cv" varchar(10) DEFAULT NULL, + "cvu" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "t1" tinytext DEFAULT NULL, + "t2" text DEFAULT NULL, + "t3" mediumtext DEFAULT NULL, + "t4" longtext DEFAULT NULL, + "enum1" varchar(1) DEFAULT NULL, + "set1" varchar(5) DEFAULT NULL, + "blob1" tinyblob DEFAULT NULL, + "blob2" longblob DEFAULT NULL, + "blob3" mediumblob DEFAULT NULL, + "blob4" longblob DEFAULT NULL, + "dd" datetime DEFAULT NULL, + "yy" year(4) DEFAULT NULL, + "tm0" time DEFAULT NULL, + "tm3" time(3) DEFAULT NULL, + "tm6" time(6) DEFAULT NULL, + "dt0" datetime DEFAULT NULL, + "dt3" datetime(3) DEFAULT NULL, + "dt6" datetime(6) DEFAULT NULL, + "ts0" timestamp NULL DEFAULT NULL, + "ts3" timestamp(3) NULL DEFAULT NULL, + "ts6" timestamp(6) NULL DEFAULT NULL +) +SELECT * FROM t2; +bit6 0 +bit7 A +bit8 ~ +i1 11 +i2 12 +i3 13 +i4 14 +i8 18 +ff 21 +fd 22 +dc100 10 +dc103 10.123 +dc209 10.123456789 +cc char +cv varchar +cvu varcharu8 +t1 text1 +t2 text2 +t3 text3 +t4 text4 +enum1 b +set1 a,c +blob1 blob1 +blob2 blob2 +blob3 blob3 +blob4 blob4 +dd 2001-01-01 00:00:00 +yy 2001 +tm0 00:00:01 +tm3 00:00:03.333 +tm6 00:00:06.666666 +dt0 2001-01-01 00:00:01 +dt3 2001-01-03 00:00:01.333 +dt6 2001-01-06 00:00:01.666666 +ts0 2002-01-01 00:00:01 +ts3 2002-01-03 00:00:01.333 +ts6 2002-01-06 00:00:01.666666 +DROP TABLE t2; +CALL p1('select'); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def bit6 bit6 16 6 1 Y 32 0 63 +def bit7 bit7 16 7 1 Y 32 0 63 +def bit8 bit8 16 8 1 Y 32 0 63 +def i1 i1 1 4 2 Y 32768 0 63 +def i2 i2 2 6 2 Y 32768 0 63 +def i3 i3 9 9 2 Y 32768 0 63 +def i4 i4 3 11 2 Y 32768 0 63 +def i8 i8 8 20 2 Y 32768 0 63 +def ff ff 4 12 2 Y 32768 31 63 +def fd fd 5 22 2 Y 32768 31 63 +def dc100 dc100 246 11 2 Y 32768 0 63 +def dc103 dc103 246 12 6 Y 32768 3 63 +def dc209 dc209 246 22 12 Y 32768 9 63 +def cc cc 254 10 4 Y 0 0 8 +def cv cv 253 10 7 Y 0 0 8 +def cvu cvu 253 10 9 Y 0 0 8 +def t1 t1 252 255 5 Y 16 0 8 +def t2 t2 252 65535 5 Y 16 0 8 +def t3 t3 252 16777215 5 Y 16 0 8 +def t4 t4 252 4294967295 5 Y 16 0 8 +def enum1 enum1 254 1 1 Y 256 0 8 +def set1 set1 254 5 3 Y 2048 0 8 +def blob1 blob1 252 255 5 Y 144 0 63 +def blob2 blob2 252 4294967295 5 Y 144 0 63 +def blob3 blob3 252 16777215 5 Y 144 0 63 +def blob4 blob4 252 4294967295 5 Y 144 0 63 +def dd dd 12 19 19 Y 128 0 63 +def yy yy 13 4 4 Y 32864 0 63 +def tm0 tm0 11 10 8 Y 128 0 63 +def tm3 tm3 11 14 12 Y 128 3 63 +def tm6 tm6 11 17 15 Y 128 6 63 +def dt0 dt0 12 19 19 Y 128 0 63 +def dt3 dt3 12 23 23 Y 128 3 63 +def dt6 dt6 12 26 26 Y 128 6 63 +def ts0 ts0 7 19 19 Y 160 0 63 +def ts3 ts3 7 23 23 Y 160 3 63 +def ts6 ts6 7 26 26 Y 160 6 63 +bit6 0 +bit7 A +bit8 ~ +i1 11 +i2 12 +i3 13 +i4 14 +i8 18 +ff 21 +fd 22 +dc100 10 +dc103 10.123 +dc209 10.123456789 +cc char +cv varchar +cvu varcharu8 +t1 text1 +t2 text2 +t3 text3 +t4 text4 +enum1 b +set1 a,c +blob1 blob1 +blob2 blob2 +blob3 blob3 +blob4 blob4 +dd 2001-01-01 00:00:00 +yy 2001 +tm0 00:00:01 +tm3 00:00:03.333 +tm6 00:00:06.666666 +dt0 2001-01-01 00:00:01 +dt3 2001-01-03 00:00:01.333 +dt6 2001-01-06 00:00:01.666666 +ts0 2002-01-01 00:00:01 +ts3 2002-01-03 00:00:01.333 +ts6 2002-01-06 00:00:01.666666 +# +# VIEW +# +ALTER TABLE t1 RENAME t0; +CREATE VIEW t1 AS SELECT * FROM t0; +CALL p1('create'); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "bit6" bit(6) DEFAULT NULL, + "bit7" bit(7) DEFAULT NULL, + "bit8" bit(8) DEFAULT NULL, + "i1" tinyint(4) DEFAULT NULL, + "i2" smallint(6) DEFAULT NULL, + "i3" mediumint(9) DEFAULT NULL, + "i4" int(11) DEFAULT NULL, + "i8" bigint(20) DEFAULT NULL, + "ff" float DEFAULT NULL, + "fd" double DEFAULT NULL, + "dc100" decimal(10,0) DEFAULT NULL, + "dc103" decimal(10,3) DEFAULT NULL, + "dc209" decimal(20,9) DEFAULT NULL, + "cc" char(10) DEFAULT NULL, + "cv" varchar(10) DEFAULT NULL, + "cvu" varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "t1" tinytext DEFAULT NULL, + "t2" text DEFAULT NULL, + "t3" mediumtext DEFAULT NULL, + "t4" longtext DEFAULT NULL, + "enum1" varchar(1) DEFAULT NULL, + "set1" varchar(5) DEFAULT NULL, + "blob1" tinyblob DEFAULT NULL, + "blob2" longblob DEFAULT NULL, + "blob3" mediumblob DEFAULT NULL, + "blob4" longblob DEFAULT NULL, + "dd" datetime DEFAULT NULL, + "yy" year(4) DEFAULT NULL, + "tm0" time DEFAULT NULL, + "tm3" time(3) DEFAULT NULL, + "tm6" time(6) DEFAULT NULL, + "dt0" datetime DEFAULT NULL, + "dt3" datetime(3) DEFAULT NULL, + "dt6" datetime(6) DEFAULT NULL, + "ts0" timestamp NULL DEFAULT NULL, + "ts3" timestamp(3) NULL DEFAULT NULL, + "ts6" timestamp(6) NULL DEFAULT NULL +) +SELECT * FROM t2; +bit6 0 +bit7 A +bit8 ~ +i1 11 +i2 12 +i3 13 +i4 14 +i8 18 +ff 21 +fd 22 +dc100 10 +dc103 10.123 +dc209 10.123456789 +cc char +cv varchar +cvu varcharu8 +t1 text1 +t2 text2 +t3 text3 +t4 text4 +enum1 b +set1 a,c +blob1 blob1 +blob2 blob2 +blob3 blob3 +blob4 blob4 +dd 2001-01-01 00:00:00 +yy 2001 +tm0 00:00:01 +tm3 00:00:03.333 +tm6 00:00:06.666666 +dt0 2001-01-01 00:00:01 +dt3 2001-01-03 00:00:01.333 +dt6 2001-01-06 00:00:01.666666 +ts0 2002-01-01 00:00:01 +ts3 2002-01-03 00:00:01.333 +ts6 2002-01-06 00:00:01.666666 +DROP TABLE t2; +CALL p1('select'); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def bit6 bit6 16 6 1 Y 32 0 63 +def bit7 bit7 16 7 1 Y 32 0 63 +def bit8 bit8 16 8 1 Y 32 0 63 +def i1 i1 1 4 2 Y 32768 0 63 +def i2 i2 2 6 2 Y 32768 0 63 +def i3 i3 9 9 2 Y 32768 0 63 +def i4 i4 3 11 2 Y 32768 0 63 +def i8 i8 8 20 2 Y 32768 0 63 +def ff ff 4 12 2 Y 32768 31 63 +def fd fd 5 22 2 Y 32768 31 63 +def dc100 dc100 246 11 2 Y 32768 0 63 +def dc103 dc103 246 12 6 Y 32768 3 63 +def dc209 dc209 246 22 12 Y 32768 9 63 +def cc cc 254 10 4 Y 0 0 8 +def cv cv 253 10 7 Y 0 0 8 +def cvu cvu 253 10 9 Y 0 0 8 +def t1 t1 252 255 5 Y 16 0 8 +def t2 t2 252 65535 5 Y 16 0 8 +def t3 t3 252 16777215 5 Y 16 0 8 +def t4 t4 252 4294967295 5 Y 16 0 8 +def enum1 enum1 254 1 1 Y 256 0 8 +def set1 set1 254 5 3 Y 2048 0 8 +def blob1 blob1 252 255 5 Y 144 0 63 +def blob2 blob2 252 4294967295 5 Y 144 0 63 +def blob3 blob3 252 16777215 5 Y 144 0 63 +def blob4 blob4 252 4294967295 5 Y 144 0 63 +def dd dd 12 19 19 Y 128 0 63 +def yy yy 13 4 4 Y 32864 0 63 +def tm0 tm0 11 10 8 Y 128 0 63 +def tm3 tm3 11 14 12 Y 128 3 63 +def tm6 tm6 11 17 15 Y 128 6 63 +def dt0 dt0 12 19 19 Y 128 0 63 +def dt3 dt3 12 23 23 Y 128 3 63 +def dt6 dt6 12 26 26 Y 128 6 63 +def ts0 ts0 7 19 19 Y 160 0 63 +def ts3 ts3 7 23 23 Y 160 3 63 +def ts6 ts6 7 26 26 Y 160 6 63 +bit6 0 +bit7 A +bit8 ~ +i1 11 +i2 12 +i3 13 +i4 14 +i8 18 +ff 21 +fd 22 +dc100 10 +dc103 10.123 +dc209 10.123456789 +cc char +cv varchar +cvu varcharu8 +t1 text1 +t2 text2 +t3 text3 +t4 text4 +enum1 b +set1 a,c +blob1 blob1 +blob2 blob2 +blob3 blob3 +blob4 blob4 +dd 2001-01-01 00:00:00 +yy 2001 +tm0 00:00:01 +tm3 00:00:03.333 +tm6 00:00:06.666666 +dt0 2001-01-01 00:00:01 +dt3 2001-01-03 00:00:01.333 +dt6 2001-01-06 00:00:01.666666 +ts0 2002-01-01 00:00:01 +ts3 2002-01-03 00:00:01.333 +ts6 2002-01-06 00:00:01.666666 +DROP VIEW t1; +DROP TABLE t0; +DROP PROCEDURE p1; +# +# VIEW with subqueries +# +CREATE TABLE t1 (a INT,b INT); +INSERT INTO t1 VALUES (10,1),(20,2),(30,3),(40,4); +SELECT AVG(a) FROM t1; +AVG(a) +25.0000 +CREATE VIEW v1 AS SELECT a,1 as b FROM t1 WHERE a>(SELECT AVG(a) FROM t1) AND b>(SELECT 1); +SELECT * FROM v1; +a b +30 1 +40 1 +CREATE PROCEDURE p1 +AS +a v1.a%TYPE := 10; +b v1.b%TYPE := 1; +BEGIN +SELECT a,b; +END; +$$ +CALL p1; +a b +10 1 +DROP PROCEDURE p1; +CREATE FUNCTION f1 RETURN INT +AS +a v1.a%TYPE := 10; +b v1.b%TYPE := 1; +BEGIN +RETURN a+b; +END; +$$ +SELECT f1(); +f1() +11 +DROP FUNCTION f1; +DROP VIEW v1; +DROP TABLE t1; +# +# %TYPE variables + INFORMATION_SCHEMA +# +CREATE PROCEDURE p1 +AS +tables_table_name INFORMATION_SCHEMA.TABLES.TABLE_NAME%TYPE; +tables_table_rows INFORMATION_SCHEMA.TABLES.TABLE_ROWS%TYPE; +processlist_info INFORMATION_SCHEMA.PROCESSLIST.INFO%TYPE; +processlist_info_binary INFORMATION_SCHEMA.PROCESSLIST.INFO_BINARY%TYPE; +BEGIN +CREATE TABLE t1 AS SELECT +tables_table_name, +tables_table_rows, +processlist_info, +processlist_info_binary; +END; +$$ +CALL p1(); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "tables_table_name" varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "tables_table_rows" bigint(21) unsigned DEFAULT NULL, + "processlist_info" longtext CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, + "processlist_info_binary" blob(65535) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# %TYPE + Table structure change +# Data type for both a0 and a1 is chosen in the very beginning +# +CREATE PROCEDURE p1 +AS +a0 t1.a%TYPE; +BEGIN +ALTER TABLE t1 MODIFY a VARCHAR(10); -- This does not affect a1 +DECLARE +a1 t1.a%TYPE; +BEGIN +CREATE TABLE t2 AS SELECT a0, a1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +END; +END +$$ +CREATE TABLE t1 (a INT); +CALL p1; +Table Create Table +t2 CREATE TABLE "t2" ( + "a0" int(11) DEFAULT NULL, + "a1" int(11) DEFAULT NULL +) +DROP TABLE t1; +DROP PROCEDURE p1; +# +# %TYPE in parameters +# +CREATE TABLE t1 (a VARCHAR(10)); +CREATE DATABASE test1; +CREATE TABLE test1.t1 (b SMALLINT); +CREATE PROCEDURE p1(a t1.a%TYPE, b test1.t1.b%TYPE) +AS +BEGIN +CREATE TABLE t2 AS SELECT a, b; +END; +$$ +CALL p1('test', 123); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" varchar(10) DEFAULT NULL, + "b" smallint(6) DEFAULT NULL +) +SELECT * FROM t2; +a b +test 123 +DROP TABLE t2; +DROP PROCEDURE p1; +DROP TABLE test1.t1; +DROP DATABASE test1; +DROP TABLE t1; +# +# %TYPE in a stored function variables and arguments +# +CREATE TABLE t1 (a INT); +SET sql_mode=ORACLE; +CREATE FUNCTION f1 (prm t1.a%TYPE) RETURN INT +AS +a t1.a%TYPE:= prm; +BEGIN +RETURN a; +END; +$$ +SELECT f1(20); +f1(20) +20 +DROP FUNCTION f1; +DROP TABLE t1; +# +# %TYPE in function RETURN clause is not supported yet +# +CREATE FUNCTION f1 RETURN t1.a%TYPE +AS +BEGIN +RETURN 0; +END; +$$ +ERROR HY000: Unknown data type: 't1' +# +# End of MDEV-10577 sql_mode=ORACLE: %TYPE in variable declarations +# +# +# MDEV-12089 sql_mode=ORACLE: Understand optional routine name after the END keyword +# +CREATE FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END f1; +$$ +DROP FUNCTION f1; +CREATE FUNCTION test.f1 RETURN INT AS +BEGIN +RETURN 10; +END test.f1; +$$ +DROP FUNCTION f1; +CREATE FUNCTION test.f1 RETURN INT AS +BEGIN +RETURN 10; +END test2.f1; +$$ +ERROR HY000: END identifier 'test2.f1' does not match 'test.f1' +CREATE FUNCTION test.f1 RETURN INT AS +BEGIN +RETURN 10; +END test.f2; +$$ +ERROR HY000: END identifier 'test.f2' does not match 'test.f1' +CREATE FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END test.f2; +$$ +ERROR HY000: END identifier 'test.f2' does not match 'test.f1' +CREATE FUNCTION f1 RETURN INT AS +BEGIN +RETURN 10; +END test2.f1; +$$ +ERROR HY000: END identifier 'test2.f1' does not match 'test.f1' +CREATE PROCEDURE p1 AS +BEGIN +NULL; +END p1; +$$ +DROP PROCEDURE p1; +CREATE PROCEDURE test.p1 AS +BEGIN +NULL; +END test.p1; +$$ +DROP PROCEDURE p1; +CREATE PROCEDURE test.p1 AS +BEGIN +NULL; +END test2.p1; +$$ +ERROR HY000: END identifier 'test2.p1' does not match 'test.p1' +CREATE PROCEDURE test.p1 AS +BEGIN +NULL; +END test.p2; +$$ +ERROR HY000: END identifier 'test.p2' does not match 'test.p1' +CREATE PROCEDURE p1 AS +BEGIN +NULL; +END test.p2; +$$ +ERROR HY000: END identifier 'test.p2' does not match 'test.p1' +CREATE PROCEDURE p1 AS +BEGIN +NULL; +END test2.p1; +$$ +ERROR HY000: END identifier 'test2.p1' does not match 'test.p1' +# +# MDEV-12107 sql_mode=ORACLE: Inside routines the CALL keywoard is optional +# +CREATE OR REPLACE PROCEDURE p1(a INT) AS +BEGIN +SELECT 'This is p1' AS "comment"; +END; +/ +CREATE OR REPLACE PROCEDURE p2 AS +BEGIN +SELECT 'This is p2' AS "comment"; +END; +/ +BEGIN +p1(10); +p2; +test.p1(10); +test.p2; +END; +/ +comment +This is p1 +comment +This is p2 +comment +This is p1 +comment +This is p2 +CREATE PROCEDURE p3 AS +BEGIN +p1(10); +p2; +test.p1(10); +test.p2; +END +/ +CALL p3; +comment +This is p1 +comment +This is p2 +comment +This is p1 +comment +This is p2 +DROP PROCEDURE p3; +DROP PROCEDURE p2; +DROP PROCEDURE p1; +# +# MDEV-12854 Synchronize CREATE..SELECT data type and result set metadata data type for INT functions +# +SELECT SQL%ROWCOUNT; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def SQL%ROWCOUNT 8 21 1 N 32897 0 63 +SQL%ROWCOUNT +0 +# +# MDEV-13686 EXCEPTION reserved keyword in SQL_MODE=oracle but not in Oracle itself +# +CREATE TABLE t1 (c1 int); +CREATE VIEW v1 AS SELECT c1 exception FROM t1; +SELECT exception FROM v1; +exception +DROP VIEW v1; +DROP TABLE t1; +# +# MDEV-14139 Anchored data types for variables +# +BEGIN NOT ATOMIC +DECLARE a a%TYPE; +END; +$$ +ERROR 42000: Undeclared variable: a +DECLARE +int11 INT; +dec103 DECIMAL(10,3); +flt0 FLOAT; +dbl0 DOUBLE; +enum0 ENUM('a','b'); +bit3 BIT(3); +varchar10 VARCHAR(10); +text1 TEXT; +tinytext1 TINYTEXT; +mediumtext1 MEDIUMTEXT; +longtext1 LONGTEXT; +time3 TIME(3); +datetime4 DATETIME(4); +timestamp5 TIMESTAMP(5); +date0 DATE; +a_int11 int11%TYPE; +a_dec103 dec103%TYPE; +a_flt0 flt0%TYPE; +a_dbl0 dbl0%TYPE; +a_bit3 bit3%TYPE; +a_enum0 enum0%TYPE; +a_varchar10 varchar10%TYPE; +a_text1 text1%TYPE; +a_tinytext1 tinytext1%TYPE; +a_mediumtext1 mediumtext1%TYPE; +a_longtext1 longtext1%TYPE; +a_time3 time3%TYPE; +a_datetime4 datetime4%TYPE; +a_timestamp5 timestamp5%TYPE; +a_date0 date0%TYPE; +aa_int11 a_int11%TYPE; +aa_dec103 a_dec103%TYPE; +aa_flt0 a_flt0%TYPE; +aa_dbl0 a_dbl0%TYPE; +aa_bit3 a_bit3%TYPE; +aa_enum0 a_enum0%TYPE; +aa_varchar10 a_varchar10%TYPE; +aa_text1 a_text1%TYPE; +aa_tinytext1 a_tinytext1%TYPE; +aa_mediumtext1 a_mediumtext1%TYPE; +aa_longtext1 a_longtext1%TYPE; +aa_time3 a_time3%TYPE; +aa_datetime4 a_datetime4%TYPE; +aa_timestamp5 a_timestamp5%TYPE; +aa_date0 a_date0%TYPE; +BEGIN +CREATE TABLE t1 AS +SELECT a_int11,a_dec103,a_flt0,a_dbl0,a_bit3, +a_enum0,a_varchar10, +a_text1,a_tinytext1,a_mediumtext1,a_longtext1, +a_time3,a_datetime4,a_timestamp5,a_date0; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 AS +SELECT aa_int11,aa_dec103,aa_flt0,aa_dbl0,aa_bit3, +aa_enum0,aa_varchar10, +aa_text1,aa_tinytext1,aa_mediumtext1,aa_longtext1, +aa_time3,aa_datetime4,aa_timestamp5,aa_date0; +SHOW CREATE TABLE t1; +DROP TABLE t1; +END; +$$ +Table Create Table +t1 CREATE TABLE "t1" ( + "a_int11" int(11) DEFAULT NULL, + "a_dec103" decimal(10,3) DEFAULT NULL, + "a_flt0" float DEFAULT NULL, + "a_dbl0" double DEFAULT NULL, + "a_bit3" bit(3) DEFAULT NULL, + "a_enum0" varchar(1) DEFAULT NULL, + "a_varchar10" varchar(10) DEFAULT NULL, + "a_text1" text DEFAULT NULL, + "a_tinytext1" tinytext DEFAULT NULL, + "a_mediumtext1" mediumtext DEFAULT NULL, + "a_longtext1" longtext DEFAULT NULL, + "a_time3" time(3) DEFAULT NULL, + "a_datetime4" datetime(4) DEFAULT NULL, + "a_timestamp5" timestamp(5) NULL DEFAULT NULL, + "a_date0" datetime DEFAULT NULL +) +Table Create Table +t1 CREATE TABLE "t1" ( + "aa_int11" int(11) DEFAULT NULL, + "aa_dec103" decimal(10,3) DEFAULT NULL, + "aa_flt0" float DEFAULT NULL, + "aa_dbl0" double DEFAULT NULL, + "aa_bit3" bit(3) DEFAULT NULL, + "aa_enum0" varchar(1) DEFAULT NULL, + "aa_varchar10" varchar(10) DEFAULT NULL, + "aa_text1" text DEFAULT NULL, + "aa_tinytext1" tinytext DEFAULT NULL, + "aa_mediumtext1" mediumtext DEFAULT NULL, + "aa_longtext1" longtext DEFAULT NULL, + "aa_time3" time(3) DEFAULT NULL, + "aa_datetime4" datetime(4) DEFAULT NULL, + "aa_timestamp5" timestamp(5) NULL DEFAULT NULL, + "aa_date0" datetime DEFAULT NULL +) +# +# MDEV-11160 "Incorrect column name" when "CREATE TABLE t1 AS SELECT spvar" +# +CREATE TABLE t1 (x INT); +INSERT INTO t1 VALUES (10); +CREATE VIEW v1 AS SELECT x+1 AS a,x+1 AS b FROM t1; +CREATE PROCEDURE p1 +AS +a INT := 1; +b INT := 2; +BEGIN +CREATE TABLE t2 AS SELECT a,b FROM v1; +SHOW CREATE TABLE t2; +SELECT * FROM t2; +DROP TABLE t2; +END; +$$ +CALL p1(); +Table Create Table +t2 CREATE TABLE "t2" ( + "a" int(11) DEFAULT NULL, + "b" int(11) DEFAULT NULL +) +a b +1 2 +DROP PROCEDURE p1; +DROP VIEW v1; +DROP TABLE t1; +# +# MDEV-14228 MariaDB crashes with function +# +CREATE TABLE t1 (c VARCHAR(16), KEY(c)); +INSERT INTO t1 VALUES ('foo'); +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS +v VARCHAR2(16); +BEGIN +FOR v IN (SELECT DISTINCT c FROM t1) +LOOP +IF (v = 'bar') THEN +SELECT 1 INTO @a; +END IF; +END LOOP; +RETURN 'qux'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS +v t1%ROWTYPE; +BEGIN +IF v = 'bar' THEN +NULL; +END IF; +RETURN 'qux'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +CREATE FUNCTION f1() RETURN VARCHAR(16) +IS +v ROW(a INT); +BEGIN +IF v = 'bar' THEN +NULL; +END IF; +RETURN 'qux'; +END $$ +SELECT f1(); +ERROR HY000: Illegal parameter data types row and varchar for operation '=' +DROP FUNCTION f1; +DROP TABLE t1; +DECLARE +v ROW(a INT); +BEGIN +SELECT v IN ('a','b'); +END $$ +ERROR HY000: Illegal parameter data types row and varchar for operation 'in' +DECLARE +v ROW(a INT); +BEGIN +SELECT 'a' IN (v,'b'); +END $$ +ERROR HY000: Illegal parameter data types varchar and row for operation 'in' +DECLARE +v ROW(a INT); +BEGIN +SELECT 'a' IN ('b',v); +END $$ +ERROR HY000: Illegal parameter data types varchar and row for operation 'in' +# +# MDEV-17253 Oracle compatibility: The REVERSE key word for FOR loop behaves incorrectly +# +DECLARE +totalprice DECIMAL(12,2):=NULL; +loop_start INTEGER := 1; +BEGIN +FOR idx IN REVERSE loop_start..10 LOOP +SELECT idx; +END LOOP; +END; +$$ +idx +10 +idx +9 +idx +8 +idx +7 +idx +6 +idx +5 +idx +4 +idx +3 +idx +2 +idx +1 +CREATE PROCEDURE p1 AS +loop_start INTEGER := 1; +BEGIN +FOR idx IN REVERSE 3..loop_start LOOP +SELECT idx; +END LOOP; +END; +$$ +CALL p1(); +DROP PROCEDURE p1; +CREATE PROCEDURE p1 AS +loop_start INTEGER := 1; +BEGIN +FOR idx IN REVERSE loop_start..3 LOOP +SELECT idx; +END LOOP; +END; +$$ +CALL p1(); +idx +3 +idx +2 +idx +1 +DROP PROCEDURE p1; +# +# MDEV-28588 SIGSEGV in __memmove_avx_unaligned_erms, strmake_root +# +SET sql_mode=ORACLE; +BEGIN END; +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr AFTER INSERT ON t1 FOR EACH ROW BEGIN END; +SELECT ACTION_STATEMENT FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA='test' AND TRIGGER_NAME='tr'; +ACTION_STATEMENT BEGIN END +DROP TRIGGER tr; +DROP TABLE t1; +# +# End of 10.3 tests +# +# +# MDEV-19637 Crash on an SP variable assignment to a wrong subselect +# +DECLARE +a INT; +BEGIN +SET a=(SELECT 1 FROM DUAL UNION SELECT HIGH_PRIORITY 2 FROM DUAL); +END; +$$ +ERROR 42000: Incorrect usage/placement of 'HIGH_PRIORITY' +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/compat/oracle/r/statement-expr.result b/mysql-test/suite/compat/oracle/r/statement-expr.result new file mode 100644 index 00000000..ab4dce9a --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/statement-expr.result @@ -0,0 +1,69 @@ +SET sql_mode=ORACLE; +# +# Start of 10.3 tests +# +CREATE TABLE t1 (id INT, id1 INT); +INSERT INTO t1 VALUES (1,7); +INSERT INTO t1 VALUES (1,8); +SELECT ROW(1,7) IN (SELECT id, id1 FROM t1 WHERE id1= 8); +ROW(1,7) IN (SELECT id, id1 FROM t1 WHERE id1= 8) +0 +EXECUTE IMMEDIATE 'SELECT ROW(1, 7) IN (SELECT id, id1 FROM t1 WHERE id1= 8)'; +ROW(1, 7) IN (SELECT id, id1 FROM t1 WHERE id1= 8) +0 +DROP TABLE t1; +EXECUTE IMMEDIATE 'SELECT ?' USING (1 IN (SELECT * FROM t1)); +ERROR 42000: EXECUTE..USING does not support subqueries or stored functions +EXECUTE IMMEDIATE 'SELECT ?' USING (SELECT * FROM t1); +ERROR 42000: EXECUTE..USING does not support subqueries or stored functions +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (10); +CREATE PROCEDURE p1(a INT) AS BEGIN NULL; END; +$$ +CALL p1((1) IN (SELECT * FROM t1)); +CALL p1(EXISTS (SELECT * FROM t1)); +DROP PROCEDURE p1; +DROP TABLE t1; +SIGNAL SQLSTATE '01000' SET MYSQL_ERRNO=(1 IN (SELECT * FROM t1)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(1 IN (SELECT * FROM t1))' at line 1 +SIGNAL SQLSTATE '01000' SET MYSQL_ERRNO=EXISTS (SELECT * FROM t1); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'EXISTS (SELECT * FROM t1)' at line 1 +BEGIN NOT ATOMIC +DECLARE CONTINUE HANDLER FOR SQLWARNING +RESIGNAL SET MYSQL_ERRNO=(1 IN (SELECT * FROM t1)); +SIGNAL SQLSTATE '01000'; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(1 IN (SELECT * FROM t1)); +SIGNAL SQLSTATE '01000'; +END' at line 3 +BEGIN NOT ATOMIC +DECLARE CONTINUE HANDLER FOR SQLWARNING +RESIGNAL SET MYSQL_ERRNO=EXISTS (SELECT * FROM t1); +SIGNAL SQLSTATE '01000'; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'EXISTS (SELECT * FROM t1); +SIGNAL SQLSTATE '01000'; +END' at line 3 +PREPARE stmt FROM (1 IN (SELECT * FROM t1)); +ERROR 42000: PREPARE..FROM does not support subqueries or stored functions +PREPARE stmt FROM EXISTS (SELECT * FROM t1); +ERROR 42000: PREPARE..FROM does not support subqueries or stored functions +EXECUTE IMMEDIATE (1 IN (SELECT * FROM t1)); +ERROR 42000: EXECUTE IMMEDIATE does not support subqueries or stored functions +EXECUTE IMMEDIATE EXISTS (SELECT * FROM t1); +ERROR 42000: EXECUTE IMMEDIATE does not support subqueries or stored functions +GET DIAGNOSTICS CONDITION (1 IN (SELECT * FROM t1)) @errno=MYSQL_ERRNO; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(1 IN (SELECT * FROM t1)) @errno=MYSQL_ERRNO' at line 1 +GET DIAGNOSTICS CONDITION EXISTS (SELECT * FROM t1) @errno=MYSQL_ERRNO; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'EXISTS (SELECT * FROM t1) @errno=MYSQL_ERRNO' at line 1 +PURGE BINARY LOGS BEFORE (1 IN (SELECT * FROM t1)); +ERROR 42000: PURGE..BEFORE does not support subqueries or stored functions +PURGE BINARY LOGS BEFORE EXISTS (SELECT * FROM t1); +ERROR 42000: PURGE..BEFORE does not support subqueries or stored functions +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +DO 1 IN (SELECT * FROM t1); +DO EXISTS (SELECT * FROM t1); +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/table_value_constr.result b/mysql-test/suite/compat/oracle/r/table_value_constr.result new file mode 100644 index 00000000..af071433 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/table_value_constr.result @@ -0,0 +1,2509 @@ +SET sql_mode=ORACLE; +create table t1 (a int, b int); +insert into t1 values (1,2),(4,6),(9,7), +(1,1),(2,5),(7,8); +# just VALUES +values (1,2); +1 2 +1 2 +values (1,2), (3,4), (5.6,0); +1 2 +1.0 2 +3.0 4 +5.6 0 +values ('abc', 'def'); +abc def +abc def +# UNION that uses VALUES structure(s) +select 1,2 +union +values (1,2); +1 2 +1 2 +values (1,2) +union +select 1,2; +1 2 +1 2 +select 1,2 +union +values (1,2),(3,4),(5,6),(7,8); +1 2 +1 2 +3 4 +5 6 +7 8 +select 3,7 +union +values (1,2),(3,4),(5,6); +3 7 +3 7 +1 2 +3 4 +5 6 +select 3,7,4 +union +values (1,2,5),(4,5,6); +3 7 4 +3 7 4 +1 2 5 +4 5 6 +select 1,2 +union +values (1,7),(3,6.5); +1 2 +1 2.0 +1 7.0 +3 6.5 +select 1,2 +union +values (1,2.0),(3,6); +1 2 +1 2.0 +3 6.0 +select 1.8,2 +union +values (1,2),(3,6); +1.8 2 +1.8 2 +1.0 2 +3.0 6 +values (1,2.4),(3,6) +union +select 2.8,9; +1 2.4 +1.0 2.4 +3.0 6.0 +2.8 9.0 +values (1,2),(3,4),(5,6),(7,8) +union +select 5,6; +1 2 +1 2 +3 4 +5 6 +7 8 +select 'ab','cdf' +union +values ('al','zl'),('we','q'); +ab cdf +ab cdf +al zl +we q +values ('ab', 'cdf') +union +select 'ab','cdf'; +ab cdf +ab cdf +values (1,2) +union +values (1,2),(5,6); +1 2 +1 2 +5 6 +values (1,2) +union +values (3,4),(5,6); +1 2 +1 2 +3 4 +5 6 +values (1,2) +union +values (1,2) +union values (4,5); +1 2 +1 2 +4 5 +# UNION ALL that uses VALUES structure +values (1,2),(3,4) +union all +select 5,6; +1 2 +1 2 +3 4 +5 6 +values (1,2),(3,4) +union all +select 1,2; +1 2 +1 2 +3 4 +1 2 +select 5,6 +union all +values (1,2),(3,4); +5 6 +5 6 +1 2 +3 4 +select 1,2 +union all +values (1,2),(3,4); +1 2 +1 2 +1 2 +3 4 +values (1,2) +union all +values (1,2),(5,6); +1 2 +1 2 +1 2 +5 6 +values (1,2) +union all +values (3,4),(5,6); +1 2 +1 2 +3 4 +5 6 +values (1,2) +union all +values (1,2) +union all +values (4,5); +1 2 +1 2 +1 2 +4 5 +values (1,2) +union all +values (1,2) +union values (1,2); +1 2 +1 2 +values (1,2) +union +values (1,2) +union all +values (1,2); +1 2 +1 2 +1 2 +# EXCEPT that uses VALUES structure(s) +select 1,2 +except +values (3,4),(5,6); +1 2 +1 2 +select 1,2 +except +values (1,2),(3,4); +1 2 +values (1,2),(3,4) +except +select 5,6; +1 2 +1 2 +3 4 +values (1,2),(3,4) +except +select 1,2; +1 2 +3 4 +values (1,2),(3,4) +except +values (5,6); +1 2 +1 2 +3 4 +values (1,2),(3,4) +except +values (1,2); +1 2 +3 4 +# INTERSECT that uses VALUES structure(s) +select 1,2 +intersect +values (3,4),(5,6); +1 2 +select 1,2 +intersect +values (1,2),(3,4); +1 2 +1 2 +values (1,2),(3,4) +intersect +select 5,6; +1 2 +values (1,2),(3,4) +intersect +select 1,2; +1 2 +1 2 +values (1,2),(3,4) +intersect +values (5,6); +1 2 +values (1,2),(3,4) +intersect +values (1,2); +1 2 +1 2 +# combination of different structures that uses VALUES structures : UNION + EXCEPT +values (1,2),(3,4) +except +select 1,2 +union values (1,2); +1 2 +1 2 +3 4 +values (1,2),(3,4) +except +values (1,2) +union +values (1,2); +1 2 +1 2 +3 4 +values (1,2),(3,4) +except +values (1,2) +union +values (3,4); +1 2 +3 4 +values (1,2),(3,4) +union +values (1,2) +except +values (1,2); +1 2 +3 4 +# combination of different structures that uses VALUES structures : UNION ALL + EXCEPT +values (1,2),(3,4) +except +select 1,2 +union all +values (1,2); +1 2 +1 2 +3 4 +values (1,2),(3,4) +except +values (1,2) +union all +values (1,2); +1 2 +1 2 +3 4 +values (1,2),(3,4) +except +values (1,2) +union all +values (3,4); +1 2 +3 4 +3 4 +values (1,2),(3,4) +union all +values (1,2) +except +values (1,2); +1 2 +3 4 +# combination of different structures that uses VALUES structures : UNION + INTERSECT +values (1,2),(3,4) +intersect +select 1,2 +union +values (1,2); +1 2 +1 2 +values (1,2),(3,4) +intersect +values (1,2) +union +values (1,2); +1 2 +1 2 +values (1,2),(3,4) +intersect +values (1,2) +union +values (3,4); +1 2 +1 2 +3 4 +values (1,2),(3,4) +union +values (1,2) +intersect +values (1,2); +1 2 +1 2 +# combination of different structures that uses VALUES structures : UNION ALL + INTERSECT +values (1,2),(3,4) +intersect +select 1,2 +union all +values (1,2); +1 2 +1 2 +1 2 +values (1,2),(3,4) +intersect +values (1,2) +union all +values (1,2); +1 2 +1 2 +1 2 +values (1,2),(3,4) +intersect +values (1,2) +union all +values (3,4); +1 2 +1 2 +3 4 +values (1,2),(3,4) +union all +values (1,2) +intersect +values (1,2); +1 2 +1 2 +# combination of different structures that uses VALUES structures : UNION + UNION ALL +values (1,2),(3,4) +union all +select 1,2 +union +values (1,2); +1 2 +1 2 +3 4 +values (1,2),(3,4) +union all +values (1,2) +union +values (1,2); +1 2 +1 2 +3 4 +values (1,2),(3,4) +union all +values (1,2) +union +values (3,4); +1 2 +1 2 +3 4 +values (1,2),(3,4) +union +values (1,2) +union all +values (1,2); +1 2 +1 2 +3 4 +1 2 +values (1,2) +union +values (1,2) +union all +values (1,2); +1 2 +1 2 +1 2 +# CTE that uses VALUES structure(s) : non-recursive CTE +with t2 as +( +values (1,2),(3,4) +) +select * from t2; +1 2 +1 2 +3 4 +with t2 as +( +select 1,2 +union +values (1,2) +) +select * from t2; +1 2 +1 2 +with t2 as +( +select 1,2 +union +values (1,2),(3,4) +) +select * from t2; +1 2 +1 2 +3 4 +with t2 as +( +values (1,2) +union +select 1,2 +) +select * from t2; +1 2 +1 2 +with t2 as +( +values (1,2),(3,4) +union +select 1,2 +) +select * from t2; +1 2 +1 2 +3 4 +with t2 as +( +values (5,6) +union +values (1,2),(3,4) +) +select * from t2; +5 6 +5 6 +1 2 +3 4 +with t2 as +( +values (1,2) +union +values (1,2),(3,4) +) +select * from t2; +1 2 +1 2 +3 4 +with t2 as +( +select 1,2 +union all +values (1,2),(3,4) +) +select * from t2; +1 2 +1 2 +1 2 +3 4 +with t2 as +( +values (1,2),(3,4) +union all +select 1,2 +) +select * from t2; +1 2 +1 2 +3 4 +1 2 +with t2 as +( +values (1,2) +union all +values (1,2),(3,4) +) +select * from t2; +1 2 +1 2 +1 2 +3 4 +# recursive CTE that uses VALUES structure(s) : singe VALUES structure as anchor +with recursive t2(a,b) as +( +values(1,1) +union +select t1.a, t1.b +from t1,t2 +where t1.a=t2.a +) +select * from t2; +a b +1 1 +1 2 +with recursive t2(a,b) as +( +values(1,1) +union +select t1.a+1, t1.b +from t1,t2 +where t1.a=t2.a +) +select * from t2; +a b +1 1 +2 2 +2 1 +3 5 +# recursive CTE that uses VALUES structure(s) : several VALUES structures as anchors +with recursive t2(a,b) as +( +values(1,1) +union +values (3,4) +union +select t2.a+1, t1.b +from t1,t2 +where t1.a=t2.a +) +select * from t2; +a b +1 1 +3 4 +2 2 +2 1 +3 5 +# recursive CTE that uses VALUES structure(s) : that uses UNION ALL +with recursive t2(a,b,st) as +( +values(1,1,1) +union all +select t2.a, t1.b, t2.st+1 +from t1,t2 +where t1.a=t2.a and st<3 +) +select * from t2; +a b st +1 1 1 +1 2 2 +1 1 2 +1 2 3 +1 2 3 +1 1 3 +1 1 3 +# recursive CTE that uses VALUES structure(s) : computation of factorial (first 10 elements) +with recursive fact(n,f) as +( +values(1,1) +union +select n+1,f*n from fact where n < 10 +) +select * from fact; +n f +1 1 +2 1 +3 2 +4 6 +5 24 +6 120 +7 720 +8 5040 +9 40320 +10 362880 +# Derived table that uses VALUES structure(s) : singe VALUES structure +select * from (values (1,2),(3,4)) as t2; +1 2 +1 2 +3 4 +# Derived table that uses VALUES structure(s) : UNION with VALUES structure(s) +select * from (select 1,2 union values (1,2)) as t2; +1 2 +1 2 +select * from (select 1,2 union values (1,2),(3,4)) as t2; +1 2 +1 2 +3 4 +select * from (values (1,2) union select 1,2) as t2; +1 2 +1 2 +select * from (values (1,2),(3,4) union select 1,2) as t2; +1 2 +1 2 +3 4 +select * from (values (5,6) union values (1,2),(3,4)) as t2; +5 6 +5 6 +1 2 +3 4 +select * from (values (1,2) union values (1,2),(3,4)) as t2; +1 2 +1 2 +3 4 +# Derived table that uses VALUES structure(s) : UNION ALL with VALUES structure(s) +select * from (select 1,2 union all values (1,2),(3,4)) as t2; +1 2 +1 2 +1 2 +3 4 +select * from (values (1,2),(3,4) union all select 1,2) as t2; +1 2 +1 2 +3 4 +1 2 +select * from (values (1,2) union all values (1,2),(3,4)) as t2; +1 2 +1 2 +1 2 +3 4 +# CREATE VIEW that uses VALUES structure(s) : singe VALUES structure +create view v1 as values (1,2),(3,4); +select * from v1; +1 2 +1 2 +3 4 +drop view v1; +# CREATE VIEW that uses VALUES structure(s) : UNION with VALUES structure(s) +create view v1 as +select 1,2 +union +values (1,2); +select * from v1; +1 2 +1 2 +drop view v1; +create view v1 as +select 1,2 +union +values (1,2),(3,4); +select * from v1; +1 2 +1 2 +3 4 +drop view v1; +create view v1 as +values (1,2) +union +select 1,2; +select * from v1; +1 2 +1 2 +drop view v1; +create view v1 as +values (1,2),(3,4) +union +select 1,2; +select * from v1; +1 2 +1 2 +3 4 +drop view v1; +create view v1 as +values (5,6) +union +values (1,2),(3,4); +select * from v1; +5 6 +5 6 +1 2 +3 4 +drop view v1; +# CREATE VIEW that uses VALUES structure(s) : UNION ALL with VALUES structure(s) +create view v1 as +values (1,2) +union +values (1,2),(3,4); +select * from v1; +1 2 +1 2 +3 4 +drop view v1; +create view v1 as +select 1,2 +union all +values (1,2),(3,4); +select * from v1; +1 2 +1 2 +1 2 +3 4 +drop view v1; +create view v1 as +values (1,2),(3,4) +union all +select 1,2; +select * from v1; +1 2 +1 2 +3 4 +1 2 +drop view v1; +create view v1 as +values (1,2) +union all +values (1,2),(3,4); +select * from v1; +1 2 +1 2 +1 2 +3 4 +drop view v1; +# IN-subquery with VALUES structure(s) : simple case +select * from t1 +where a in (values (1)); +a b +1 2 +1 1 +select * from t1 +where a in (select * from (values (1)) as tvc_0); +a b +1 2 +1 1 +explain extended select * from t1 +where a in (values (1)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00 +3 MATERIALIZED <derived2> ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" semi join ((values (1)) "tvc_0") where 1 +explain extended select * from t1 +where a in (select * from (values (1)) as tvc_0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00 +2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" semi join ((values (1)) "tvc_0") where 1 +# IN-subquery with VALUES structure(s) : UNION with VALUES on the first place +select * from t1 +where a in (values (1) union select 2); +a b +1 2 +1 1 +2 5 +select * from t1 +where a in (select * from (values (1)) as tvc_0 union +select 2); +a b +1 2 +1 1 +2 5 +explain extended select * from t1 +where a in (values (1) union select 2); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +4 DEPENDENT SUBQUERY <derived2> ref key0 key0 4 func 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union4,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1" union /* select#3 */ select 2 having <cache>("test"."t1"."a") = <ref_null_helper>(2)))) +explain extended select * from t1 +where a in (select * from (values (1)) as tvc_0 union +select 2); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY <derived3> ref key0 key0 4 func 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1" union /* select#4 */ select 2 having <cache>("test"."t1"."a") = <ref_null_helper>(2)))) +# IN-subquery with VALUES structure(s) : UNION with VALUES on the second place +select * from t1 +where a in (select 2 union values (1)); +a b +1 2 +1 1 +2 5 +select * from t1 +where a in (select 2 union +select * from (values (1)) tvc_0); +a b +1 2 +1 1 +2 5 +explain extended select * from t1 +where a in (select 2 union values (1)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION <derived3> ref key0 key0 4 func 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select 2 having <cache>("test"."t1"."a") = <ref_null_helper>(2) union /* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1"))) +explain extended select * from t1 +where a in (select 2 union +select * from (values (1)) tvc_0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION <derived4> ref key0 key0 4 func 2 100.00 +4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select 2 having <cache>("test"."t1"."a") = <ref_null_helper>(2) union /* select#3 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1"))) +# IN-subquery with VALUES structure(s) : UNION ALL +select * from t1 +where a in (values (1) union all select b from t1); +a b +1 2 +1 1 +2 5 +7 8 +select * from t1 +where a in (select * from (values (1)) as tvc_0 union all +select b from t1); +a b +1 2 +1 1 +2 5 +7 8 +explain extended select * from t1 +where a in (values (1) union all select b from t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +4 DEPENDENT SUBQUERY <derived2> ref key0 key0 4 func 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 6 100.00 Using where +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1" union all /* select#3 */ select "test"."t1"."b" from "test"."t1" where <cache>("test"."t1"."a") = "test"."t1"."b"))) +explain extended select * from t1 +where a in (select * from (values (1)) as tvc_0 union all +select b from t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY <derived3> ref key0 key0 4 func 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 6 100.00 Using where +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1" union all /* select#4 */ select "test"."t1"."b" from "test"."t1" where <cache>("test"."t1"."a") = "test"."t1"."b"))) +# NOT IN subquery with VALUES structure(s) : simple case +select * from t1 +where a not in (values (1),(2)); +a b +4 6 +9 7 +7 8 +select * from t1 +where a not in (select * from (values (1),(2)) as tvc_0); +a b +4 6 +9 7 +7 8 +explain extended select * from t1 +where a not in (values (1),(2)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +3 MATERIALIZED <derived2> ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a","test"."t1"."a" in ( <materialize> (/* select#3 */ select "tvc_0"."1" from (values (1),(2)) "tvc_0" ), <primary_index_lookup>("test"."t1"."a" in <temporary table> on distinct_key where "test"."t1"."a" = "<subquery3>"."1")))) +explain extended select * from t1 +where a not in (select * from (values (1),(2)) as tvc_0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a","test"."t1"."a" in ( <materialize> (/* select#2 */ select "tvc_0"."1" from (values (1),(2)) "tvc_0" ), <primary_index_lookup>("test"."t1"."a" in <temporary table> on distinct_key where "test"."t1"."a" = "<subquery2>"."1")))) +# NOT IN subquery with VALUES structure(s) : UNION with VALUES on the first place +select * from t1 +where a not in (values (1) union select 2); +a b +4 6 +9 7 +7 8 +select * from t1 +where a not in (select * from (values (1)) as tvc_0 union +select 2); +a b +4 6 +9 7 +7 8 +explain extended select * from t1 +where a not in (values (1) union select 2); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +4 DEPENDENT SUBQUERY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union4,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where trigcond(<cache>("test"."t1"."a") = "tvc_0"."1") union /* select#3 */ select 2 having trigcond(<cache>("test"."t1"."a") = <ref_null_helper>(2))))) +explain extended select * from t1 +where a not in (select * from (values (1)) as tvc_0 union +select 2); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 100.00 Using where +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select "tvc_0"."1" from (values (1)) "tvc_0" where trigcond(<cache>("test"."t1"."a") = "tvc_0"."1") union /* select#4 */ select 2 having trigcond(<cache>("test"."t1"."a") = <ref_null_helper>(2))))) +# NOT IN subquery with VALUES structure(s) : UNION with VALUES on the second place +select * from t1 +where a not in (select 2 union values (1)); +a b +4 6 +9 7 +7 8 +select * from t1 +where a not in (select 2 union +select * from (values (1)) as tvc_0); +a b +4 6 +9 7 +7 8 +explain extended select * from t1 +where a not in (select 2 union values (1)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION <derived3> ALL NULL NULL NULL NULL 2 100.00 Using where +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select 2 having trigcond(<cache>("test"."t1"."a") = <ref_null_helper>(2)) union /* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where trigcond(<cache>("test"."t1"."a") = "tvc_0"."1")))) +explain extended select * from t1 +where a not in (select 2 union +select * from (values (1)) as tvc_0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION <derived4> ALL NULL NULL NULL NULL 2 100.00 Using where +4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where !<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select 2 having trigcond(<cache>("test"."t1"."a") = <ref_null_helper>(2)) union /* select#3 */ select "tvc_0"."1" from (values (1)) "tvc_0" where trigcond(<cache>("test"."t1"."a") = "tvc_0"."1")))) +# ANY-subquery with VALUES structure(s) : simple case +select * from t1 +where a = any (values (1),(2)); +a b +1 2 +1 1 +2 5 +select * from t1 +where a = any (select * from (values (1),(2)) as tvc_0); +a b +1 2 +1 1 +2 5 +explain extended select * from t1 +where a = any (values (1),(2)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00 +3 MATERIALIZED <derived2> ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" semi join ((values (1),(2)) "tvc_0") where 1 +explain extended select * from t1 +where a = any (select * from (values (1),(2)) as tvc_0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00 +2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" semi join ((values (1),(2)) "tvc_0") where 1 +# ANY-subquery with VALUES structure(s) : UNION with VALUES on the first place +select * from t1 +where a = any (values (1) union select 2); +a b +1 2 +1 1 +2 5 +select * from t1 +where a = any (select * from (values (1)) as tvc_0 union +select 2); +a b +1 2 +1 1 +2 5 +explain extended select * from t1 +where a = any (values (1) union select 2); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +4 DEPENDENT SUBQUERY <derived2> ref key0 key0 4 func 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union4,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1" union /* select#3 */ select 2 having <cache>("test"."t1"."a") = <ref_null_helper>(2)))) +explain extended select * from t1 +where a = any (select * from (values (1)) as tvc_0 union +select 2); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY <derived3> ref key0 key0 4 func 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1" union /* select#4 */ select 2 having <cache>("test"."t1"."a") = <ref_null_helper>(2)))) +# ANY-subquery with VALUES structure(s) : UNION with VALUES on the second place +select * from t1 +where a = any (select 2 union values (1)); +a b +1 2 +1 1 +2 5 +select * from t1 +where a = any (select 2 union +select * from (values (1)) as tvc_0); +a b +1 2 +1 1 +2 5 +explain extended select * from t1 +where a = any (select 2 union values (1)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION <derived3> ref key0 key0 4 func 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select 2 having <cache>("test"."t1"."a") = <ref_null_helper>(2) union /* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1"))) +explain extended select * from t1 +where a = any (select 2 union +select * from (values (1)) as tvc_0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION <derived4> ref key0 key0 4 func 2 100.00 +4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select 2 having <cache>("test"."t1"."a") = <ref_null_helper>(2) union /* select#3 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1"))) +# ALL-subquery with VALUES structure(s) : simple case +select * from t1 +where a = all (values (1)); +a b +1 2 +1 1 +select * from t1 +where a = all (select * from (values (1)) as tvc_0); +a b +1 2 +1 1 +explain extended select * from t1 +where a = all (values (1)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +3 DEPENDENT SUBQUERY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <not>(<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#3 */ select "tvc_0"."1" from (values (1)) "tvc_0" where trigcond(<cache>("test"."t1"."a") <> "tvc_0"."1"))))) +explain extended select * from t1 +where a = all (select * from (values (1)) as tvc_0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 100.00 Using where +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <not>(<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select "tvc_0"."1" from (values (1)) "tvc_0" where trigcond(<cache>("test"."t1"."a") <> "tvc_0"."1"))))) +# ALL-subquery with VALUES structure(s) : UNION with VALUES on the first place +select * from t1 +where a = all (values (1) union select 1); +a b +1 2 +1 1 +select * from t1 +where a = all (select * from (values (1)) as tvc_0 union +select 1); +a b +1 2 +1 1 +explain extended select * from t1 +where a = all (values (1) union select 1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +4 DEPENDENT SUBQUERY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union4,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <not>(<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where trigcond(<cache>("test"."t1"."a") <> "tvc_0"."1") union /* select#3 */ select 1 having trigcond(<cache>("test"."t1"."a") <> <ref_null_helper>(1)))))) +explain extended select * from t1 +where a = all (select * from (values (1)) as tvc_0 union +select 1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 100.00 Using where +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <not>(<expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select "tvc_0"."1" from (values (1)) "tvc_0" where trigcond(<cache>("test"."t1"."a") <> "tvc_0"."1") union /* select#4 */ select 1 having trigcond(<cache>("test"."t1"."a") <> <ref_null_helper>(1)))))) +# ALL-subquery with VALUES structure(s) : UNION with VALUES on the second place +select * from t1 +where a = any (select 1 union values (1)); +a b +1 2 +1 1 +select * from t1 +where a = any (select 1 union +select * from (values (1)) as tvc_0); +a b +1 2 +1 1 +explain extended select * from t1 +where a = any (select 1 union values (1)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 DEPENDENT UNION <derived3> ref key0 key0 4 func 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select 1 having <cache>("test"."t1"."a") = <ref_null_helper>(1) union /* select#4 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1"))) +explain extended select * from t1 +where a = any (select 1 union +select * from (values (1)) as tvc_0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION <derived4> ref key0 key0 4 func 2 100.00 +4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1" where <expr_cache><"test"."t1"."a">(<in_optimizer>("test"."t1"."a",<exists>(/* select#2 */ select 1 having <cache>("test"."t1"."a") = <ref_null_helper>(1) union /* select#3 */ select "tvc_0"."1" from (values (1)) "tvc_0" where <cache>("test"."t1"."a") = "tvc_0"."1"))) +# prepare statement that uses VALUES structure(s): single VALUES structure +prepare stmt1 from ' +values (1,2); +'; +execute stmt1; +1 2 +1 2 +execute stmt1; +1 2 +1 2 +deallocate prepare stmt1; +# prepare statement that uses VALUES structure(s): UNION with VALUES structure(s) +prepare stmt1 from ' + select 1,2 + union + values (1,2),(3,4); +'; +execute stmt1; +1 2 +1 2 +3 4 +execute stmt1; +1 2 +1 2 +3 4 +deallocate prepare stmt1; +prepare stmt1 from ' + values (1,2),(3,4) + union + select 1,2; +'; +execute stmt1; +1 2 +1 2 +3 4 +execute stmt1; +1 2 +1 2 +3 4 +deallocate prepare stmt1; +prepare stmt1 from ' + select 1,2 + union + values (3,4) + union + values (1,2); +'; +execute stmt1; +1 2 +1 2 +3 4 +execute stmt1; +1 2 +1 2 +3 4 +deallocate prepare stmt1; +prepare stmt1 from ' + values (5,6) + union + values (1,2),(3,4); +'; +execute stmt1; +5 6 +5 6 +1 2 +3 4 +execute stmt1; +5 6 +5 6 +1 2 +3 4 +deallocate prepare stmt1; +# prepare statement that uses VALUES structure(s): UNION ALL with VALUES structure(s) +prepare stmt1 from ' + select 1,2 + union + values (1,2),(3,4); +'; +execute stmt1; +1 2 +1 2 +3 4 +execute stmt1; +1 2 +1 2 +3 4 +deallocate prepare stmt1; +prepare stmt1 from ' + values (1,2),(3,4) + union all + select 1,2; +'; +execute stmt1; +1 2 +1 2 +3 4 +1 2 +execute stmt1; +1 2 +1 2 +3 4 +1 2 +deallocate prepare stmt1; +prepare stmt1 from ' + select 1,2 + union all + values (3,4) + union all + values (1,2); +'; +execute stmt1; +1 2 +1 2 +3 4 +1 2 +execute stmt1; +1 2 +1 2 +3 4 +1 2 +deallocate prepare stmt1; +prepare stmt1 from ' + values (1,2) + union all + values (1,2),(3,4); +'; +execute stmt1; +1 2 +1 2 +1 2 +3 4 +execute stmt1; +1 2 +1 2 +1 2 +3 4 +deallocate prepare stmt1; +# explain query that uses VALUES structure(s): single VALUES structure +explain +values (1,2); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +explain format=json +values (1,2); +EXPLAIN +{ + "query_block": { + "union_result": { + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +# explain query that uses VALUES structure(s): UNION with VALUES structure(s) +explain +select 1,2 +union +values (1,2),(3,4); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +explain +values (1,2),(3,4) +union +select 1,2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +explain +values (5,6) +union +values (1,2),(3,4); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +explain format=json +select 1,2 +union +values (1,2),(3,4); +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +explain format=json +values (1,2),(3,4) +union +select 1,2; +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +explain format=json +values (5,6) +union +values (1,2),(3,4); +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +explain +select 1,2 +union +values (3,4) +union +values (1,2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2,3> ALL NULL NULL NULL NULL NULL +explain format=json +select 1,2 +union +values (3,4) +union +values (1,2); +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2,3>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +# explain query that uses VALUES structure(s): UNION ALL with VALUES structure(s) +explain +select 1,2 +union +values (1,2),(3,4); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL +explain +values (1,2),(3,4) +union all +select 1,2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +explain +values (1,2) +union all +values (1,2),(3,4); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +explain format=json +values (1,2),(3,4) +union all +select 1,2; +EXPLAIN +{ + "query_block": { + "union_result": { + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +explain format=json +select 1,2 +union +values (1,2),(3,4); +EXPLAIN +{ + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +explain format=json +values (1,2) +union all +values (1,2),(3,4); +EXPLAIN +{ + "query_block": { + "union_result": { + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +explain +select 1,2 +union all +values (3,4) +union all +values (1,2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +explain format=json +select 1,2 +union all +values (3,4) +union all +values (1,2); +EXPLAIN +{ + "query_block": { + "union_result": { + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +# analyze query that uses VALUES structure(s): single VALUES structure +analyze +values (1,2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +analyze format=json +values (1,2); +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +# analyze query that uses VALUES structure(s): UNION with VALUES structure(s) +analyze +select 1,2 +union +values (1,2),(3,4); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL 2.00 NULL NULL +analyze +values (1,2),(3,4) +union +select 1,2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL 2.00 NULL NULL +analyze +values (5,6) +union +values (1,2),(3,4); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL 3.00 NULL NULL +analyze format=json +select 1,2 +union +values (1,2),(3,4); +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "r_loops": 1, + "r_rows": 2, + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +analyze format=json +values (1,2),(3,4) +union +select 1,2; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "r_loops": 1, + "r_rows": 2, + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +analyze format=json +values (5,6) +union +values (1,2),(3,4); +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "r_loops": 1, + "r_rows": 3, + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +analyze +select 1,2 +union +values (3,4) +union +values (1,2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2,3> ALL NULL NULL NULL NULL NULL 2.00 NULL NULL +analyze format=json +select 1,2 +union +values (3,4) +union +values (1,2); +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "table_name": "<union1,2,3>", + "access_type": "ALL", + "r_loops": 1, + "r_rows": 2, + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +# analyze query that uses VALUES structure(s): UNION ALL with VALUES structure(s) +analyze +select 1,2 +union +values (1,2),(3,4); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL 2.00 NULL NULL +analyze +values (1,2),(3,4) +union all +select 1,2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +analyze +values (1,2) +union all +values (1,2),(3,4); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +analyze format=json +values (1,2),(3,4) +union all +select 1,2; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +analyze format=json +select 1,2 +union +values (1,2),(3,4); +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "table_name": "<union1,2>", + "access_type": "ALL", + "r_loops": 1, + "r_rows": 2, + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +analyze format=json +values (1,2) +union all +values (1,2),(3,4); +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +analyze +select 1,2 +union all +values (3,4) +union all +values (1,2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used +analyze format=json +select 1,2 +union all +values (3,4) +union all +values (1,2); +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "union_result": { + "query_specifications": [ + { + "query_block": { + "select_id": 1, + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 2, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } +} +# different number of values in TVC +values (1,2),(3,4,5); +ERROR HY000: The used table value constructor has a different number of values +# illegal parameter data types in TVC +values (1,point(1,1)),(1,1); +ERROR HY000: Illegal parameter data types point and int for operation 'TABLE VALUE CONSTRUCTOR' +values (1,point(1,1)+1); +ERROR HY000: Illegal parameter data types point and int for operation '+' +# field reference in TVC +select * from (values (1), (b), (2)) as new_tvc; +ERROR HY000: Field reference 'b' can't be used in table value constructor +select * from (values (1), (t1.b), (2)) as new_tvc; +ERROR HY000: Field reference 't1.b' can't be used in table value constructor +drop table t1; +# +# MDEV-15940: cursor over TVC +# +DECLARE +v INT; +CURSOR cur IS VALUES(7); +BEGIN +OPEN cur; +FETCH cur INTO v; +SELECT v; +END; +| +v +7 +DECLARE +v INT DEFAULT 0; +BEGIN +FOR a IN (VALUES (7)) LOOP +SET v = v + 1; +END LOOP; +SELECT v; +END; +| +v +1 +# +# MDEV-16038: empty row in TVC +# +with t as (values (),()) select 1 from t; +ERROR HY000: Row with no elements is not allowed in table value constructor in this context +# +# MDEV-17017: TVC in derived table +# +create table t1 (a int); +insert into t1 values (9), (3), (2); +select * from (values (7), (5), (8), (1), (3), (8), (1)) t; +7 +7 +5 +8 +1 +3 +8 +1 +explain select * from (values (7), (5), (8), (1), (3), (8), (1)) t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +select * from (values (1,11), (7,77), (3,31), (4,42)) t; +1 11 +1 11 +7 77 +3 31 +4 42 +explain select * from (values (1,11), (7,77), (3,31), (4,42)) t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +select * from (values (7), (5), (8), (1) union values (3), (8), (1)) t; +7 +7 +5 +8 +1 +3 +explain select * from (values (7), (5), (8), (1) union values (3), (8), (1)) t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +select * from (values (7), (5), (8), (1) union select * from t1) t; +7 +7 +5 +8 +1 +9 +3 +2 +explain select * from (values (7), (5), (8), (1) union select * from t1) t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION t1 ALL NULL NULL NULL NULL 3 +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +drop table t1; +# +# MDEV-16930: expression in the first row of TVC specifying derived table +# +SELECT 1 + 1, 2, 'abc'; +1 + 1 2 abc +2 2 abc +SELECT * FROM (SELECT 1 + 1, 2, 'abc') t; +1 + 1 2 abc +2 2 abc +WITH cte AS (SELECT 1 + 1, 2, 'abc') SELECT * FROM cte; +1 + 1 2 abc +2 2 abc +SELECT 1 + 1, 2, 'abc' UNION SELECT 3+4, 3, 'abc'; +1 + 1 2 abc +2 2 abc +7 3 abc +CREATE VIEW v1 AS SELECT 1 + 1, 2, 'abc'; +SELECT * FROM v1; +1 + 1 2 abc +2 2 abc +DROP VIEW v1; +VALUES(1 + 1,2,'abc'); +1 + 1 2 abc +2 2 abc +SELECT * FROM (VALUES(1 + 1,2,'abc')) t; +1 + 1 2 abc +2 2 abc +# +# MDEV-17894: tvc with ORDER BY ... LIMIT +# +values (5), (7), (1), (3), (4) limit 2; +5 +5 +7 +explain extended values (5), (7), (1), (3), (4) limit 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 values (5),(7),(1),(3),(4) limit 2 +values (5), (7), (1), (3), (4) limit 2 offset 1; +5 +7 +1 +explain extended values (5), (7), (1), (3), (4) limit 2 offset 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 values (5),(7),(1),(3),(4) limit 1,2 +values (5), (7), (1), (3), (4) order by 1 limit 2; +5 +1 +3 +explain extended values (5), (7), (1), (3), (4) order by 1 limit 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 +NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 values (5),(7),(1),(3),(4) order by 1 limit 2 +values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1; +5 +3 +4 +explain extended values (5), (7), (1), (3), (4) order by 1 limit 2 offset 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 +NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 values (5),(7),(1),(3),(4) order by 1 limit 1,2 +values (5), (7), (1), (3), (4) order by 1; +5 +1 +3 +4 +5 +7 +explain extended values (5), (7), (1), (3), (4) order by 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 +NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 values (5),(7),(1),(3),(4) order by 1 +values (5,90), (7,20), (1,70), (3,50), (4,10) order by 2; +5 90 +4 10 +7 20 +3 50 +1 70 +5 90 +explain extended values (5,90), (7,20), (1,70), (3,50), (4,10) order by 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 +NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 values (5,90),(7,20),(1,70),(3,50),(4,10) order by 2 +select 2 union (values (5), (7), (1), (3), (4) limit 2); +2 +2 +5 +7 +explain extended select 2 union (values (5), (7), (1), (3), (4) limit 2); +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 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 2 AS "2" union (values (5),(7),(1),(3),(4) limit 2) +select 2 union (values (5), (7), (1), (3), (4) limit 2 offset 1); +2 +2 +7 +1 +explain extended select 2 union (values (5), (7), (1), (3), (4) limit 2 offset 1); +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 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 2 AS "2" union (values (5),(7),(1),(3),(4) limit 1,2) +select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2); +2 +2 +1 +3 +explain extended select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2); +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 +3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 2 AS "2" union (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2) +select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1); +2 +2 +3 +4 +explain extended select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1); +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 +3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 2 AS "2" union (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 1,2) +(values (5), (7), (1), (3), (4) limit 2) union select 2; +5 +5 +7 +2 +explain extended (values (5), (7), (1), (3), (4) limit 2) union select 2; +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 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 (values (5),(7),(1),(3),(4) limit 2) union /* select#2 */ select 2 AS "2" +(values (5), (7), (1), (3), (4) limit 2 offset 1) union select 2; +5 +7 +1 +2 +explain extended (values (5), (7), (1), (3), (4) limit 2 offset 1) union select 2; +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 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union /* select#2 */ select 2 AS "2" +(values (5), (7), (1), (3), (4) order by 1 limit 2) union select 2; +5 +1 +3 +2 +explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2) union select 2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 (/* select#1 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2) union /* select#2 */ select 2 AS "2" +(values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1) union select 2; +5 +3 +4 +2 +explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1) union select 2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 (/* select#1 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 1,2) union /* select#2 */ select 2 AS "2" +select 3 union all (values (5), (7), (1), (3), (4) limit 2 offset 3); +3 +3 +3 +4 +explain extended select 3 union all (values (5), (7), (1), (3), (4) limit 2 offset 3); +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 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 /* select#1 */ select 3 AS "3" union all (values (5),(7),(1),(3),(4) limit 3,2) +(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3; +5 +3 +4 +3 +explain extended (values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3; +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 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 (values (5),(7),(1),(3),(4) limit 3,2) union all /* select#2 */ select 3 AS "3" +select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2); +3 +3 +1 +3 +explain extended select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2); +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 +3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 3 AS "3" union all (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2) +(values (5), (7), (1), (3), (4) order by 1 limit 2) union all select 3; +5 +1 +3 +3 +explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2) union all select 3; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 (/* select#1 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2) union all /* select#2 */ select 3 AS "3" +( values (5), (7), (1), (3), (4) limit 2 offset 1 ) +union +( values (5), (7), (1), (3), (4) order by 1 limit 2 ); +5 +7 +1 +3 +explain extended ( values (5), (7), (1), (3), (4) limit 2 offset 1 ) +union +( values (5), (7), (1), (3), (4) order by 1 limit 2 ); +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 +3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2) +( values (5), (7), (1), (3), (4) limit 2 offset 1 ) +union all +( values (5), (7), (1), (3), (4) order by 1 limit 2 ); +5 +7 +1 +1 +3 +explain extended ( values (5), (7), (1), (3), (4) limit 2 offset 1 ) +union all +( values (5), (7), (1), (3), (4) order by 1 limit 2 ); +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 +3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union all (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2) +(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3 order by 1; +5 +3 +3 +4 +explain extended (values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3 order by 1; +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 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 (values (5),(7),(1),(3),(4) limit 3,2) union all /* select#2 */ select 3 AS "3" order by 1 +(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 order by 1; +5 +3 +3 +4 +5 +explain extended (values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 order by 1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 (/* select#1 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 1,3) union all /* select#2 */ select 3 AS "3" order by 1 +(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 +order by 1 limit 2 offset 1; +5 +3 +4 +explain extended (values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 +order by 1 limit 2 offset 1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 (/* select#1 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 1,3) union all /* select#2 */ select 3 AS "3" order by 1 limit 1,2 +values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3; +ERROR 42S22: Unknown column '3' in 'order clause' +create view v1 as values (5), (7), (1), (3), (4) order by 1 limit 2; +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS values (5),(7),(1),(3),(4) order by 1 limit 2 latin1 latin1_swedish_ci +select * from v1; +5 +1 +3 +drop view v1; +create view v1 as +( values (5), (7), (1), (3), (4) limit 2 offset 1 ) +union +( values (5), (7), (1), (3), (4) order by 1 limit 2 ); +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS (values (5),(7),(1),(3),(4) limit 1,2) union (values (5),(7),(1),(3),(4) order by 1 limit 2) latin1 latin1_swedish_ci +select * from v1; +5 +7 +1 +3 +drop view v1; +create view v1 as values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3; +ERROR 42S22: Unknown column '3' in 'order clause' +create view v1 as +( values (5), (7), (1), (3), (4) limit 2 offset 1 ) +union +( values (5), (7), (1), (3), (4) order by 2 limit 2 ); +ERROR 42S22: Unknown column '2' in 'order clause' diff --git a/mysql-test/suite/compat/oracle/r/trigger.result b/mysql-test/suite/compat/oracle/r/trigger.result new file mode 100644 index 00000000..7c24c78b --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/trigger.result @@ -0,0 +1,100 @@ +set sql_mode=ORACLE; +:NEW.a := 1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':NEW.a := 1' at line 1 +:OLD.a := 1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':OLD.a := 1' at line 1 +:OLa.a := 1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':OLa.a := 1' at line 1 +SELECT :NEW.a; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a' at line 1 +SELECT :OLD.a; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a' at line 1 +SELECT :OLa.a; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a' at line 1 +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW NEW.a:= 10; +INSERT INTO t1 VALUES (); +SELECT * FROM t1; +a +10 +DROP TRIGGER tr1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW :NEW.a:= 10; +INSERT INTO t1 VALUES (); +SELECT * FROM t1; +a +10 +DROP TRIGGER tr1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW +BEGIN +IF :NEW.a IS NULL +THEN +:NEW.a:= 10; +END IF; +END; +/ +INSERT INTO t1 VALUES (NULL); +SELECT * FROM t1; +a +10 +DROP TRIGGER tr1; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE UPDATE ON t1 FOR EACH ROW +BEGIN +IF :OLD.a IS NULL +THEN +:NEW.a:= 10; +END IF; +END; +/ +INSERT INTO t1 VALUES (NULL); +UPDATE t1 SET a=NULL; +SELECT * FROM t1; +a +10 +DROP TRIGGER tr1; +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT, c INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 +FOR EACH ROW +DECLARE +cnt INT := 0; +BEGIN +IF :NEW.a IS NULL THEN cnt:=cnt+1; END IF; +IF :NEW.b IS NULL THEN cnt:=cnt+1; END IF; +IF :NEW.c IS NULL THEN :NEW.c:=cnt; END IF; +END; +/ +INSERT INTO t1 VALUES (); +INSERT INTO t1 VALUES (1, NULL, NULL); +INSERT INTO t1 VALUES (NULL, 1, NULL); +INSERT INTO t1 VALUES (1, 1, NULL); +SELECT * FROM t1; +a b c +NULL NULL 2 +1 NULL 1 +NULL 1 1 +1 1 0 +DROP TABLE t1; +# +# MDEV-10577 sql_mode=ORACLE: %TYPE in variable declarations +# +CREATE TABLE t1 (a INT, b INT, total INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 +FOR EACH ROW +DECLARE +va t1.a%TYPE:= :NEW.a; +vb t1.b%TYPE:= :NEW.b; +BEGIN +:NEW.total:= va + vb; +END; +$$ +INSERT INTO t1 (a,b) VALUES (10, 20); +SELECT * FROM t1; +a b total +10 20 30 +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/truncate.result b/mysql-test/suite/compat/oracle/r/truncate.result new file mode 100644 index 00000000..f04ce09a --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/truncate.result @@ -0,0 +1,10 @@ +SET sql_mode=ORACLE; +# +# MDEV-10588 sql_mode=ORACLE: TRUNCATE TABLE t1 [ {DROP|REUSE} STORAGE ] +# +CREATE TABLE t1 (a INT); +TRUNCATE TABLE t1 REUSE STORAGE; +TRUNCATE TABLE t1 DROP STORAGE; +DROP TABLE t1; +CREATE TABLE reuse (reuse INT); +DROP TABLE reuse; diff --git a/mysql-test/suite/compat/oracle/r/type_blob.result b/mysql-test/suite/compat/oracle/r/type_blob.result new file mode 100644 index 00000000..27740947 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/type_blob.result @@ -0,0 +1,26 @@ +SET sql_mode=ORACLE; +CREATE TABLE t1 (a BLOB); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longblob DEFAULT NULL +) +DROP TABLE t1; +# +# MDEV-20263 sql_mode=ORACLE: BLOB(65535) should not translate to LONGBLOB +# +CREATE TABLE t1 ( +c1 BLOB(100), +c2 BLOB(65535), +c3 BLOB(16777215), +c4 BLOB(16777216) +); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "c1" tinyblob DEFAULT NULL, + "c2" blob(65535) DEFAULT NULL, + "c3" mediumblob DEFAULT NULL, + "c4" longblob DEFAULT NULL +) +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/type_clob.result b/mysql-test/suite/compat/oracle/r/type_clob.result new file mode 100644 index 00000000..f96572ea --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/type_clob.result @@ -0,0 +1,15 @@ +SET sql_mode=ORACLE; +CREATE TABLE clob (clob INT); +SHOW CREATE TABLE clob; +Table Create Table +clob CREATE TABLE "clob" ( + "clob" int(11) DEFAULT NULL +) +DROP TABLE clob; +CREATE TABLE t1 (a CLOB); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" longtext DEFAULT NULL +) +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/type_date.result b/mysql-test/suite/compat/oracle/r/type_date.result new file mode 100644 index 00000000..c9bda19b --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/type_date.result @@ -0,0 +1,155 @@ +SET sql_mode=ORACLE; +CREATE TABLE t1 (a DATE); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" datetime DEFAULT NULL +) +DROP TABLE t1; +# +# MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode +# +SET sql_mode=DEFAULT; +CREATE TABLE t1 (a unknown.DATE); +ERROR HY000: Unknown data type: 'unknown.date' +SET sql_mode=DEFAULT; +CREATE TABLE t1 ( +def_date DATE, +mdb_date mariadb_schema.DATE, +ora_date oracle_schema.DATE, +max_date maxdb_schema.DATE +); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `def_date` date DEFAULT NULL, + `mdb_date` date DEFAULT NULL, + `ora_date` datetime DEFAULT NULL, + `max_date` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SET sql_mode=ORACLE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "def_date" mariadb_schema.date DEFAULT NULL, + "mdb_date" mariadb_schema.date DEFAULT NULL, + "ora_date" datetime DEFAULT NULL, + "max_date" mariadb_schema.date DEFAULT NULL +) +DROP TABLE t1; +SET sql_mode=ORACLE; +CREATE TABLE t1 ( +def_date DATE, +mdb_date mariadb_schema.DATE, +ora_date oracle_schema.DATE, +max_date maxdb_schema.DATE +); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "def_date" datetime DEFAULT NULL, + "mdb_date" mariadb_schema.date DEFAULT NULL, + "ora_date" datetime DEFAULT NULL, + "max_date" mariadb_schema.date DEFAULT NULL +) +SET sql_mode=DEFAULT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `def_date` datetime DEFAULT NULL, + `mdb_date` date DEFAULT NULL, + `ora_date` datetime DEFAULT NULL, + `max_date` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; +# +# ALTER..MODIFY and ALTER..CHANGE understand qualifiers +# +SET sql_mode=DEFAULT; +CREATE TABLE t1 (a DATE); +INSERT INTO t1 VALUES ('2001-01-01'); +SET sql_mode=ORACLE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mariadb_schema.date DEFAULT NULL +) +SELECT * FROM t1; +a +2001-01-01 +ALTER TABLE t1 MODIFY a DATE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" datetime DEFAULT NULL +) +SELECT * FROM t1; +a +2001-01-01 00:00:00 +ALTER TABLE t1 MODIFY a mariadb_schema.DATE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" mariadb_schema.date DEFAULT NULL +) +SELECT * FROM t1; +a +2001-01-01 +ALTER TABLE t1 MODIFY a oracle_schema.DATE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" datetime DEFAULT NULL +) +SELECT * FROM t1; +a +2001-01-01 00:00:00 +ALTER TABLE t1 CHANGE a b mariadb_schema.DATE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "b" mariadb_schema.date DEFAULT NULL +) +SELECT * FROM t1; +b +2001-01-01 +ALTER TABLE t1 CHANGE b a oracle_schema.DATE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" datetime DEFAULT NULL +) +SELECT * FROM t1; +a +2001-01-01 00:00:00 +DROP TABLE t1; +# +# Qualified syntax is not supported yet in SP +# See MDEV-23353 Qualified data types in SP +# +SET sql_mode=ORACLE; +CREATE FUNCTION f1() RETURN mariadb_schema.DATE AS +BEGIN +RETURN CURRENT_DATE; +END; +$$ +ERROR HY000: Unknown data type: 'mariadb_schema' +CREATE PROCEDURE p1(a mariadb_schema.DATE) AS +BEGIN +NULL; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') AS +BEGIN +NULL; +END' at line 1 +CREATE PROCEDURE p1() AS +a mariadb_schema.DATE; +BEGIN +NULL; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '; +BEGIN +NULL; +END' at line 2 diff --git a/mysql-test/suite/compat/oracle/r/type_number.result b/mysql-test/suite/compat/oracle/r/type_number.result new file mode 100644 index 00000000..c0848fdc --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/type_number.result @@ -0,0 +1,15 @@ +SET sql_mode=ORACLE; +CREATE TABLE t1 (a NUMBER); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" double DEFAULT NULL +) +DROP TABLE t1; +CREATE TABLE t1 (a NUMBER(10,2)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" decimal(10,2) DEFAULT NULL +) +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/type_raw.result b/mysql-test/suite/compat/oracle/r/type_raw.result new file mode 100644 index 00000000..1698c96d --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/type_raw.result @@ -0,0 +1,15 @@ +SET sql_mode=ORACLE; +CREATE TABLE raw (raw INT); +SHOW CREATE TABLE raw; +Table Create Table +raw CREATE TABLE "raw" ( + "raw" int(11) DEFAULT NULL +) +DROP TABLE raw; +CREATE TABLE t1 (a RAW(10)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varbinary(10) DEFAULT NULL +) +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/type_varchar.result b/mysql-test/suite/compat/oracle/r/type_varchar.result new file mode 100644 index 00000000..906e1686 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/type_varchar.result @@ -0,0 +1,9 @@ +SET sql_mode=ORACLE; +# +# MDEV-11275 sql_mode=ORACLE: CAST(..AS VARCHAR(N)) +# +SELECT CAST(123 AS VARCHAR(10)) FROM DUAL; +CAST(123 AS VARCHAR(10)) +123 +SELECT CAST(123 AS VARCHAR) FROM DUAL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') FROM DUAL' at line 1 diff --git a/mysql-test/suite/compat/oracle/r/type_varchar2.result b/mysql-test/suite/compat/oracle/r/type_varchar2.result new file mode 100644 index 00000000..5030cfba --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/type_varchar2.result @@ -0,0 +1,23 @@ +SET sql_mode=ORACLE; +CREATE TABLE varchar2 (varchar2 INT); +SHOW CREATE TABLE varchar2; +Table Create Table +varchar2 CREATE TABLE "varchar2" ( + "varchar2" int(11) DEFAULT NULL +) +DROP TABLE varchar2; +CREATE TABLE t1 (a VARCHAR2(10)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" varchar(10) DEFAULT NULL +) +DROP TABLE t1; +# +# MDEV-11275 sql_mode=ORACLE: CAST(..AS VARCHAR(N)) +# +SELECT CAST(123 AS VARCHAR2(10)) FROM DUAL; +CAST(123 AS VARCHAR2(10)) +123 +SELECT CAST(123 AS VARCHAR2) FROM DUAL; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') FROM DUAL' at line 1 diff --git a/mysql-test/suite/compat/oracle/r/update_innodb.result b/mysql-test/suite/compat/oracle/r/update_innodb.result new file mode 100644 index 00000000..1dae643e --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/update_innodb.result @@ -0,0 +1,26 @@ +# +# MDEV-19535 sql_mode=ORACLE: 'SELECT INTO @var FOR UPDATE' does not lock the table +# +SET sql_mode='ORACLE'; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) engine=innodb; +INSERT INTO t1 VALUES (1); +START TRANSACTION; +SELECT a AS a_con1 FROM t1 INTO @a FOR UPDATE; +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +connect con2,localhost,root,,; +SET sql_mode='ORACLE'; +START TRANSACTION; +SELECT a AS a_con2 FROM t1 INTO @a FOR UPDATE;; +connection default; +UPDATE t1 SET a=a+100; +COMMIT; +connection con2; +Warnings: +Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead +SELECT a AS con2 FROM t1; +con2 +101 +COMMIT; +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/variables.result b/mysql-test/suite/compat/oracle/r/variables.result new file mode 100644 index 00000000..a7067d7b --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/variables.result @@ -0,0 +1,39 @@ +SET sql_mode=oracle; +# +# MDEV-10411 Providing compatibility for basic PL/SQL constructs +# Part 6: Assignment operator +# +max_sort_length:=1030; +SELECT @@max_sort_length; +@@max_sort_length +1030 +max_sort_length:=DEFAULT; +# +# Testing that SP variables shadow global variables in assignments +# +CREATE PROCEDURE p1 +AS +BEGIN +max_sort_length:=1030; +DECLARE +max_sort_length INT DEFAULT 1031; +BEGIN +SELECT @@max_sort_length, max_sort_length; +max_sort_length:=1032; +SELECT @@max_sort_length, max_sort_length; +END; +SELECT @@max_sort_length; +max_sort_length:= DEFAULT; +END; +$$ +CALL p1(); +@@max_sort_length max_sort_length +1030 1031 +@@max_sort_length max_sort_length +1030 1032 +@@max_sort_length +1030 +DROP PROCEDURE p1; +# +# End of MDEV-10411 Providing compatibility for basic PL/SQL constructs (part 6) +# diff --git a/mysql-test/suite/compat/oracle/r/vcol.result b/mysql-test/suite/compat/oracle/r/vcol.result new file mode 100644 index 00000000..89118bad --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/vcol.result @@ -0,0 +1,23 @@ +# +# MDEV-13500 sql_mode=ORACLE: can't create a virtual column with function MOD +# +SET sql_mode=ORACLE; +CREATE TABLE t1 (c1 INTEGER, c2 INTEGER AS (c1 MOD 10) VIRTUAL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "c1" int(11) DEFAULT NULL, + "c2" int(11) GENERATED ALWAYS AS ("c1" MOD 10) VIRTUAL +) +INSERT INTO t1 (c1) VALUES (999); +SELECT * FROM t1; +c1 c2 +999 9 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE VIEW v1 AS SELECT a MOD 10 FROM t1; +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select "t1"."a" MOD 10 AS "a MOD 10" from "t1" latin1 latin1_swedish_ci +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/versioning.result b/mysql-test/suite/compat/oracle/r/versioning.result new file mode 100644 index 00000000..bbecfa1f --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/versioning.result @@ -0,0 +1,24 @@ +SET sql_mode=ORACLE; +# +# MDEV-15975 PL/SQL parser does not understand historical queries +# +CREATE TABLE t1 (a INT) WITH SYSTEM VERSIONING; +INSERT INTO t1 VALUES (10); +DELETE FROM t1; +INSERT INTO t1 VALUES (20); +SELECT * FROM t1 FOR SYSTEM_TIME ALL; +a +10 +20 +SELECT * FROM t1 FOR SYSTEM_TIME AS OF (NOW()+INTERVAL 10 YEAR); +a +20 +DROP TABLE t1; +# +# MDEV-17959 Assertion `opt_bootstrap || mysql_parse_status || thd->lex->select_stack_top == 0' failed in parse_sql upon DELETE HISTORY under ORACLE mode +# +SET SQL_MODE= ORACLE; +CREATE TABLE t1 (a INT); +DELETE HISTORY FROM t1; +ERROR HY000: Table `t1` is not system-versioned +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/r/win.result b/mysql-test/suite/compat/oracle/r/win.result new file mode 100644 index 00000000..b11eba0d --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/win.result @@ -0,0 +1,17 @@ +SET sql_mode=ORACLE; +# +# MDEV-13384: "window" seems like a reserved column name but it's not listed as one +# +# Currently we allow window as an identifier, except for table aliases. +# +CREATE TABLE door (id INT, window VARCHAR(10)); +SELECT id +FROM door as window; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'window' at line 2 +SELECT id, window +FROM door; +id window +SELECT id, window +FROM door as window; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'window' at line 2 +DROP TABLE door; |