1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-11952 Oracle-style packages: stage#5

- CREATE PACKAGE [BODY] statements are now
  entirely written to mysql.proc with type='PACKAGE' and type='PACKAGE BODY'.
- CREATE PACKAGE BODY now supports IF NOT EXISTS
- DROP PACKAGE BODY now supports IF EXISTS
- CREATE OR REPLACE PACKAGE [BODY] is now supported
- CREATE PACKAGE [BODY] now support the DEFINER clause:

    CREATE DEFINER user@host PACKAGE pkg ... END;
    CREATE DEFINER user@host PACKAGE BODY pkg ... END;

- CREATE PACKAGE [BODY] now supports SQL SECURITY and COMMENT clauses, e.g.:

    CREATE PACKAGE p1 SQL SECURITY INVOKER COMMENT "comment" AS ... END;

- Package routines are now created from the package CREATE PACKAGE BODY
  statement and don't produce individual records in mysql.proc.

- CREATE PACKAGE BODY now supports package-wide variables.
  Package variables can be read and set inside package routines.
  Package variables are stored in a separate sp_rcontext,
  which is cached in THD on the first packate routine call.

- CREATE PACKAGE BODY now supports the initialization section.

- All public routines (i.e. declared in CREATE PACKAGE)
  must have implementations in CREATE PACKAGE BODY

- Only public package routines are available outside of the package

- {CREATE|DROP} PACKAGE [BODY] now respects CREATE ROUTINE and ALTER ROUTINE
  privileges

- "GRANT EXECUTE ON PACKAGE BODY pkg" is now supported

- SHOW CREATE PACKAGE [BODY] is now supported

- SHOW PACKAGE [BODY] STATUS is now supported

- CREATE and DROP for PACKAGE [BODY] now works for non-current databases

- mysqldump now supports packages

- "SHOW {PROCEDURE|FUNCTION) CODE pkg.routine" now works for package routines

- "SHOW PACKAGE BODY CODE pkg" now works (the package initialization section)

- A new package body level MDL was added

- Recursive calls for package procedures are now possible

- Routine forward declarations in CREATE PACKATE BODY are now supported.

- Package body variables now work as SP OUT parameters

- Package body variables now work as SELECT INTO targets

- Package body variables now support ROW, %ROWTYPE, %TYPE
This commit is contained in:
Alexander Barkov
2017-08-18 23:36:42 +04:00
parent 83ea839fb1
commit 583eb96c24
86 changed files with 11064 additions and 278 deletions

View File

@ -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 */

View File

@ -0,0 +1,183 @@
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
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
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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -0,0 +1,75 @@
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;
$$
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;

View File

@ -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_INTENTION_EXCLUSIVE
LOCK_TYPE Global read 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;

View File

@ -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 utf8 */;
/*!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 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 */ ;
/*!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' */ ;
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 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 */ ;
/*!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' */ ;
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 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 */ ;
/*!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' */ ;
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 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 */ ;
/*!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' */ ;
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

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -166,6 +166,13 @@ 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/

View File

@ -0,0 +1,158 @@
--source include/not_embedded.inc
--source include/have_binlog_format_statement.inc
--disable_query_log
reset master; # get rid of previous tests binlog
--enable_query_log
SET sql_mode=ORACLE;
DELIMITER $$;
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;
$$
CREATE PACKAGE BODY p1 AS
PROCEDURE p1 AS
BEGIN
NULL;
END;
FUNCTION f1 RETURN INT AS
BEGIN
RETURN 10;
END;
END;
$$
DELIMITER ;$$
DROP PACKAGE BODY p1;
DROP PACKAGE p1;
DROP PACKAGE IF EXISTS p1;
--echo #
--echo # Creating a package with a COMMENT clause
--echo #
DELIMITER $$;
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;
$$
DELIMITER ;$$
DROP PACKAGE p1;
--echo #
--echo # Creating a package with a different DEFINER
--echo #
DELIMITER $$;
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;
$$
DELIMITER ;$$
DROP PACKAGE p1;
--echo #
--echo # Creating a package with a different DEFINER, with SQL SECURITY INVOKER
--echo #
DELIMITER $$;
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;
$$
DELIMITER ;$$
DROP PACKAGE p1;
--echo #
--echo # Creating a new package in a remote database
--echo #
CREATE DATABASE test2;
DELIMITER $$;
CREATE PACKAGE test2.test2 COMMENT 'package-test2-comment' AS
FUNCTION f1 RETURN INT;
PROCEDURE p1;
END
$$
DELIMITER ;$$
DELIMITER $$;
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;
$$
DELIMITER ;$$
DROP PACKAGE BODY test2.test2;
DROP PACKAGE test2.test2;
DROP DATABASE test2;
--echo #
--echo # MDEV-13139 Package-wide variables in CREATE PACKAGE
--echo #
CREATE TABLE t1 (a INT);
DELIMITER $$;
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;
$$
DELIMITER ;$$
CALL p1.p1();
CALL p1.p1();
SELECT * FROM t1;
--source sp-cache-invalidate.inc
CALL p1.p1();
CALL p1.p1();
SELECT * FROM t1;
DROP PACKAGE p1;
DROP TABLE t1;
--let $binlog_file = LAST
source include/show_binlog_events.inc;

