Skip to content

Commit

Permalink
MDEV-11598 Assertion `!table || (!table->read_set || bitmap_is_set(ta…
Browse files Browse the repository at this point in the history
…ble->read_set, field_index))' failed

Found and fixed 2 problems:

- Filesort addon fields didn't mark virtual columns properly
- multi-range-read calculated vcol bitmap but was not using it.
  This caused wrong vcol field to be calculated on read, which caused the assert.
  • Loading branch information
montywi committed Jan 11, 2017
1 parent de22cd3 commit 135e144
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 43 deletions.
51 changes: 51 additions & 0 deletions mysql-test/suite/vcol/inc/vcol_keys.inc
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,54 @@ create table t1 (a int, b double as (rand()));
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
alter table t1 add index (b);
drop table t1;

#
# MDEV-11598 Assertion `!table || (!table->read_set... failed
#

CREATE OR REPLACE TABLE t1 (
f2 DOUBLE NOT NULL DEFAULT '0',
f3 DOUBLE NOT NULL DEFAULT '0',
f4 DOUBLE,
f5 DOUBLE DEFAULT '0',
v4 DOUBLE AS (IF(f4,f3,f2)) VIRTUAL,
KEY (f5),
KEY (v4)
);

INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,4,1,0),(5,7,NULL,0);
INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f3, f5, f3 FROM t1;
INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,0,NULL,1);
INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f5, f5, f3 FROM t1;
DELETE FROM t1 WHERE f5 = 1 OR v4 = 4 ORDER BY f5,v4 LIMIT 9;
SELECT * from t1;
DROP TABLE t1;

# Another similar failure

CREATE TABLE t1 (
d DECIMAL(63,0) NOT NULL DEFAULT 0,
c VARCHAR(64) NOT NULL DEFAULT '',
vd DECIMAL(63,0) AS (d) VIRTUAL,
vc VARCHAR(2048) AS (c) VIRTUAL,
pk BIGINT AUTO_INCREMENT,
PRIMARY KEY(pk));

INSERT INTO t1 (d,c) VALUES (0.5,'foo');
SELECT * FROM t1 WHERE vc != 'bar' ORDER BY vd;
DROP TABLE t1;

#
# MDEV-11729: Crash when using partial indexed virtual fields
#

CREATE TABLE t1 (
pk BIGINT,
c CHAR(64) NOT NULL DEFAULT '',
vc CHAR(64) AS (c) VIRTUAL,
PRIMARY KEY(pk),
INDEX(vc(32))
);
DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
DROP TABLE t1;

47 changes: 47 additions & 0 deletions mysql-test/suite/vcol/r/vcol_keys_innodb.result
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,50 @@ create table t1 (a int, b double as (rand()));
alter table t1 add index (b);
ERROR HY000: Function or expression 'rand()' cannot be used in the GENERATED ALWAYS AS clause of `b`
drop table t1;
CREATE OR REPLACE TABLE t1 (
f2 DOUBLE NOT NULL DEFAULT '0',
f3 DOUBLE NOT NULL DEFAULT '0',
f4 DOUBLE,
f5 DOUBLE DEFAULT '0',
v4 DOUBLE AS (IF(f4,f3,f2)) VIRTUAL,
KEY (f5),
KEY (v4)
);
INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,4,1,0),(5,7,NULL,0);
INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f3, f5, f3 FROM t1;
INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,0,NULL,1);
INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f5, f5, f3 FROM t1;
DELETE FROM t1 WHERE f5 = 1 OR v4 = 4 ORDER BY f5,v4 LIMIT 9;
SELECT * from t1;
f2 f3 f4 f5 v4
5 7 NULL 0 5
5 4 0 4 5
5 7 0 7 5
5 0 0 4 5
5 0 0 7 5
5 7 7 7 7
5 1 1 0 1
DROP TABLE t1;
CREATE TABLE t1 (
d DECIMAL(63,0) NOT NULL DEFAULT 0,
c VARCHAR(64) NOT NULL DEFAULT '',
vd DECIMAL(63,0) AS (d) VIRTUAL,
vc VARCHAR(2048) AS (c) VIRTUAL,
pk BIGINT AUTO_INCREMENT,
PRIMARY KEY(pk));
INSERT INTO t1 (d,c) VALUES (0.5,'foo');
Warnings:
Note 1265 Data truncated for column 'd' at row 1
SELECT * FROM t1 WHERE vc != 'bar' ORDER BY vd;
d c vd vc pk
1 foo 1 foo 1
DROP TABLE t1;
CREATE TABLE t1 (
pk BIGINT,
c CHAR(64) NOT NULL DEFAULT '',
vc CHAR(64) AS (c) VIRTUAL,
PRIMARY KEY(pk),
INDEX(vc(32))
);
DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
DROP TABLE t1;
47 changes: 47 additions & 0 deletions mysql-test/suite/vcol/r/vcol_keys_myisam.result
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,50 @@ create table t1 (a int, b double as (rand()));
alter table t1 add index (b);
ERROR HY000: Function or expression 'rand()' cannot be used in the GENERATED ALWAYS AS clause of `b`
drop table t1;
CREATE OR REPLACE TABLE t1 (
f2 DOUBLE NOT NULL DEFAULT '0',
f3 DOUBLE NOT NULL DEFAULT '0',
f4 DOUBLE,
f5 DOUBLE DEFAULT '0',
v4 DOUBLE AS (IF(f4,f3,f2)) VIRTUAL,
KEY (f5),
KEY (v4)
);
INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,4,1,0),(5,7,NULL,0);
INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f3, f5, f3 FROM t1;
INSERT INTO t1 (f2,f3,f4,f5) VALUES (5,0,NULL,1);
INSERT INTO t1 (f2,f3,f4,f5) SELECT f2, f5, f5, f3 FROM t1;
DELETE FROM t1 WHERE f5 = 1 OR v4 = 4 ORDER BY f5,v4 LIMIT 9;
SELECT * from t1;
f2 f3 f4 f5 v4
5 7 NULL 0 5
5 4 0 4 5
5 7 0 7 5
5 0 0 4 5
5 0 0 7 5
5 7 7 7 7
5 1 1 0 1
DROP TABLE t1;
CREATE TABLE t1 (
d DECIMAL(63,0) NOT NULL DEFAULT 0,
c VARCHAR(64) NOT NULL DEFAULT '',
vd DECIMAL(63,0) AS (d) VIRTUAL,
vc VARCHAR(2048) AS (c) VIRTUAL,
pk BIGINT AUTO_INCREMENT,
PRIMARY KEY(pk));
INSERT INTO t1 (d,c) VALUES (0.5,'foo');
Warnings:
Note 1265 Data truncated for column 'd' at row 1
SELECT * FROM t1 WHERE vc != 'bar' ORDER BY vd;
d c vd vc pk
1 foo 1 foo 1
DROP TABLE t1;
CREATE TABLE t1 (
pk BIGINT,
c CHAR(64) NOT NULL DEFAULT '',
vc CHAR(64) AS (c) VIRTUAL,
PRIMARY KEY(pk),
INDEX(vc(32))
);
DELETE FROM t1 WHERE vc IS NULL ORDER BY pk;
DROP TABLE t1;
11 changes: 11 additions & 0 deletions sql/field.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10864,3 +10864,14 @@ bool Field::save_in_field_ignore_value(bool view_error_processing)
return save_in_field_default_value(view_error_processing);
return 0; // ignore
}


