Skip to content

Commit

Permalink
MDEV-16217: Assertion `!table || (!table->read_set || bitmap_is_set(t…
Browse files Browse the repository at this point in the history
…able->read_set, field_index))' failed in Field_num::get_date

- clean up DEFAULT() to work only with default value and correctly print
  itself.
- fix of DBUG_ASSERT about fields read/write
- fix of field marking for write based really on the thd->mark_used_columns flag
  • Loading branch information
sanja-byelkin committed Nov 14, 2018
1 parent c688ab2 commit 01d3e40
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 5 deletions.
10 changes: 9 additions & 1 deletion mysql-test/r/func_default.result
Expand Up @@ -8,13 +8,21 @@ explain extended select default(str), default(strnull), default(intg), default(r
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select default('') AS `default(str)`,default('') AS `default(strnull)`,default(0) AS `default(intg)`,default(0) AS `default(rel)` from dual
Note 1003 select default(`test`.`t1`.`str`) AS `default(str)`,default(`test`.`t1`.`strnull`) AS `default(strnull)`,default(`test`.`t1`.`intg`) AS `default(intg)`,default(`test`.`t1`.`rel`) AS `default(rel)` from dual
select * from t1 where str <> default(str);
str strnull intg rel
0 0
explain select * from t1 where str <> default(str);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
create view v1 as select default(str), default(strnull), default(intg), default(rel) from t1;
select * from v1;
default(str) default(strnull) default(intg) default(rel)
def NULL 10 3.14
show create view v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select default(`t1`.`str`) AS `default(str)`,default(`t1`.`strnull`) AS `default(strnull)`,default(`t1`.`intg`) AS `default(intg)`,default(`t1`.`rel`) AS `default(rel)` from `t1` latin1 latin1_swedish_ci
drop view v1;
drop table t1;
CREATE TABLE t1 (id int(11), s varchar(20));
INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');
Expand Down
57 changes: 57 additions & 0 deletions mysql-test/r/func_time.result
Expand Up @@ -3423,3 +3423,60 @@ DROP TABLE t1,t2;
#
# End of 10.1 tests
#
#
# MDEV-16217: Assertion `!table || (!table->read_set ||
# bitmap_is_set(table->read_set, field_index))'
# failed in Field_num::get_date
#
CREATE TABLE t1 (pk int default 0, a1 date);
INSERT INTO t1 VALUES (1,'1900-01-01'),(2,NULL),(3,NULL),(4,NULL);
CREATE VIEW v1 AS
SELECT t1.pk AS pk, t1.a1 AS a1 FROM t1;
SELECT a1 BETWEEN (('2018-08-24')) AND (DEFAULT(pk)) FROM v1;
a1 BETWEEN (('2018-08-24')) AND (DEFAULT(pk))
0
NULL
NULL
NULL
SELECT a1 BETWEEN (('2018-08-24')) AND (~ DEFAULT(pk)) FROM v1;
a1 BETWEEN (('2018-08-24')) AND (~ DEFAULT(pk))
0
NULL
NULL
NULL
Warnings:
Warning 1292 Incorrect datetime value: '18446744073709551615'
CREATE TABLE t2 (pk int default 1, a1 date);
INSERT INTO t2 VALUES (4,NULL);
CREATE view v2 as SELECT default(t1.pk), default(t2.pk), t1.pk from t1,t2;
select * from v2;
default(t1.pk) default(t2.pk) pk
0 1 1
0 1 2
0 1 3
0 1 4
show create view v2;
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select default(`t1`.`pk`) AS `default(t1.pk)`,default(`t2`.`pk`) AS `default(t2.pk)`,`t1`.`pk` AS `pk` from (`t1` join `t2`) latin1 latin1_swedish_ci
CREATE view v3 as SELECT default(pk) from t2;
select * from v3;
default(pk)
1
explain extended select * from v3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select default(`test`.`t2`.`pk`) AS `default(pk)` from dual
explain extended select default(pk) from t2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
Warnings:
Note 1003 select default(`test`.`t2`.`pk`) AS `default(pk)` from dual
show create view v3;
View Create View character_set_client collation_connection
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select default(`t2`.`pk`) AS `default(pk)` from `t2` latin1 latin1_swedish_ci
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
#
# End of 10.2 tests
#
5 changes: 5 additions & 0 deletions mysql-test/t/func_default.test
Expand Up @@ -11,6 +11,11 @@ explain extended select default(str), default(strnull), default(intg), default(r
select * from t1 where str <> default(str);
explain select * from t1 where str <> default(str);

create view v1 as select default(str), default(strnull), default(intg), default(rel) from t1;
select * from v1;
show create view v1;
drop view v1;

#TODO: uncomment when bug will be fixed
#create table t2 select default(str), default(strnull), default(intg), default(rel) from t1;
#show create table from t1;
Expand Down
32 changes: 32 additions & 0 deletions mysql-test/t/func_time.test
Expand Up @@ -1910,3 +1910,35 @@ DROP TABLE t1,t2;
--echo #
--echo # End of 10.1 tests
--echo #

--echo #
--echo # MDEV-16217: Assertion `!table || (!table->read_set ||
--echo # bitmap_is_set(table->read_set, field_index))'
--echo # failed in Field_num::get_date
--echo #
CREATE TABLE t1 (pk int default 0, a1 date);
INSERT INTO t1 VALUES (1,'1900-01-01'),(2,NULL),(3,NULL),(4,NULL);

CREATE VIEW v1 AS
SELECT t1.pk AS pk, t1.a1 AS a1 FROM t1;

SELECT a1 BETWEEN (('2018-08-24')) AND (DEFAULT(pk)) FROM v1;
SELECT a1 BETWEEN (('2018-08-24')) AND (~ DEFAULT(pk)) FROM v1;

CREATE TABLE t2 (pk int default 1, a1 date);
INSERT INTO t2 VALUES (4,NULL);
CREATE view v2 as SELECT default(t1.pk), default(t2.pk), t1.pk from t1,t2;
select * from v2;
show create view v2;
CREATE view v3 as SELECT default(pk) from t2;
select * from v3;
explain extended select * from v3;
explain extended select default(pk) from t2;
show create view v3;

DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;

--echo #
--echo # End of 10.2 tests
--echo #
17 changes: 15 additions & 2 deletions sql/field.cc
Expand Up @@ -70,8 +70,21 @@ const char field_separator=',';
#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
((ulong) ((1LL << MY_MIN(arg, 4) * 8) - 1))

#define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
#define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED DBUG_ASSERT(is_stat_field || !table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || (table->vcol_set && bitmap_is_set(table->vcol_set, field_index))))
// Column marked for read or the field set to read out or record[0] or [1]
#define ASSERT_COLUMN_MARKED_FOR_READ \
DBUG_ASSERT(!table || \
(!table->read_set || \
bitmap_is_set(table->read_set, field_index) || \
(!(ptr >= table->record[0] && \
ptr < table->record[0] + table->s->reclength))))

#define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED \
DBUG_ASSERT(is_stat_field || !table || \
(!table->write_set || \
bitmap_is_set(table->write_set, field_index) || \
(!(ptr >= table->record[0] && \
ptr < table->record[0] + table->s->reclength))) || \
(table->vcol_set && bitmap_is_set(table->vcol_set, field_index)))

#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")

Expand Down
1 change: 1 addition & 0 deletions sql/field.h
Expand Up @@ -630,6 +630,7 @@ class Virtual_column_info: public Sql_alloc
bool utf8; /* Already in utf8 */
Item *expr;
LEX_STRING name; /* Name of constraint */
/* see VCOL_* (VCOL_FIELD_REF, ...) */
uint flags;

Virtual_column_info()
Expand Down
25 changes: 23 additions & 2 deletions sql/item.cc
Expand Up @@ -8818,8 +8818,19 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
fixed= 1;
return FALSE;
}

/*
DEFAULT() do not need table field so should not ask handler to bring
field value (mark column for read)
*/
enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
thd->mark_used_columns= MARK_COLUMNS_NONE;
if (!arg->fixed && arg->fix_fields(thd, &arg))
{
thd->mark_used_columns= save_mark_used_columns;
goto error;
}
thd->mark_used_columns= save_mark_used_columns;


real_arg= arg->real_item();
Expand All @@ -8839,15 +8850,19 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
goto error;
memcpy((void *)def_field, (void *)field_arg->field,
field_arg->field->size_of());
IF_DBUG(def_field->is_stat_field=1,); // a hack to fool ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED
// If non-constant default value expression
if (def_field->default_value && def_field->default_value->flags)
{
uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length());
if (!newptr)
goto error;
/*
Even if DEFAULT() do not read tables fields, the default value
expression can do it.
*/
fix_session_vcol_expr_for_read(thd, def_field, def_field->default_value);
if (thd->mark_used_columns != MARK_COLUMNS_NONE)
def_field->default_value->expr->walk(&Item::register_field_in_read_map, 1, 0);
def_field->default_value->expr->update_used_tables();
def_field->move_field(newptr+1, def_field->maybe_null() ? newptr : 0, 1);
}
else
Expand All @@ -8871,6 +8886,12 @@ void Item_default_value::print(String *str, enum_query_type query_type)
return;
}
str->append(STRING_WITH_LEN("default("));
/*
We take DEFAULT from a field so do not need it value in case of const
tables but its name so we set QT_NO_DATA_EXPANSION (as we print for
table definition, also we do not need table and database name)
*/
query_type= (enum_query_type) (query_type | QT_NO_DATA_EXPANSION);
arg->print(str, query_type);
str->append(')');
}
Expand Down
5 changes: 5 additions & 0 deletions sql/item.h
Expand Up @@ -5230,6 +5230,11 @@ class Item_default_value : public Item_field
return false;
}
table_map used_tables() const;
virtual void update_used_tables()
{
if (field && field->default_value)
field->default_value->expr->update_used_tables();
}
Field *get_tmp_table_field() { return 0; }
Item *get_tmp_table_item(THD *thd) { return this; }
Item_field *field_for_view_update() { return 0; }
Expand Down

0 comments on commit 01d3e40

Please sign in to comment.