View File

@ -0,0 +1,134 @@
--source include/master-slave.inc
connection master;
SET sql_mode=ORACLE;
DELIMITER $$;
CREATE PACKAGE pack AS
FUNCTION f1 RETURN INT;
PROCEDURE p1;
END;
$$
DELIMITER ;$$
DELIMITER $$;
CREATE PACKAGE BODY pack AS
FUNCTION f1 RETURN INT AS
BEGIN
RETURN 10;
END;
PROCEDURE p1 AS
BEGIN
SELECT f1();
END;
END pack;
$$
DELIMITER ;$$
sync_slave_with_master;
connection slave;
--vertical_results
--replace_column 13 # 14 #
SELECT * FROM mysql.proc WHERE db='test' AND name='pack';
--replace_column 13 # 14 #
SELECT * FROM mysql.proc WHERE db='test' AND name LIKE 'pack.%';
--horizontal_results
SET @@sql_mode=ORACLE;
SELECT pack.f1();
CALL pack.p1();
SET @@sql_mode=DEFAULT;
connection master;
DROP PACKAGE pack;
sync_slave_with_master;
connection slave;
SELECT COUNT(*) FROM mysql.proc WHERE db='test' AND name='pack';
--echo #
--echo # Creating a package with a COMMENT
--echo #
connection master;
DELIMITER $$;
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;
$$
DELIMITER ;$$
SELECT definer, name, security_type, type, `comment` FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type;
sync_slave_with_master;
SELECT definer, name, security_type, type, `comment` FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type;
connection master;
DROP PACKAGE p1;
sync_slave_with_master;
--echo #
--echo # Creating a package with a different DEFINER
--echo #
connection master;
DELIMITER $$;
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;
$$
DELIMITER ;$$
SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type;
sync_slave_with_master;
SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type;
connection master;
DROP PACKAGE p1;
sync_slave_with_master;
--echo #
--echo # Creating a package with a different DEFINER + SQL SECURITY INVOKER
--echo #
connection master;
DELIMITER $$;
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;
$$
DELIMITER ;$$
SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type;
sync_slave_with_master;
SELECT definer, name, security_type, type FROM mysql.proc WHERE name LIKE 'p1%' ORDER BY definer, name, type;
connection master;
DROP PACKAGE p1;
sync_slave_with_master;
--source include/rpl_end.inc

View File

@ -0,0 +1,36 @@
--source include/master-slave.inc
connection master;
SET sql_mode=ORACLE;
--echo #
--echo # MDEV-13139 Package-wide variables in CREATE PACKAGE
--echo #
connection master;
DELIMITER $$;
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;
$$
DELIMITER ;$$
CALL p1.p1();
CALL p1.p1();
SELECT * FROM t1;
sync_slave_with_master;
SELECT * FROM t1;
connection master;
DROP PACKAGE p1;
DROP TABLE t1;
sync_slave_with_master;
--source include/rpl_end.inc

View File

@ -0,0 +1,11 @@
--echo # sp-cache-invalidate
--disable_query_log
DELIMITER $$;
CREATE FUNCTION dummy RETURN INT AS
BEGIN
RETURN 1;
END;
$$
DELIMITER ;$$
DROP FUNCTION dummy;
--enable_query_log

View File

