Skip to content

MDEV-39916: Crash with having filter when being pushed down#5352

Merged
bsrikanth-mariadb merged 2 commits into
10.11from
10.11-MDEV-39916-Crash-with-Having_filter
Jul 15, 2026
Merged

MDEV-39916: Crash with having filter when being pushed down#5352
bsrikanth-mariadb merged 2 commits into
10.11from
10.11-MDEV-39916-Crash-with-Having_filter

Conversation

@bsrikanth-mariadb

@bsrikanth-mariadb bsrikanth-mariadb commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

MDEV-39916: Crash when pushing "NOT col" from HAVING into WHERE

"NOT column" rewrites itself into "column = 0" in fix_fields().
However the rewrite is not done when the "column" is wrapped in an Item_ref.

Later, pushdown_from_having_into_where() will strip the Item_ref object
and will call
Item_func_not(Item_field())->fix_fields(thd, ref=NULL);
This call will attempt the rewrite and crash when writing into NULL pointer.

Fixed this in two places:

  • Make Item_func_not::fix_fields() use real_item() and so recognize fields
    wrapped in Item_ref-like objects.

  • Make pushdown_from_having_into_where() pass the right pointer as
    fix_fields() argument.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@spetrunia

Copy link
Copy Markdown
Member

Review input from the optimizer call: We should avoid making calls to item->fix_fields(..., NULL) unless we definitely know that item is the kind of item that will not try to substitute itself (which is not the case here).

@bsrikanth-mariadb bsrikanth-mariadb force-pushed the 10.11-MDEV-39916-Crash-with-Having_filter branch from c7220a4 to f0a86f3 Compare July 8, 2026 05:30
Comment thread sql/sql_lex.cc Outdated
@spetrunia

Copy link
Copy Markdown
Member

Please also add this change as a separate commit:

--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1181,7 +1181,13 @@ class st_select_lex: public st_select_lex_node
 
   /* List of references to fields referenced from inner selects */
   List<Item_outer_ref> inner_refs_list;
+
+  /*
+    Pushdown from HAVING into WHERE optimization: conditions from the HAVING
+    clause that should be added into the WHERE.
+  */
   List<Item> attach_to_conds;
+
   /* Saved values of the WHERE and HAVING clauses*/
   Item::cond_result cond_value, having_value;
   /* 

@spetrunia

Copy link
Copy Markdown
Member

An experimental diff to side-step the problem:
allow Item_func_not(X) rewrite itself to "X=0" even when X is an Item_ref.

For some reason, Item_ref->ref points to the Item_ref itself before it is fixed so we need to call fix_fields() for it to be able to use item_ref->real_item().

--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -6829,7 +6829,11 @@ Item *Item_func_not::neg_transformer(THD *thd)   /* NOT(x)  ->  x */
 bool Item_func_not::fix_fields(THD *thd, Item **ref)
 {
   args[0]->under_not(this);
-  if (args[0]->type() == FIELD_ITEM)
+  // psergey:
+  if (args[0]->fix_fields(thd, &args[0]))
+    return true;
+ 
+  if (args[0]->real_item()->type() == FIELD_ITEM)
   {
     /* replace  "NOT <field>" with "<field> == 0" */
     Query_arena backup, *arena;

@bsrikanth-mariadb bsrikanth-mariadb force-pushed the 10.11-MDEV-39916-Crash-with-Having_filter branch 4 times, most recently from e4053b9 to e130df4 Compare July 10, 2026 03:22
@spetrunia

Copy link
Copy Markdown
Member

use fix_fields_if_needed() as Claude has suggested.

@spetrunia

Copy link
Copy Markdown
Member

Commit comment suggestion.

MDEV-39916: Crash when pushing "NOT col" from HAVING into WHERE

"NOT column" rewrites itself into "column = 0" in fix_fields().
However the rewrite is not done when the "column" is wrapped in an Item_ref.

Later, pushdown_from_having_into_where() will strip the Item_ref object 
and will call
  Item_func_not(Item_field())->fix_fields(thd, ref=NULL);
This call will attempt the rewrite and crash when writing into NULL pointer.

Fixed this in two places:
* Make Ittem_func_not::fix_fields() use real_item() and so recognize fields 
  wrapped in Item_ref-like objects.

* Make pushdown_from_having_into_where() pass the right pointer as 
  fix_fields() argument.

@bsrikanth-mariadb bsrikanth-mariadb force-pushed the 10.11-MDEV-39916-Crash-with-Having_filter branch from e130df4 to b548dfa Compare July 11, 2026 14:23
@spetrunia

Copy link
Copy Markdown
Member
  • Please fix the typo in the commit comment : Ittem_func_not
  • In the testcase , use the new MDEV description:
MDEV-39916: Crash when pushing "NOT col" from HAVING into WHERE

@spetrunia spetrunia self-requested a review July 15, 2026 12:21

@spetrunia spetrunia 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.

Ok to push after the above is addressed.

@bsrikanth-mariadb bsrikanth-mariadb force-pushed the 10.11-MDEV-39916-Crash-with-Having_filter branch 2 times, most recently from ce3b11d to d63a6c1 Compare July 15, 2026 13:27
"NOT column" rewrites itself into "column = 0" in fix_fields().
However the rewrite is not done when the "column" is wrapped in an Item_ref.

Later, pushdown_from_having_into_where() will strip the Item_ref object
and will call
  Item_func_not(Item_field())->fix_fields(thd, ref=NULL);
This call will attempt the rewrite and crash when writing into NULL pointer.

Fixed this in two places:
* Make Item_func_not::fix_fields() use real_item() and so recognize fields
  wrapped in Item_ref-like objects.

* Make pushdown_from_having_into_where() pass the right pointer as
  fix_fields() argument.
Add comments near "List<Item> attach_to_conds", inside class
st_select_lex, stating that the conditions from having clause into where
optimization are added to this list.
@bsrikanth-mariadb bsrikanth-mariadb force-pushed the 10.11-MDEV-39916-Crash-with-Having_filter branch from d63a6c1 to 5552e25 Compare July 15, 2026 13:55
@bsrikanth-mariadb bsrikanth-mariadb merged commit 5552e25 into 10.11 Jul 15, 2026
16 of 17 checks passed
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