mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW
Part#2 (final): rewritting the code to pass the correct enum_sp_aggregate_type to the sp_head constructor, so sp_head never changes its aggregation type later on. The grammar has been simplified and defragmented. This allowed to check aggregate specific instructions right after a routine body has been scanned, by calling new LEX methods: sp_body_finalize_{procedure|function|trigger|event}() Moving some C++ code from *.yy to a few new helper methods in LEX.
This commit is contained in:
@ -37,7 +37,7 @@ set x=5;
|
|||||||
fetch group next row;
|
fetch group next row;
|
||||||
return x+1;
|
return x+1;
|
||||||
end |
|
end |
|
||||||
ERROR HY000: Non-aggregate function contains aggregate specific instructions: (FETCH GROUP NEXT ROW)
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
create aggregate function f1(x INT) returns INT
|
create aggregate function f1(x INT) returns INT
|
||||||
begin
|
begin
|
||||||
declare continue handler for not found return x;
|
declare continue handler for not found return x;
|
||||||
@ -1153,3 +1153,36 @@ i sum(i)
|
|||||||
NULL 8
|
NULL 8
|
||||||
drop function agg_sum;
|
drop function agg_sum;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW
|
||||||
|
#
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
CREATE DEFINER=root@localhost FUNCTION f1() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
CREATE TRIGGER tr1
|
||||||
|
AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE EVENT ev1
|
||||||
|
ON SCHEDULE EVERY 1 HOUR
|
||||||
|
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
|
||||||
|
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
|
||||||
|
DO FETCH GROUP NEXT ROW;
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
@ -965,3 +965,54 @@ select i, sum(i) from t1 group by i with rollup;
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
drop function agg_sum;
|
drop function agg_sum;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE DEFINER=root@localhost FUNCTION f1() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE TRIGGER tr1
|
||||||
|
AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE EVENT ev1
|
||||||
|
ON SCHEDULE EVERY 1 HOUR
|
||||||
|
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
|
||||||
|
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
|
||||||
|
DO FETCH GROUP NEXT ROW;
|
||||||
|
@ -11,7 +11,7 @@ set x=5;
|
|||||||
fetch group next row;
|
fetch group next row;
|
||||||
return x+1;
|
return x+1;
|
||||||
end |
|
end |
|
||||||
ERROR HY000: Non-aggregate function contains aggregate specific instructions: (FETCH GROUP NEXT ROW)
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
CREATE TABLE marks(stud_id INT, grade_count INT);
|
CREATE TABLE marks(stud_id INT, grade_count INT);
|
||||||
INSERT INTO marks VALUES (1,6), (2,4), (3,7), (4,5), (5,8);
|
INSERT INTO marks VALUES (1,6), (2,4), (3,7), (4,5), (5,8);
|
||||||
SELECT * FROM marks;
|
SELECT * FROM marks;
|
||||||
@ -56,3 +56,81 @@ aggregate_count(stud_id)
|
|||||||
5
|
5
|
||||||
DROP FUNCTION IF EXISTS aggregate_count;
|
DROP FUNCTION IF EXISTS aggregate_count;
|
||||||
DROP TABLE marks;
|
DROP TABLE marks;
|
||||||
|
#
|
||||||
|
# MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW
|
||||||
|
#
|
||||||
|
CREATE PROCEDURE p1 AS
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
CREATE DEFINER=root@localhost FUNCTION f1 RETURN INT AS
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
CREATE TRIGGER tr1
|
||||||
|
AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE EVENT ev1
|
||||||
|
ON SCHEDULE EVERY 1 HOUR
|
||||||
|
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
|
||||||
|
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
|
||||||
|
DO FETCH GROUP NEXT ROW;
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
CREATE PACKAGE pkg1 AS
|
||||||
|
PROCEDURE p1;
|
||||||
|
FUNCTION f1 RETURN INT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CREATE PACKAGE BODY pkg1 AS
|
||||||
|
PROCEDURE p1 AS
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW; -- In a package procedure
|
||||||
|
END;
|
||||||
|
FUNCTION f1 RETURN INT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
CREATE PACKAGE BODY pkg1 AS
|
||||||
|
PROCEDURE p1 AS
|
||||||
|
BEGIN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
FUNCTION f1 RETURN INT AS
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW; -- In a package function
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
CREATE PACKAGE BODY pkg1 AS
|
||||||
|
PROCEDURE p1 AS
|
||||||
|
BEGIN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
FUNCTION f1 RETURN INT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW; -- In a package executable section
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
ERROR HY000: Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context
|
||||||
|
DROP PACKAGE pkg1;
|
||||||
|
@ -64,3 +64,107 @@ DROP FUNCTION IF EXISTS aggregate_count;
|
|||||||
|
|
||||||
|
|
||||||
DROP TABLE marks;
|
DROP TABLE marks;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-18813 PROCEDURE and anonymous blocks silently ignore FETCH GROUP NEXT ROW
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE PROCEDURE p1 AS
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
BEGIN NOT ATOMIC
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE DEFINER=root@localhost FUNCTION f1 RETURN INT AS
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE TRIGGER tr1
|
||||||
|
AFTER INSERT ON t1 FOR EACH ROW
|
||||||
|
FETCH GROUP NEXT ROW;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE EVENT ev1
|
||||||
|
ON SCHEDULE EVERY 1 HOUR
|
||||||
|
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
|
||||||
|
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
|
||||||
|
DO FETCH GROUP NEXT ROW;
|
||||||
|
|
||||||
|
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PACKAGE pkg1 AS
|
||||||
|
PROCEDURE p1;
|
||||||
|
FUNCTION f1 RETURN INT;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE PACKAGE BODY pkg1 AS
|
||||||
|
PROCEDURE p1 AS
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW; -- In a package procedure
|
||||||
|
END;
|
||||||
|
FUNCTION f1 RETURN INT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE PACKAGE BODY pkg1 AS
|
||||||
|
PROCEDURE p1 AS
|
||||||
|
BEGIN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
FUNCTION f1 RETURN INT AS
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW; -- In a package function
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
|
||||||
|
--error ER_NOT_AGGREGATE_FUNCTION
|
||||||
|
CREATE PACKAGE BODY pkg1 AS
|
||||||
|
PROCEDURE p1 AS
|
||||||
|
BEGIN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
FUNCTION f1 RETURN INT AS
|
||||||
|
BEGIN
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
FETCH GROUP NEXT ROW; -- In a package executable section
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
|
||||||
|
DELIMITER ;$$
|
||||||
|
DROP PACKAGE pkg1;
|
||||||
|
@ -7811,7 +7811,7 @@ ER_ARGUMENT_OUT_OF_RANGE
|
|||||||
ER_WRONG_TYPE_OF_ARGUMENT
|
ER_WRONG_TYPE_OF_ARGUMENT
|
||||||
eng "%s function only accepts arguments that can be converted to numerical types"
|
eng "%s function only accepts arguments that can be converted to numerical types"
|
||||||
ER_NOT_AGGREGATE_FUNCTION
|
ER_NOT_AGGREGATE_FUNCTION
|
||||||
eng "Non-aggregate function contains aggregate specific instructions: (FETCH GROUP NEXT ROW)"
|
eng "Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context"
|
||||||
ER_INVALID_AGGREGATE_FUNCTION
|
ER_INVALID_AGGREGATE_FUNCTION
|
||||||
eng "Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function"
|
eng "Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function"
|
||||||
ER_INVALID_VALUE_TO_LIMIT
|
ER_INVALID_VALUE_TO_LIMIT
|
||||||
|
@ -489,7 +489,8 @@ sp_head::operator delete(void *ptr, size_t size) throw()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sp_head::sp_head(sp_package *parent, const Sp_handler *sph)
|
sp_head::sp_head(sp_package *parent, const Sp_handler *sph,
|
||||||
|
enum_sp_aggregate_type agg_type)
|
||||||
:Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP),
|
:Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP),
|
||||||
Database_qualified_name(&null_clex_str, &null_clex_str),
|
Database_qualified_name(&null_clex_str, &null_clex_str),
|
||||||
m_parent(parent),
|
m_parent(parent),
|
||||||
@ -522,6 +523,7 @@ sp_head::sp_head(sp_package *parent, const Sp_handler *sph)
|
|||||||
m_pcont(new (&main_mem_root) sp_pcontext()),
|
m_pcont(new (&main_mem_root) sp_pcontext()),
|
||||||
m_cont_level(0)
|
m_cont_level(0)
|
||||||
{
|
{
|
||||||
|
set_chistics_agg_type(agg_type);
|
||||||
m_first_instance= this;
|
m_first_instance= this;
|
||||||
m_first_free_instance= this;
|
m_first_free_instance= this;
|
||||||
m_last_cached_sp= this;
|
m_last_cached_sp= this;
|
||||||
@ -547,7 +549,7 @@ sp_head::sp_head(sp_package *parent, const Sp_handler *sph)
|
|||||||
sp_package::sp_package(LEX *top_level_lex,
|
sp_package::sp_package(LEX *top_level_lex,
|
||||||
const sp_name *name,
|
const sp_name *name,
|
||||||
const Sp_handler *sph)
|
const Sp_handler *sph)
|
||||||
:sp_head(NULL, sph),
|
:sp_head(NULL, sph, DEFAULT_AGGREGATE),
|
||||||
m_current_routine(NULL),
|
m_current_routine(NULL),
|
||||||
m_top_level_lex(top_level_lex),
|
m_top_level_lex(top_level_lex),
|
||||||
m_rcontext(NULL),
|
m_rcontext(NULL),
|
||||||
@ -2681,6 +2683,17 @@ sp_head::set_chistics(const st_sp_chistics &chistics)
|
|||||||
m_chistics.comment.length);
|
m_chistics.comment.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
sp_head::set_c_chistics(const st_sp_chistics &chistics)
|
||||||
|
{
|
||||||
|
// Set all chistics but preserve agg_type.
|
||||||
|
enum_sp_aggregate_type save_agg_type= agg_type();
|
||||||
|
set_chistics(chistics);
|
||||||
|
set_chistics_agg_type(save_agg_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sp_head::set_info(longlong created, longlong modified,
|
sp_head::set_info(longlong created, longlong modified,
|
||||||
const st_sp_chistics &chistics, sql_mode_t sql_mode)
|
const st_sp_chistics &chistics, sql_mode_t sql_mode)
|
||||||
@ -5134,6 +5147,36 @@ bool sp_head::spvar_fill_table_rowtype_reference(THD *thd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool sp_head::check_group_aggregate_instructions_forbid() const
|
||||||
|
{
|
||||||
|
if (unlikely(m_flags & sp_head::HAS_AGGREGATE_INSTR))
|
||||||
|
{
|
||||||
|
my_error(ER_NOT_AGGREGATE_FUNCTION, MYF(0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool sp_head::check_group_aggregate_instructions_require() const
|
||||||
|
{
|
||||||
|
if (unlikely(!(m_flags & HAS_AGGREGATE_INSTR)))
|
||||||
|
{
|
||||||
|
my_error(ER_INVALID_AGGREGATE_FUNCTION, MYF(0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool sp_head::check_group_aggregate_instructions_function() const
|
||||||
|
{
|
||||||
|
return agg_type() == GROUP_AGGREGATE ?
|
||||||
|
check_group_aggregate_instructions_require() :
|
||||||
|
check_group_aggregate_instructions_forbid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In Oracle mode stored routines have an optional name
|
In Oracle mode stored routines have an optional name
|
||||||
at the end of a declaration:
|
at the end of a declaration:
|
||||||
|
@ -183,6 +183,11 @@ private:
|
|||||||
set_chistics() makes sure this.
|
set_chistics() makes sure this.
|
||||||
*/
|
*/
|
||||||
Sp_chistics m_chistics;
|
Sp_chistics m_chistics;
|
||||||
|
void set_chistics(const st_sp_chistics &chistics);
|
||||||
|
inline void set_chistics_agg_type(enum enum_sp_aggregate_type type)
|
||||||
|
{
|
||||||
|
m_chistics.agg_type= type;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
sql_mode_t m_sql_mode; ///< For SHOW CREATE and execution
|
sql_mode_t m_sql_mode; ///< For SHOW CREATE and execution
|
||||||
bool m_explicit_name; /**< Prepend the db name? */
|
bool m_explicit_name; /**< Prepend the db name? */
|
||||||
@ -319,7 +324,8 @@ public:
|
|||||||
static void
|
static void
|
||||||
operator delete(void *ptr, size_t size) throw ();
|
operator delete(void *ptr, size_t size) throw ();
|
||||||
|
|
||||||
sp_head(sp_package *parent, const Sp_handler *handler);
|
sp_head(sp_package *parent, const Sp_handler *handler,
|
||||||
|
enum_sp_aggregate_type);
|
||||||
|
|
||||||
/// Initialize after we have reset mem_root
|
/// Initialize after we have reset mem_root
|
||||||
void
|
void
|
||||||
@ -413,6 +419,9 @@ public:
|
|||||||
Item *val, LEX *lex);
|
Item *val, LEX *lex);
|
||||||
bool check_package_routine_end_name(const LEX_CSTRING &end_name) const;
|
bool check_package_routine_end_name(const LEX_CSTRING &end_name) const;
|
||||||
bool check_standalone_routine_end_name(const sp_name *end_name) const;
|
bool check_standalone_routine_end_name(const sp_name *end_name) const;
|
||||||
|
bool check_group_aggregate_instructions_function() const;
|
||||||
|
bool check_group_aggregate_instructions_forbid() const;
|
||||||
|
bool check_group_aggregate_instructions_require() const;
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
Generate a code to set a single cursor parameter variable.
|
Generate a code to set a single cursor parameter variable.
|
||||||
@ -730,11 +739,7 @@ public:
|
|||||||
const LEX_CSTRING &db,
|
const LEX_CSTRING &db,
|
||||||
const LEX_CSTRING &table);
|
const LEX_CSTRING &table);
|
||||||
|
|
||||||
void set_chistics(const st_sp_chistics &chistics);
|
void set_c_chistics(const st_sp_chistics &chistics);
|
||||||
inline void set_chistics_agg_type(enum enum_sp_aggregate_type type)
|
|
||||||
{
|
|
||||||
m_chistics.agg_type= type;
|
|
||||||
}
|
|
||||||
void set_info(longlong created, longlong modified,
|
void set_info(longlong created, longlong modified,
|
||||||
const st_sp_chistics &chistics, sql_mode_t sql_mode);
|
const st_sp_chistics &chistics, sql_mode_t sql_mode);
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "sql_admin.h" // Sql_cmd_analyze/Check..._table
|
#include "sql_admin.h" // Sql_cmd_analyze/Check..._table
|
||||||
#include "sql_partition.h"
|
#include "sql_partition.h"
|
||||||
#include "sql_partition_admin.h" // Sql_cmd_alter_table_*_part
|
#include "sql_partition_admin.h" // Sql_cmd_alter_table_*_part
|
||||||
|
#include "event_parse_data.h"
|
||||||
|
|
||||||
void LEX::parse_error(uint err_number)
|
void LEX::parse_error(uint err_number)
|
||||||
{
|
{
|
||||||
@ -6469,13 +6470,14 @@ sp_name *LEX::make_sp_name(THD *thd, const LEX_CSTRING *name1,
|
|||||||
|
|
||||||
|
|
||||||
sp_head *LEX::make_sp_head(THD *thd, const sp_name *name,
|
sp_head *LEX::make_sp_head(THD *thd, const sp_name *name,
|
||||||
const Sp_handler *sph)
|
const Sp_handler *sph,
|
||||||
|
enum_sp_aggregate_type agg_type)
|
||||||
{
|
{
|
||||||
sp_package *package= get_sp_package();
|
sp_package *package= get_sp_package();
|
||||||
sp_head *sp;
|
sp_head *sp;
|
||||||
|
|
||||||
/* Order is important here: new - reset - init */
|
/* Order is important here: new - reset - init */
|
||||||
if (likely((sp= new sp_head(package, sph))))
|
if (likely((sp= new sp_head(package, sph, agg_type))))
|
||||||
{
|
{
|
||||||
sp->reset_thd_mem_root(thd);
|
sp->reset_thd_mem_root(thd);
|
||||||
sp->init(this);
|
sp->init(this);
|
||||||
@ -6498,7 +6500,8 @@ sp_head *LEX::make_sp_head(THD *thd, const sp_name *name,
|
|||||||
|
|
||||||
|
|
||||||
sp_head *LEX::make_sp_head_no_recursive(THD *thd, const sp_name *name,
|
sp_head *LEX::make_sp_head_no_recursive(THD *thd, const sp_name *name,
|
||||||
const Sp_handler *sph)
|
const Sp_handler *sph,
|
||||||
|
enum_sp_aggregate_type agg_type)
|
||||||
{
|
{
|
||||||
sp_package *package= thd->lex->get_sp_package();
|
sp_package *package= thd->lex->get_sp_package();
|
||||||
/*
|
/*
|
||||||
@ -6516,13 +6519,13 @@ sp_head *LEX::make_sp_head_no_recursive(THD *thd, const sp_name *name,
|
|||||||
(package &&
|
(package &&
|
||||||
(sph == &sp_handler_package_procedure ||
|
(sph == &sp_handler_package_procedure ||
|
||||||
sph == &sp_handler_package_function)))
|
sph == &sp_handler_package_function)))
|
||||||
return make_sp_head(thd, name, sph);
|
return make_sp_head(thd, name, sph, agg_type);
|
||||||
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), sph->type_str());
|
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), sph->type_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LEX::sp_body_finalize_procedure(THD *thd)
|
bool LEX::sp_body_finalize_routine(THD *thd)
|
||||||
{
|
{
|
||||||
if (sphead->check_unresolved_goto())
|
if (sphead->check_unresolved_goto())
|
||||||
return true;
|
return true;
|
||||||
@ -6532,6 +6535,13 @@ bool LEX::sp_body_finalize_procedure(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LEX::sp_body_finalize_procedure(THD *thd)
|
||||||
|
{
|
||||||
|
return sphead->check_group_aggregate_instructions_forbid() ||
|
||||||
|
sp_body_finalize_routine(thd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LEX::sp_body_finalize_procedure_standalone(THD *thd,
|
bool LEX::sp_body_finalize_procedure_standalone(THD *thd,
|
||||||
const sp_name *end_name)
|
const sp_name *end_name)
|
||||||
{
|
{
|
||||||
@ -6542,25 +6552,41 @@ bool LEX::sp_body_finalize_procedure_standalone(THD *thd,
|
|||||||
|
|
||||||
bool LEX::sp_body_finalize_function(THD *thd)
|
bool LEX::sp_body_finalize_function(THD *thd)
|
||||||
{
|
{
|
||||||
if (sphead->is_not_allowed_in_function("function"))
|
if (sphead->is_not_allowed_in_function("function") ||
|
||||||
|
sphead->check_group_aggregate_instructions_function())
|
||||||
return true;
|
return true;
|
||||||
if (!(sphead->m_flags & sp_head::HAS_RETURN))
|
if (!(sphead->m_flags & sp_head::HAS_RETURN))
|
||||||
{
|
{
|
||||||
my_error(ER_SP_NORETURN, MYF(0), ErrConvDQName(sphead).ptr());
|
my_error(ER_SP_NORETURN, MYF(0), ErrConvDQName(sphead).ptr());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (sp_body_finalize_procedure(thd))
|
if (sp_body_finalize_routine(thd))
|
||||||
return true;
|
return true;
|
||||||
(void) is_native_function_with_warn(thd, &sphead->m_name);
|
(void) is_native_function_with_warn(thd, &sphead->m_name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LEX::sp_body_finalize_function_standalone(THD *thd,
|
bool LEX::sp_body_finalize_trigger(THD *thd)
|
||||||
const sp_name *end_name)
|
|
||||||
{
|
{
|
||||||
return sp_body_finalize_function(thd) ||
|
return sphead->is_not_allowed_in_function("trigger") ||
|
||||||
sphead->check_standalone_routine_end_name(end_name);
|
sp_body_finalize_procedure(thd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LEX::sp_body_finalize_event(THD *thd)
|
||||||
|
{
|
||||||
|
event_parse_data->body_changed= true;
|
||||||
|
return sp_body_finalize_procedure(thd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LEX::stmt_create_stored_function_finalize_standalone(const sp_name *end_name)
|
||||||
|
{
|
||||||
|
if (sphead->check_standalone_routine_end_name(end_name))
|
||||||
|
return true;
|
||||||
|
stmt_create_routine_finalize();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6855,7 +6881,7 @@ bool LEX::maybe_start_compound_statement(THD *thd)
|
|||||||
{
|
{
|
||||||
if (!sphead)
|
if (!sphead)
|
||||||
{
|
{
|
||||||
if (!make_sp_head(thd, NULL, &sp_handler_procedure))
|
if (!make_sp_head(thd, NULL, &sp_handler_procedure, DEFAULT_AGGREGATE))
|
||||||
return true;
|
return true;
|
||||||
sphead->set_suid(SP_IS_NOT_SUID);
|
sphead->set_suid(SP_IS_NOT_SUID);
|
||||||
sphead->set_body_start(thd, thd->m_parser_state->m_lip.get_cpp_ptr());
|
sphead->set_body_start(thd, thd->m_parser_state->m_lip.get_cpp_ptr());
|
||||||
@ -8376,6 +8402,7 @@ bool LEX::create_package_finalize(THD *thd,
|
|||||||
exp ? ErrConvDQName(name).ptr() : name->m_name.str);
|
exp ? ErrConvDQName(name).ptr() : name->m_name.str);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// TODO: reuse code in LEX::create_package_finalize and sp_head::set_stmt_end
|
||||||
sphead->m_body.length= body_end - body_start;
|
sphead->m_body.length= body_end - body_start;
|
||||||
if (unlikely(!(sphead->m_body.str= thd->strmake(body_start,
|
if (unlikely(!(sphead->m_body.str= thd->strmake(body_start,
|
||||||
sphead->m_body.length))))
|
sphead->m_body.length))))
|
||||||
@ -8390,7 +8417,8 @@ bool LEX::create_package_finalize(THD *thd,
|
|||||||
sphead->restore_thd_mem_root(thd);
|
sphead->restore_thd_mem_root(thd);
|
||||||
sp_package *pkg= sphead->get_package();
|
sp_package *pkg= sphead->get_package();
|
||||||
DBUG_ASSERT(pkg);
|
DBUG_ASSERT(pkg);
|
||||||
return pkg->validate_after_parser(thd);
|
return sphead->check_group_aggregate_instructions_forbid() ||
|
||||||
|
pkg->validate_after_parser(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -10326,3 +10354,40 @@ bool LEX::stmt_purge_before(Item *item)
|
|||||||
value_list.push_front(item, thd->mem_root);
|
value_list.push_front(item, thd->mem_root);
|
||||||
return check_main_unit_semantics();
|
return check_main_unit_semantics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LEX::stmt_create_udf_function(const DDL_options_st &options,
|
||||||
|
enum_sp_aggregate_type agg_type,
|
||||||
|
const Lex_ident_sys_st &name,
|
||||||
|
Item_result return_type,
|
||||||
|
const LEX_CSTRING &soname)
|
||||||
|
{
|
||||||
|
if (stmt_create_function_start(options))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (unlikely(is_native_function(thd, &name)))
|
||||||
|
{
|
||||||
|
my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0), name.str);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sql_command= SQLCOM_CREATE_FUNCTION;
|
||||||
|
udf.name= name;
|
||||||
|
udf.returns= return_type;
|
||||||
|
udf.dl= soname.str;
|
||||||
|
udf.type= agg_type == GROUP_AGGREGATE ? UDFTYPE_AGGREGATE :
|
||||||
|
UDFTYPE_FUNCTION;
|
||||||
|
stmt_create_routine_finalize();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LEX::stmt_create_stored_function_start(const DDL_options_st &options,
|
||||||
|
enum_sp_aggregate_type agg_type,
|
||||||
|
const sp_name *spname)
|
||||||
|
{
|
||||||
|
if (stmt_create_function_start(options) ||
|
||||||
|
unlikely(!make_sp_head_no_recursive(thd, spname,
|
||||||
|
&sp_handler_function, agg_type)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -241,6 +241,14 @@ enum enum_sp_suid_behaviour
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum enum_sp_aggregate_type
|
||||||
|
{
|
||||||
|
DEFAULT_AGGREGATE= 0,
|
||||||
|
NOT_AGGREGATE,
|
||||||
|
GROUP_AGGREGATE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* These may not be declared yet */
|
/* These may not be declared yet */
|
||||||
class Table_ident;
|
class Table_ident;
|
||||||
class sql_exchange;
|
class sql_exchange;
|
||||||
@ -371,13 +379,6 @@ enum enum_sp_data_access
|
|||||||
SP_MODIFIES_SQL_DATA
|
SP_MODIFIES_SQL_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
enum enum_sp_aggregate_type
|
|
||||||
{
|
|
||||||
DEFAULT_AGGREGATE= 0,
|
|
||||||
NOT_AGGREGATE,
|
|
||||||
GROUP_AGGREGATE
|
|
||||||
};
|
|
||||||
|
|
||||||
const LEX_CSTRING sp_data_access_name[]=
|
const LEX_CSTRING sp_data_access_name[]=
|
||||||
{
|
{
|
||||||
{ STRING_WITH_LEN("") },
|
{ STRING_WITH_LEN("") },
|
||||||
@ -3734,12 +3735,16 @@ public:
|
|||||||
sp_name *make_sp_name(THD *thd, const LEX_CSTRING *name1,
|
sp_name *make_sp_name(THD *thd, const LEX_CSTRING *name1,
|
||||||
const LEX_CSTRING *name2);
|
const LEX_CSTRING *name2);
|
||||||
sp_name *make_sp_name_package_routine(THD *thd, const LEX_CSTRING *name);
|
sp_name *make_sp_name_package_routine(THD *thd, const LEX_CSTRING *name);
|
||||||
sp_head *make_sp_head(THD *thd, const sp_name *name, const Sp_handler *sph);
|
sp_head *make_sp_head(THD *thd, const sp_name *name, const Sp_handler *sph,
|
||||||
|
enum_sp_aggregate_type agg_type);
|
||||||
sp_head *make_sp_head_no_recursive(THD *thd, const sp_name *name,
|
sp_head *make_sp_head_no_recursive(THD *thd, const sp_name *name,
|
||||||
const Sp_handler *sph);
|
const Sp_handler *sph,
|
||||||
|
enum_sp_aggregate_type agg_type);
|
||||||
|
bool sp_body_finalize_routine(THD *);
|
||||||
|
bool sp_body_finalize_trigger(THD *);
|
||||||
|
bool sp_body_finalize_event(THD *);
|
||||||
bool sp_body_finalize_function(THD *);
|
bool sp_body_finalize_function(THD *);
|
||||||
bool sp_body_finalize_procedure(THD *);
|
bool sp_body_finalize_procedure(THD *);
|
||||||
bool sp_body_finalize_function_standalone(THD *, const sp_name *end_name);
|
|
||||||
bool sp_body_finalize_procedure_standalone(THD *, const sp_name *end_name);
|
bool sp_body_finalize_procedure_standalone(THD *, const sp_name *end_name);
|
||||||
sp_package *create_package_start(THD *thd,
|
sp_package *create_package_start(THD *thd,
|
||||||
enum_sql_command command,
|
enum_sql_command command,
|
||||||
@ -4502,6 +4507,17 @@ public:
|
|||||||
{
|
{
|
||||||
pop_select(); // main select
|
pop_select(); // main select
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool stmt_create_stored_function_start(const DDL_options_st &options,
|
||||||
|
enum_sp_aggregate_type,
|
||||||
|
const sp_name *name);
|
||||||
|
bool stmt_create_stored_function_finalize_standalone(const sp_name *end_name);
|
||||||
|
|
||||||
|
bool stmt_create_udf_function(const DDL_options_st &options,
|
||||||
|
enum_sp_aggregate_type agg_type,
|
||||||
|
const Lex_ident_sys_st &name,
|
||||||
|
Item_result return_type,
|
||||||
|
const LEX_CSTRING &soname);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
165
sql/sql_yacc.yy
165
sql/sql_yacc.yy
@ -758,6 +758,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
|
|||||||
|
|
||||||
/* enums */
|
/* enums */
|
||||||
enum enum_sp_suid_behaviour sp_suid;
|
enum enum_sp_suid_behaviour sp_suid;
|
||||||
|
enum enum_sp_aggregate_type sp_aggregate_type;
|
||||||
enum enum_view_suid view_suid;
|
enum enum_view_suid view_suid;
|
||||||
enum Condition_information_item::Name cond_info_item_name;
|
enum Condition_information_item::Name cond_info_item_name;
|
||||||
enum enum_diag_condition_item_name diag_condition_item_name;
|
enum enum_diag_condition_item_name diag_condition_item_name;
|
||||||
@ -2061,10 +2062,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||||||
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
|
||||||
view_list_opt view_list view_select
|
view_list_opt view_list view_select
|
||||||
trigger_tail sp_tail sf_tail event_tail
|
trigger_tail sp_tail event_tail
|
||||||
udf_tail
|
|
||||||
create_function_tail
|
|
||||||
create_aggregate_function_tail
|
|
||||||
install uninstall partition_entry binlog_base64_event
|
install uninstall partition_entry binlog_base64_event
|
||||||
normal_key_options normal_key_opts all_key_opt
|
normal_key_options normal_key_opts all_key_opt
|
||||||
spatial_key_options fulltext_key_options normal_key_opt
|
spatial_key_options fulltext_key_options normal_key_opt
|
||||||
@ -2107,6 +2105,7 @@ END_OF_INPUT
|
|||||||
|
|
||||||
%type <plsql_cursor_attr> plsql_cursor_attr
|
%type <plsql_cursor_attr> plsql_cursor_attr
|
||||||
%type <sp_suid> sp_suid
|
%type <sp_suid> sp_suid
|
||||||
|
%type <sp_aggregate_type> opt_aggregate
|
||||||
|
|
||||||
%type <num> sp_decl_idents sp_decl_idents_init_vars
|
%type <num> sp_decl_idents sp_decl_idents_init_vars
|
||||||
%type <num> sp_handler_type sp_hcond_list
|
%type <num> sp_handler_type sp_hcond_list
|
||||||
@ -2860,42 +2859,37 @@ create:
|
|||||||
{
|
{
|
||||||
Lex->pop_select(); //main select
|
Lex->pop_select(); //main select
|
||||||
}
|
}
|
||||||
| create_or_replace definer FUNCTION_SYM opt_if_not_exists
|
| create_or_replace definer opt_aggregate FUNCTION_SYM opt_if_not_exists
|
||||||
|
sp_name '('
|
||||||
{
|
{
|
||||||
if (Lex->stmt_create_function_start($1 | $4))
|
if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
sf_tail
|
sp_fdparam_list ')'
|
||||||
|
sf_return_type
|
||||||
|
sf_c_chistics_and_body
|
||||||
{
|
{
|
||||||
Lex->stmt_create_routine_finalize();
|
Lex->stmt_create_routine_finalize();
|
||||||
}
|
}
|
||||||
| create_or_replace definer AGGREGATE_SYM FUNCTION_SYM opt_if_not_exists
|
| create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
|
||||||
|
sp_name '('
|
||||||
{
|
{
|
||||||
if (Lex->stmt_create_function_start($1 | $5))
|
if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
sf_tail_aggregate
|
sp_fdparam_list ')'
|
||||||
|
sf_return_type
|
||||||
|
sf_c_chistics_and_body
|
||||||
{
|
{
|
||||||
Lex->stmt_create_routine_finalize();
|
Lex->stmt_create_routine_finalize();
|
||||||
}
|
}
|
||||||
| create_or_replace no_definer FUNCTION_SYM opt_if_not_exists
|
| create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
|
||||||
|
ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
|
||||||
{
|
{
|
||||||
if (Lex->stmt_create_function_start($1 | $4))
|
if (Lex->stmt_create_udf_function($1 | $5, $3, $6,
|
||||||
|
(Item_result) $8, $10))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
create_function_tail
|
|
||||||
{
|
|
||||||
Lex->stmt_create_routine_finalize();
|
|
||||||
}
|
|
||||||
| create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM opt_if_not_exists
|
|
||||||
{
|
|
||||||
if (Lex->stmt_create_function_start($1 | $5))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
create_aggregate_function_tail
|
|
||||||
{
|
|
||||||
Lex->stmt_create_routine_finalize();
|
|
||||||
}
|
|
||||||
| create_or_replace USER_SYM opt_if_not_exists clear_privileges
|
| create_or_replace USER_SYM opt_if_not_exists clear_privileges
|
||||||
grant_list opt_require_clause opt_resource_options opt_account_locking opt_password_expiration
|
grant_list opt_require_clause opt_resource_options opt_account_locking opt_password_expiration
|
||||||
{
|
{
|
||||||
@ -2923,38 +2917,6 @@ create:
|
|||||||
{ }
|
{ }
|
||||||
;
|
;
|
||||||
|
|
||||||
sf_tail_not_aggregate:
|
|
||||||
sf_tail
|
|
||||||
{
|
|
||||||
if (unlikely(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR))
|
|
||||||
{
|
|
||||||
my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0)));
|
|
||||||
}
|
|
||||||
Lex->sphead->set_chistics_agg_type(NOT_AGGREGATE);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
sf_tail_aggregate:
|
|
||||||
sf_tail
|
|
||||||
{
|
|
||||||
if (unlikely(!(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)))
|
|
||||||
{
|
|
||||||
my_yyabort_error((ER_INVALID_AGGREGATE_FUNCTION, MYF(0)));
|
|
||||||
}
|
|
||||||
Lex->sphead->set_chistics_agg_type(GROUP_AGGREGATE);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
create_function_tail:
|
|
||||||
sf_tail_not_aggregate { }
|
|
||||||
| udf_tail { Lex->udf.type= UDFTYPE_FUNCTION; }
|
|
||||||
;
|
|
||||||
|
|
||||||
create_aggregate_function_tail:
|
|
||||||
sf_tail_aggregate { }
|
|
||||||
| udf_tail { Lex->udf.type= UDFTYPE_AGGREGATE; }
|
|
||||||
;
|
|
||||||
|
|
||||||
opt_sequence:
|
opt_sequence:
|
||||||
/* empty */ { }
|
/* empty */ { }
|
||||||
| sequence_defs
|
| sequence_defs
|
||||||
@ -3275,20 +3237,17 @@ ev_sql_stmt:
|
|||||||
|
|
||||||
if (unlikely(!lex->make_sp_head(thd,
|
if (unlikely(!lex->make_sp_head(thd,
|
||||||
lex->event_parse_data->identifier,
|
lex->event_parse_data->identifier,
|
||||||
&sp_handler_procedure)))
|
&sp_handler_procedure,
|
||||||
|
DEFAULT_AGGREGATE)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
lex->sphead->set_body_start(thd, lip->get_cpp_ptr());
|
lex->sphead->set_body_start(thd, lip->get_cpp_ptr());
|
||||||
}
|
}
|
||||||
sp_proc_stmt
|
sp_proc_stmt
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
|
||||||
|
|
||||||
/* return back to the original memory root ASAP */
|
/* return back to the original memory root ASAP */
|
||||||
lex->sphead->set_stmt_end(thd);
|
if (Lex->sp_body_finalize_event(thd))
|
||||||
lex->sphead->restore_thd_mem_root(thd);
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
lex->event_parse_data->body_changed= TRUE;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -3305,6 +3264,11 @@ clear_privileges:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_aggregate:
|
||||||
|
/* Empty */ { $$= NOT_AGGREGATE; }
|
||||||
|
| AGGREGATE_SYM { $$= GROUP_AGGREGATE; }
|
||||||
|
;
|
||||||
|
|
||||||
sp_name:
|
sp_name:
|
||||||
ident '.' ident
|
ident '.' ident
|
||||||
{
|
{
|
||||||
@ -3391,7 +3355,18 @@ sp_cparams:
|
|||||||
/* Stored FUNCTION parameter declaration list */
|
/* Stored FUNCTION parameter declaration list */
|
||||||
sp_fdparam_list:
|
sp_fdparam_list:
|
||||||
/* Empty */
|
/* Empty */
|
||||||
| sp_fdparams
|
{
|
||||||
|
Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start();
|
||||||
|
Lex->sphead->m_param_end= Lex->sphead->m_param_begin;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
{
|
||||||
|
Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start();
|
||||||
|
}
|
||||||
|
sp_fdparams
|
||||||
|
{
|
||||||
|
Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_fdparams:
|
sp_fdparams:
|
||||||
@ -3465,18 +3440,6 @@ sp_opt_inout:
|
|||||||
| INOUT_SYM { $$= sp_variable::MODE_INOUT; }
|
| INOUT_SYM { $$= sp_variable::MODE_INOUT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_parenthesized_fdparam_list:
|
|
||||||
'('
|
|
||||||
{
|
|
||||||
Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1;
|
|
||||||
}
|
|
||||||
sp_fdparam_list
|
|
||||||
')'
|
|
||||||
{
|
|
||||||
Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
sp_parenthesized_pdparam_list:
|
sp_parenthesized_pdparam_list:
|
||||||
'('
|
'('
|
||||||
{
|
{
|
||||||
@ -17415,8 +17378,8 @@ compound_statement:
|
|||||||
sp_proc_stmt_compound_ok
|
sp_proc_stmt_compound_ok
|
||||||
{
|
{
|
||||||
Lex->sql_command= SQLCOM_COMPOUND;
|
Lex->sql_command= SQLCOM_COMPOUND;
|
||||||
Lex->sphead->set_stmt_end(thd);
|
if (Lex->sp_body_finalize_procedure(thd))
|
||||||
Lex->sphead->restore_thd_mem_root(thd);
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -17702,7 +17665,8 @@ trigger_tail:
|
|||||||
(*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($17);
|
(*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($17);
|
||||||
lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr();
|
lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr();
|
||||||
|
|
||||||
if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger)))
|
if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger,
|
||||||
|
DEFAULT_AGGREGATE)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
|
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
|
||||||
@ -17710,13 +17674,9 @@ trigger_tail:
|
|||||||
sp_proc_stmt /* $19 */
|
sp_proc_stmt /* $19 */
|
||||||
{ /* $20 */
|
{ /* $20 */
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
|
||||||
|
|
||||||
lex->sql_command= SQLCOM_CREATE_TRIGGER;
|
lex->sql_command= SQLCOM_CREATE_TRIGGER;
|
||||||
sp->set_stmt_end(thd);
|
if (lex->sp_body_finalize_trigger(thd))
|
||||||
sp->restore_thd_mem_root(thd);
|
|
||||||
|
|
||||||
if (unlikely(sp->is_not_allowed_in_function("trigger")))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -17738,19 +17698,6 @@ trigger_tail:
|
|||||||
|
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
udf_tail:
|
|
||||||
ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
|
|
||||||
{
|
|
||||||
LEX *lex= thd->lex;
|
|
||||||
if (unlikely(is_native_function(thd, & $1)))
|
|
||||||
my_yyabort_error((ER_NATIVE_FCT_NAME_COLLISION, MYF(0), $1.str));
|
|
||||||
lex->sql_command= SQLCOM_CREATE_FUNCTION;
|
|
||||||
lex->udf.name= $1;
|
|
||||||
lex->udf.returns= (Item_result) $3;
|
|
||||||
lex->udf.dl= $5.str;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
sf_return_type:
|
sf_return_type:
|
||||||
RETURNS_SYM
|
RETURNS_SYM
|
||||||
@ -17768,22 +17715,12 @@ sf_return_type:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sf_tail:
|
sf_c_chistics_and_body:
|
||||||
sp_name
|
|
||||||
{
|
|
||||||
if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
|
|
||||||
&sp_handler_function)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
sp_parenthesized_fdparam_list
|
|
||||||
sf_return_type
|
|
||||||
sp_c_chistics
|
sp_c_chistics
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
Lex_input_stream *lip= YYLIP;
|
lex->sphead->set_c_chistics(lex->sp_chistics);
|
||||||
|
lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
|
||||||
lex->sphead->set_chistics(lex->sp_chistics);
|
|
||||||
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
|
|
||||||
}
|
}
|
||||||
sp_proc_stmt_in_returns_clause
|
sp_proc_stmt_in_returns_clause
|
||||||
{
|
{
|
||||||
@ -17792,17 +17729,19 @@ sf_tail:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
sp_tail:
|
sp_tail:
|
||||||
sp_name
|
sp_name
|
||||||
{
|
{
|
||||||
if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
|
if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
|
||||||
&sp_handler_procedure)))
|
&sp_handler_procedure,
|
||||||
|
DEFAULT_AGGREGATE)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
sp_parenthesized_pdparam_list
|
sp_parenthesized_pdparam_list
|
||||||
sp_c_chistics
|
sp_c_chistics
|
||||||
{
|
{
|
||||||
Lex->sphead->set_chistics(Lex->sp_chistics);
|
Lex->sphead->set_c_chistics(Lex->sp_chistics);
|
||||||
Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
|
Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
|
||||||
}
|
}
|
||||||
sp_proc_stmt
|
sp_proc_stmt
|
||||||
|
@ -254,6 +254,7 @@ void ORAerror(THD *thd, const char *s)
|
|||||||
|
|
||||||
/* enums */
|
/* enums */
|
||||||
enum enum_sp_suid_behaviour sp_suid;
|
enum enum_sp_suid_behaviour sp_suid;
|
||||||
|
enum enum_sp_aggregate_type sp_aggregate_type;
|
||||||
enum enum_view_suid view_suid;
|
enum enum_view_suid view_suid;
|
||||||
enum Condition_information_item::Name cond_info_item_name;
|
enum Condition_information_item::Name cond_info_item_name;
|
||||||
enum enum_diag_condition_item_name diag_condition_item_name;
|
enum enum_diag_condition_item_name diag_condition_item_name;
|
||||||
@ -1565,9 +1566,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||||||
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
|
||||||
view_list_opt view_list view_select
|
view_list_opt view_list view_select
|
||||||
trigger_tail event_tail
|
trigger_tail event_tail
|
||||||
udf_tail
|
|
||||||
create_function_tail_standalone
|
|
||||||
create_aggregate_function_tail_standalone
|
|
||||||
install uninstall partition_entry binlog_base64_event
|
install uninstall partition_entry binlog_base64_event
|
||||||
normal_key_options normal_key_opts all_key_opt
|
normal_key_options normal_key_opts all_key_opt
|
||||||
spatial_key_options fulltext_key_options normal_key_opt
|
spatial_key_options fulltext_key_options normal_key_opt
|
||||||
@ -1587,7 +1585,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||||||
opt_delete_gtid_domain
|
opt_delete_gtid_domain
|
||||||
asrow_attribute
|
asrow_attribute
|
||||||
set_assign
|
set_assign
|
||||||
sf_tail_standalone
|
|
||||||
sp_tail_standalone
|
sp_tail_standalone
|
||||||
opt_constraint_no_id
|
opt_constraint_no_id
|
||||||
END_OF_INPUT
|
END_OF_INPUT
|
||||||
@ -1613,6 +1610,7 @@ END_OF_INPUT
|
|||||||
|
|
||||||
%type <plsql_cursor_attr> plsql_cursor_attr
|
%type <plsql_cursor_attr> plsql_cursor_attr
|
||||||
%type <sp_suid> sp_suid
|
%type <sp_suid> sp_suid
|
||||||
|
%type <sp_aggregate_type> opt_aggregate
|
||||||
|
|
||||||
%type <num> sp_decl_idents sp_decl_idents_init_vars
|
%type <num> sp_decl_idents sp_decl_idents_init_vars
|
||||||
%type <num> sp_handler_type sp_hcond_list
|
%type <num> sp_handler_type sp_hcond_list
|
||||||
@ -2381,41 +2379,66 @@ create:
|
|||||||
{
|
{
|
||||||
Lex->pop_select(); //main select
|
Lex->pop_select(); //main select
|
||||||
}
|
}
|
||||||
| create_or_replace definer FUNCTION_SYM opt_if_not_exists
|
| create_or_replace definer opt_aggregate FUNCTION_SYM opt_if_not_exists
|
||||||
|
sp_name RETURN_ORACLE_SYM
|
||||||
{
|
{
|
||||||
if (Lex->stmt_create_function_start($1 | $4))
|
if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
sf_tail_standalone
|
sf_return_type
|
||||||
|
sf_c_chistics_and_body_standalone
|
||||||
|
opt_sp_name
|
||||||
{
|
{
|
||||||
Lex->stmt_create_routine_finalize();
|
if (Lex->stmt_create_stored_function_finalize_standalone($11))
|
||||||
}
|
|
||||||
| create_or_replace definer AGGREGATE_SYM FUNCTION_SYM opt_if_not_exists
|
|
||||||
{
|
|
||||||
if (Lex->stmt_create_function_start($1 | $5))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
sf_tail_aggregate_standalone
|
| create_or_replace definer opt_aggregate FUNCTION_SYM opt_if_not_exists
|
||||||
|
sp_name '('
|
||||||
{
|
{
|
||||||
Lex->stmt_create_routine_finalize();
|
if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
|
||||||
}
|
|
||||||
| create_or_replace no_definer FUNCTION_SYM opt_if_not_exists
|
|
||||||
{
|
|
||||||
if (Lex->stmt_create_function_start($1 | $4))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
create_function_tail_standalone
|
sp_fdparam_list ')'
|
||||||
|
RETURN_ORACLE_SYM sf_return_type
|
||||||
|
sf_c_chistics_and_body_standalone
|
||||||
|
opt_sp_name
|
||||||
{
|
{
|
||||||
Lex->stmt_create_routine_finalize();
|
if (Lex->stmt_create_stored_function_finalize_standalone($14))
|
||||||
}
|
|
||||||
| create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM opt_if_not_exists
|
|
||||||
{
|
|
||||||
if (Lex->stmt_create_function_start($1 | $5))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
create_aggregate_function_tail_standalone
|
| create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
|
||||||
|
sp_name RETURN_ORACLE_SYM
|
||||||
{
|
{
|
||||||
Lex->stmt_create_routine_finalize();
|
if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
sf_return_type
|
||||||
|
sf_c_chistics_and_body_standalone
|
||||||
|
opt_sp_name
|
||||||
|
{
|
||||||
|
if (Lex->stmt_create_stored_function_finalize_standalone($11))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
|
||||||
|
sp_name '('
|
||||||
|
{
|
||||||
|
if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
sp_fdparam_list ')'
|
||||||
|
RETURN_ORACLE_SYM sf_return_type
|
||||||
|
sf_c_chistics_and_body_standalone
|
||||||
|
opt_sp_name
|
||||||
|
{
|
||||||
|
if (Lex->stmt_create_stored_function_finalize_standalone($14))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
|
||||||
|
ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
|
||||||
|
{
|
||||||
|
if (Lex->stmt_create_udf_function($1 | $5, $3, $6,
|
||||||
|
(Item_result) $8, $10))
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| create_or_replace USER_SYM opt_if_not_exists clear_privileges
|
| create_or_replace USER_SYM opt_if_not_exists clear_privileges
|
||||||
grant_list opt_require_clause opt_resource_options opt_account_locking opt_password_expiration
|
grant_list opt_require_clause opt_resource_options opt_account_locking opt_password_expiration
|
||||||
@ -2454,7 +2477,7 @@ create:
|
|||||||
&sp_handler_package_spec,
|
&sp_handler_package_spec,
|
||||||
$5, $1 | $4))))
|
$5, $1 | $4))))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
pkg->set_chistics(Lex->sp_chistics);
|
pkg->set_c_chistics(Lex->sp_chistics);
|
||||||
}
|
}
|
||||||
opt_package_specification_element_list END
|
opt_package_specification_element_list END
|
||||||
remember_end_opt opt_sp_name
|
remember_end_opt opt_sp_name
|
||||||
@ -2474,7 +2497,7 @@ create:
|
|||||||
&sp_handler_package_body,
|
&sp_handler_package_body,
|
||||||
$6, $1 | $5))))
|
$6, $1 | $5))))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
pkg->set_chistics(Lex->sp_chistics);
|
pkg->set_c_chistics(Lex->sp_chistics);
|
||||||
Lex->sp_block_init(thd);
|
Lex->sp_block_init(thd);
|
||||||
}
|
}
|
||||||
package_implementation_declare_section
|
package_implementation_declare_section
|
||||||
@ -2495,39 +2518,6 @@ create:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sf_tail_not_aggregate_standalone:
|
|
||||||
sf_tail_standalone
|
|
||||||
{
|
|
||||||
if (unlikely(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR))
|
|
||||||
{
|
|
||||||
my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0)));
|
|
||||||
}
|
|
||||||
Lex->sphead->set_chistics_agg_type(NOT_AGGREGATE);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
sf_tail_aggregate_standalone:
|
|
||||||
sf_tail_standalone
|
|
||||||
{
|
|
||||||
if (unlikely(!(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)))
|
|
||||||
{
|
|
||||||
my_yyabort_error((ER_INVALID_AGGREGATE_FUNCTION, MYF(0)));
|
|
||||||
}
|
|
||||||
Lex->sphead->set_chistics_agg_type(GROUP_AGGREGATE);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
create_function_tail_standalone:
|
|
||||||
sf_tail_not_aggregate_standalone { }
|
|
||||||
| udf_tail { Lex->udf.type= UDFTYPE_FUNCTION; }
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
create_aggregate_function_tail_standalone:
|
|
||||||
sf_tail_aggregate_standalone { }
|
|
||||||
| udf_tail { Lex->udf.type= UDFTYPE_AGGREGATE; }
|
|
||||||
;
|
|
||||||
|
|
||||||
package_implementation_executable_section:
|
package_implementation_executable_section:
|
||||||
END
|
END
|
||||||
{
|
{
|
||||||
@ -2584,13 +2574,14 @@ package_specification_function:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
thd->lex= $2;
|
thd->lex= $2;
|
||||||
if (unlikely(!$2->make_sp_head_no_recursive(thd, spname,
|
if (unlikely(!$2->make_sp_head_no_recursive(thd, spname,
|
||||||
&sp_handler_package_function)))
|
&sp_handler_package_function,
|
||||||
|
NOT_AGGREGATE)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
$1->sphead->get_package()->m_current_routine= $2;
|
$1->sphead->get_package()->m_current_routine= $2;
|
||||||
(void) is_native_function_with_warn(thd, &$3);
|
(void) is_native_function_with_warn(thd, &$3);
|
||||||
}
|
}
|
||||||
opt_sp_parenthesized_fdparam_list
|
opt_sp_parenthesized_fdparam_list
|
||||||
sf_return_type
|
RETURN_ORACLE_SYM sf_return_type
|
||||||
sp_c_chistics
|
sp_c_chistics
|
||||||
{
|
{
|
||||||
sp_head *sp= thd->lex->sphead;
|
sp_head *sp= thd->lex->sphead;
|
||||||
@ -2610,7 +2601,8 @@ package_specification_procedure:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
thd->lex= $2;
|
thd->lex= $2;
|
||||||
if (unlikely(!$2->make_sp_head_no_recursive(thd, spname,
|
if (unlikely(!$2->make_sp_head_no_recursive(thd, spname,
|
||||||
&sp_handler_package_procedure)))
|
&sp_handler_package_procedure,
|
||||||
|
DEFAULT_AGGREGATE)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
$1->sphead->get_package()->m_current_routine= $2;
|
$1->sphead->get_package()->m_current_routine= $2;
|
||||||
}
|
}
|
||||||
@ -2660,11 +2652,6 @@ package_implementation_function_body:
|
|||||||
}
|
}
|
||||||
sp_body opt_package_routine_end_name
|
sp_body opt_package_routine_end_name
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR))
|
|
||||||
{
|
|
||||||
my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0)));
|
|
||||||
}
|
|
||||||
Lex->sphead->set_chistics_agg_type(NOT_AGGREGATE);
|
|
||||||
if (unlikely(thd->lex->sp_body_finalize_function(thd) ||
|
if (unlikely(thd->lex->sp_body_finalize_function(thd) ||
|
||||||
thd->lex->sphead->check_package_routine_end_name($5)))
|
thd->lex->sphead->check_package_routine_end_name($5)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@ -3043,20 +3030,17 @@ ev_sql_stmt:
|
|||||||
|
|
||||||
if (unlikely(!lex->make_sp_head(thd,
|
if (unlikely(!lex->make_sp_head(thd,
|
||||||
lex->event_parse_data->identifier,
|
lex->event_parse_data->identifier,
|
||||||
&sp_handler_procedure)))
|
&sp_handler_procedure,
|
||||||
|
DEFAULT_AGGREGATE)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
lex->sphead->set_body_start(thd, lip->get_cpp_ptr());
|
lex->sphead->set_body_start(thd, lip->get_cpp_ptr());
|
||||||
}
|
}
|
||||||
sp_proc_stmt
|
sp_proc_stmt
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
|
||||||
|
|
||||||
/* return back to the original memory root ASAP */
|
/* return back to the original memory root ASAP */
|
||||||
lex->sphead->set_stmt_end(thd);
|
if (Lex->sp_body_finalize_event(thd))
|
||||||
lex->sphead->restore_thd_mem_root(thd);
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
lex->event_parse_data->body_changed= TRUE;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -3073,6 +3057,11 @@ clear_privileges:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_aggregate:
|
||||||
|
/* Empty */ { $$= NOT_AGGREGATE; }
|
||||||
|
| AGGREGATE_SYM { $$= GROUP_AGGREGATE; }
|
||||||
|
;
|
||||||
|
|
||||||
sp_name:
|
sp_name:
|
||||||
ident '.' ident
|
ident '.' ident
|
||||||
{
|
{
|
||||||
@ -3186,7 +3175,18 @@ sp_cparams:
|
|||||||
/* Stored FUNCTION parameter declaration list */
|
/* Stored FUNCTION parameter declaration list */
|
||||||
sp_fdparam_list:
|
sp_fdparam_list:
|
||||||
/* Empty */
|
/* Empty */
|
||||||
| sp_fdparams
|
{
|
||||||
|
Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start();
|
||||||
|
Lex->sphead->m_param_end= Lex->sphead->m_param_begin;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
{
|
||||||
|
Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start();
|
||||||
|
}
|
||||||
|
sp_fdparams
|
||||||
|
{
|
||||||
|
Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_fdparams:
|
sp_fdparams:
|
||||||
@ -3293,18 +3293,6 @@ sp_opt_inout:
|
|||||||
| IN_SYM OUT_SYM { $$= sp_variable::MODE_INOUT; }
|
| IN_SYM OUT_SYM { $$= sp_variable::MODE_INOUT; }
|
||||||
;
|
;
|
||||||
|
|
||||||
sp_parenthesized_fdparam_list:
|
|
||||||
'('
|
|
||||||
{
|
|
||||||
Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1;
|
|
||||||
}
|
|
||||||
sp_fdparam_list
|
|
||||||
')'
|
|
||||||
{
|
|
||||||
Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
sp_parenthesized_pdparam_list:
|
sp_parenthesized_pdparam_list:
|
||||||
'('
|
'('
|
||||||
{
|
{
|
||||||
@ -3327,7 +3315,7 @@ sp_no_param:
|
|||||||
|
|
||||||
opt_sp_parenthesized_fdparam_list:
|
opt_sp_parenthesized_fdparam_list:
|
||||||
sp_no_param
|
sp_no_param
|
||||||
| sp_parenthesized_fdparam_list
|
| '(' sp_fdparam_list ')'
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_sp_parenthesized_pdparam_list:
|
opt_sp_parenthesized_pdparam_list:
|
||||||
@ -17620,8 +17608,8 @@ compound_statement:
|
|||||||
sp_proc_stmt_compound_ok
|
sp_proc_stmt_compound_ok
|
||||||
{
|
{
|
||||||
Lex->sql_command= SQLCOM_COMPOUND;
|
Lex->sql_command= SQLCOM_COMPOUND;
|
||||||
Lex->sphead->set_stmt_end(thd);
|
if (Lex->sp_body_finalize_procedure(thd))
|
||||||
Lex->sphead->restore_thd_mem_root(thd);
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -17908,7 +17896,8 @@ trigger_tail:
|
|||||||
(*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($17);
|
(*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($17);
|
||||||
lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr();
|
lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr();
|
||||||
|
|
||||||
if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger)))
|
if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger,
|
||||||
|
DEFAULT_AGGREGATE)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
|
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
|
||||||
@ -17916,15 +17905,9 @@ trigger_tail:
|
|||||||
sp_proc_stmt /* $19 */
|
sp_proc_stmt /* $19 */
|
||||||
{ /* $20 */
|
{ /* $20 */
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
|
||||||
if (unlikely(sp->check_unresolved_goto()))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
|
|
||||||
lex->sql_command= SQLCOM_CREATE_TRIGGER;
|
lex->sql_command= SQLCOM_CREATE_TRIGGER;
|
||||||
sp->set_stmt_end(thd);
|
if (lex->sp_body_finalize_trigger(thd))
|
||||||
sp->restore_thd_mem_root(thd);
|
|
||||||
|
|
||||||
if (unlikely(sp->is_not_allowed_in_function("trigger")))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -17946,22 +17929,7 @@ trigger_tail:
|
|||||||
|
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
udf_tail:
|
|
||||||
ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
|
|
||||||
{
|
|
||||||
LEX *lex= thd->lex;
|
|
||||||
if (unlikely(is_native_function(thd, & $1)))
|
|
||||||
my_yyabort_error((ER_NATIVE_FCT_NAME_COLLISION, MYF(0), $1.str));
|
|
||||||
lex->sql_command= SQLCOM_CREATE_FUNCTION;
|
|
||||||
lex->udf.name= $1;
|
|
||||||
lex->udf.returns= (Item_result) $3;
|
|
||||||
lex->udf.dl= $5.str;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
sf_return_type:
|
sf_return_type:
|
||||||
RETURN_ORACLE_SYM
|
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->init_last_field(&lex->sphead->m_return_field_def,
|
lex->init_last_field(&lex->sphead->m_return_field_def,
|
||||||
@ -17976,28 +17944,17 @@ sf_return_type:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sf_tail_standalone:
|
sf_c_chistics_and_body_standalone:
|
||||||
sp_name
|
|
||||||
{
|
|
||||||
if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
|
|
||||||
&sp_handler_function)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
opt_sp_parenthesized_fdparam_list
|
|
||||||
sf_return_type
|
|
||||||
sp_c_chistics
|
sp_c_chistics
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
Lex_input_stream *lip= YYLIP;
|
lex->sphead->set_c_chistics(lex->sp_chistics);
|
||||||
|
lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
|
||||||
lex->sphead->set_chistics(lex->sp_chistics);
|
|
||||||
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
|
|
||||||
}
|
}
|
||||||
sp_tail_is
|
sp_tail_is
|
||||||
sp_body
|
sp_body
|
||||||
opt_sp_name
|
|
||||||
{
|
{
|
||||||
if (unlikely(Lex->sp_body_finalize_function_standalone(thd, $9)))
|
if (unlikely(Lex->sp_body_finalize_function(thd)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -18006,13 +17963,14 @@ sp_tail_standalone:
|
|||||||
sp_name
|
sp_name
|
||||||
{
|
{
|
||||||
if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
|
if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
|
||||||
&sp_handler_procedure)))
|
&sp_handler_procedure,
|
||||||
|
DEFAULT_AGGREGATE)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
opt_sp_parenthesized_pdparam_list
|
opt_sp_parenthesized_pdparam_list
|
||||||
sp_c_chistics
|
sp_c_chistics
|
||||||
{
|
{
|
||||||
Lex->sphead->set_chistics(Lex->sp_chistics);
|
Lex->sphead->set_c_chistics(Lex->sp_chistics);
|
||||||
Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
|
Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
|
||||||
}
|
}
|
||||||
sp_tail_is
|
sp_tail_is
|
||||||
|
Reference in New Issue
Block a user