void Field::register_field_in_read_map()
{
if (vcol_info)
{
Item *vcol_item= vcol_info->expr;
vcol_item->walk(&Item::register_field_in_read_map, 1, 0);
}
bitmap_set_bit(table->read_set, field_index);
}
3 changes: 3 additions & 0 deletions sql/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,9 @@ class Field: public Value_source
bool save_in_field_default_value(bool view_eror_processing);
bool save_in_field_ignore_value(bool view_error_processing);

/* Mark field in read map. Updates also virtual fields */
void register_field_in_read_map();

friend int cre_myisam(char * name, register TABLE *form, uint options,
ulonglong auto_increment_value);
friend class Copy_field;
Expand Down
32 changes: 12 additions & 20 deletions sql/filesort.cc
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
TABLE *sort_form;
handler *file;
MY_BITMAP *save_read_set, *save_write_set, *save_vcol_set;

Item *sort_cond;
DBUG_ENTER("find_all_keys");
DBUG_PRINT("info",("using: %s",
(select ? select->quick ? "ranges" : "where":
Expand Down Expand Up @@ -754,22 +754,22 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
/* Remember original bitmaps */
save_read_set= sort_form->read_set;
save_write_set= sort_form->write_set;
save_vcol_set= sort_form->vcol_set;
save_vcol_set= sort_form->vcol_set;

/* Set up temporary column read map for columns used by sort */
bitmap_clear_all(&sort_form->tmp_set);
/* Temporary set for register_used_fields and register_field_in_read_map */
sort_form->read_set= &sort_form->tmp_set;
sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set,
&sort_form->tmp_set);
register_used_fields(param);
if (quick_select)
select->quick->add_used_key_part_to_set(sort_form->read_set);
select->quick->add_used_key_part_to_set();

Item *sort_cond= !select ?
0 : !select->pre_idx_push_select_cond ?
select->cond : select->pre_idx_push_select_cond;
sort_cond= (!select ? 0 :
(!select->pre_idx_push_select_cond ?
select->cond : select->pre_idx_push_select_cond));
if (sort_cond)
sort_cond->walk(&Item::register_field_in_read_map, 1, sort_form);
sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set,
&sort_form->tmp_set);
sort_form->file->column_bitmaps_signal();

if (quick_select)
{
Expand Down Expand Up @@ -1259,7 +1259,6 @@ static void register_used_fields(Sort_param *param)
{
reg1 SORT_FIELD *sort_field;
TABLE *table=param->sort_form;
MY_BITMAP *bitmap= table->read_set;

for (sort_field= param->local_sortorder ;
sort_field != param->end ;
Expand All @@ -1269,14 +1268,7 @@ static void register_used_fields(Sort_param *param)
if ((field= sort_field->field))
{
if (field->table == table)
{
if (field->vcol_info)
{
Item *vcol_item= field->vcol_info->expr;
vcol_item->walk(&Item::register_field_in_read_map, 1, 0);
}
bitmap_set_bit(bitmap, field->field_index);
}
field->register_field_in_read_map();
}
else
{ // Item
Expand All @@ -1289,7 +1281,7 @@ static void register_used_fields(Sort_param *param)
SORT_ADDON_FIELD *addonf= param->addon_field;
Field *field;
for ( ; (field= addonf->field) ; addonf++)
bitmap_set_bit(bitmap, field->field_index);
field->register_field_in_read_map();
}
else
{
Expand Down
Loading

0 comments on commit 135e144

Please sign in to comment.