From 4e6484db137ecaec44cfc5bd8e59ee91bdff6511 Mon Sep 17 00:00:00 2001 From: "Daniel R. Fiala" Date: Mon, 13 Jun 2022 13:06:37 +0200 Subject: [PATCH 1/2] Fixed(PS-7745) - (Stored procedure execution fails if contains a functional index) https://jira.percona.com/browse/PS-7745 **Problem:** A Stored Procedure execution fails after some executions when a functional index is present in the SP definition. The error behaves differently depending on the versions I tested: 8.0.23 (PS, Community): It only fails when using a temporary table. After the third execution, all the subsequent executions fail. 8.0.25 (Community): It also fails on normal tables. How to Repeat ``` DROP PROCEDURE IF EXISTS `sproc`; DELIMITER $$ CREATE PROCEDURE `sproc`() BEGIN DROP TEMPORARY TABLE IF EXISTS `T1`; CREATE TEMPORARY TABLE `T1`( `C1` INT, KEY ( ( `C1` > 0 ) ) ); SELECT 1 FROM ( SELECT 1 `C2` ) `T2`; END$$ DELIMITER ; Now if you invoke that procedure 3 times in a row: mysql> CALL `sproc`(); CALL `sproc`(); CALL `sproc`(); +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) ERROR 3107 (HY000): Generated column can refer only to generated columns defined prior to it. On 8.0.25 (Community) The error is ERROR 3754 (HY000): Functional index 'functional_index' cannot refer to an auto-increment column. ``` **Cause:** The issue happens when checks are performed again during a query in the function `pre_validate_value_generator_expr()` and column index of the functional index is not available. **Solution:** This solution disables some checks if a column index is not available in the function `pre_validate_value_generator_expr()` during the second and later queries. It is safe because these checks are done in the function `validate_value_generator_expr()` during the first query. The column index is available there. --- mysql-test/suite/rocksdb/r/issue7745.result | 20 ++++++++++++++++++++ mysql-test/suite/rocksdb/t/issue7745.test | 18 ++++++++++++++++++ sql/item.cc | 3 +-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/rocksdb/r/issue7745.result create mode 100644 mysql-test/suite/rocksdb/t/issue7745.test diff --git a/mysql-test/suite/rocksdb/r/issue7745.result b/mysql-test/suite/rocksdb/r/issue7745.result new file mode 100644 index 000000000000..78548ea9e6f6 --- /dev/null +++ b/mysql-test/suite/rocksdb/r/issue7745.result @@ -0,0 +1,20 @@ +CREATE PROCEDURE `sproc`() +BEGIN +DROP TEMPORARY TABLE IF EXISTS `t1`; +CREATE TEMPORARY TABLE `t1`( +`c1` INT, +KEY ( ( `c1` > 0 ) ) +); +SELECT 1 FROM ( SELECT 1 `c2` ) `t2`; +END| +CALL `sproc`(); +1 +1 +CALL `sproc`(); +1 +1 +CALL `sproc`(); +1 +1 +DROP PROCEDURE `sproc`; +DROP TEMPORARY TABLE `t1`; diff --git a/mysql-test/suite/rocksdb/t/issue7745.test b/mysql-test/suite/rocksdb/t/issue7745.test new file mode 100644 index 000000000000..8c9b061b3b86 --- /dev/null +++ b/mysql-test/suite/rocksdb/t/issue7745.test @@ -0,0 +1,18 @@ +--source include/have_rocksdb.inc + +DELIMITER |; +CREATE PROCEDURE `sproc`() +BEGIN + DROP TEMPORARY TABLE IF EXISTS `t1`; + CREATE TEMPORARY TABLE `t1`( + `c1` INT, + KEY ( ( `c1` > 0 ) ) + ); + SELECT 1 FROM ( SELECT 1 `c2` ) `t2`; +END| +DELIMITER ;| + +CALL `sproc`(); CALL `sproc`(); CALL `sproc`(); + +DROP PROCEDURE `sproc`; +DROP TEMPORARY TABLE `t1`; diff --git a/sql/item.cc b/sql/item.cc index a5e8a901e2a7..efbadb84f871 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1037,7 +1037,6 @@ bool Item_field::check_function_as_value_generator(uchar *checker_args) { } int fld_idx = func_args->col_index; - assert(fld_idx > -1); /* Don't allow the GC (or default expression) to refer itself or another GC @@ -1046,7 +1045,7 @@ bool Item_field::check_function_as_value_generator(uchar *checker_args) { if ((func_args->source != VGS_CHECK_CONSTRAINT) && (field->is_gcol() || field->has_insert_default_general_value_expression()) && - field->field_index() >= fld_idx) { + (fld_idx >= 0 && field->field_index() >= fld_idx)) { func_args->err_code = (func_args->source == VGS_GENERATED_COLUMN) ? ER_GENERATED_COLUMN_NON_PRIOR : ER_DEFAULT_VAL_GENERATED_NON_PRIOR; From 9c095048ab002628325b56f9cc186f8b27ab2a2b Mon Sep 17 00:00:00 2001 From: "Daniel R. Fiala" Date: Wed, 22 Mar 2023 23:43:01 +0100 Subject: [PATCH 2/2] fixup! Fixed(PS-7745) - (Stored procedure execution fails if contains a functional index) --- mysql-test/{suite/rocksdb => }/r/issue7745.result | 0 mysql-test/{suite/rocksdb => }/t/issue7745.test | 2 -- 2 files changed, 2 deletions(-) rename mysql-test/{suite/rocksdb => }/r/issue7745.result (100%) rename mysql-test/{suite/rocksdb => }/t/issue7745.test (89%) diff --git a/mysql-test/suite/rocksdb/r/issue7745.result b/mysql-test/r/issue7745.result similarity index 100% rename from mysql-test/suite/rocksdb/r/issue7745.result rename to mysql-test/r/issue7745.result diff --git a/mysql-test/suite/rocksdb/t/issue7745.test b/mysql-test/t/issue7745.test similarity index 89% rename from mysql-test/suite/rocksdb/t/issue7745.test rename to mysql-test/t/issue7745.test index 8c9b061b3b86..f66d9090e463 100644 --- a/mysql-test/suite/rocksdb/t/issue7745.test +++ b/mysql-test/t/issue7745.test @@ -1,5 +1,3 @@ ---source include/have_rocksdb.inc - DELIMITER |; CREATE PROCEDURE `sproc`() BEGIN