[Commits] 44bcd544b78: MDEV-16722: Assertion `type() != NULL_ITEM' failed
revision-id: 44bcd544b785840d09b856540080866eeb9144b4 (mariadb-10.3.6-33-g44bcd544b78) parent(s): 4b0cedf82d8d8ba582648dcb4a2620c146862a43 author: Varun Gupta committer: Varun Gupta timestamp: 2018-08-08 11:54:11 +0530 message: MDEV-16722: Assertion `type() != NULL_ITEM' failed We hit this assert during the create of a temporary table field because the current code does not handle the case when the value of the NAME_CONST function is NULL. Fixed this by allowing creation of temporary table fields even for the case when NAME_CONST returns NULL value. Introduced tmp_table_field_from_field_type_maybe_null() function in Item class so both Item_basic_value and Item_name_const can use it. --- mysql-test/main/win.result | 11 +++++++++++ mysql-test/main/win.test | 9 +++++++++ sql/item.cc | 22 ++++++---------------- sql/item.h | 23 ++++++++++++++++++++--- sql/sql_select.cc | 41 ++++++++++++++++------------------------- 5 files changed, 62 insertions(+), 44 deletions(-) diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 3d56cd8e435..1a3467bba7a 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3315,5 +3315,16 @@ COUNT(DISTINCT t2.a2) rank() OVER (ORDER BY t2.b1) 1 3 DROP TABLE t1,t2; # +# MDEV-16722: Assertion `type() != NULL_ITEM' failed +# +create table t1 (a int); +insert into t1 values (1),(2),(3); +SELECT row_number() OVER (order by a) FROM t1 order by NAME_CONST('myname',NULL); +row_number() OVER (order by a) +1 +2 +3 +drop table t1; +# # Start of 10.3 tests # diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index d483cdbaa83..2efa0d562c8 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -2083,6 +2083,15 @@ SELECT COUNT(DISTINCT t2.a2), FROM t2 ,t1 GROUP BY t2.b1 ORDER BY t1.a1; DROP TABLE t1,t2; +--echo # +--echo # MDEV-16722: Assertion `type() != NULL_ITEM' failed +--echo # + +create table t1 (a int); +insert into t1 values (1),(2),(3); +SELECT row_number() OVER (order by a) FROM t1 order by NAME_CONST('myname',NULL); +drop table t1; + --echo # --echo # Start of 10.3 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 68aed25a580..68f7f6334ab 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2164,7 +2164,6 @@ Item_name_const::Item_name_const(THD *thd, Item *name_arg, Item *val): Item_fixed_hybrid(thd), value_item(val), name_item(name_arg) { Item::maybe_null= TRUE; - valid_args= true; if (!name_item->basic_const_item()) goto err; @@ -2183,7 +2182,6 @@ Item_name_const::Item_name_const(THD *thd, Item *name_arg, Item *val): } err: - valid_args= false; my_error(ER_WRONG_ARGUMENTS, MYF(0), "NAME_CONST"); } @@ -2191,24 +2189,16 @@ Item_name_const::Item_name_const(THD *thd, Item *name_arg, Item *val): Item::Type Item_name_const::type() const { /* - As - 1. one can try to create the Item_name_const passing non-constant - arguments, although it's incorrect and - 2. the type() method can be called before the fix_fields() to get - type information for a further type cast, e.g. - if (item->type() == FIELD_ITEM) - ((Item_field *) item)->... - we return NULL_ITEM in the case to avoid wrong casting. - - valid_args guarantees value_item->basic_const_item(); if type is - FUNC_ITEM, then we have a fudged item_func_neg() on our hands - and return the underlying type. + + We are guarenteed that value_item->basic_const_item(), if not + an error is thrown that WRONG ARGUMENTS are supplied to + NAME_CONST function. + If type is FUNC_ITEM, then we have a fudged item_func_neg() + on our hands and return the underlying type. For Item_func_set_collation() e.g. NAME_CONST('name', 'value' COLLATE collation) we return its 'value' argument type. */ - if (!valid_args) - return NULL_ITEM; Item::Type value_type= value_item->type(); if (value_type == FUNC_ITEM) { diff --git a/sql/item.h b/sql/item.h index f6f4684f643..a5648cdd92d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -820,6 +820,10 @@ class Item: public Value_source, return tmp_table_field_from_field_type(table); } Field *create_tmp_field_int(TABLE *table, uint convert_int_length); + Field *tmp_table_field_from_field_type_maybe_null(TABLE *table, + Tmp_field_src *src, + const Tmp_field_param *param, + bool is_explicit_null); void push_note_converted_to_negative_complement(THD *thd); void push_note_converted_to_positive_complement(THD *thd); @@ -2649,7 +2653,20 @@ class Item_basic_value :public Item, Item_basic_value(THD *thd): Item(thd) {} public: Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src, - const Tmp_field_param *param); + const Tmp_field_param *param) + { + + /* + create_tmp_field_ex() for this type of Items is called for: + - CREATE TABLE ... SELECT + - In ORDER BY: SELECT max(a) FROM t1 GROUP BY a ORDER BY 'const'; + - In CURSORS: + DECLARE c CURSOR FOR SELECT 'test'; + OPEN c; + */ + return tmp_table_field_from_field_type_maybe_null(table, src, param, + type() == Item::NULL_ITEM); + } bool eq(const Item *item, bool binary_cmp) const; const Type_all_attributes *get_type_all_attributes_from_const() const { return this; } @@ -2990,7 +3007,6 @@ class Item_name_const : public Item_fixed_hybrid { Item *value_item; Item *name_item; - bool valid_args; public: Item_name_const(THD *thd, Item *name_arg, Item *val); @@ -3023,7 +3039,8 @@ class Item_name_const : public Item_fixed_hybrid DECLARE c CURSOR FOR SELECT NAME_CONST('x','y') FROM t1; OPEN c; */ - return create_tmp_field_ex_simple(table, src, param); + return tmp_table_field_from_field_type_maybe_null(table, src, param, + type() == Item::NULL_ITEM); } int save_in_field(Field *field, bool no_conversions) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 25b01e49a2f..c0f3e14f82e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -16591,6 +16591,22 @@ Field *Item::create_tmp_field_int(TABLE *table, uint convert_int_length) *this, table); } +Field *Item::tmp_table_field_from_field_type_maybe_null(TABLE *table, + Tmp_field_src *src, + const Tmp_field_param *param, + bool is_explicit_null) +{ + DBUG_ASSERT(!param->make_copy_field()); + DBUG_ASSERT(!is_result_field()); + Field *result; + if ((result= tmp_table_field_from_field_type(table))) + { + if (result && is_explicit_null) + result->is_created_from_null_item= true; + } + return result; +} + Field *Item_sum::create_tmp_field(bool group, TABLE *table) { @@ -16821,31 +16837,6 @@ Field *Item_func_sp::create_tmp_field_ex(TABLE *table, return result; } - -Field *Item_basic_value::create_tmp_field_ex(TABLE *table, - Tmp_field_src *src, - const Tmp_field_param *param) -{ - /* - create_tmp_field_ex() for this type of Items is called for: - - CREATE TABLE ... SELECT - - In ORDER BY: SELECT max(a) FROM t1 GROUP BY a ORDER BY 'const'; - - In CURSORS: - DECLARE c CURSOR FOR SELECT 'test'; - OPEN c; - */ - DBUG_ASSERT(!param->make_copy_field()); - DBUG_ASSERT(!is_result_field()); - Field *result; - if ((result= tmp_table_field_from_field_type(table))) - { - if (type() == Item::NULL_ITEM) // Item_null or Item_param - result->is_created_from_null_item= true; - } - return result; -} - - /** Create field for temporary table.
participants (1)
-
Varun