@ -0,0 +1,182 @@
-- source include/have_debug.inc
SET sql_mode=ORACLE;
DELIMITER $$;
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;
$$
DELIMITER ;$$
SHOW PROCEDURE CODE pkg1.p1;
SHOW FUNCTION CODE pkg1.f1;
SHOW PACKAGE BODY CODE pkg1;
CALL pkg1.p2show;
DROP PACKAGE pkg1;
CREATE TABLE t1 (a INT);
DELIMITER $$;
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;
$$
DELIMITER ;$$
SHOW PROCEDURE CODE pkg1.p1;
SHOW PACKAGE BODY CODE pkg1;
DROP PACKAGE pkg1;
DROP TABLE t1;
DELIMITER $$;
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;
$$
DELIMITER ;$$
SHOW PROCEDURE CODE pkg1.p1;
SHOW PACKAGE BODY CODE pkg1;
DROP PACKAGE pkg1;
CREATE TABLE t1 (a INT, b TEXT);
DELIMITER $$;
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;
$$
DELIMITER ;$$
SHOW PROCEDURE CODE pkg1.p1;
SHOW PACKAGE BODY CODE pkg1;
DROP PACKAGE pkg1;
DROP TABLE t1;

View File

@ -0,0 +1,6 @@
--echo #
--echo # MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
--echo #
SET @object_type='db';
--source sp-package-concurrent-dml.inc

View File

@ -0,0 +1,10 @@
--echo #
--echo # MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
--echo #
SET @object_type='package_replace_pkg1';
--source sp-package-concurrent-dml.inc
SET @object_type='package_body_replace_pkg1';
--source sp-package-concurrent-dml.inc

View File

@ -0,0 +1,6 @@
--echo #
--echo # MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
--echo #
SET @object_type='trigger';
--source sp-package-concurrent-dml.inc

View File

@ -0,0 +1,6 @@
--echo #
--echo # MDEV-15070 Crash when doing a CREATE VIEW inside a package routine
--echo #
SET @object_type='view';
--source sp-package-concurrent-dml.inc

View File

@ -0,0 +1,107 @@
--echo #
--echo # Start of sp-package-concurrent-dml.inc
--echo #
--source include/count_sessions.inc
let $object_type= `SELECT @object_type`;
SET sql_mode=ORACLE;
DELIMITER $$;
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;
$$
DELIMITER ;$$
connect (con2,localhost,root);
connection con2;
DO GET_LOCK('mdev15070', 120);
connection default;
send CALL pkg1.p1;
connection con2;
let $wait_condition=
SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE state = "User lock" AND info LIKE "%GET_LOCK%mdev15070%";
--source include/wait_condition.inc
if ($object_type==view)
{
CREATE VIEW v1 AS SELECT 1 AS c;
DROP VIEW v1;
}
if ($object_type==package_replace_pkg1)
{
SET sql_mode=ORACLE;
DELIMITER $$;
CREATE OR REPLACE PACKAGE pkg1 AS
PROCEDURE p1;
END;
$$
DELIMITER ;$$
DROP PACKAGE pkg1;
}
if ($object_type==package_body_replace_pkg1)
{
SET sql_mode=ORACLE;
DELIMITER $$;
CREATE OR REPLACE PACKAGE BODY pkg1 AS
PROCEDURE p1 AS
BEGIN
SELECT 'This is p1 version 2' AS msg;
END;
END;
$$
DELIMITER ;$$
DROP PACKAGE pkg1;
}
if ($object_type==trigger)
{
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;
}
if ($object_type=='db')
{
CREATE DATABASE test1;
CREATE FUNCTION test1.f1() RETURNS INT RETURN 10;
DROP DATABASE test1;
}
DO RELEASE_LOCK('mdev15070');
disconnect con2;
connection default;
reap;
DROP PACKAGE IF EXISTS pkg1;
--source include/wait_until_count_sessions.inc

View File

