mirror of
https://github.com/MariaDB/server.git
synced 2025-07-05 12:42:17 +03:00
This commit implements aggregate stored functions. The basic idea behind the feature is: * Implement a special instruction FETCH GROUP NEXT ROW that will pause the execution of the stored function. When the instruction is reached, execution of the initial query resumes "as if" the function returned. This gives the server the opportunity to advance to the next row in the result set. * Stored aggregates behave like regular aggregate functions. The implementation of thus resides in the class Item_sum_sp. Because it is an aggregate function, for each new row in the group, the Item_sum_sp::add() method will be called. This is when execution resumes and the function does another iteration to "add" one extra element to the final result. * When the end of group is reached, val_xxx() method will be called for the item. This case is handled by another execute step for the stored function, only with a special flag to force a call to the return handler. See Item_sum_sp::execute() for details. To allow this pause and resume semantic, we must preserve the function context across executions. This is stored in Item_sp::sp_query_arena only for aggregate stored functions, but has no impact for regular functions. We also enforce aggregate functions to include the "FETCH GROUP NEXT ROW" instruction. Signed-off-by: Vicențiu Ciorbaru <vicentiu@mariadb.org>
55 lines
2.1 KiB
Plaintext
55 lines
2.1 KiB
Plaintext
SET timestamp=UNIX_TIMESTAMP('2014-09-30 08:00:00');
|
|
CREATE FUNCTION f1(str char(20))
|
|
RETURNS CHAR(100)
|
|
RETURN CONCAT('Hello, ', str, '!');
|
|
SELECT * FROM mysql.proc WHERE name like 'f1';
|
|
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate
|
|
test f1 FUNCTION f1 SQL CONTAINS_SQL NO DEFINER str char(20) char(100) CHARSET latin1 RETURN CONCAT('Hello, ', str, '!') root@localhost 2014-09-30 08:00:00 2014-09-30 08:00:00 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci RETURN CONCAT('Hello, ', str, '!') NONE
|
|
SELECT f1('world');
|
|
f1('world')
|
|
Hello, world!
|
|
CREATE FUNCTION f1(str char(20))
|
|
RETURNS TEXT
|
|
RETURN CONCAT('Hello2, ', str, '!');
|
|
ERROR 42000: FUNCTION f1 already exists
|
|
SELECT body FROM mysql.proc WHERE name like 'f1';
|
|
body
|
|
RETURN CONCAT('Hello, ', str, '!')
|
|
CREATE FUNCTION IF NOT EXISTS f1(str char(20))
|
|
RETURNS CHAR(100)
|
|
RETURN CONCAT('Hello3, ', str, '!');
|
|
Warnings:
|
|
Note 1304 FUNCTION f1 already exists
|
|
SELECT body FROM mysql.proc WHERE name like 'f1';
|
|
body
|
|
RETURN CONCAT('Hello, ', str, '!')
|
|
CREATE OR REPLACE FUNCTION IF NOT EXISTS f1(str char(20))
|
|
RETURNS CHAR(100)
|
|
RETURN CONCAT('Hello4, ', str, '!');
|
|
ERROR HY000: Incorrect usage of OR REPLACE and IF NOT EXISTS
|
|
SELECT body FROM mysql.proc WHERE name like 'f1';
|
|
body
|
|
RETURN CONCAT('Hello, ', str, '!')
|
|
CREATE OR REPLACE FUNCTION f1(str char(20))
|
|
RETURNS CHAR(100)
|
|
RETURN CONCAT('Hello5, ', str, '!');
|
|
SELECT body FROM mysql.proc WHERE name like 'f1';
|
|
body
|
|
RETURN CONCAT('Hello5, ', str, '!')
|
|
DROP FUNCTION f1;
|
|
CREATE FUNCTION IF NOT EXISTS f1(str char(20))
|
|
RETURNS CHAR(100)
|
|
RETURN CONCAT('Hello6, ', str, '!');
|
|
SELECT body FROM mysql.proc WHERE name like 'f1';
|
|
body
|
|
RETURN CONCAT('Hello6, ', str, '!')
|
|
SELECT f1('world');
|
|
f1('world')
|
|
Hello6, world!
|
|
DROP FUNCTION IF EXISTS f1;
|
|
SELECT body FROM mysql.proc WHERE name like 'f1';
|
|
body
|
|
DROP FUNCTION IF EXISTS f1;
|
|
Warnings:
|
|
Note 1305 FUNCTION test.f1 does not exist
|