From 6179a8efdc9d3fb6474f62cf2f65a733b2648d6a Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 15 Aug 2017 09:37:16 +0400 Subject: [PATCH 1/2] MDEV-13526 Add Type_handler::Item_val_bool() --- sql/item.cc | 30 ------------------------------ sql/item.h | 5 ++++- sql/sql_type.cc | 32 ++++++++++++++++++++++++++++++++ sql/sql_type.h | 11 +++++++++++ 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 7d3f8788c3f..f84c2aff0a3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -109,36 +109,6 @@ void Item::push_note_converted_to_positive_complement(THD *thd) } -/** - @todo - Make this functions class dependent -*/ - -bool Item::val_bool() -{ - switch(result_type()) { - case INT_RESULT: - return val_int() != 0; - case DECIMAL_RESULT: - { - my_decimal decimal_value; - my_decimal *val= val_decimal(&decimal_value); - if (val) - return !my_decimal_is_zero(val); - return 0; - } - case REAL_RESULT: - case STRING_RESULT: - return val_real() != 0.0; - case ROW_RESULT: - case TIME_RESULT: - DBUG_ASSERT(0); - return 0; // Wrong (but safe) - } - return 0; // Wrong (but safe) -} - - /** Get date/time/datetime. Optionally extend TIME result to DATETIME. diff --git a/sql/item.h b/sql/item.h index 1f487999e83..75c14c6338a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1047,7 +1047,10 @@ public: FALSE value is false or NULL TRUE value is true (not equal to 0) */ - virtual bool val_bool(); + virtual bool val_bool() + { + return type_handler()->Item_val_bool(this); + } virtual String *val_nodeset(String*) { return 0; } /* diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 6e99655c28b..906bc5d0acf 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -3077,6 +3077,38 @@ bool Type_handler_geometry:: #endif +/*************************************************************************/ + +bool Type_handler_real_result::Item_val_bool(Item *item) const +{ + return item->val_real() != 0.0; +} + +bool Type_handler_int_result::Item_val_bool(Item *item) const +{ + return item->val_int() != 0; +} + +bool Type_handler_decimal_result::Item_val_bool(Item *item) const +{ + my_decimal decimal_value; + my_decimal *val= item->val_decimal(&decimal_value); + if (val) + return !my_decimal_is_zero(val); + return false; +} + +bool Type_handler_temporal_result::Item_val_bool(Item *item) const +{ + return item->val_real() != 0.0; +} + +bool Type_handler_string_result::Item_val_bool(Item *item) const +{ + return item->val_real() != 0.0; +} + + /*************************************************************************/ longlong Type_handler_real_result:: diff --git a/sql/sql_type.h b/sql/sql_type.h index 27fb8a8f7da..e6a1d8f31ff 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -891,6 +891,7 @@ public: virtual bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const= 0; + virtual bool Item_val_bool(Item *item) const= 0; virtual longlong Item_val_int_signed_typecast(Item *item) const= 0; virtual longlong Item_val_int_unsigned_typecast(Item *item) const= 0; @@ -1147,6 +1148,11 @@ public: DBUG_ASSERT(0); return true; } + bool Item_val_bool(Item *item) const + { + DBUG_ASSERT(0); + return false; + } longlong Item_val_int_signed_typecast(Item *item) const { DBUG_ASSERT(0); @@ -1352,6 +1358,7 @@ public: bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) const; bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const; + bool Item_val_bool(Item *item) const; longlong Item_val_int_signed_typecast(Item *item) const; longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; @@ -1427,6 +1434,7 @@ public: bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; + bool Item_val_bool(Item *item) const; longlong Item_val_int_signed_typecast(Item *item) const; longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; @@ -1494,6 +1502,7 @@ public: bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; + bool Item_val_bool(Item *item) const; longlong Item_val_int_signed_typecast(Item *item) const; longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; @@ -1564,6 +1573,7 @@ public: bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; + bool Item_val_bool(Item *item) const; longlong Item_val_int_signed_typecast(Item *item) const; longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; @@ -1673,6 +1683,7 @@ public: bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) const; bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const; + bool Item_val_bool(Item *item) const; longlong Item_val_int_signed_typecast(Item *item) const; longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; From 22c9663d8563b4f825f28db978661e60ec618db5 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 15 Aug 2017 09:55:09 +0400 Subject: [PATCH 2/2] MDEV-13527 Crash when EXPLAIN SELECT .. INTO row_sp_variable.field --- mysql-test/r/sp-row.result | 10 ++++++++++ mysql-test/suite/compat/oracle/r/sp-row.result | 11 +++++++++++ mysql-test/suite/compat/oracle/t/sp-row.test | 13 +++++++++++++ mysql-test/t/sp-row.test | 13 +++++++++++++ sql/sql_yacc.yy | 2 +- sql/sql_yacc_ora.yy | 2 +- 6 files changed, 49 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp-row.result b/mysql-test/r/sp-row.result index c3204fe043b..61c0660cf71 100644 --- a/mysql-test/r/sp-row.result +++ b/mysql-test/r/sp-row.result @@ -2246,3 +2246,13 @@ b 10 DROP PROCEDURE p1; DROP TABLE t1; +# +# MDEV-13527 Crash when EXPLAIN SELECT .. INTO row_sp_variable.field +# +BEGIN NOT ATOMIC +DECLARE a ROW(a INT); +EXPLAIN SELECT 1 INTO a.a; +END; +$$ +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used diff --git a/mysql-test/suite/compat/oracle/r/sp-row.result b/mysql-test/suite/compat/oracle/r/sp-row.result index 86b6b9a530b..16421cd45ac 100644 --- a/mysql-test/suite/compat/oracle/r/sp-row.result +++ b/mysql-test/suite/compat/oracle/r/sp-row.result @@ -3070,3 +3070,14 @@ b 10 DROP PROCEDURE p1; DROP TABLE t1; +# +# MDEV-13527 Crash when EXPLAIN SELECT .. INTO row_sp_variable.field +# +DECLARE +a ROW(a INT); +BEGIN +EXPLAIN SELECT 1 INTO a.a; +END; +$$ +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used diff --git a/mysql-test/suite/compat/oracle/t/sp-row.test b/mysql-test/suite/compat/oracle/t/sp-row.test index 5d97bf02fa2..94cc5db9802 100644 --- a/mysql-test/suite/compat/oracle/t/sp-row.test +++ b/mysql-test/suite/compat/oracle/t/sp-row.test @@ -2375,3 +2375,16 @@ DELIMITER ;$$ CALL p1; DROP PROCEDURE p1; DROP TABLE t1; + +--echo # +--echo # MDEV-13527 Crash when EXPLAIN SELECT .. INTO row_sp_variable.field +--echo # + +DELIMITER $$; +DECLARE + a ROW(a INT); +BEGIN + EXPLAIN SELECT 1 INTO a.a; +END; +$$ +DELIMITER ;$$ diff --git a/mysql-test/t/sp-row.test b/mysql-test/t/sp-row.test index 6ed8b4495f4..e213d4dbc2d 100644 --- a/mysql-test/t/sp-row.test +++ b/mysql-test/t/sp-row.test @@ -1471,3 +1471,16 @@ DELIMITER ;$$ CALL p1; DROP PROCEDURE p1; DROP TABLE t1; + + +--echo # +--echo # MDEV-13527 Crash when EXPLAIN SELECT .. INTO row_sp_variable.field +--echo # + +DELIMITER $$; +BEGIN NOT ATOMIC + DECLARE a ROW(a INT); + EXPLAIN SELECT 1 INTO a.a; +END; +$$ +DELIMITER ;$$ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 49eda48c451..56b434229e2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -12155,7 +12155,7 @@ select_outvar: } | ident '.' ident { - if (!($$= Lex->create_outvar(thd, &$1, &$3))) + if (!($$= Lex->create_outvar(thd, &$1, &$3)) && Lex->result) MYSQL_YYABORT; } ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 80c9375e777..660212dd4b0 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -12218,7 +12218,7 @@ select_outvar: } | ident '.' ident { - if (!($$= Lex->create_outvar(thd, &$1, &$3))) + if (!($$= Lex->create_outvar(thd, &$1, &$3)) && Lex->result) MYSQL_YYABORT; } ;