@ -0,0 +1,62 @@
-- source include/have_innodb.inc
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';
INSERT INTO t1 VALUES (10,'none');
DELIMITER $$;
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;
$$
DELIMITER ;$$
CALL pkg1.p1;
SELECT * FROM t1 ORDER BY a;
DELETE FROM t1;
--source sp-cache-invalidate.inc
START TRANSACTION;
CALL pkg1.p1;
SELECT * FROM t1 ORDER BY a;
ROLLBACK;
SELECT * FROM t1 ORDER BY a;
DELETE FROM t1;
--source sp-cache-invalidate.inc
INSERT INTO t1 VALUES (20,'none');
START TRANSACTION;
CALL pkg1.p1;
SELECT * FROM t1 ORDER BY a;
COMMIT;
SELECT * FROM t1 ORDER BY a;
DELETE FROM t1;
--source sp-cache-invalidate.inc
INSERT INTO t1 VALUES (20,'none');
START TRANSACTION;
CALL pkg1.p1;
SELECT * FROM t1 ORDER BY a;
ROLLBACK;
SELECT * FROM t1 ORDER BY a;
DELETE FROM t1;
DROP PACKAGE pkg1;
DROP TABLE t1;

View File

@ -0,0 +1,110 @@
--source include/have_metadata_lock_info.inc
#
# This test demonstrates that:
# - A call to a package routine acquires a shared MDL lock on the entire package
# - "DROP PACKAGE" waits until the currently running package routines end
#
SET sql_mode=ORACLE;
DO GET_LOCK('lock',300);
#
# conn1 will execute package pkg1 routines and
# and therefore acquire a shared MDL on "package body pkg1"
#
connect (conn1,localhost,root,,);
SET sql_mode=ORACLE;
let $conn1_id= `SELECT CONNECTION_ID()`;
DELIMITER $$;
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;
$$
DELIMITER ;$$
send SELECT pkg1.f1();
#
# wait for conn1 to actually start execution of pkg1.p1
#
connection default;
let $wait_timeout= 60;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID=$conn1_id AND INFO LIKE '%GET_LOCK%' AND STATE='User lock';
--source include/wait_condition.inc
#
# conn2 will do "DROP PACKAGE pkg1".
# It will acquire an exclusive MDL on "package body pkg1", and therefore
# it should wait until conn1 ends the package routine execution
#
connect (conn2,localhost,root,,);
let $conn2_id= `SELECT CONNECTION_ID()`;
SET sql_mode=ORACLE;
send DROP PACKAGE pkg1;
#
# wait for conn2 to actually enter the "DROP" statement and get locked by conn1
#
connection default;
let $wait_timeout= 60;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID=$conn2_id
AND INFO LIKE '%DROP PACKAGE%'
AND STATE='Waiting for stored package body metadata lock';
--source include/wait_condition.inc
#
# Now we have three threads involved.
# The following I_S query will check that the threads are in these states:
#
# default (0) - is holding a user lock 'lock'
# conn1 (1) - is executing the package procedure test.pkg1.p1,
# is holding a shared MDL on 'package body pkg1',
# is waiting for the user lock 'lock' to be released
# conn2 (2) - is waiting for 'conn1' to end execution of test.pkg1.* routines,
# to acquire an exclusive MDL on 'package body pkg1',
# to DROP the package pkg1
#
--vertical_results
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;
--horizontal_results
#
# Now let conn1 finish the package routine execution
#
DO RELEASE_LOCK('lock');
connection conn1;
reap;
disconnect conn1;
#
# Now conn2 should actually DROP the package
#
connection conn2;
reap;
disconnect conn2;
connection default;

View File

@ -0,0 +1,93 @@
--source include/not_embedded.inc
SET sql_mode=ORACLE;
#
# Create a standalone procedure test.p1 and a package pkg1.
# The standalone routine test.p1 and the package routines call each other.
#
DELIMITER $$;
CREATE PROCEDURE p1 AS
BEGIN
SELECT pkg1.f1(); -- a standalone routine calls a package routine
END;
$$
DELIMITER ;$$
DELIMITER $$;
CREATE PACKAGE pkg1 AS
PROCEDURE p1;
FUNCTION f1 RETURN INT;
END;
$$
DELIMITER ;$$
DELIMITER $$;
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;
$$
DELIMITER ;$$
CALL p1;
CALL pkg1.p1;
SELECT pkg1.f1();
#
# Create specifications for one more package, without a BODY
#
DELIMITER $$;
CREATE PACKAGE pkg2 AS
PROCEDURE p1;
FUNCTION f1 RETURN INT;
END;
$$
DELIMITER ;$$
--exec $MYSQL_DUMP --skip-comments --routines test
--exec $MYSQL_DUMP --skip-comments --routines --xml test
let $dump = $MYSQLTEST_VARDIR/tmp/sp-package-mysqldump.sql;
--exec $MYSQL_DUMP --compact --routines test > $dump
DROP PACKAGE pkg1;
DROP PACKAGE pkg2;
DROP PROCEDURE p1;
--exec $MYSQL test < $dump
--vertical_results
--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
SHOW PACKAGE STATUS;
--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
SHOW PACKAGE BODY STATUS;
--horizontal_results
SHOW CREATE PACKAGE pkg1;
SHOW CREATE PACKAGE pkg2;
SHOW CREATE PACKAGE BODY pkg1;
CALL p1;
CALL pkg1.p1;
SELECT pkg1.f1();
DROP PACKAGE pkg1;
DROP PACKAGE pkg2;
DROP PROCEDURE p1;
--echo # removing the dump file
--error 0,1
--remove_file $dump

