diff options
author | Alexander Barkov <bar@mariadb.com> | 2018-03-23 14:23:48 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2018-03-27 07:59:57 +0400 |
commit | 902ace096816697ee5d5ac06bd5caea67b624c40 (patch) | |
tree | 6de24c00892127c7ac9cb9394ae9410ca3bba764 /mysql-test/suite/compat | |
parent | ad647cc84ebf331d59b24e81bffe89be2f5b1ed7 (diff) | |
download | mariadb-git-902ace096816697ee5d5ac06bd5caea67b624c40.tar.gz |
MDEV-15620 Crash when using "SET @@NEW.a=expr" inside a trigger
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
Diffstat (limited to 'mysql-test/suite/compat')
-rw-r--r-- | mysql-test/suite/compat/oracle/r/func_misc.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/parser.result | 18 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/trigger.result | 6 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/parser.test | 24 |
4 files changed, 46 insertions, 4 deletions
diff --git a/mysql-test/suite/compat/oracle/r/func_misc.result b/mysql-test/suite/compat/oracle/r/func_misc.result index 0e2ba0c6f50..f285423b446 100644 --- a/mysql-test/suite/compat/oracle/r/func_misc.result +++ b/mysql-test/suite/compat/oracle/r/func_misc.result @@ -35,7 +35,7 @@ CALL p1('SELECT 1'); Error1: 0 normal, successful completition CALL p1('xxx'); 'Error2: ' || SQLCODE || ' ' || SQLERRM -Error2: 1193 Unknown system variable 'xxx' +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 diff --git a/mysql-test/suite/compat/oracle/r/parser.result b/mysql-test/suite/compat/oracle/r/parser.result new file mode 100644 index 00000000000..29588a68045 --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/parser.result @@ -0,0 +1,18 @@ +SET sql_mode=ORACLE; +# +# MDEV-15620 Crash when using "SET @@NEW.a=expr" inside a trigger +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @@NEW.a=0; +ERROR HY000: Unknown structured system variable or ROW routine variable 'NEW' +DROP TABLE t1; +# +# MDEV-15615 Unexpected syntax error instead of "Unknown system variable" inside an SP +# +DECLARE +a INT; +BEGIN +SET GLOBAL a=10; +END; +$$ +ERROR HY000: Unknown system variable 'a' diff --git a/mysql-test/suite/compat/oracle/r/trigger.result b/mysql-test/suite/compat/oracle/r/trigger.result index f77a56546fa..7c24c78bba6 100644 --- a/mysql-test/suite/compat/oracle/r/trigger.result +++ b/mysql-test/suite/compat/oracle/r/trigger.result @@ -1,10 +1,10 @@ set sql_mode=ORACLE; :NEW.a := 1; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a := 1' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':NEW.a := 1' at line 1 :OLD.a := 1; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a := 1' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':OLD.a := 1' at line 1 :OLa.a := 1; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a := 1' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':OLa.a := 1' at line 1 SELECT :NEW.a; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a' at line 1 SELECT :OLD.a; diff --git a/mysql-test/suite/compat/oracle/t/parser.test b/mysql-test/suite/compat/oracle/t/parser.test new file mode 100644 index 00000000000..5aa37c1cd33 --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/parser.test @@ -0,0 +1,24 @@ +SET sql_mode=ORACLE; + +--echo # +--echo # MDEV-15620 Crash when using "SET @@NEW.a=expr" inside a trigger +--echo # + +CREATE TABLE t1 (a INT); +--error ER_UNKNOWN_STRUCTURED_VARIABLE +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @@NEW.a=0; +DROP TABLE t1; + +--echo # +--echo # MDEV-15615 Unexpected syntax error instead of "Unknown system variable" inside an SP +--echo # + +DELIMITER $$; +--error ER_UNKNOWN_SYSTEM_VARIABLE +DECLARE + a INT; +BEGIN + SET GLOBAL a=10; +END; +$$ +DELIMITER ;$$ |