mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-10801 sql_mode: dynamic SQL placeholders
This commit is contained in:
67
mysql-test/suite/compat/oracle/r/binlog_stm_ps.result
Normal file
67
mysql-test/suite/compat/oracle/r/binlog_stm_ps.result
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
SET sql_mode=ORACLE;
|
||||||
|
#
|
||||||
|
# MDEV-10801 sql_mode: dynamic SQL placeholders
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT);
|
||||||
|
SET @a=10, @b=20;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (?,?)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:a,:b)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:aaa,:bbb)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:"a",:"b")';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:"aaa",:"bbb")';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:1,:2)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:222,:111)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:0,:65535)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:65535,:0)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b
|
||||||
|
10 20
|
||||||
|
10 20
|
||||||
|
10 20
|
||||||
|
10 20
|
||||||
|
10 20
|
||||||
|
10 20
|
||||||
|
10 20
|
||||||
|
10 20
|
||||||
|
10 20
|
||||||
|
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 TABLE t1 (a INT, b INT)
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (10,20)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
DROP TABLE t1;
|
41
mysql-test/suite/compat/oracle/r/ps.result
Normal file
41
mysql-test/suite/compat/oracle/r/ps.result
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
SET sql_mode=ORACLE;
|
||||||
|
#
|
||||||
|
# MDEV-10801 sql_mode: dynamic SQL placeholders
|
||||||
|
#
|
||||||
|
SET @a=10, @b=20;
|
||||||
|
PREPARE stmt FROM 'SELECT ?,?';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
? ?
|
||||||
|
10 20
|
||||||
|
PREPARE stmt FROM 'SELECT :a,:b';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
:a :b
|
||||||
|
10 20
|
||||||
|
PREPARE stmt FROM 'SELECT :aaa,:bbb';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
:aaa :bbb
|
||||||
|
10 20
|
||||||
|
PREPARE stmt FROM 'SELECT :"a",:"b"';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
:"a" :"b"
|
||||||
|
10 20
|
||||||
|
PREPARE stmt FROM 'SELECT :"aaa",:"bbb"';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
:"aaa" :"bbb"
|
||||||
|
10 20
|
||||||
|
PREPARE stmt FROM 'SELECT :1,:2';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
:1 :2
|
||||||
|
10 20
|
||||||
|
PREPARE stmt FROM 'SELECT :222,:111';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
:222 :111
|
||||||
|
10 20
|
||||||
|
PREPARE stmt FROM 'SELECT :0,:65535';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
:0 :65535
|
||||||
|
10 20
|
||||||
|
PREPARE stmt FROM 'SELECT :65535,:0';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
:65535 :0
|
||||||
|
10 20
|
37
mysql-test/suite/compat/oracle/t/binlog_stm_ps.test
Normal file
37
mysql-test/suite/compat/oracle/t/binlog_stm_ps.test
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
--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;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-10801 sql_mode: dynamic SQL placeholders
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, b INT);
|
||||||
|
SET @a=10, @b=20;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (?,?)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:a,:b)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:aaa,:bbb)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:"a",:"b")';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:"aaa",:"bbb")';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:1,:2)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:222,:111)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:0,:65535)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'INSERT INTO t1 VALUES (:65535,:0)';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
--let $binlog_file = LAST
|
||||||
|
source include/show_binlog_events.inc;
|
||||||
|
DROP TABLE t1;
|
25
mysql-test/suite/compat/oracle/t/ps.test
Normal file
25
mysql-test/suite/compat/oracle/t/ps.test
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
SET sql_mode=ORACLE;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-10801 sql_mode: dynamic SQL placeholders
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET @a=10, @b=20;
|
||||||
|
PREPARE stmt FROM 'SELECT ?,?';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'SELECT :a,:b';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'SELECT :aaa,:bbb';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'SELECT :"a",:"b"';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'SELECT :"aaa",:"bbb"';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'SELECT :1,:2';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'SELECT :222,:111';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'SELECT :0,:65535';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
||||||
|
PREPARE stmt FROM 'SELECT :65535,:0';
|
||||||
|
EXECUTE stmt USING @a, @b;
|
@@ -3341,9 +3341,10 @@ default_set_param_func(Item_param *param,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item_param::Item_param(THD *thd, uint pos_in_query_arg):
|
Item_param::Item_param(THD *thd, char *name_arg,
|
||||||
|
uint pos_in_query_arg, uint len_in_query_arg):
|
||||||
Item_basic_value(thd),
|
Item_basic_value(thd),
|
||||||
Rewritable_query_parameter(pos_in_query_arg, 1),
|
Rewritable_query_parameter(pos_in_query_arg, len_in_query_arg),
|
||||||
Type_handler_hybrid_field_type(MYSQL_TYPE_VARCHAR),
|
Type_handler_hybrid_field_type(MYSQL_TYPE_VARCHAR),
|
||||||
state(NO_VALUE),
|
state(NO_VALUE),
|
||||||
/* Don't pretend to be a literal unless value for this item is set. */
|
/* Don't pretend to be a literal unless value for this item is set. */
|
||||||
@@ -3360,7 +3361,7 @@ Item_param::Item_param(THD *thd, uint pos_in_query_arg):
|
|||||||
*/
|
*/
|
||||||
m_is_settable_routine_parameter(true)
|
m_is_settable_routine_parameter(true)
|
||||||
{
|
{
|
||||||
name= (char*) "?";
|
name= name_arg;
|
||||||
/*
|
/*
|
||||||
Since we can't say whenever this item can be NULL or cannot be NULL
|
Since we can't say whenever this item can be NULL or cannot be NULL
|
||||||
before mysql_stmt_execute(), so we assuming that it can be NULL until
|
before mysql_stmt_execute(), so we assuming that it can be NULL until
|
||||||
|
@@ -2813,7 +2813,8 @@ public:
|
|||||||
enum Item_result cmp_type () const
|
enum Item_result cmp_type () const
|
||||||
{ return Type_handler_hybrid_field_type::cmp_type(); }
|
{ return Type_handler_hybrid_field_type::cmp_type(); }
|
||||||
|
|
||||||
Item_param(THD *thd, uint pos_in_query_arg);
|
Item_param(THD *thd, char *name_arg,
|
||||||
|
uint pos_in_query_arg, uint len_in_query_arg);
|
||||||
|
|
||||||
enum Type type() const
|
enum Type type() const
|
||||||
{
|
{
|
||||||
|
@@ -5876,6 +5876,33 @@ Item *LEX::create_and_link_Item_trigger_field(THD *thd, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item_param *LEX::add_placeholder(THD *thd, char *name,
|
||||||
|
uint pos_in_query, uint len_in_query)
|
||||||
|
{
|
||||||
|
if (!parsing_options.allows_variable)
|
||||||
|
{
|
||||||
|
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Item_param *item= new (thd->mem_root) Item_param(thd, name,
|
||||||
|
pos_in_query, len_in_query);
|
||||||
|
if (!item || param_list.push_back(item, thd->mem_root))
|
||||||
|
{
|
||||||
|
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item_param *LEX::add_placeholder(THD *thd, char *name,
|
||||||
|
const char *pos, const char *end)
|
||||||
|
{
|
||||||
|
const char *query_start= sphead ? sphead->m_tmp_query : thd->query();
|
||||||
|
return add_placeholder(thd, name, pos - query_start, end - pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef MYSQL_SERVER
|
#ifdef MYSQL_SERVER
|
||||||
uint binlog_unsafe_map[256];
|
uint binlog_unsafe_map[256];
|
||||||
|
|
||||||
|
@@ -3182,6 +3182,11 @@ public:
|
|||||||
bool sp_while_loop_expression(THD *thd, Item *expr);
|
bool sp_while_loop_expression(THD *thd, Item *expr);
|
||||||
bool sp_while_loop_finalize(THD *thd);
|
bool sp_while_loop_finalize(THD *thd);
|
||||||
|
|
||||||
|
Item_param *add_placeholder(THD *thd, char *name,
|
||||||
|
uint pos_in_query, uint len_in_query);
|
||||||
|
Item_param *add_placeholder(THD *thd, char *name,
|
||||||
|
const char *pos, const char *end);
|
||||||
|
|
||||||
sp_variable *sp_add_for_loop_variable(THD *thd, const LEX_STRING name,
|
sp_variable *sp_add_for_loop_variable(THD *thd, const LEX_STRING name,
|
||||||
Item *value);
|
Item *value);
|
||||||
sp_variable *sp_add_for_loop_upper_bound(THD *thd, Item *value)
|
sp_variable *sp_add_for_loop_upper_bound(THD *thd, Item *value)
|
||||||
|
@@ -13464,17 +13464,10 @@ hex_or_bin_String:
|
|||||||
param_marker:
|
param_marker:
|
||||||
PARAM_MARKER
|
PARAM_MARKER
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (!($$= Lex->add_placeholder(thd, (char *) "?",
|
||||||
Lex_input_stream *lip= YYLIP;
|
YYLIP->get_tok_start(),
|
||||||
Item_param *item;
|
YYLIP->get_tok_start() + 1)))
|
||||||
if (! lex->parsing_options.allows_variable)
|
MYSQL_YYABORT;
|
||||||
my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0)));
|
|
||||||
const char *query_start= lex->sphead ? lex->sphead->m_tmp_query
|
|
||||||
: thd->query();
|
|
||||||
item= new (thd->mem_root) Item_param(thd, lip->get_tok_start() -
|
|
||||||
query_start);
|
|
||||||
if (!($$= item) || lex->param_list.push_back(item, thd->mem_root))
|
|
||||||
my_yyabort_error((ER_OUT_OF_RESOURCES, MYF(0)));
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@@ -1006,6 +1006,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
remember_name remember_end opt_db remember_tok_start
|
remember_name remember_end opt_db remember_tok_start
|
||||||
wild_and_where
|
wild_and_where
|
||||||
field_length opt_field_length opt_field_length_default_1
|
field_length opt_field_length opt_field_length_default_1
|
||||||
|
colon_with_pos
|
||||||
|
|
||||||
%type <const_simple_string>
|
%type <const_simple_string>
|
||||||
opt_place
|
opt_place
|
||||||
@@ -8074,6 +8075,13 @@ select_item:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
colon_with_pos:
|
||||||
|
':'
|
||||||
|
{
|
||||||
|
$$= (char *) YYLIP->get_tok_start();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
remember_tok_start:
|
remember_tok_start:
|
||||||
{
|
{
|
||||||
$$= (char*) YYLIP->get_tok_start();
|
$$= (char*) YYLIP->get_tok_start();
|
||||||
@@ -13142,17 +13150,22 @@ hex_or_bin_String:
|
|||||||
param_marker:
|
param_marker:
|
||||||
PARAM_MARKER
|
PARAM_MARKER
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (!($$= Lex->add_placeholder(thd, (char *) "?",
|
||||||
Lex_input_stream *lip= YYLIP;
|
YYLIP->get_tok_start(),
|
||||||
Item_param *item;
|
YYLIP->get_tok_start() + 1)))
|
||||||
if (! lex->parsing_options.allows_variable)
|
MYSQL_YYABORT;
|
||||||
my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0)));
|
}
|
||||||
const char *query_start= lex->sphead ? lex->sphead->m_tmp_query
|
| colon_with_pos ident
|
||||||
: thd->query();
|
{
|
||||||
item= new (thd->mem_root) Item_param(thd, lip->get_tok_start() -
|
if (!($$= Lex->add_placeholder(thd, NULL,
|
||||||
query_start);
|
$1, YYLIP->get_tok_end())))
|
||||||
if (!($$= item) || lex->param_list.push_back(item, thd->mem_root))
|
MYSQL_YYABORT;
|
||||||
my_yyabort_error((ER_OUT_OF_RESOURCES, MYF(0)));
|
}
|
||||||
|
| colon_with_pos NUM
|
||||||
|
{
|
||||||
|
if (!($$= Lex->add_placeholder(thd, NULL,
|
||||||
|
$1, YYLIP->get_ptr())))
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -13538,7 +13551,7 @@ simple_ident_q:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| ':' ident '.' ident
|
| colon_with_pos ident '.' ident
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
if (lex->is_trigger_new_or_old_reference($2))
|
if (lex->is_trigger_new_or_old_reference($2))
|
||||||
@@ -14691,7 +14704,7 @@ internal_variable_name_directly_assignable:
|
|||||||
if (Lex->init_default_internal_variable(&$$, $3))
|
if (Lex->init_default_internal_variable(&$$, $3))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| ':' ident_directly_assignable '.' ident
|
| colon_with_pos ident_directly_assignable '.' ident
|
||||||
{
|
{
|
||||||
if (!Lex->is_trigger_new_or_old_reference($2))
|
if (!Lex->is_trigger_new_or_old_reference($2))
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user