mirror of
https://github.com/MariaDB/server.git
synced 2025-06-01 19:42:01 +03:00
The problem resided in this branch of the "option_value_no_option_type" rule: | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default Summary: 1. internal_variable_name initialized tmp.var to trg_new_row_fake_var (0x01). 2. The condition "if (tmp.var == NULL)" did not check the special case with trg_new_row_fake_var, so Lex->set_system_variable(&tmp, $3, $6) was called with tmp.var pointing to trg_new_row_fake_var, which created a sys_var instance pointing to 0x01 instead of a real system variable. 3. Later, at the trigger invocation time, this method was called: sys_var::do_deprecated_warning (this=0x1, thd=0x7ffe6c000a98) Notice, "this" is equal to trg_new_row_fake_var (0x01) Solution: The old implementation with separate rules internal_variable_name (in sql_yacc.yy and sql_yacc_ora.yy) and internal_variable_name_directly_assignable (in sql_yacc_ora.yy only) was too complex and hard to follow. Rewriting the code in a more straightforward way. 1. Changing LEX::set_system_variable() from: bool set_system_variable(struct sys_var_with_base *, enum_var_type, Item *); to: bool set_system_variable(enum_var_type, sys_var *, const LEX_CSTRING *, Item *); 2. Adding new methods in LEX, which operate with variable names: bool set_trigger_field(const LEX_CSTRING *, const LEX_CSTRING *, Item *); bool set_system_variable(enum_var_type var_type, const LEX_CSTRING *name, Item *val); bool set_system_variable(THD *thd, enum_var_type var_type, const LEX_CSTRING *name1, const LEX_CSTRING *name2, Item *val); bool set_default_system_variable(enum_var_type var_type, const LEX_CSTRING *name, Item *val); bool set_variable(const LEX_CSTRING *name, Item *item); 3. Changing the grammar to call the new methods directly in option_value_no_option_type, Removing rules internal_variable_name and internal_variable_name_directly_assignable. 4. Removing "struct sys_var_with_base" and trg_new_row_fake_var. Good side effect: - The code in /sql reduced from 314 to 183 lines. - MDEV-15615 Unexpected syntax error instead of "Unknown system variable" ... was also fixed automatically
320 lines
6.7 KiB
Plaintext
320 lines
6.7 KiB
Plaintext
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 completition
|
|
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 completition
|
|
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 utf8 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 completition
|
|
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 completition
|
|
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 completition
|
|
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 completition
|
|
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
|