View File

@ -0,0 +1,331 @@
--source include/not_embedded.inc
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;
SET sql_mode=ORACLE;
--echo #
--echo # User u1 cannot drop PROCEDURE, PACKAGE, PACKAGE BODY by default
--echo #
--error ER_PROCACCESS_DENIED_ERROR
DROP PROCEDURE p1;
--error ER_PROCACCESS_DENIED_ERROR
DROP PACKAGE pkg1;
--error ER_PROCACCESS_DENIED_ERROR
DROP PACKAGE BODY pkg1;
--echo #
--echo # User u1 cannot create PROCEDURE, PACKAGE, PACKAGE BODY by default
--echo #
DELIMITER $$;
--error ER_DBACCESS_DENIED_ERROR
CREATE PROCEDURE p1 AS
BEGIN
NULL;
END;
$$
DELIMITER ;$$
DELIMITER $$;
--error ER_DBACCESS_DENIED_ERROR
CREATE PACKAGE pkg1 AS
PROCEDURE p1;
END;
$$
DELIMITER ;$$
# TODO: this should probably return ER_DBACCESS_DENIED_ERROR
DELIMITER $$;
--error ER_SP_DOES_NOT_EXIST
CREATE PACKAGE BODY pkg1 AS
PROCEDURE p1 AS BEGIN NULL; END;
END;
$$
DELIMITER ;$$
--echo #
--echo # Now create a PACKAGE by root
--echo #
connection default;
USE db1;
DELIMITER $$;
CREATE PROCEDURE p1root AS
BEGIN
SELECT 1;
END;
$$
DELIMITER ;$$
DELIMITER $$;
CREATE PACKAGE pkg1 AS
PROCEDURE p1;
FUNCTION f1 RETURN TEXT;
END;
$$
DELIMITER ;$$
SHOW CREATE PACKAGE pkg1;
--echo #
--echo # u1 cannot SHOW yet:
--echo # - the standalone procedure earlier created by root
--echo # - the package specifications earlier create by root
--echo #
connection conn1;
--error ER_SP_DOES_NOT_EXIST
SHOW CREATE PROCEDURE p1root;
--error ER_SP_DOES_NOT_EXIST
SHOW CREATE PACKAGE pkg1;
--echo #
--echo # User u1 still cannot create a PACKAGE BODY
--echo #
connection conn1;
DELIMITER $$;
--error ER_DBACCESS_DENIED_ERROR
CREATE PACKAGE BODY pkg1 AS
PROCEDURE p1 AS BEGIN NULL; END;
FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is f1'; END;
END;
$$
DELIMITER ;$$
--echo #
--echo # Now grant EXECUTE:
--echo # - on the standalone procedure earlier created by root
--echo # - on the package specification earlier created by root
--echo #
connection default;
GRANT EXECUTE ON PROCEDURE db1.p1root TO u1@localhost;
GRANT EXECUTE ON PACKAGE db1.pkg1 TO u1@localhost;
--echo #
--echo # Now u1 can do SHOW for:
--echo # - the standalone procedure earlier created by root
--echo # - the package specification earlier created by root
--echo #
disconnect conn1;
connect (conn1,localhost,u1,,db1);
SET sql_mode=ORACLE;
SHOW CREATE PROCEDURE db1.p1root;
SHOW CREATE PACKAGE db1.pkg1;
--echo #
--echo # Now revoke EXECUTE and grant CREATE ROUTINE instead
--echo #
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;
--echo #
--echo # Reconnect u1 to make new grants have effect
--echo #
disconnect conn1;
connect (conn1,localhost,u1,,db1);
SET sql_mode=ORACLE;
--echo #
--echo # Now u1 can SHOW:
--echo # - standalone routines earlier created by root
--echo # - package specifications earlier created by root
--echo #
SHOW CREATE PROCEDURE p1root;
SHOW CREATE PACKAGE pkg1;
--echo #
--echo # Now u1 can CREATE, DROP and EXECUTE its own standalone procedures
--echo #
DELIMITER $$;
CREATE PROCEDURE p1 AS
BEGIN
NULL;
END;
$$
DELIMITER ;$$
SHOW GRANTS;
CALL p1;
DROP PROCEDURE p1;
SHOW GRANTS;
--echo #
--echo # Now u1 can also CREATE, DROP its own package specifications
--echo #
DELIMITER $$;
CREATE PACKAGE pkg2 AS
PROCEDURE p1;
FUNCTION f1 RETURN TEXT;
END;
$$
DELIMITER ;$$
SHOW CREATE PACKAGE pkg2;
SHOW GRANTS;
DROP PACKAGE pkg2;
SHOW GRANTS;
--echo #
--echo # Now u1 can also CREATE, DROP package bodies and EXECUTE package body routines
--echo #
DELIMITER $$;
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;
$$
DELIMITER ;$$
SHOW CREATE PACKAGE pkg1;
SHOW CREATE PACKAGE BODY pkg1;
SHOW GRANTS;
CALL pkg1.p1;
SELECT pkg1.f1();
DROP PACKAGE BODY pkg1;
SHOW GRANTS;
--echo #
--echo # Now create a PACKAGE BODY by root.
--echo # u1 does not have EXECUTE access by default.
--echo #
connection default;
DELIMITER $$;
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;
$$
DELIMITER ;$$
connection conn1;
SHOW CREATE PACKAGE pkg1;
SHOW CREATE PACKAGE BODY pkg1;
--error ER_PROCACCESS_DENIED_ERROR
CALL pkg1.p1;
--error ER_PROCACCESS_DENIED_ERROR
SELECT pkg1.f1();
--echo #
--echo # Now grant EXECUTE to u1 on the PACKAGE BODY created by root
--echo #
connection default;
GRANT EXECUTE ON PACKAGE BODY db1.pkg1 TO u1@localhost;
disconnect conn1;
connect (conn1,localhost,u1,,db1);
SELECT CURRENT_USER;
SET sql_mode=ORACLE;
SHOW GRANTS;
CALL pkg1.p1;
SELECT pkg1.f1();
connection default;
DROP PACKAGE BODY pkg1;
--echo #
--echo # u1 still cannot DROP the package specification earlier created by root.
--echo #
connection conn1;
--error ER_PROCACCESS_DENIED_ERROR
DROP PACKAGE pkg1;
--echo #
--echo # Grant ALTER ROUTINE to u1
--echo #
connection default;
GRANT ALTER ROUTINE ON db1.* TO u1@localhost;
--echo #
--echo # Now u1 can DROP:
--echo # - the standalone procedure earlier created by root
--echo # - the package specification earlier created by root
--echo #
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;
--echo #
--echo # Creator=root, definer=xxx
--echo #
CREATE USER xxx@localhost;
DELIMITER $$;
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;
$$
DELIMITER ;$$
--error ER_PROCACCESS_DENIED_ERROR
CALL p1.p1;
GRANT EXECUTE ON PACKAGE BODY test.p1 TO xxx@localhost;
CALL p1.p1;
DROP PACKAGE p1;
DROP USER xxx@localhost;
--echo #
--echo # Creator=root, definer=xxx, SQL SECURITY INVOKER
--echo #
CREATE USER xxx@localhost;
DELIMITER $$;
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;
$$
DELIMITER ;$$
CALL p1.p1;
DROP PACKAGE p1;
DROP USER xxx@localhost;

File diff suppressed because it is too large Load Diff

View File

@ -170,6 +170,11 @@ END;
DELIMITER ;/
DROP PROCEDURE p1;
--echo # 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;
DROP TABLE function;
--echo # Testing that (some) keyword_sp are allowed in Oracle-style assignments
DELIMITER /;