1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-09 11:41:36 +03:00

LIMIT ROWS EXAMINED prematurely triggers during optimization

1. LIMIT ROWS EXAMINED clause allows to abort a query if a certain limit
of rows involved in processing is exceeded. This limitation should be only
enforced during the execution phase and not the optimization.

2. Unions are often executed using so-called "fake_select_lex" which
collects the final result from union parts. During that finalization
LIMIT ROWS EXAMINED must be ignored to avoid producing a potentially
incomplete result. There is a workaround at `st_select_lex_unit::exec()`
which deactivates the limit before fake_select_lex processing, and
re-activates it when the processing is finished. However, this re-activation
does not take into account whether the limit was active before the start
of fake_select_lex processing.

3. `st_select_lex_unit::exec()` can be invoked during the optimization
phase for evaluation of constant conditions with unions. At that time
the limit trigger is not activated. Given that the re-activation
mentioned above does not respect the previous state of the limit trigger,
a premature activation of the limit may happen.

This commit fixes that behavior by storing the state of the trigger
before its deactivation at `st_select_lex_unit::exec()` and re-activating
it only if the limit was active before.

4. This commit also removes the call to `thd->lex->set_rows_examined()`
from `st_select_lex_unit::exec_recursive()` which was probably copied
from `st_select_lex_unit::exec()`. But in the context of
 `exec_recursive()` the call does not make sense as there is no
previous deactivation of the limit as at `exec()`.

Reviewed by: Dave Gosselin, Sergei Petrunia
This commit is contained in:
Oleg Smirnov
2025-09-18 21:55:17 +03:00
parent f64e3fe3f6
commit a347f7a158
4 changed files with 33 additions and 8 deletions

View File

@@ -3604,8 +3604,6 @@ public:
{
if (limit_rows_examined)
limit_rows_examined_cnt= limit_rows_examined->val_uint();
else
limit_rows_examined_cnt= ULONGLONG_MAX; // Unreachable value
}
/**
@@ -3617,7 +3615,7 @@ public:
*/
bool deactivate_limit_rows_examined()
{
bool was_activated= (limit_rows_examined_cnt == ULONGLONG_MAX);
bool was_activated= (limit_rows_examined_cnt != ULONGLONG_MAX);
limit_rows_examined_cnt= ULONGLONG_MAX; // Unreachable value
return was_activated;
}