Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
3b47587f
Commit
3b47587f
authored
Mar 01, 2019
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-18789 Port "MDEV-7773 Aggregate stored functions" to sql_yacc_ora.yy
parent
01d7727b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
195 additions
and
26 deletions
+195
-26
mysql-test/suite/compat/oracle/r/custom_aggregate_functions.result
...t/suite/compat/oracle/r/custom_aggregate_functions.result
+58
-0
mysql-test/suite/compat/oracle/t/custom_aggregate_functions.test
...est/suite/compat/oracle/t/custom_aggregate_functions.test
+66
-0
sql/sql_lex.cc
sql/sql_lex.cc
+9
-0
sql/sql_lex.h
sql/sql_lex.h
+1
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+7
-12
sql/sql_yacc_ora.yy
sql/sql_yacc_ora.yy
+54
-14
No files found.
mysql-test/suite/compat/oracle/r/custom_aggregate_functions.result
0 → 100644
View file @
3b47587f
SET sql_mode=ORACLE;
create aggregate function f1(x INT) return INT AS
begin
insert into t1(sal) values (x);
return x;
end|
ERROR HY000: Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function
create function f1(x INT) return INT AS
begin
set x=5;
fetch group next row;
return x+1;
end |
ERROR HY000: Non-aggregate function contains aggregate specific instructions: (FETCH GROUP NEXT ROW)
CREATE TABLE marks(stud_id INT, grade_count INT);
INSERT INTO marks VALUES (1,6), (2,4), (3,7), (4,5), (5,8);
SELECT * FROM marks;
stud_id grade_count
1 6
2 4
3 7
4 5
5 8
# Using PL/SQL syntax: EXCEPTION WHEN NO_DATA_FOUND
CREATE AGGREGATE FUNCTION IF NOT EXISTS aggregate_count(x INT) RETURN INT AS
count_students INT DEFAULT 0;
BEGIN
LOOP
FETCH GROUP NEXT ROW;
IF x THEN
count_students:= count_students + 1;
END IF;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN count_students;
END aggregate_count //
SELECT aggregate_count(stud_id) FROM marks;
aggregate_count(stud_id)
5
DROP FUNCTION IF EXISTS aggregate_count;
# Using SQL/PSM systax: CONTINUE HANDLER
CREATE AGGREGATE FUNCTION IF NOT EXISTS aggregate_count(x INT) RETURN INT AS
count_students INT DEFAULT 0;
CONTINUE HANDLER FOR NOT FOUND RETURN count_students;
BEGIN
LOOP
FETCH GROUP NEXT ROW;
IF x THEN
SET count_students= count_students + 1;
END IF;
END LOOP;
END //
SELECT aggregate_count(stud_id) FROM marks;
aggregate_count(stud_id)
5
DROP FUNCTION IF EXISTS aggregate_count;
DROP TABLE marks;
mysql-test/suite/compat/oracle/t/custom_aggregate_functions.test
0 → 100644
View file @
3b47587f
SET
sql_mode
=
ORACLE
;
delimiter
|
;
--
error
ER_INVALID_AGGREGATE_FUNCTION
create
aggregate
function
f1
(
x
INT
)
return
INT
AS
begin
insert
into
t1
(
sal
)
values
(
x
);
return
x
;
end
|
--
error
ER_NOT_AGGREGATE_FUNCTION
create
function
f1
(
x
INT
)
return
INT
AS
begin
set
x
=
5
;
fetch
group
next
row
;
return
x
+
1
;
end
|
DELIMITER
;
|
CREATE
TABLE
marks
(
stud_id
INT
,
grade_count
INT
);
INSERT
INTO
marks
VALUES
(
1
,
6
),
(
2
,
4
),
(
3
,
7
),
(
4
,
5
),
(
5
,
8
);
SELECT
*
FROM
marks
;
--
echo
# Using PL/SQL syntax: EXCEPTION WHEN NO_DATA_FOUND
DELIMITER
//;
CREATE
AGGREGATE
FUNCTION
IF
NOT
EXISTS
aggregate_count
(
x
INT
)
RETURN
INT
AS
count_students
INT
DEFAULT
0
;
BEGIN
LOOP
FETCH
GROUP
NEXT
ROW
;
IF
x
THEN
count_students
:=
count_students
+
1
;
END
IF
;
END
LOOP
;
EXCEPTION
WHEN
NO_DATA_FOUND
THEN
RETURN
count_students
;
END
aggregate_count
//
DELIMITER
;
//
SELECT
aggregate_count
(
stud_id
)
FROM
marks
;
DROP
FUNCTION
IF
EXISTS
aggregate_count
;
--
echo
# Using SQL/PSM systax: CONTINUE HANDLER
DELIMITER
//;
CREATE
AGGREGATE
FUNCTION
IF
NOT
EXISTS
aggregate_count
(
x
INT
)
RETURN
INT
AS
count_students
INT
DEFAULT
0
;
CONTINUE
HANDLER
FOR
NOT
FOUND
RETURN
count_students
;
BEGIN
LOOP
FETCH
GROUP
NEXT
ROW
;
IF
x
THEN
SET
count_students
=
count_students
+
1
;
END
IF
;
END
LOOP
;
END
//
DELIMITER
;
//
SELECT
aggregate_count
(
stud_id
)
FROM
marks
;
DROP
FUNCTION
IF
EXISTS
aggregate_count
;
DROP
TABLE
marks
;
sql/sql_lex.cc
View file @
3b47587f
...
@@ -8186,6 +8186,15 @@ bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name)
...
@@ -8186,6 +8186,15 @@ bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name)
}
}
bool
LEX
::
sp_add_agg_cfetch
()
{
sphead
->
m_flags
|=
sp_head
::
HAS_AGGREGATE_INSTR
;
sp_instr_agg_cfetch
*
i
=
new
(
thd
->
mem_root
)
sp_instr_agg_cfetch
(
sphead
->
instructions
(),
spcont
);
return
i
==
NULL
||
sphead
->
add_instr
(
i
);
}
bool
LEX
::
create_or_alter_view_finalize
(
THD
*
thd
,
Table_ident
*
table_ident
)
bool
LEX
::
create_or_alter_view_finalize
(
THD
*
thd
,
Table_ident
*
table_ident
)
{
{
sql_command
=
SQLCOM_CREATE_VIEW
;
sql_command
=
SQLCOM_CREATE_VIEW
;
...
...
sql/sql_lex.h
View file @
3b47587f
...
@@ -4244,6 +4244,7 @@ struct LEX: public Query_tables_list
...
@@ -4244,6 +4244,7 @@ struct LEX: public Query_tables_list
return
check_create_options
(
create_info
);
return
check_create_options
(
create_info
);
}
}
bool
sp_add_cfetch
(
THD
*
thd
,
const
LEX_CSTRING
*
name
);
bool
sp_add_cfetch
(
THD
*
thd
,
const
LEX_CSTRING
*
name
);
bool
sp_add_agg_cfetch
();
bool
set_command_with_check
(
enum_sql_command
command
,
bool
set_command_with_check
(
enum_sql_command
command
,
uint
scope
,
uint
scope
,
...
...
sql/sql_yacc.yy
View file @
3b47587f
...
@@ -2060,7 +2060,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
...
@@ -2060,7 +2060,9 @@ 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 sp_tail sf_tail event_tail
trigger_tail sp_tail sf_tail event_tail
udf_tail create_function_tail create_aggregate_function_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
...
@@ -2975,10 +2977,10 @@ create_function_tail:
...
@@ -2975,10 +2977,10 @@ create_function_tail:
;
;
create_aggregate_function_tail:
create_aggregate_function_tail:
sf_tail_aggregate
sf_tail_aggregate { }
{ }
| udf_tail { Lex->udf.type= UDFTYPE_AGGREGATE; }
| udf_tail { Lex->udf.type= UDFTYPE_AGGREGATE; }
;
;
opt_sequence:
opt_sequence:
/* empty */ { }
/* empty */ { }
| sequence_defs
| sequence_defs
...
@@ -4421,15 +4423,8 @@ sp_proc_stmt_fetch:
...
@@ -4421,15 +4423,8 @@ sp_proc_stmt_fetch:
sp_proc_stmt_fetch_head sp_fetch_list { }
sp_proc_stmt_fetch_head sp_fetch_list { }
| FETCH_SYM GROUP_SYM NEXT_SYM ROW_SYM
| FETCH_SYM GROUP_SYM NEXT_SYM ROW_SYM
{
{
LEX *lex= Lex;
if (unlikely(Lex->sp_add_agg_cfetch()))
sp_head *sp= lex->sphead;
MYSQL_YYABORT;
lex->sphead->m_flags|= sp_head::HAS_AGGREGATE_INSTR;
sp_instr_agg_cfetch *i=
new (thd->mem_root) sp_instr_agg_cfetch(sp->instructions(),
lex->spcont);
if (unlikely(i == NULL) ||
unlikely(sp->add_instr(i)))
MYSQL_YYABORT;
}
}
;
;
...
...
sql/sql_yacc_ora.yy
View file @
3b47587f
...
@@ -1563,7 +1563,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
...
@@ -1563,7 +1563,9 @@ 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 sp_tail sf_tail event_tail
trigger_tail sp_tail sf_tail event_tail
udf_tail create_function_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
...
@@ -2403,13 +2405,23 @@ create:
...
@@ -2403,13 +2405,23 @@ create:
{
{
Lex->pop_select(); //main select
Lex->pop_select(); //main select
}
}
| create_or_replace definer AGGREGATE_SYM FUNCTION_SYM
{
if (Lex->main_select_push())
MYSQL_YYABORT;
Lex->create_info.set($1);
}
sf_tail_aggregate_standalone
{
Lex->pop_select(); //main select
}
| create_or_replace no_definer FUNCTION_SYM
| create_or_replace no_definer FUNCTION_SYM
{
{
if (Lex->main_select_push())
if (Lex->main_select_push())
MYSQL_YYABORT;
MYSQL_YYABORT;
Lex->create_info.set($1);
Lex->create_info.set($1);
}
}
create_function_tail
create_function_tail
_standalone
{
{
Lex->pop_select(); //main select
Lex->pop_select(); //main select
}
}
...
@@ -2418,9 +2430,8 @@ create:
...
@@ -2418,9 +2430,8 @@ create:
if (Lex->main_select_push())
if (Lex->main_select_push())
MYSQL_YYABORT;
MYSQL_YYABORT;
Lex->create_info.set($1);
Lex->create_info.set($1);
Lex->udf.type= UDFTYPE_AGGREGATE;
}
}
udf_tail
create_aggregate_function_tail_standalone
{
{
Lex->pop_select(); //main select
Lex->pop_select(); //main select
}
}
...
@@ -2502,6 +2513,39 @@ create:
...
@@ -2502,6 +2513,39 @@ 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
{
{
...
@@ -2696,10 +2740,6 @@ package_specification_element:
...
@@ -2696,10 +2740,6 @@ package_specification_element:
}
}
;
;
create_function_tail:
sf_tail_standalone { }
| udf_tail { Lex->udf.type= UDFTYPE_FUNCTION; }
;
opt_sequence:
opt_sequence:
/* empty */ { }
/* empty */ { }
...
@@ -4281,7 +4321,12 @@ sp_proc_stmt_fetch_head:
...
@@ -4281,7 +4321,12 @@ sp_proc_stmt_fetch_head:
;
;
sp_proc_stmt_fetch:
sp_proc_stmt_fetch:
sp_proc_stmt_fetch_head sp_fetch_list { }
sp_proc_stmt_fetch_head sp_fetch_list { }
| FETCH_SYM GROUP_SYM NEXT_SYM ROW_SYM
{
if (unlikely(Lex->sp_add_agg_cfetch()))
MYSQL_YYABORT;
}
;
;
sp_proc_stmt_close:
sp_proc_stmt_close:
...
@@ -18008,11 +18053,6 @@ sf_tail:
...
@@ -18008,11 +18053,6 @@ sf_tail:
{
{
if (unlikely(Lex->sp_body_finalize_function(thd)))
if (unlikely(Lex->sp_body_finalize_function(thd)))
MYSQL_YYABORT;
MYSQL_YYABORT;
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);
}
}
;
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment