Skip to content

Commit

Permalink
Bug#27452082 ASSERTION FAILED: !TABLE->IN_USE->IS_ERROR() IN UPDATE_G…
Browse files Browse the repository at this point in the history
…ENERATED_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
percona#1 Item_func::raise_numeric_overflow
...
percona#7 Item_cond_and::val_int
percona#8 innobase_index_cond
...
percona#12 handler::index_read_map
...
percona#15 handler::multi_range_read_next
...
percona#20 rr_quick
percona#21 join_init_read_record
As val_int() has no "error" return code, the execution continues until
frame percona#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.
  • Loading branch information
Guilhem Bichot committed Mar 27, 2018
1 parent 97cf6dd commit 3b38a02
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
12 changes: 12 additions & 0 deletions mysql-test/suite/gcol/r/gcol_bugfixes.result
Original file line number Diff line number Diff line change
Expand Up @@ -868,3 +868,15 @@ LOAD DATA INFILE '../../std_data/loaddata5.dat'
INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (c1) ;
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'
DROP TABLE t1;
#
# Bug#27452082 ASSERTION FAILED: !TABLE->IN_USE->IS_ERROR() IN UPDATE_GENERATED_READ_FIELDS
#
CREATE TABLE t (
a INT,
b INT GENERATED ALWAYS AS (MAKETIME(1,1,1)) STORED,
KEY (a)
);
INSERT INTO t (a) VALUES (32767),(-1);
SELECT * FROM t WHERE a>-19106 AND a-0x4d;
ERROR 22003: BIGINT UNSIGNED value is out of range in '(`test`.`t`.`a` - 0x4d)'
DROP TABLE t;
14 changes: 14 additions & 0 deletions mysql-test/suite/gcol/t/gcol_bugfixes.test
Original file line number Diff line number Diff line change
Expand Up @@ -848,3 +848,17 @@ LOAD DATA INFILE '../../std_data/loaddata5.dat'
INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (c1) ;

DROP TABLE t1;

--echo #
--echo # Bug#27452082 ASSERTION FAILED: !TABLE->IN_USE->IS_ERROR() IN UPDATE_GENERATED_READ_FIELDS
--echo #

CREATE TABLE t (
a INT,
b INT GENERATED ALWAYS AS (MAKETIME(1,1,1)) STORED,
KEY (a)
);
INSERT INTO t (a) VALUES (32767),(-1);
--error ER_DATA_OUT_OF_RANGE
SELECT * FROM t WHERE a>-19106 AND a-0x4d;
DROP TABLE t;
5 changes: 3 additions & 2 deletions sql/table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6738,7 +6738,7 @@ void repoint_field_to_record(TABLE *table, uchar *old_rec, uchar *new_rec) {
bool update_generated_read_fields(uchar *buf, TABLE *table, uint active_index) {
DBUG_ENTER("update_generated_read_fields");
DBUG_ASSERT(table && table->vfield);
DBUG_ASSERT(!table->in_use->is_error());
if (table->in_use->is_error()) DBUG_RETURN(true);
if (active_index != MAX_KEY && table->key_read) {
/*
The covering index is providing all necessary columns, including
Expand Down Expand Up @@ -6833,7 +6833,8 @@ bool update_generated_write_fields(const MY_BITMAP *bitmap, TABLE *table) {
int error = 0;

DBUG_ASSERT(table->vfield);
DBUG_ASSERT(!table->in_use->is_error());
if (table->in_use->is_error()) DBUG_RETURN(true);

/* Iterate over generated fields in the table */
for (vfield_ptr = table->vfield; *vfield_ptr; vfield_ptr++) {
Field *vfield;
Expand Down

0 comments on commit 3b38a02

Please sign in to comment.