From 0ff8f60b45552c7c78221f3e47219feafa63eb62 Mon Sep 17 00:00:00 2001 From: "anozdrin@mysql.com" <> Date: Wed, 7 Dec 2005 17:01:17 +0300 Subject: [PATCH] Patch for WL#2894: Make stored routine variables work according to the standard. The idea is to use Field-classes to implement stored routines variables. Also, we should provide facade to Item-hierarchy by Item_field class (it is necessary, since SRVs take part in expressions). The patch fixes the following bugs: - BUG#8702: Stored Procedures: No Error/Warning shown for inappropriate data type matching; - BUG#8768: Functions: For any unsigned data type, -ve values can be passed and returned; - BUG#8769: Functions: For Int datatypes, out of range values can be passed and returned; - BUG#9078: STORED PROCDURE: Decimal digits are not displayed when we use DECIMAL datatype; - BUG#9572: Stored procedures: variable type declarations ignored; - BUG#12903: upper function does not work inside a function; - BUG#13705: parameters to stored procedures are not verified; - BUG#13808: ENUM type stored procedure parameter accepts non-enumerated data; - BUG#13909: Varchar Stored Procedure Parameter always BINARY string (ignores CHARACTER SET); - BUG#14161: Stored procedure cannot retrieve bigint unsigned; - BUG#14188: BINARY variables have no 0x00 padding; - BUG#15148: Stored procedure variables accept non-scalar values; --- mysql-test/include/sp-vars.inc | 122 +++ mysql-test/r/ctype_ujis.result | 2 +- mysql-test/r/schema.result | 1 + mysql-test/r/show_check.result | 1 + mysql-test/r/skip_name_resolve.result | 4 +- mysql-test/r/sp-big.result | 1 + mysql-test/r/sp-dynamic.result | 2 + mysql-test/r/sp-vars.result | 1077 +++++++++++++++++++ mysql-test/r/sp.result | 41 +- mysql-test/r/sum_distinct-big.result | 29 +- mysql-test/r/type_newdecimal-big.result | 31 +- mysql-test/sp-vars.test | 1273 +++++++++++++++++++++++ mysql-test/t/ctype_ujis.test | 2 +- mysql-test/t/schema.test | 6 + mysql-test/t/show_check.test | 1 + mysql-test/t/skip_name_resolve.test | 2 +- mysql-test/t/sp-big.test | 3 + mysql-test/t/sp-dynamic.test | 6 + mysql-test/t/sp.test | 9 +- mysql-test/t/type_newdecimal-big.test | 31 +- sql/field.cc | 347 ++++++ sql/field.h | 18 + sql/item.cc | 197 ++-- sql/item.h | 249 +++-- sql/item_func.cc | 51 +- sql/item_func.h | 4 +- sql/mysql_priv.h | 3 +- sql/sp.cc | 2 +- sql/sp_head.cc | 952 +++++++++-------- sql/sp_head.h | 61 +- sql/sp_pcontext.cc | 75 +- sql/sp_pcontext.h | 98 +- sql/sp_rcontext.cc | 304 +++++- sql/sp_rcontext.h | 148 +-- sql/sql_class.cc | 10 +- sql/sql_class.h | 2 +- sql/sql_parse.cc | 328 +----- sql/sql_select.cc | 13 + sql/sql_select.h | 1 - sql/sql_trigger.cc | 6 +- sql/sql_yacc.yy | 227 ++-- 41 files changed, 4486 insertions(+), 1254 deletions(-) create mode 100644 mysql-test/include/sp-vars.inc create mode 100644 mysql-test/r/sp-vars.result create mode 100644 mysql-test/sp-vars.test diff --git a/mysql-test/include/sp-vars.inc b/mysql-test/include/sp-vars.inc new file mode 100644 index 00000000000..3e02c9d1709 --- /dev/null +++ b/mysql-test/include/sp-vars.inc @@ -0,0 +1,122 @@ +delimiter |; + +--------------------------------------------------------------------------- + +CREATE PROCEDURE sp_vars_check_dflt() +BEGIN + DECLARE v1 TINYINT DEFAULT 1e200; + DECLARE v1u TINYINT UNSIGNED DEFAULT 1e200; + DECLARE v2 TINYINT DEFAULT -1e200; + DECLARE v2u TINYINT UNSIGNED DEFAULT -1e200; + DECLARE v3 TINYINT DEFAULT 300; + DECLARE v3u TINYINT UNSIGNED DEFAULT 300; + DECLARE v4 TINYINT DEFAULT -300; + DECLARE v4u TINYINT UNSIGNED DEFAULT -300; + + DECLARE v5 TINYINT DEFAULT 10 * 10 * 10; + DECLARE v5u TINYINT UNSIGNED DEFAULT 10 * 10 * 10; + DECLARE v6 TINYINT DEFAULT -10 * 10 * 10; + DECLARE v6u TINYINT UNSIGNED DEFAULT -10 * 10 * 10; + + DECLARE v7 TINYINT DEFAULT '10'; + DECLARE v8 TINYINT DEFAULT '10 '; + DECLARE v9 TINYINT DEFAULT ' 10 '; + DECLARE v10 TINYINT DEFAULT 'String 10 '; + DECLARE v11 TINYINT DEFAULT 'String10'; + DECLARE v12 TINYINT DEFAULT '10 String'; + DECLARE v13 TINYINT DEFAULT '10String'; + DECLARE v14 TINYINT DEFAULT concat('10', ' '); + DECLARE v15 TINYINT DEFAULT concat(' ', '10'); + DECLARE v16 TINYINT DEFAULT concat('Hello, ', 'world'); + + DECLARE v17 DECIMAL(64, 2) DEFAULT 12; + DECLARE v18 DECIMAL(64, 2) DEFAULT 12.123; + DECLARE v19 DECIMAL(64, 2) DEFAULT 11 + 1; + DECLARE v20 DECIMAL(64, 2) DEFAULT 12 + 0.123; + + SELECT v1, v1u, v2, v2u, v3, v3u, v4, v4u; + SELECT v5, v5u, v6, v6u; + SELECT v7, v8, v9, v10, v11, v12, v13, v14, v15, v16; + SELECT v17, v18, v19, v20; +END| + +--------------------------------------------------------------------------- + +CREATE PROCEDURE sp_vars_check_assignment() +BEGIN + DECLARE i1, i2, i3, i4 TINYINT; + DECLARE u1, u2, u3, u4 TINYINT UNSIGNED; + DECLARE d1, d2, d3 DECIMAL(64, 2); + + SET i1 = 1e200; + SET i2 = -1e200; + SET i3 = 300; + SET i4 = -300; + + SELECT i1, i2, i3, i4; + + SET i1 = 10 * 10 * 10; + SET i2 = -10 * 10 * 10; + SET i3 = sign(10 * 10) * 10 * 20; + SET i4 = sign(-10 * 10) * -10 * 20; + + SELECT i1, i2, i3, i4; + + SET u1 = 1e200; + SET u2 = -1e200; + SET u3 = 300; + SET u4 = -300; + + SELECT u1, u2, u3, u4; + + SET u1 = 10 * 10 * 10; + SET u2 = -10 * 10 * 10; + SET u3 = sign(10 * 10) * 10 * 20; + SET u4 = sign(-10 * 10) * -10 * 20; + + SELECT u1, u2, u3, u4; + + SET d1 = 1234; + SET d2 = 1234.12; + SET d3 = 1234.1234; + + SELECT d1, d2, d3; + + SET d1 = 12 * 100 + 34; + SET d2 = 12 * 100 + 34 + 0.12; + SET d3 = 12 * 100 + 34 + 0.1234; + + SELECT d1, d2, d3; +END| + +--------------------------------------------------------------------------- + +CREATE FUNCTION sp_vars_check_ret1() RETURNS TINYINT +BEGIN + RETURN 1e200; +END| + +--------------------------------------------------------------------------- + +CREATE FUNCTION sp_vars_check_ret2() RETURNS TINYINT +BEGIN + RETURN 10 * 10 * 10; +END| + +--------------------------------------------------------------------------- + +CREATE FUNCTION sp_vars_check_ret3() RETURNS TINYINT +BEGIN + RETURN 'Hello, world'; +END| + +--------------------------------------------------------------------------- + +CREATE FUNCTION sp_vars_check_ret4() RETURNS DECIMAL(64, 2) +BEGIN + RETURN 12 * 10 + 34 + 0.1234; +END| + +--------------------------------------------------------------------------- + +delimiter ;| diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result index 15de93440fc..2e14fe34430 100644 --- a/mysql-test/r/ctype_ujis.result +++ b/mysql-test/r/ctype_ujis.result @@ -2317,7 +2317,7 @@ CREATE TABLE t2(c2 char(2)) default charset = ujis; INSERT INTO t1 VALUES(_ujis 0xA4A2); CREATE PROCEDURE sp1() BEGIN -DECLARE a CHAR(1); +DECLARE a CHAR(2) CHARSET ujis; DECLARE cur1 CURSOR FOR SELECT c1 FROM t1; OPEN cur1; FETCH cur1 INTO a; diff --git a/mysql-test/r/schema.result b/mysql-test/r/schema.result index 48e6ebcfad2..538abd8d039 100644 --- a/mysql-test/r/schema.result +++ b/mysql-test/r/schema.result @@ -1,3 +1,4 @@ +drop database if exists mysqltest1; create schema foo; show create schema foo; Database Create Database diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index fdb0db602ff..61a820b4469 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1,6 +1,7 @@ drop table if exists t1,t2; drop table if exists t1aa,t2aa; drop database if exists mysqltest; +drop database if exists mysqltest1; delete from mysql.user where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3'; delete from mysql.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3'; flush privileges; diff --git a/mysql-test/r/skip_name_resolve.result b/mysql-test/r/skip_name_resolve.result index a969c5c9ae0..8ef52e75238 100644 --- a/mysql-test/r/skip_name_resolve.result +++ b/mysql-test/r/skip_name_resolve.result @@ -10,5 +10,5 @@ user() # show processlist; Id User Host db Command Time State Info -# root # test Sleep # NULL -# root # test Query # NULL show processlist + root test