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
|
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';
|
CREATE FUNCTION f1() RETURNS VARCHAR(10) RETURN 'test';
|
||||||
EXECUTE IMMEDIATE 'SELECT ? FROM DUAL' USING f1();
|
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;
|
DROP FUNCTION f1;
|
||||||
#
|
#
|
||||||
# DDL
|
# DDL
|
||||||
|
@ -163,7 +163,7 @@ RETURN 'test';
|
|||||||
END;
|
END;
|
||||||
$$
|
$$
|
||||||
EXECUTE IMMEDIATE 'SELECT ? FROM DUAL' USING f1();
|
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;
|
DROP FUNCTION f1;
|
||||||
#
|
#
|
||||||
# Testing simple expressions
|
# 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)
|
bool Protocol_text::send_out_parameters(List<Item_param> *sp_params)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(sp_params->elements ==
|
DBUG_ASSERT(sp_params->elements == thd->lex->prepared_stmt.param_count());
|
||||||
thd->lex->prepared_stmt_params.elements);
|
|
||||||
|
|
||||||
List_iterator_fast<Item_param> item_param_it(*sp_params);
|
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)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -1214,7 +1214,7 @@ public:
|
|||||||
|
|
||||||
int insert(THD *thd, Statement *statement);
|
int insert(THD *thd, Statement *statement);
|
||||||
|
|
||||||
Statement *find_by_name(LEX_CSTRING *name)
|
Statement *find_by_name(const LEX_CSTRING *name)
|
||||||
{
|
{
|
||||||
Statement *stmt;
|
Statement *stmt;
|
||||||
stmt= (Statement*)my_hash_search(&names_hash, (uchar*)name->str,
|
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;
|
with_persistent_for_clause= FALSE;
|
||||||
column_list= NULL;
|
column_list= NULL;
|
||||||
index_list= NULL;
|
index_list= NULL;
|
||||||
prepared_stmt_params.empty();
|
prepared_stmt.lex_start();
|
||||||
auxiliary_table_list.empty();
|
auxiliary_table_list.empty();
|
||||||
unit.next= unit.master= unit.link_next= unit.return_to= 0;
|
unit.next= unit.master= unit.link_next= unit.return_to= 0;
|
||||||
unit.prev= unit.link_prev= 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;
|
ident= soname;
|
||||||
return false;
|
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_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;
|
class Query_arena_memroot;
|
||||||
/* The state of the lex parsing. This is saved in the THD struct */
|
/* 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
|
struct LEX: public Query_tables_list
|
||||||
{
|
{
|
||||||
SELECT_LEX_UNIT unit; /* most upper unit */
|
SELECT_LEX_UNIT unit; /* most upper unit */
|
||||||
@ -3254,12 +3314,7 @@ public:
|
|||||||
creating or last of tables referenced by foreign keys).
|
creating or last of tables referenced by foreign keys).
|
||||||
*/
|
*/
|
||||||
TABLE_LIST *create_last_non_select_table;
|
TABLE_LIST *create_last_non_select_table;
|
||||||
/* Prepared statements SQL syntax:*/
|
Lex_prepared_stmt prepared_stmt;
|
||||||
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;
|
|
||||||
sp_head *sphead;
|
sp_head *sphead;
|
||||||
sp_name *spname;
|
sp_name *spname;
|
||||||
bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling
|
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_buf(THD *, const LEX_CSTRING &qbuf);
|
||||||
bool sp_proc_stmt_statement_finalize(THD *, bool no_lookahead);
|
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);
|
sp_variable *sp_param_init(LEX_CSTRING *name);
|
||||||
bool sp_param_fill_definition(sp_variable *spvar);
|
bool sp_param_fill_definition(sp_variable *spvar);
|
||||||
|
|
||||||
@ -4403,6 +4446,11 @@ public:
|
|||||||
const Lex_ident_sys_st &name);
|
const Lex_ident_sys_st &name);
|
||||||
bool stmt_uninstall_plugin_by_soname(const DDL_options_st &opt,
|
bool stmt_uninstall_plugin_by_soname(const DDL_options_st &opt,
|
||||||
const LEX_CSTRING &soname);
|
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();
|
empty();
|
||||||
}
|
}
|
||||||
T *elem(uint n) { return (T*) base_list::elem(n); }
|
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();
|
void setup_set_params();
|
||||||
virtual Query_arena::Type type() const;
|
virtual Query_arena::Type type() const;
|
||||||
virtual void cleanup_stmt();
|
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 void close_cursor() { delete cursor; cursor= 0; }
|
||||||
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
|
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
|
||||||
inline bool is_sql_prepare() const { return flags & (uint) IS_SQL_PREPARE; }
|
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:
|
This function can return pointers to very different memory classes:
|
||||||
- a static string "NULL", if the item returned NULL
|
- a static string "NULL", if the item returned NULL
|
||||||
@ -2689,13 +2689,15 @@ end:
|
|||||||
@retval true on error (out of memory)
|
@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;
|
return true;
|
||||||
|
|
||||||
const String *str= prepared_stmt_code->val_str(buffer);
|
const String *str= m_code->val_str(buffer);
|
||||||
if (prepared_stmt_code->null_value)
|
if (m_code->null_value)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Prepare source was NULL, so we need to set "str" to
|
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)
|
void mysql_sql_stmt_prepare(THD *thd)
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
LEX_CSTRING *name= &lex->prepared_stmt_name;
|
const LEX_CSTRING *name= &lex->prepared_stmt.name();
|
||||||
Prepared_statement *stmt;
|
Prepared_statement *stmt;
|
||||||
LEX_CSTRING query;
|
LEX_CSTRING query;
|
||||||
DBUG_ENTER("mysql_sql_stmt_prepare");
|
DBUG_ENTER("mysql_sql_stmt_prepare");
|
||||||
@ -2801,7 +2803,7 @@ void mysql_sql_stmt_prepare(THD *thd)
|
|||||||
See comments in get_dynamic_sql_string().
|
See comments in get_dynamic_sql_string().
|
||||||
*/
|
*/
|
||||||
StringBuffer<256> buffer;
|
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)))
|
! (stmt= new Prepared_statement(thd)))
|
||||||
{
|
{
|
||||||
DBUG_VOID_RETURN; /* out of memory */
|
DBUG_VOID_RETURN; /* out of memory */
|
||||||
@ -2864,7 +2866,7 @@ void mysql_sql_stmt_execute_immediate(THD *thd)
|
|||||||
LEX_CSTRING query;
|
LEX_CSTRING query;
|
||||||
DBUG_ENTER("mysql_sql_stmt_execute_immediate");
|
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;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2876,7 +2878,7 @@ void mysql_sql_stmt_execute_immediate(THD *thd)
|
|||||||
See comments in get_dynamic_sql_string().
|
See comments in get_dynamic_sql_string().
|
||||||
*/
|
*/
|
||||||
StringBuffer<256> buffer;
|
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)))
|
!(stmt= new Prepared_statement(thd)))
|
||||||
DBUG_VOID_RETURN; // out of memory
|
DBUG_VOID_RETURN; // out of memory
|
||||||
|
|
||||||
@ -3265,7 +3267,7 @@ void mysql_sql_stmt_execute(THD *thd)
|
|||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
Prepared_statement *stmt;
|
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 */
|
/* Query text for binary, general or slow log, if any of them is open */
|
||||||
String expanded_query;
|
String expanded_query;
|
||||||
DBUG_ENTER("mysql_sql_stmt_execute");
|
DBUG_ENTER("mysql_sql_stmt_execute");
|
||||||
@ -3278,7 +3280,7 @@ void mysql_sql_stmt_execute(THD *thd)
|
|||||||
DBUG_VOID_RETURN;
|
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");
|
my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -3286,7 +3288,7 @@ void mysql_sql_stmt_execute(THD *thd)
|
|||||||
|
|
||||||
DBUG_PRINT("info",("stmt: %p", stmt));
|
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;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3506,7 +3508,7 @@ void mysqld_stmt_close(THD *thd, char *packet)
|
|||||||
void mysql_sql_stmt_close(THD *thd)
|
void mysql_sql_stmt_close(THD *thd)
|
||||||
{
|
{
|
||||||
Prepared_statement* stmt;
|
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,
|
DBUG_PRINT("info", ("DEALLOCATE PREPARE: %.*s\n", (int) name->length,
|
||||||
name->str));
|
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.length= name_arg->length;
|
||||||
name.str= (char*) memdup_root(mem_root, name_arg->str, 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)
|
if (is_sql_ps)
|
||||||
{
|
{
|
||||||
/* SQL prepared statement */
|
/* 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);
|
expanded_query);
|
||||||
}
|
}
|
||||||
else if (param_count)
|
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)))
|
if (unlikely(prepare(query, query_len)))
|
||||||
DBUG_RETURN(true);
|
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");
|
my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
|
||||||
deallocate_immediate();
|
deallocate_immediate();
|
||||||
|
@ -1856,7 +1856,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||||||
|
|
||||||
%type <item>
|
%type <item>
|
||||||
literal insert_ident order_ident temporal_literal
|
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
|
variable variable_aux bool_pri
|
||||||
predicate bit_expr parenthesized_expr
|
predicate bit_expr parenthesized_expr
|
||||||
table_wild simple_expr column_default_non_parenthesized_expr udf_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
|
expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
|
||||||
ident_list ident_list_arg opt_expr_list
|
ident_list ident_list_arg opt_expr_list
|
||||||
decode_when_list_oracle
|
decode_when_list_oracle
|
||||||
|
execute_using
|
||||||
|
execute_params
|
||||||
|
|
||||||
%type <sp_cursor_stmt>
|
%type <sp_cursor_stmt>
|
||||||
sp_cursor_stmt_lex
|
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
|
select_var_list select_var_list_init help
|
||||||
opt_extended_describe shutdown
|
opt_extended_describe shutdown
|
||||||
opt_format_json
|
opt_format_json
|
||||||
prepare prepare_src execute deallocate
|
prepare execute deallocate
|
||||||
statement
|
statement
|
||||||
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
|
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
|
opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
|
||||||
@ -2306,9 +2308,7 @@ statement:
|
|||||||
deallocate:
|
deallocate:
|
||||||
deallocate_or_drop PREPARE_SYM ident
|
deallocate_or_drop PREPARE_SYM ident
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
Lex->stmt_deallocate_prepare($3);
|
||||||
lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
|
|
||||||
lex->prepared_stmt_name= $3;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2320,14 +2320,8 @@ deallocate_or_drop:
|
|||||||
prepare:
|
prepare:
|
||||||
PREPARE_SYM ident FROM prepare_src
|
PREPARE_SYM ident FROM prepare_src
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (Lex->stmt_prepare($2, $4))
|
||||||
if (unlikely(lex->table_or_sp_used()))
|
|
||||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
|
||||||
"PREPARE..FROM"));
|
|
||||||
if (Lex->check_main_unit_semantics())
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
lex->sql_command= SQLCOM_PREPARE;
|
|
||||||
lex->prepared_stmt_name= $2;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2335,63 +2329,48 @@ prepare_src:
|
|||||||
{ Lex->expr_allows_subselect= false; }
|
{ Lex->expr_allows_subselect= false; }
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
Lex->prepared_stmt_code= $2;
|
|
||||||
Lex->expr_allows_subselect= true;
|
Lex->expr_allows_subselect= true;
|
||||||
|
$$= $2;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
execute:
|
execute:
|
||||||
EXECUTE_SYM ident
|
EXECUTE_SYM ident execute_using
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (Lex->stmt_execute($2, $3))
|
||||||
lex->sql_command= SQLCOM_EXECUTE;
|
|
||||||
lex->prepared_stmt_name= $2;
|
|
||||||
}
|
|
||||||
execute_using
|
|
||||||
{
|
|
||||||
if (Lex->check_main_unit_semantics())
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| EXECUTE_SYM IMMEDIATE_SYM prepare_src
|
| EXECUTE_SYM IMMEDIATE_SYM prepare_src execute_using
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->table_or_sp_used()))
|
if (Lex->stmt_execute_immediate($3, $4))
|
||||||
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())
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
execute_using:
|
execute_using:
|
||||||
/* nothing */
|
/* nothing */ { $$= NULL; }
|
||||||
| USING { Lex->expr_allows_subselect= false; }
|
| USING { Lex->expr_allows_subselect= false; }
|
||||||
execute_var_list
|
execute_params
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->table_or_sp_used()))
|
$$= $3;
|
||||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
|
||||||
"EXECUTE..USING"));
|
|
||||||
Lex->expr_allows_subselect= true;
|
Lex->expr_allows_subselect= true;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
execute_var_list:
|
execute_params:
|
||||||
execute_var_list ',' execute_var_ident
|
|
||||||
| execute_var_ident
|
|
||||||
;
|
|
||||||
|
|
||||||
execute_var_ident:
|
|
||||||
expr_or_default
|
expr_or_default
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->prepared_stmt_params.push_back($1,
|
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
|
||||||
thd->mem_root)))
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| execute_params ',' expr_or_default
|
||||||
|
{
|
||||||
|
if (($$= $1)->push_back($3, thd->mem_root))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/* help */
|
/* help */
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@ -11833,9 +11812,7 @@ opt_expr_list:
|
|||||||
expr_list:
|
expr_list:
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
$$= new (thd->mem_root) List<Item>;
|
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
|
||||||
if (unlikely($$ == NULL) ||
|
|
||||||
unlikely($$->push_back($1, thd->mem_root)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| expr_list ',' expr
|
| expr_list ',' expr
|
||||||
|
@ -1357,7 +1357,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||||||
|
|
||||||
%type <item>
|
%type <item>
|
||||||
literal insert_ident order_ident temporal_literal
|
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
|
variable variable_aux bool_pri
|
||||||
predicate bit_expr parenthesized_expr
|
predicate bit_expr parenthesized_expr
|
||||||
table_wild simple_expr column_default_non_parenthesized_expr udf_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
|
expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
|
||||||
ident_list ident_list_arg opt_expr_list
|
ident_list ident_list_arg opt_expr_list
|
||||||
decode_when_list_oracle
|
decode_when_list_oracle
|
||||||
|
execute_using
|
||||||
|
execute_params
|
||||||
|
|
||||||
%type <sp_cursor_stmt>
|
%type <sp_cursor_stmt>
|
||||||
sp_cursor_stmt_lex
|
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
|
select_var_list select_var_list_init help
|
||||||
opt_extended_describe shutdown
|
opt_extended_describe shutdown
|
||||||
opt_format_json
|
opt_format_json
|
||||||
prepare prepare_src execute deallocate
|
prepare execute deallocate
|
||||||
statement
|
statement
|
||||||
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
|
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
|
opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
|
||||||
@ -1827,9 +1829,7 @@ statement:
|
|||||||
deallocate:
|
deallocate:
|
||||||
deallocate_or_drop PREPARE_SYM ident
|
deallocate_or_drop PREPARE_SYM ident
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
Lex->stmt_deallocate_prepare($3);
|
||||||
lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
|
|
||||||
lex->prepared_stmt_name= $3;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -1841,12 +1841,8 @@ deallocate_or_drop:
|
|||||||
prepare:
|
prepare:
|
||||||
PREPARE_SYM ident FROM prepare_src
|
PREPARE_SYM ident FROM prepare_src
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (Lex->stmt_prepare($2, $4))
|
||||||
if (unlikely(lex->table_or_sp_used()))
|
MYSQL_YYABORT;
|
||||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
|
||||||
"PREPARE..FROM"));
|
|
||||||
lex->sql_command= SQLCOM_PREPARE;
|
|
||||||
lex->prepared_stmt_name= $2;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -1854,57 +1850,48 @@ prepare_src:
|
|||||||
{ Lex->expr_allows_subselect= false; }
|
{ Lex->expr_allows_subselect= false; }
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
Lex->prepared_stmt_code= $2;
|
|
||||||
Lex->expr_allows_subselect= true;
|
Lex->expr_allows_subselect= true;
|
||||||
|
$$= $2;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
execute:
|
execute:
|
||||||
EXECUTE_SYM ident
|
EXECUTE_SYM ident execute_using
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (Lex->stmt_execute($2, $3))
|
||||||
lex->sql_command= SQLCOM_EXECUTE;
|
MYSQL_YYABORT;
|
||||||
lex->prepared_stmt_name= $2;
|
|
||||||
}
|
}
|
||||||
execute_using
|
| EXECUTE_SYM IMMEDIATE_SYM prepare_src execute_using
|
||||||
{}
|
|
||||||
| EXECUTE_SYM IMMEDIATE_SYM prepare_src
|
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->table_or_sp_used()))
|
if (Lex->stmt_execute_immediate($3, $4))
|
||||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
MYSQL_YYABORT;
|
||||||
"EXECUTE IMMEDIATE"));
|
|
||||||
Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE;
|
|
||||||
}
|
}
|
||||||
execute_using
|
|
||||||
{}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
execute_using:
|
execute_using:
|
||||||
/* nothing */
|
/* nothing */ { $$= NULL; }
|
||||||
| USING { Lex->expr_allows_subselect= false; }
|
| USING { Lex->expr_allows_subselect= false; }
|
||||||
execute_var_list
|
execute_params
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->table_or_sp_used()))
|
$$= $3;
|
||||||
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
|
|
||||||
"EXECUTE..USING"));
|
|
||||||
Lex->expr_allows_subselect= true;
|
Lex->expr_allows_subselect= true;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
execute_var_list:
|
execute_params:
|
||||||
execute_var_list ',' execute_var_ident
|
|
||||||
| execute_var_ident
|
|
||||||
;
|
|
||||||
|
|
||||||
execute_var_ident:
|
|
||||||
expr_or_default
|
expr_or_default
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->prepared_stmt_params.push_back($1,
|
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
|
||||||
thd->mem_root)))
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| execute_params ',' expr_or_default
|
||||||
|
{
|
||||||
|
if (($$= $1)->push_back($3, thd->mem_root))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/* help */
|
/* help */
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@ -11919,9 +11906,7 @@ opt_expr_list:
|
|||||||
expr_list:
|
expr_list:
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
$$= new (thd->mem_root) List<Item>;
|
if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
|
||||||
if (unlikely($$ == NULL) ||
|
|
||||||
unlikely($$->push_back($1, thd->mem_root)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| expr_list ',' expr
|
| expr_list ',' expr
|
||||||
|
Reference in New Issue
Block a user