summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorSergei Petrunia <sergey@mariadb.com>2022-04-21 22:45:31 +0300
committerSergei Petrunia <sergey@mariadb.com>2022-04-22 18:05:30 +0300
commit807945f2eb5fa22e6f233cc17b85a2e141efe2c8 (patch)
tree2b9c96f3c3c3d08e49d475ed5eff584bc5d94703 /sql/item_cmpfunc.cc
parent32041e7058db02dd312833a0bfc50437a64546ea (diff)
downloadmariadb-git-807945f2eb5fa22e6f233cc17b85a2e141efe2c8.tar.gz
MDEV-26402: A SEGV in Item_field::used_tables/update_depend_map_for_order...
When doing condition pushdown from HAVING into WHERE, Item_equal::create_pushable_equalities() calls item->set_extraction_flag(IMMUTABLE_FL) for constant items. Then, Item::cleanup_excluding_immutables_processor() checks for this flag to see if it should call item->cleanup() or leave the item as-is. The failure happens when a constant item has a non-constant one inside it, like: (tbl.col=0 AND impossible_cond) item->walk(cleanup_excluding_immutables_processor) works in a bottom-up way so it 1. will call Item_func_eq(tbl.col=0)->cleanup() 2. will not call Item_cond_and->cleanup (as the AND is constant) This creates an item tree where a fixed Item has an un-fixed Item inside it which eventually causes an assertion failure. Fixed by introducing this rule: instead of just calling item->set_extraction_flag(IMMUTABLE_FL); we call Item::walk() to set the flag for all sub-items of the item.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc12
1 files changed, 11 insertions, 1 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 15f1766b2e6..0ec20efdf27 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -7533,7 +7533,17 @@ bool Item_equal::create_pushable_equalities(THD *thd,
if (!eq || equalities->push_back(eq, thd->mem_root))
return true;
if (!clone_const)
- right_item->set_extraction_flag(IMMUTABLE_FL);
+ {
+ /*
+ Also set IMMUTABLE_FL for any sub-items of the right_item.
+ This is needed to prevent Item::cleanup_excluding_immutables_processor
+ from peforming cleanup of the sub-items and so creating an item tree
+ where a fixed item has non-fixed items inside it.
+ */
+ int new_flag= IMMUTABLE_FL;
+ right_item->walk(&Item::set_extraction_flag_processor, false,
+ (void*)&new_flag);
+ }
}
while ((item=it++))