diff options
author | Rex <rex.johnston@mariadb.com> | 2023-01-23 14:35:14 +1200 |
---|---|---|
committer | Rex <rex.johnston@mariadb.com> | 2023-02-01 06:18:55 +1200 |
commit | 9739c26fec71b1118ccbf09a9b673a8d28b2110c (patch) | |
tree | a4dbf96cf32e9f556f550317a4c2e2f734a3317b /sql | |
parent | c45630327c3477c24aea25692021bb7732e4a64a (diff) | |
download | mariadb-git-bb-10.3-MDEV-28622.tar.gz |
MDEV-28620, MDEV-28621, MDEV-28622 Server crash in /sql/item_subselect.cc *bb-10.3-MDEV-28622
Optimizer has eliminated subquery for various reasons.
Attempting to walk or access Item_subselect (and descendents)
values causes issues for these removed Items. Fixed by setting
either fixed_const, null_value or checking eliminated.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_subselect.cc | 69 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 |
2 files changed, 67 insertions, 4 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 6472bb86a37..02f786e7090 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -153,7 +153,10 @@ void Item_subselect::cleanup() } if (engine) engine->cleanup(); - reset(); + + if (!eliminated || !thd || !thd->lex || !thd->lex->result) + reset(); + filesort_buffer.free_sort_buffer(); my_free(sortbuffer.str); sortbuffer.str= 0; @@ -362,6 +365,8 @@ bool Item_subselect::enumerate_field_refs_processor(void *arg) bool Item_subselect::mark_as_eliminated_processor(void *arg) { eliminated= TRUE; + if (!null_value) + forced_const= TRUE; return FALSE; } @@ -382,6 +387,8 @@ bool Item_subselect::eliminate_subselect_processor(void *arg) if (!unit->is_excluded()) unit->exclude(); eliminated= TRUE; + if (!null_value) + forced_const= TRUE; return FALSE; } @@ -660,6 +667,8 @@ int walk_items_for_table_list(Item_processor processor, bool Item_subselect::walk(Item_processor processor, bool walk_subquery, void *argument) { + if (eliminated) + return 0; if (!(unit->uncacheable & ~UNCACHEABLE_DEPENDENT) && engine->is_executed() && !unit->describe) { @@ -1329,12 +1338,12 @@ void Item_singlerow_subselect::bring_value() { if (!exec() && assigned()) { - null_value= true; + null_value= TRUE; for (uint i= 0; i < max_columns ; i++) { if (!row[i]->null_value) { - null_value= false; + null_value= FALSE; return; } } @@ -1348,6 +1357,15 @@ double Item_singlerow_subselect::val_real() DBUG_ASSERT(fixed == 1); if (forced_const) return value->val_real(); + else + { + if (eliminated) + { + null_value= TRUE; + return 0; + } + } + if (!exec() && !value->null_value) { null_value= FALSE; @@ -1369,6 +1387,15 @@ longlong Item_singlerow_subselect::val_int() null_value= value->null_value; return val; } + else + { + if (eliminated) + { + null_value= TRUE; + return 0; + } + } + if (!exec() && !value->null_value) { null_value= FALSE; @@ -1391,6 +1418,15 @@ String *Item_singlerow_subselect::val_str(String *str) null_value= value->null_value; return res; } + else + { + if (eliminated) + { + null_value= TRUE; + return 0; + } + } + if (!exec() && !value->null_value) { null_value= FALSE; @@ -1413,7 +1449,16 @@ my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value) my_decimal *val= value->val_decimal(decimal_value); null_value= value->null_value; return val; + } + else + { + if (eliminated) + { + null_value= TRUE; + return 0; + } } + if (!exec() && !value->null_value) { null_value= FALSE; @@ -1437,6 +1482,15 @@ bool Item_singlerow_subselect::val_bool() null_value= value->null_value; return val; } + else + { + if (eliminated) + { + null_value= TRUE; + return 0; + } + } + if (!exec() && !value->null_value) { null_value= FALSE; @@ -1460,6 +1514,15 @@ bool Item_singlerow_subselect::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) null_value= value->null_value; return val; } + else + { + if (eliminated) + { + null_value= TRUE; + return 0; + } + } + if (!exec() && !value->null_value) { null_value= FALSE; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 58d9b232722..7eb90fc789e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1198,7 +1198,7 @@ JOIN::prepare(TABLE_LIST *tables_init, */ if (select_lex->master_unit()->item && // 1) select_lex->first_cond_optimization && // 2) - !thd->lex->is_view_context_analysis()) // 3) + !thd->lex->is_ps_or_view_context_analysis()) // 3) { remove_redundant_subquery_clauses(select_lex); } |