Skip to content

Commit 3b38a02

Browse files
author
Guilhem Bichot
committed
Bug#27452082 ASSERTION FAILED: !TABLE->IN_USE->IS_ERROR() IN UPDATE_GENERATED_READ_FIELDS
It's a SELECT with WHERE "(-1) minus 0x4d". this operation has a result type of "unsigned" (because 0x4d is unsigned integer) and the result (-78) doesn't fit int an unsigned type. This WHERE is evaluated by InnoDB in index condition pushdown: #0 my_error #1 Item_func::raise_numeric_overflow ... #7 Item_cond_and::val_int #8 innobase_index_cond ... #12 handler::index_read_map ... #15 handler::multi_range_read_next ... #20 rr_quick #21 join_init_read_record As val_int() has no "error" return code, the execution continues until frame #12; there we call update_generated_read_fields(), which has an assertion about thd->is_error() which fails. Fix: it would be nice to detect error as soon as it happens, i.e. in innodb code right after it calls val_bool(). But innodb's index condition pushdown functions only have found / not found return codes so they cannot signal "error" to the upper layers. Same is true for MyISAM. Moreover, "thd" isn't easily accessible there. Adding a detection a bit above in the stack (handler::* functions which do index reads) is also possible but would require fixing ~20 functions. The chosen fix here is to change update_generated_*_fields() to return error if thd->is_error() is true. Note that the removed assertion was already one cause of bug 27041382.
1 parent 97cf6dd commit 3b38a02

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

mysql-test/suite/gcol/r/gcol_bugfixes.result

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,3 +868,15 @@ LOAD DATA INFILE '../../std_data/loaddata5.dat'
868868
INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (c1) ;
869869
ERROR 42000: Trigger 'trg1' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't1 VALUES (1)' at line 1'
870870
DROP TABLE t1;
871+
#
872+
# Bug#27452082 ASSERTION FAILED: !TABLE->IN_USE->IS_ERROR() IN UPDATE_GENERATED_READ_FIELDS
873+
#
874+
CREATE TABLE t (
875+
a INT,
876+
b INT GENERATED ALWAYS AS (MAKETIME(1,1,1)) STORED,
877+
KEY (a)
878+
);
879+
INSERT INTO t (a) VALUES (32767),(-1);
880+
SELECT * FROM t WHERE a>-19106 AND a-0x4d;
881+
ERROR 22003: BIGINT UNSIGNED value is out of range in '(`test`.`t`.`a` - 0x4d)'
882+
DROP TABLE t;

mysql-test/suite/gcol/t/gcol_bugfixes.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,3 +848,17 @@ LOAD DATA INFILE '../../std_data/loaddata5.dat'
848848
INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (c1) ;
849849

850850
DROP TABLE t1;
851+
852+
--echo #
853+
--echo # Bug#27452082 ASSERTION FAILED: !TABLE->IN_USE->IS_ERROR() IN UPDATE_GENERATED_READ_FIELDS
854+
--echo #
855+
856+
CREATE TABLE t (
857+
a INT,
858+
b INT GENERATED ALWAYS AS (MAKETIME(1,1,1)) STORED,
859+
KEY (a)
860+
);
861+
INSERT INTO t (a) VALUES (32767),(-1);
862+
--error ER_DATA_OUT_OF_RANGE
863+
SELECT * FROM t WHERE a>-19106 AND a-0x4d;
864+
DROP TABLE t;

sql/table.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6738,7 +6738,7 @@ void repoint_field_to_record(TABLE *table, uchar *old_rec, uchar *new_rec) {
67386738
bool update_generated_read_fields(uchar *buf, TABLE *table, uint active_index) {
67396739
DBUG_ENTER("update_generated_read_fields");
67406740
DBUG_ASSERT(table && table->vfield);
6741-
DBUG_ASSERT(!table->in_use->is_error());
6741+
if (table->in_use->is_error()) DBUG_RETURN(true);
67426742
if (active_index != MAX_KEY && table->key_read) {
67436743
/*
67446744
The covering index is providing all necessary columns, including
@@ -6833,7 +6833,8 @@ bool update_generated_write_fields(const MY_BITMAP *bitmap, TABLE *table) {
68336833
int error = 0;
68346834

68356835
DBUG_ASSERT(table->vfield);
6836-
DBUG_ASSERT(!table->in_use->is_error());
6836+
if (table->in_use->is_error()) DBUG_RETURN(true);
6837+
68376838
/* Iterate over generated fields in the table */
68386839
for (vfield_ptr = table->vfield; *vfield_ptr; vfield_ptr++) {
68396840
Field *vfield;

0 commit comments

Comments
 (0)