Skip to content

MDEV-26940 Item_cond::remove_eq_conds leaves corrupt Item_equal - #5360

Open
mariadb-RexJohnston wants to merge 1 commit into
10.11from
10.11-MDEV-26940
Open

MDEV-26940 Item_cond::remove_eq_conds leaves corrupt Item_equal#5360
mariadb-RexJohnston wants to merge 1 commit into
10.11from
10.11-MDEV-26940

Conversation

@mariadb-RexJohnston

Copy link
Copy Markdown
Member

pushdown_cond_for_derived/merge_into_list/remove_eq_conds leaves an Item_equal in an invalid state. This Item_equal is later used by find_producing_item causing an assert in debug builds and perhaps incorrect results in a release build.

Affected queries will likely have an outer condition pushed down into 2 different derived tables based on the same base table.

@DaveGosselin-MariaDB DaveGosselin-MariaDB left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline are my review comments. Here are some comments from Claude as well:

Orphan left corrupt after merge — sql/item_cmpfunc.cc:7046 · correctness · PLAUSIBLE
merge() repoints only members still in item->equal_items, leaving item itself with with_const==TRUE over a non-const head. It misses (a) fields fi.remove() stripped from the merged-in equality before merge() ran (item_cmpfunc.cc:7109, which ran once in this test), and (b) a popped const that is a const-table field. Either can trip the new assert (debug) or mis-substitute (release) on other queries. Not reproduced by the committed test.

Unconditional set_item_equal may steal upper-level back-pointers — sql/item_cmpfunc.cc:7056 · correctness · PLAUSIBLE (low confidence)
On the direct-merge path (check_simple_equality, sql_select.cc:16943 — untested here), copied equalities share member Item objects; repointing them unconditionally can redirect a field's item_equal away from the upper-level original, risking wrong results. No concrete repro.

Comment thread sql/item_cmpfunc.h
Comment thread sql/item_cmpfunc.cc Outdated
@mariadb-RexJohnston

Copy link
Copy Markdown
Member Author

Unconditional set_item_equal may steal upper-level back-pointers — sql/item_cmpfunc.cc:7056 · correctness · PLAUSIBLE (low confidence) On the direct-merge path (check_simple_equality, sql_select.cc:16943 — untested here), copied equalities share member Item objects; repointing them unconditionally can redirect a field's item_equal away from the upper-level original, risking wrong results. No concrete repro.

As there is only one item_equal pointer, we need to look at what is used for and whether it matters which Item_equal object we are pointing at. It's main use is obtaining the contents of containing Item_equal, not the object itself (like find_producing_item()).

Aside: multiple Item_equal's containing the same item is exactly what our test case contains, and it's the merge process itself that should leave only one (or zero) instances of Item_equal behind.

pushdown_cond_for_derived/merge_into_list/remove_eq_conds leaves
an Item_equal in an invalid state.  This Item_equal is later used
by find_producing_item causing an assert in debug builds and perhaps
incorrect results in a release build. This Item_equal should no longer
be referred to, so rather than correct the Item_equal, we correct the
reference used later to look up our base table field.

Affected queries will likely have an outer condition pushed down into
2 different derived tables based on the same base table.

@DaveGosselin-MariaDB DaveGosselin-MariaDB left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Please let @spetrunia have the final say.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants