mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-18796 Synchronize PS grammar between sql_yacc.yy and sql_yacc_ora.yy
This commit is contained in:
@ -4663,7 +4663,7 @@ EXECUTE IMMEDIATE 'SELECT ? FROM DUAL' USING (SELECT 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 'SELECT 1)' at line 1
|
||||
CREATE FUNCTION f1() RETURNS VARCHAR(10) RETURN 'test';
|
||||
EXECUTE IMMEDIATE 'SELECT ? FROM DUAL' USING f1();
|
||||
ERROR 42000: EXECUTE..USING does not support subqueries or stored functions
|
||||
ERROR 42000: EXECUTE IMMEDIATE does not support subqueries or stored functions
|
||||
DROP FUNCTION f1;
|
||||
#
|
||||
# DDL
|
||||
|
@ -163,7 +163,7 @@ RETURN 'test';
|
||||
END;
|
||||
$$
|
||||
EXECUTE IMMEDIATE 'SELECT ? FROM DUAL' USING f1();
|
||||
ERROR 42000: EXECUTE..USING does not support subqueries or stored functions
|
||||
ERROR 42000: EXECUTE IMMEDIATE does not support subqueries or stored functions
|
||||
DROP FUNCTION f1;
|
||||
#
|
||||
# Testing simple expressions
|
||||
|
@ -1338,11 +1338,10 @@ bool Protocol_text::store_time(MYSQL_TIME *tm, int decimals)
|
||||
|
||||
bool Protocol_text::send_out_parameters(List<Item_param> *sp_params)
|
||||
{
|
||||
DBUG_ASSERT(sp_params->elements ==
|
||||
thd->lex->prepared_stmt_params.elements);
|
||||
DBUG_ASSERT(sp_params->elements == thd->lex->prepared_stmt.param_count());
|
||||
|
||||
List_iterator_fast<Item_param> item_param_it(*sp_params);
|
||||
List_iterator_fast<Item> param_it(thd->lex->prepared_stmt_params);
|
||||
List_iterator_fast<Item> param_it(thd->lex->prepared_stmt.params());
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -1214,7 +1214,7 @@ public:
|
||||
|
||||
int insert(THD *thd, Statement *statement);
|
||||
|
||||
Statement *find_by_name(LEX_CSTRING *name)
|
||||
Statement *find_by_name(const LEX_CSTRING *name)
|
||||
{
|
||||
Statement *stmt;
|
||||
stmt= (Statement*)my_hash_search(&names_hash, (uchar*)name->str,
|
||||
|
@ -705,7 +705,7 @@ void LEX::start(THD *thd_arg)
|
||||
with_persistent_for_clause= FALSE;
|
||||
column_list= NULL;
|
||||
index_list= NULL;
|
||||
prepared_stmt_params.empty();
|
||||
prepared_stmt.lex_start();
|
||||
auxiliary_table_list.empty();
|
||||
unit.next= unit.master= unit.link_next= unit.return_to= 0;
|
||||
unit.prev= unit.link_prev= 0;
|
||||
@ -10216,3 +10216,50 @@ bool LEX::stmt_uninstall_plugin_by_soname(const DDL_options_st &opt,
|
||||
ident= soname;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LEX::stmt_prepare_validate(const char *stmt_type)
|
||||
{
|
||||
if (unlikely(table_or_sp_used()))
|
||||
{
|
||||
my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), stmt_type);
|
||||
return true;
|
||||
}
|
||||
return check_main_unit_semantics();
|
||||
}
|
||||
|
||||
|
||||
bool LEX::stmt_prepare(const Lex_ident_sys_st &ident, Item *code)
|
||||
{
|
||||
sql_command= SQLCOM_PREPARE;
|
||||
if (stmt_prepare_validate("PREPARE..FROM"))
|
||||
return true;
|
||||
prepared_stmt.set(ident, code, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LEX::stmt_execute_immediate(Item *code, List<Item> *params)
|
||||
{
|
||||
sql_command= SQLCOM_EXECUTE_IMMEDIATE;
|
||||
if (stmt_prepare_validate("EXECUTE IMMEDIATE"))
|
||||
return true;
|
||||
static const Lex_ident_sys immediate(STRING_WITH_LEN("IMMEDIATE"));
|
||||
prepared_stmt.set(immediate, code, params);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LEX::stmt_execute(const Lex_ident_sys_st &ident, List<Item> *params)
|
||||
{
|
||||
sql_command= SQLCOM_EXECUTE;
|
||||
prepared_stmt.set(ident, NULL, params);
|
||||
return stmt_prepare_validate("EXECUTE..USING");
|
||||
}
|
||||
|
||||
|
||||
void LEX::stmt_deallocate_prepare(const Lex_ident_sys_st &ident)
|
||||
{
|
||||
sql_command= SQLCOM_DEALLOCATE_PREPARE;
|
||||
prepared_stmt.set(ident, NULL, NULL);
|
||||
}
|
||||
|
@ -169,6 +169,16 @@ public:
|
||||
{
|
||||
((LEX_CSTRING &) *this)= null_clex_str;
|
||||
}
|
||||
Lex_ident_sys(const char *name, size_t length)
|
||||
{
|
||||
LEX_CSTRING tmp= {name, length};
|
||||
set_valid_utf8(&tmp);
|
||||
}
|
||||
Lex_ident_sys & operator=(const Lex_ident_sys_st &name)
|
||||
{
|
||||
Lex_ident_sys_st::operator=(name);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -2990,6 +3000,56 @@ struct Account_options: public USER_RESOURCES
|
||||
class Query_arena_memroot;
|
||||
/* The state of the lex parsing. This is saved in the THD struct */
|
||||
|
||||
|
||||
class Lex_prepared_stmt
|
||||
{
|
||||
Lex_ident_sys m_name; // Statement name (in all queries)
|
||||
Item *m_code; // PREPARE or EXECUTE IMMEDIATE source expression
|
||||
List<Item> m_params; // List of parameters for EXECUTE [IMMEDIATE]
|
||||
public:
|
||||
|
||||
Lex_prepared_stmt()
|
||||
:m_code(NULL)
|
||||
{ }
|
||||
const Lex_ident_sys &name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
uint param_count() const
|
||||
{
|
||||
return m_params.elements;
|
||||
}
|
||||
List<Item> ¶ms()
|
||||
{
|
||||
return m_params;
|
||||
}
|
||||
void set(const Lex_ident_sys_st &ident, Item *code, List<Item> *params)
|
||||
{
|
||||
DBUG_ASSERT(m_params.elements == 0);
|
||||
m_name= ident;
|
||||
m_code= code;
|
||||
if (params)
|
||||
m_params= *params;
|
||||
}
|
||||
bool params_fix_fields(THD *thd)
|
||||
{
|
||||
// Fix Items in the EXECUTE..USING list
|
||||
List_iterator_fast<Item> param_it(m_params);
|
||||
while (Item *param= param_it++)
|
||||
{
|
||||
if (param->fix_fields_if_needed_for_scalar(thd, 0))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool get_dynamic_sql_string(THD *thd, LEX_CSTRING *dst, String *buffer);
|
||||
void lex_start()
|
||||
{
|
||||
m_params.empty();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct LEX: public Query_tables_list
|
||||
{
|
||||
SELECT_LEX_UNIT unit; /* most upper unit */
|
||||
@ -3254,12 +3314,7 @@ public:
|
||||
creating or last of tables referenced by foreign keys).
|
||||
*/
|
||||
TABLE_LIST *create_last_non_select_table;
|
||||
/* Prepared statements SQL syntax:*/
|
||||
LEX_CSTRING prepared_stmt_name; /* Statement name (in all queries) */
|
||||
/* PREPARE or EXECUTE IMMEDIATE source expression */
|
||||
Item *prepared_stmt_code;
|
||||
/* Names of user variables holding parameters (in EXECUTE) */
|
||||
List<Item> prepared_stmt_params;
|
||||
Lex_prepared_stmt prepared_stmt;
|
||||
sp_head *sphead;
|
||||
sp_name *spname;
|
||||
bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling
|
||||
@ -3647,18 +3702,6 @@ public:
|
||||
bool sp_proc_stmt_statement_finalize_buf(THD *, const LEX_CSTRING &qbuf);
|
||||
bool sp_proc_stmt_statement_finalize(THD *, bool no_lookahead);
|
||||
|
||||
bool get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer);
|
||||
bool prepared_stmt_params_fix_fields(THD *thd)
|
||||
{
|
||||
// Fix Items in the EXECUTE..USING list
|
||||
List_iterator_fast<Item> param_it(prepared_stmt_params);
|
||||
while (Item *param= param_it++)
|
||||
{
|
||||
if (param->fix_fields_if_needed_for_scalar(thd, 0))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
sp_variable *sp_param_init(LEX_CSTRING *name);
|
||||
bool sp_param_fill_definition(sp_variable *spvar);
|
||||
|
||||
@ -4403,6 +4446,11 @@ public:
|
||||
const Lex_ident_sys_st &name);
|
||||
bool stmt_uninstall_plugin_by_soname(const DDL_options_st &opt,
|
||||
const LEX_CSTRING &soname);
|
||||
bool stmt_prepare_validate(const char *stmt_type);
|
||||
bool stmt_prepare(const Lex_ident_sys_st &ident, Item *code);
|
||||
bool stmt_execute(const Lex_ident_sys_st &ident, List<Item> *params);
|
||||
bool stmt_execute_immediate(Item *code, List<Item> *params);
|
||||
void stmt_deallocate_prepare(const Lex_ident_sys_st &ident);
|
||||
};
|
||||
|
||||
|
||||
|
@ -518,6 +518,12 @@ public:
|
||||
empty();
|
||||
}
|
||||
T *elem(uint n) { return (T*) base_list::elem(n); }
|
||||
// Create a new list with one element
|
||||
static List<T> *make(MEM_ROOT *mem_root, T *first)
|
||||
{
|
||||
List<T> *res= new (mem_root) List<T>;
|
||||
return res == NULL || res->push_back(first, mem_root) ? NULL : res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -190,7 +190,7 @@ public:
|
||||
void setup_set_params();
|
||||
virtual Query_arena::Type type() const;
|
||||
virtual void cleanup_stmt();
|
||||
bool set_name(LEX_CSTRING *name);
|
||||
bool set_name(const LEX_CSTRING *name);
|
||||
inline void close_cursor() { delete cursor; cursor= 0; }
|
||||
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
|
||||
inline bool is_sql_prepare() const { return flags & (uint) IS_SQL_PREPARE; }
|
||||
@ -2664,7 +2664,7 @@ end:
|
||||
}
|
||||
|
||||
/**
|
||||
Get an SQL statement from an item in lex->prepared_stmt_code.
|
||||
Get an SQL statement from an item in m_code.
|
||||
|
||||
This function can return pointers to very different memory classes:
|
||||
- a static string "NULL", if the item returned NULL
|
||||
@ -2689,13 +2689,15 @@ end:
|
||||
@retval true on error (out of memory)
|
||||
*/
|
||||
|
||||
bool LEX::get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer)
|
||||
bool Lex_prepared_stmt::get_dynamic_sql_string(THD *thd,
|
||||
LEX_CSTRING *dst,
|
||||
String *buffer)
|
||||
{
|
||||
if (prepared_stmt_code->fix_fields_if_needed_for_scalar(thd, NULL))
|
||||
if (m_code->fix_fields_if_needed_for_scalar(thd, NULL))
|
||||
return true;
|
||||
|
||||
const String *str= prepared_stmt_code->val_str(buffer);
|
||||
if (prepared_stmt_code->null_value)
|
||||
const String *str= m_code->val_str(buffer);
|
||||
if (m_code->null_value)
|
||||
{
|
||||
/*
|
||||
Prepare source was NULL, so we need to set "str" to
|
||||
@ -2776,7 +2778,7 @@ bool LEX::get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer)
|
||||
void mysql_sql_stmt_prepare(THD *thd)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
LEX_CSTRING *name= &lex->prepared_stmt_name;
|
||||
const LEX_CSTRING *name= &lex->prepared_stmt.name();
|
||||
Prepared_statement *stmt;
|
||||
LEX_CSTRING query;
|
||||
DBUG_ENTER("mysql_sql_stmt_prepare");
|
||||
@ -2801,7 +2803,7 @@ void mysql_sql_stmt_prepare(THD *thd)
|
||||
See comments in get_dynamic_sql_string().
|
||||
*/
|
||||
StringBuffer<256> buffer;
|
||||
if (lex->get_dynamic_sql_string(&query, &buffer) ||
|
||||
if (lex->prepared_stmt.get_dynamic_sql_string(thd, &query, &buffer) ||
|
||||
! (stmt= new Prepared_statement(thd)))
|
||||
{
|
||||
DBUG_VOID_RETURN; /* out of memory */
|
||||
@ -2864,7 +2866,7 @@ void mysql_sql_stmt_execute_immediate(THD *thd)
|
||||
LEX_CSTRING query;
|
||||
DBUG_ENTER("mysql_sql_stmt_execute_immediate");
|
||||
|
||||
if (lex->prepared_stmt_params_fix_fields(thd))
|
||||
if (lex->prepared_stmt.params_fix_fields(thd))
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
/*
|
||||
@ -2876,7 +2878,7 @@ void mysql_sql_stmt_execute_immediate(THD *thd)
|
||||
See comments in get_dynamic_sql_string().
|
||||
*/
|
||||
StringBuffer<256> buffer;
|
||||
if (lex->get_dynamic_sql_string(&query, &buffer) ||
|
||||
if (lex->prepared_stmt.get_dynamic_sql_string(thd, &query, &buffer) ||
|
||||
!(stmt= new Prepared_statement(thd)))
|
||||
DBUG_VOID_RETURN; // out of memory
|
||||
|
||||
@ -3265,7 +3267,7 @@ void mysql_sql_stmt_execute(THD *thd)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
Prepared_statement *stmt;
|
||||
LEX_CSTRING *name= &lex->prepared_stmt_name;
|
||||
const LEX_CSTRING *name= &lex->prepared_stmt.name();
|
||||
/* Query text for binary, general or slow log, if any of them is open */
|
||||
String expanded_query;
|
||||
DBUG_ENTER("mysql_sql_stmt_execute");
|
||||
@ -3278,7 +3280,7 @@ void mysql_sql_stmt_execute(THD *thd)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
if (stmt->param_count != lex->prepared_stmt_params.elements)
|
||||
if (stmt->param_count != lex->prepared_stmt.param_count())
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
|
||||
DBUG_VOID_RETURN;
|
||||
@ -3286,7 +3288,7 @@ void mysql_sql_stmt_execute(THD *thd)
|
||||
|
||||
DBUG_PRINT("info",("stmt: %p", stmt));
|
||||
|
||||
if (lex->prepared_stmt_params_fix_fields(thd))
|
||||
if (lex->prepared_stmt.params_fix_fields(thd))
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
/*
|
||||
@ -3506,7 +3508,7 @@ void mysqld_stmt_close(THD *thd, char *packet)
|
||||
void mysql_sql_stmt_close(THD *thd)
|
||||
{
|
||||
Prepared_statement* stmt;
|
||||
LEX_CSTRING *name= &thd->lex->prepared_stmt_name;
|
||||
const LEX_CSTRING *name= &thd->lex->prepared_stmt.name();
|
||||
DBUG_PRINT("info", ("DEALLOCATE PREPARE: %.*s\n", (int) name->length,
|
||||
name->str));
|
||||
|
||||
@ -3871,7 +3873,7 @@ void Prepared_statement::cleanup_stmt()
|
||||
}
|
||||
|
||||
|
||||
bool Prepared_statement::set_name(LEX_CSTRING *name_arg)
|
||||
bool Prepared_statement::set_name(const LEX_CSTRING *name_arg)
|
||||
{
|
||||
name.length= name_arg->length;
|
||||
name.str= (char*) memdup_root(mem_root, name_arg->str, name_arg->length);
|
||||
@ -4120,7 +4122,7 @@ Prepared_statement::set_parameters(String *expanded_query,
|
||||
if (is_sql_ps)
|
||||
{
|
||||
/* SQL prepared statement */
|
||||
res= set_params_from_actual_params(this, thd->lex->prepared_stmt_params,
|
||||
res= set_params_from_actual_params(this, thd->lex->prepared_stmt.params(),
|
||||
expanded_query);
|
||||
}
|
||||
else if (param_count)
|
||||
@ -4849,7 +4851,7 @@ bool Prepared_statement::execute_immediate(const char *query, uint query_len)
|
||||
if (unlikely(prepare(query, query_len)))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
if (param_count != thd->lex->prepared_stmt_params.elements)
|
||||
if (param_count != thd->lex->prepared_stmt.param_count())
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
|
||||
deallocate_immediate();
|
||||
|
@ -1856,7 +1856,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
|
||||
%type <item>
|
||||
literal insert_ident order_ident temporal_literal
|
||||
simple_ident expr sum_expr in_sum_expr
|
||||
simple_ident expr prepare_src sum_expr in_sum_expr
|
||||
variable variable_aux bool_pri
|
||||
predicate bit_expr parenthesized_expr
|
||||
table_wild simple_expr column_default_non_parenthesized_expr udf_expr
|
||||
@ -1897,6 +1897,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
|
||||
ident_list ident_list_arg opt_expr_list
|
||||
decode_when_list_oracle
|
||||
execute_using
|
||||
execute_params
|
||||
|
||||
%type <sp_cursor_stmt>
|
||||
sp_cursor_stmt_lex
|
||||
@ -2054,7 +2056,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
select_var_list select_var_list_init help
|
||||
opt_extended_describe shutdown
|
||||
opt_format_json
|
||||
prepare prepare_src execute deallocate
|
||||
prepare execute deallocate
|
||||
statement
|
||||
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
|
||||
opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
|
||||
@ -2306,9 +2308,7 @@ statement:
|
||||
deallocate:
|
||||
deallocate_or_drop PREPARE_SYM ident
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
|
||||
lex->prepared_stmt_name= $3;
|
||||
Lex->stmt_deallocate_prepare($3);
|
||||
}
|
||||
;
|
||||
|
||||
@ -2320,14 +2320,8 @@ deallocate_or_drop:
|
||||
prepare:
|
||||
PREPARE_SYM ident FROM prepare_src
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
if (unlikely(lex->table_or_sp_used()))
|
||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
||||
"PREPARE..FROM"));
|
||||
if (Lex->check_main_unit_semantics())
|
||||
if (Lex->stmt_prepare($2, $4))
|
||||
MYSQL_YYABORT;
|
||||
lex->sql_command= SQLCOM_PREPARE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
}
|
||||
;
|
||||
|
||||
@ -2335,63 +2329,48 @@ prepare_src:
|
||||
{ Lex->expr_allows_subselect= false; }
|
||||
expr
|
||||
{
|
||||
Lex->prepared_stmt_code= $2;
|
||||
Lex->expr_allows_subselect= true;
|
||||
$$= $2;
|
||||
}
|
||||
;
|
||||
|
||||
execute:
|
||||
EXECUTE_SYM ident
|
||||
EXECUTE_SYM ident execute_using
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
lex->sql_command= SQLCOM_EXECUTE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
}
|
||||
execute_using
|
||||
{
|
||||
if (Lex->check_main_unit_semantics())
|
||||
if (Lex->stmt_execute($2, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| EXECUTE_SYM IMMEDIATE_SYM prepare_src
|
||||
| EXECUTE_SYM IMMEDIATE_SYM prepare_src execute_using
|
||||
{
|
||||
if (unlikely(Lex->table_or_sp_used()))
|
||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
||||
"EXECUTE IMMEDIATE"));
|
||||
Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE;
|
||||
}
|
||||
execute_using
|
||||
{
|
||||
if (Lex->check_main_unit_semantics())
|
||||
if (Lex->stmt_execute_immediate($3, $4))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
execute_using:
|
||||
/* nothing */
|
||||
/* nothing */ { $$= NULL; }
|
||||
| USING { Lex->expr_allows_subselect= false; }
|
||||
execute_var_list
|
||||
execute_params
|
||||
{
|
||||
if (unlikely(Lex->table_or_sp_used()))
|
||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
||||
"EXECUTE..USING"));
|
||||
$$= $3;
|
||||
Lex->expr_allows_subselect= true;
|
||||
}
|
||||
;
|
||||
|
||||
execute_var_list:
|
||||
execute_var_list ',' execute_var_ident
|
||||
| execute_var_ident
|
||||
;
|
||||
|
||||
execute_var_ident:
|
||||
execute_params:
|
||||
expr_or_default
|
||||
{
|
||||
if (unlikely(Lex->prepared_stmt_params.push_back($1,
|
||||
thd->mem_root)))
|
||||
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| execute_params ',' expr_or_default
|
||||
{
|
||||
if (($$= $1)->push_back($3, thd->mem_root))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/* help */
|
||||
|
||||
help:
|
||||
@ -11833,9 +11812,7 @@ opt_expr_list:
|
||||
expr_list:
|
||||
expr
|
||||
{
|
||||
$$= new (thd->mem_root) List<Item>;
|
||||
if (unlikely($$ == NULL) ||
|
||||
unlikely($$->push_back($1, thd->mem_root)))
|
||||
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| expr_list ',' expr
|
||||
|
@ -1357,7 +1357,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
|
||||
%type <item>
|
||||
literal insert_ident order_ident temporal_literal
|
||||
simple_ident expr sum_expr in_sum_expr
|
||||
simple_ident expr prepare_src sum_expr in_sum_expr
|
||||
variable variable_aux bool_pri
|
||||
predicate bit_expr parenthesized_expr
|
||||
table_wild simple_expr column_default_non_parenthesized_expr udf_expr
|
||||
@ -1398,6 +1398,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
|
||||
ident_list ident_list_arg opt_expr_list
|
||||
decode_when_list_oracle
|
||||
execute_using
|
||||
execute_params
|
||||
|
||||
%type <sp_cursor_stmt>
|
||||
sp_cursor_stmt_lex
|
||||
@ -1557,7 +1559,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
select_var_list select_var_list_init help
|
||||
opt_extended_describe shutdown
|
||||
opt_format_json
|
||||
prepare prepare_src execute deallocate
|
||||
prepare execute deallocate
|
||||
statement
|
||||
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
|
||||
opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
|
||||
@ -1827,9 +1829,7 @@ statement:
|
||||
deallocate:
|
||||
deallocate_or_drop PREPARE_SYM ident
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
|
||||
lex->prepared_stmt_name= $3;
|
||||
Lex->stmt_deallocate_prepare($3);
|
||||
}
|
||||
;
|
||||
|
||||
@ -1841,12 +1841,8 @@ deallocate_or_drop:
|
||||
prepare:
|
||||
PREPARE_SYM ident FROM prepare_src
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
if (unlikely(lex->table_or_sp_used()))
|
||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
||||
"PREPARE..FROM"));
|
||||
lex->sql_command= SQLCOM_PREPARE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
if (Lex->stmt_prepare($2, $4))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
@ -1854,57 +1850,48 @@ prepare_src:
|
||||
{ Lex->expr_allows_subselect= false; }
|
||||
expr
|
||||
{
|
||||
Lex->prepared_stmt_code= $2;
|
||||
Lex->expr_allows_subselect= true;
|
||||
$$= $2;
|
||||
}
|
||||
;
|
||||
|
||||
execute:
|
||||
EXECUTE_SYM ident
|
||||
EXECUTE_SYM ident execute_using
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
lex->sql_command= SQLCOM_EXECUTE;
|
||||
lex->prepared_stmt_name= $2;
|
||||
if (Lex->stmt_execute($2, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
execute_using
|
||||
{}
|
||||
| EXECUTE_SYM IMMEDIATE_SYM prepare_src
|
||||
| EXECUTE_SYM IMMEDIATE_SYM prepare_src execute_using
|
||||
{
|
||||
if (unlikely(Lex->table_or_sp_used()))
|
||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
||||
"EXECUTE IMMEDIATE"));
|
||||
Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE;
|
||||
if (Lex->stmt_execute_immediate($3, $4))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
execute_using
|
||||
{}
|
||||
;
|
||||
|
||||
execute_using:
|
||||
/* nothing */
|
||||
/* nothing */ { $$= NULL; }
|
||||
| USING { Lex->expr_allows_subselect= false; }
|
||||
execute_var_list
|
||||
execute_params
|
||||
{
|
||||
if (unlikely(Lex->table_or_sp_used()))
|
||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
||||
"EXECUTE..USING"));
|
||||
$$= $3;
|
||||
Lex->expr_allows_subselect= true;
|
||||
}
|
||||
;
|
||||
|
||||
execute_var_list:
|
||||
execute_var_list ',' execute_var_ident
|
||||
| execute_var_ident
|
||||
;
|
||||
|
||||
execute_var_ident:
|
||||
execute_params:
|
||||
expr_or_default
|
||||
{
|
||||
if (unlikely(Lex->prepared_stmt_params.push_back($1,
|
||||
thd->mem_root)))
|
||||
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| execute_params ',' expr_or_default
|
||||
{
|
||||
if (($$= $1)->push_back($3, thd->mem_root))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/* help */
|
||||
|
||||
help:
|
||||
@ -11919,9 +11906,7 @@ opt_expr_list:
|
||||
expr_list:
|
||||
expr
|
||||
{
|
||||
$$= new (thd->mem_root) List<Item>;
|
||||
if (unlikely($$ == NULL) ||
|
||||
unlikely($$->push_back($1, thd->mem_root)))
|
||||
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| expr_list ',' expr
|
||||
|
Reference in New Issue
Block a user