Skip to content

MDEV-37713/MDEV-37714 Fold boolean literals in SELECT-list#4754

Open
jaeheonshim wants to merge 1 commit into
MariaDB:mainfrom
jaeheonshim:MDEV-37713
Open

MDEV-37713/MDEV-37714 Fold boolean literals in SELECT-list#4754
jaeheonshim wants to merge 1 commit into
MariaDB:mainfrom
jaeheonshim:MDEV-37713

Conversation

@jaeheonshim
Copy link
Copy Markdown

@jaeheonshim jaeheonshim commented Mar 8, 2026

The order of evaluation of the expressions that appear in a SELECT-list is undefined. This change exploits this fact by recursively folding TRUE/FALSE literals in OR/AND expressions which may allow for skipping evaluation of some parts of the expression or even the whole expression.

Example

Setup

CREATE TABLE t1(c0 INT8);
CREATE TABLE t2(c0 INT8);
INSERT INTO t1 VALUES(1);
INSERT INTO t2 SELECT seq FROM seq_1_to_10000000;

Before

SELECT (SELECT MIN(c0) FROM t2)<0 OR true;
+------------------------------------+
| (SELECT MIN(c0) FROM t2)<0 OR true |
+------------------------------------+
|                                  1 |
+------------------------------------+
1 row in set (1.335 sec)


SELECT ((SELECT MIN(c0) FROM t2)<0 AND false) OR (SELECT MAX(c0) FROM t1)>0;
+----------------------------------------------------------------------+
| ((SELECT MIN(c0) FROM t2)<0 AND false) OR (SELECT MAX(c0) FROM t1)>0 |
+----------------------------------------------------------------------+
|                                                                    1 |
+----------------------------------------------------------------------+
1 row in set (1.413 sec)

After

SELECT (SELECT MIN(c0) FROM t2)<0 OR true;
+------------------------------------+
| (SELECT MIN(c0) FROM t2)<0 OR true |
+------------------------------------+
|                                  1 |
+------------------------------------+
1 row in set (0.000 sec)


SELECT ((SELECT MIN(c0) FROM t2)<0 AND false) OR (SELECT MAX(c0) FROM t1)>0;
+----------------------------------------------------------------------+
| ((SELECT MIN(c0) FROM t2)<0 AND false) OR (SELECT MAX(c0) FROM t1)>0 |
+----------------------------------------------------------------------+
|                                                                    1 |
+----------------------------------------------------------------------+
1 row in set (0.000 sec)

@jaeheonshim jaeheonshim force-pushed the MDEV-37713 branch 3 times, most recently from 8acdfc3 to 3dc42db Compare March 8, 2026 07:52
@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Mar 9, 2026
Copy link
Copy Markdown
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution! This is a preliminary review.

Please also add a test case.

And, the jira mentions one optimization you're not really doing:

SELECT (a > 0 AND a < 0) FROM t1;
SELECT (a > 0 OR a <=0) FROM t1;

Would you consider doing this too? Or, if you wont, we'll need to open a sub-task Jira instead of using the current one.

Comment thread sql/item_cmpfunc.cc
Comment thread sql/sql_base.cc Outdated
@jaeheonshim
Copy link
Copy Markdown
Author

And, the jira mentions one optimization you're not really doing:

SELECT (a > 0 AND a < 0) FROM t1;
SELECT (a > 0 OR a <=0) FROM t1;

Would you consider doing this too? Or, if you wont, we'll need to open a sub-task Jira instead of using the current one.

Unfortunately, I don't think something like that can be added. We would risk breaking the semantics of the sql query. For example, if a is NULL, we cannot fold the expression (a > 0 AND a < 0) to FALSE, as the correct answer should be NULL.

Comment thread sql/item_cmpfunc.cc
Comment thread sql/sql_base.cc Outdated
@gkodinov
Copy link
Copy Markdown
Member

gkodinov commented Apr 2, 2026

There hasn't been any activity for more than 3 weeks now. Closing due to inactivity. If you would like to keep working on that please ping me or anybody else of the MariaDB committers to re-open the PR for you.

@gkodinov gkodinov closed this Apr 2, 2026
@grooverdan grooverdan reopened this Apr 10, 2026
@jaeheonshim jaeheonshim force-pushed the MDEV-37713 branch 6 times, most recently from c439d1a to 8003be3 Compare April 14, 2026 05:25
Comment thread mysql-test/main/literal_boolean_cond_folding.test
@grooverdan grooverdan assigned spetrunia and Olernov and unassigned spetrunia Apr 14, 2026
@grooverdan grooverdan requested a review from Olernov April 16, 2026 07:31
@Olernov
Copy link
Copy Markdown
Contributor

Olernov commented Apr 16, 2026

@jaeheonshim , generally we try to avoid test files names like mdev_xxxx.test as not descriptive enough. I'd suggest something like boolean_cond_folding.test

@Olernov
Copy link
Copy Markdown
Contributor

Olernov commented Apr 16, 2026

remove_eq_conds() protects against deeply nested expressions with:

if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL))
{
  *cond_value= Item::COND_FALSE;
  return (COND*) 0;                           // Fatal error flag is set!
}

The recursive simplify_cond() has no such guard. For deeply nested AND/OR trees, this could potentially overflow the stack.

@jaeheonshim
Copy link
Copy Markdown
Author

@Olernov , thanks for the suggestions! I added the check_stack_overrun in simplify_cond as well, and also changed the name of the tests.

@Olernov
Copy link
Copy Markdown
Contributor

Olernov commented May 1, 2026

  1. setup_fields is a general-purpose function called from many places (INSERT, UPDATE, LOAD, etc.). Embedding optimization logic here is unusual. Consider placing it at JOIN::optimize_inner or at least JOIN::prepare after fix_fields().
  2. Add protection against view transformation: !thd->lex->is_view_context_analysis()) , see examples at JOIN::prepare, otherwise the view is created malformed:
create view v1 as SELECT (SELECT MIN(c0) FROM t2)<0 OR true from t1;
show create view v1;
View    Create View     character_set_client    collation_connection
v1      CREATE ... VIEW `v1` AS select 1 AS `(SELECT MIN(c0) FROM t2)<0 OR true` from `t1`
  1. Add tests for UPDATE and INSERT to your file if those statements exercise the new logic.

And please address other unresolved comments here, thank you!

Comment thread sql/item_cmpfunc.cc
Comment thread mysql-test/main/literal_boolean_cond_folding.test Outdated
Copy link
Copy Markdown
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

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

LGTM. You already did cover the truth tables in tests it seems.

Please keep working with @Olernov on the final review.

@jaeheonshim
Copy link
Copy Markdown
Author

@Olernov , I moved simplify_cond to JOIN::prepare (I tried to put it in JOIN::optimize but the optimization only works if the query is rewritten before setup_fields it seems), added the guard against view context analysis and also a test to ensure the view is created properly, and addressed other unresolved comments.

Ready for your review!

@jaeheonshim jaeheonshim requested a review from Olernov May 5, 2026 06:03
Comment thread sql/item_cmpfunc.cc
Comment thread sql/item_cmpfunc.cc Outdated
The order of evaluation of the expressions that appear in a SELECT-list
is undefined. This change exploits this fact by recursively folding
TRUE/FALSE literals in OR/AND expressions which may allow for skipping
evaluation of some parts of the expression or even the whole expression.
Copy link
Copy Markdown
Contributor

@Olernov Olernov left a comment

Choose a reason for hiding this comment

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

@jaeheonshim, now everything is OK, thanks for good work! Now this PR needs to pass the testing, I'll re-assign JIRA tasks to the QA team.

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

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

5 participants