diff --git a/mysql-test/suite/compat/oracle/r/sp-param.result b/mysql-test/suite/compat/oracle/r/sp-param.result index 15e1516efdb..301c0f09fc5 100644 --- a/mysql-test/suite/compat/oracle/r/sp-param.result +++ b/mysql-test/suite/compat/oracle/r/sp-param.result @@ -216,3 +216,189 @@ 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 1 +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)) +65535 +CALL p2(65536); +LENGTH(f1(str,padlen)) +65535 +Warnings: +Warning 1265 Data truncated for column 'pin' at row 1 +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); +length(pout) +21845 +CALL p2(21846); +ERROR 22001: Data too long for column 'pin' at row 1 +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(21845); +length(pout) +21845 +CALL p2(21846); +ERROR 22001: Data too long for column 'pin' at row 1 +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(65535); +LENGTH(f1(str,padlen)) +65535 +CALL p2(65536); +ERROR 22001: Data too long for column 'pin' at row 1 +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(21845); +LENGTH(f1(str,padlen)) +21845 +CALL p2(21846); +ERROR 22001: Data too long for column 'pin' at row 1 +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(21845); +LENGTH(f1(str,padlen)) +21845 +CALL p2(21846); +ERROR 22001: Data too long for column 'pin' at row 1 +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(65535); +LENGTH(f1(str,padlen)) +65535 +CALL p2(65536); +ERROR 22001: Data too long for column 'pin' at row 1 +DROP PROCEDURE p2; +DROP FUNCTION f1; diff --git a/mysql-test/suite/compat/oracle/t/sp-param.test b/mysql-test/suite/compat/oracle/t/sp-param.test index 0a6d7dec0fd..769aeca93d4 100644 --- a/mysql-test/suite/compat/oracle/t/sp-param.test +++ b/mysql-test/suite/compat/oracle/t/sp-param.test @@ -117,3 +117,228 @@ end; / drop procedure p1 / +DELIMITER ;/ + + +# +# Procedure, non-strict mode +# + +SET sql_mode=ORACLE; +DELIMITER /; +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; +/ +DELIMITER ;/ +CALL p2(10); +CALL p2(11); +DROP PROCEDURE p1; +DROP PROCEDURE p2; + + +# +# Function, not-strict mode +# + +SET sql_mode=ORACLE; +DELIMITER /; +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; +/ +DELIMITER ;/ +CALL p2(65535); +CALL p2(65536); +DROP PROCEDURE p2; +DROP FUNCTION f1; + + +# +# Procedure, utf8 formal parameter, latin actual parameter +# + +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +DELIMITER /; +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; +/ +DELIMITER ;/ +CALL p2(21844); +CALL p2(21845); +--error ER_DATA_TOO_LONG +CALL p2(21846); +DROP PROCEDURE p2; +DROP PROCEDURE p1; + + +# +# Procedure, utf8 formal parameter, utf8 actual parameter +# + +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +DELIMITER /; +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; +/ +DELIMITER ;/ +CALL p2(21845); +--error ER_DATA_TOO_LONG +CALL p2(21846); +DROP PROCEDURE p2; +DROP PROCEDURE p1; + + +# +# Function, latin1 formal parameter, latin1 actual parameter +# + +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +DELIMITER /; +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; +/ +DELIMITER ;/ +CALL p2(65535); +--error ER_DATA_TOO_LONG +CALL p2(65536); +DROP PROCEDURE p2; +DROP FUNCTION f1; + + +# +# Function, utf8 formal parameter, utf8 actual parameter +# + +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +DELIMITER /; +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; +/ +DELIMITER ;/ +CALL p2(21845); +--error ER_DATA_TOO_LONG +CALL p2(21846); +DROP PROCEDURE p2; +DROP FUNCTION f1; + + +# +# Function, utf8 formal parameter, latin1 actual parameter +# + +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +DELIMITER /; +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; +/ +DELIMITER ;/ +CALL p2(21845); +--error ER_DATA_TOO_LONG +CALL p2(21846); +DROP PROCEDURE p2; +DROP FUNCTION f1; + + +# +# Function, latin1 formal parameter, utf8 actual parameter +# + +SET sql_mode='ORACLE,STRICT_TRANS_TABLES'; +DELIMITER /; +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; +/ +DELIMITER ;/ +CALL p2(65535); +--error ER_DATA_TOO_LONG +CALL p2(65536); +DROP PROCEDURE p2; +DROP FUNCTION f1; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 72ce5d65a5d..16688a4ae63 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1674,9 +1674,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, thd->set_n_backup_active_arena(&call_arena, &backup_arena); for (uint i= 0 ; i < argcount ; i++) - { largs.push_back(argp[i]); - } if (!(nctx= rcontext_create(thd, return_value_fld, &largs))) { diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 339d24ebeb6..737d01f7b89 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -2384,6 +2384,8 @@ Field *Type_handler_set::make_table_field(const LEX_CSTRING *name, attr.collation); } +/*************************************************************************/ + /* If length is not specified for a varchar parameter, set length to the maximum length of the actual argument. Goals are: