summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Gupta <varun.gupta@mariadb.com>2020-05-14 18:38:49 +0530
committerVarun Gupta <varun.gupta@mariadb.com>2020-05-15 15:13:06 +0530
commitd49233caf696ba5896ff9119ca1a07039368ab23 (patch)
treeedd6eb2c15f39f5436f7ad00580879d41ea7d1c9
parent1408e26d0b15ea95d3d017bb059cd65b53b00a86 (diff)
downloadmariadb-git-d49233caf696ba5896ff9119ca1a07039368ab23.tar.gz
MDEV-18100: User defined aggregate functions not working correctly when the schema is changed
The issue here was that when the schema was changed the value for the THD::server_status is ored with SERVER_SESSION_STATE_CHANGED. For custom aggregate functions, currently we check if the server_status is equal to SERVER_STATUS_LAST_ROW_SENT then we should terminate the execution of the custom aggregate function as there are no more rows to fetch. So the check should be that if the server status has the bit set for SERVER_STATUS_LAST_ROW_SENT then we should terminate the execution of the custom aggregate function.
-rw-r--r--mysql-test/main/custom_aggregate_functions.result33
-rw-r--r--mysql-test/main/custom_aggregate_functions.test33
-rw-r--r--sql/item_sum.cc8
-rw-r--r--sql/sp_head.cc2
4 files changed, 72 insertions, 4 deletions
diff --git a/mysql-test/main/custom_aggregate_functions.result b/mysql-test/main/custom_aggregate_functions.result
index 0a27334f58e..8ad7b4b4dc0 100644
--- a/mysql-test/main/custom_aggregate_functions.result
+++ b/mysql-test/main/custom_aggregate_functions.result
@@ -1153,3 +1153,36 @@ i sum(i)
NULL 8
drop function agg_sum;
drop table t1;
+#
+# User defined aggregate functions not working correctly when the schema is changed
+#
+CREATE SCHEMA IF NOT EXISTS common_schema;
+CREATE SCHEMA IF NOT EXISTS another_schema;
+DROP FUNCTION IF EXISTS common_schema.add_ints |
+Warnings:
+Note 1305 FUNCTION common_schema.add_ints does not exist
+CREATE FUNCTION common_schema.add_ints(int_1 INT, int_2 INT) RETURNS INT NO SQL
+BEGIN
+RETURN int_1 + int_2;
+END |
+DROP FUNCTION IF EXISTS common_schema.sum_ints |
+Warnings:
+Note 1305 FUNCTION common_schema.sum_ints does not exist
+CREATE AGGREGATE FUNCTION common_schema.sum_ints(int_val INT) RETURNS INT
+BEGIN
+DECLARE result INT DEFAULT 0;
+DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN result;
+LOOP FETCH GROUP NEXT ROW;
+SET result = common_schema.add_ints(result, int_val);
+END LOOP;
+END |
+use common_schema;
+SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t;
+common_schema.sum_ints(seq)
+3
+USE another_schema;
+SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t;
+common_schema.sum_ints(seq)
+3
+drop database common_schema;
+drop database another_schema;
diff --git a/mysql-test/main/custom_aggregate_functions.test b/mysql-test/main/custom_aggregate_functions.test
index ab799b48bdb..4d9dd0a4929 100644
--- a/mysql-test/main/custom_aggregate_functions.test
+++ b/mysql-test/main/custom_aggregate_functions.test
@@ -965,3 +965,36 @@ select i, sum(i) from t1 group by i with rollup;
# Cleanup
drop function agg_sum;
drop table t1;
+
+--echo #
+--echo # User defined aggregate functions not working correctly when the schema is changed
+--echo #
+
+CREATE SCHEMA IF NOT EXISTS common_schema;
+CREATE SCHEMA IF NOT EXISTS another_schema;
+DELIMITER |;
+DROP FUNCTION IF EXISTS common_schema.add_ints |
+CREATE FUNCTION common_schema.add_ints(int_1 INT, int_2 INT) RETURNS INT NO SQL
+BEGIN
+ RETURN int_1 + int_2;
+END |
+DROP FUNCTION IF EXISTS common_schema.sum_ints |
+CREATE AGGREGATE FUNCTION common_schema.sum_ints(int_val INT) RETURNS INT
+BEGIN
+ DECLARE result INT DEFAULT 0;
+ DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN result;
+ LOOP FETCH GROUP NEXT ROW;
+ SET result = common_schema.add_ints(result, int_val);
+ END LOOP;
+END |
+
+DELIMITER ;|
+
+use common_schema;
+SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t;
+
+USE another_schema;
+SELECT common_schema.sum_ints(seq) FROM (SELECT 1 seq UNION ALL SELECT 2) t;
+
+drop database common_schema;
+drop database another_schema;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 91b75b776e2..d843e87fa03 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1384,10 +1384,12 @@ Item_sum_sp::execute()
bool res;
uint old_server_status= thd->server_status;
- /* We set server status so we can send a signal to exit from the
- function with the return value. */
+ /*
+ We set server status so we can send a signal to exit from the
+ function with the return value.
+ */
- thd->server_status= SERVER_STATUS_LAST_ROW_SENT;
+ thd->server_status|= SERVER_STATUS_LAST_ROW_SENT;
res= Item_sp::execute(thd, &null_value, args, arg_count);
thd->server_status= old_server_status;
return res;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index ba130881d68..f36650bafe9 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -4431,7 +4431,7 @@ sp_instr_agg_cfetch::execute(THD *thd, uint *nextp)
else
{
thd->spcont->pause_state= FALSE;
- if (thd->server_status == SERVER_STATUS_LAST_ROW_SENT)
+ if (thd->server_status & SERVER_STATUS_LAST_ROW_SENT)
{
my_message(ER_SP_FETCH_NO_DATA,
ER_THD(thd, ER_SP_FETCH_NO_DATA), MYF(0));