revision-id: 637c2d76a0332058b8771be37c17d077f297f0b1 (mariadb-10.2.16-67-g637c2d76a03) parent(s): 1e8b79d966fca2ae541477972ac759be5ee60c4e author: Oleksandr Byelkin committer: Oleksandr Byelkin timestamp: 2018-08-08 12:24:37 +0200 message: fix default() itself after talking to serg --- mysql-test/r/func_default.result | 2 +- mysql-test/r/func_time.result | 2 +- mysql-test/t/func_time.test | 6 +++--- sql/field.cc | 21 +++++++++++++++++++-- sql/field.h | 1 + sql/item.cc | 25 ++++++++++++++++++++++++- sql/item.h | 14 +++++--------- sql/sql_base.cc | 2 +- 8 files changed, 55 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/func_default.result b/mysql-test/r/func_default.result index 535be10da86..1f331af287c 100644 --- a/mysql-test/r/func_default.result +++ b/mysql-test/r/func_default.result @@ -8,7 +8,7 @@ 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(`str`) AS `default(str)`,default(`strnull`) AS `default(strnull)`,default(`intg`) AS `default(intg)`,default(`rel`) AS `default(rel)` from dual select * from t1 where str <> default(str); str strnull intg rel 0 0 diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index d3e81a8f2ee..51f51820efc 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -3267,7 +3267,7 @@ DROP TABLE t1,t2; # 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 +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)) diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 98b5f968fe0..c8859feee93 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -1865,10 +1865,10 @@ DROP TABLE t1,t2; --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 + +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; diff --git a/sql/field.cc b/sql/field.cc index 9ca9663f066..e12adbf47b3 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -70,8 +70,25 @@ 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) && \ + !(ptr >= table->record[1] && \ + ptr < table->record[1] + 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) && \ + !(ptr >= table->record[1] && \ + ptr < table->record[1] + table->s->reclength))) || \ + (table->vcol_set && bitmap_is_set(table->vcol_set, field_index))) #define FLAGSTR(S,F) ((S) & (F) ? #F " " : "") diff --git a/sql/field.h b/sql/field.h index 22c276478b6..55c3ed4c4bd 100644 --- a/sql/field.h +++ b/sql/field.h @@ -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() diff --git a/sql/item.cc b/sql/item.cc index 58d2b7dbfc0..91fe7ff03aa 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8917,8 +8917,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(); @@ -8938,12 +8949,16 @@ 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); @@ -8970,6 +8985,14 @@ 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 | + QT_ITEM_IDENT_SKIP_DB_NAMES | + QT_ITEM_IDENT_SKIP_TABLE_NAMES); arg->print(str, query_type); str->append(')'); } diff --git a/sql/item.h b/sql/item.h index 54cd358112d..d252a256f76 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5316,6 +5316,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->walk(&Item::register_field_in_read_map, 1, 0); + } Field *get_tmp_table_field() { return 0; } Item *get_tmp_table_item(THD *thd) { return this; } Item_field *field_for_view_update() { return 0; } @@ -5649,15 +5654,6 @@ class Item_cache: public Item_basic_constant, example->split_sum_func2(thd, ref_pointer_array, fields, &example, flags); } Item *get_example() const { return example; } - /* - Functiuons like DEFAULT() are constant but still read from tables and - update them, so we should gave that chance to them in case of caching. - */ - virtual void update_used_tables() - { - if (example) - return example->update_used_tables(); - } virtual Item *convert_to_basic_const_item(THD *thd) { return 0; }; Item *derived_field_transformer_for_having(THD *thd, uchar *arg) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 36bf39ea8f3..2c5bdf01468 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5688,7 +5688,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, TABLE *table= field_to_set->table; if (thd->mark_used_columns == MARK_COLUMNS_READ) bitmap_set_bit(table->read_set, field_to_set->field_index); - else + else if (thd->mark_used_columns == MARK_COLUMNS_WRITE) bitmap_set_bit(table->write_set, field_to_set->field_index); } }