Skip to content

Commit 95c3ea7

Browse files
author
Dag Wanvik
committed
Bug#33279604 Instance crash when run a SQL query with many window functions
The immediate reason for this issue is the stack size of the thread, which is not large enough to accomodate the number of windows of a query specification in the query, cf. also Bug#33364125, when creating iterator from access path. This patch limits the number of windows, be they named or implicit, in a query specification (SELECT) to 127. If this number is exceeded, an error message will be given. Note that even that number may require increasing the default thread stack size on some platforms. The default stack size for MDS should be tuned to make 127 fit. Also, in order to make this number safe, we increase the range of plan_idx, since each temporary table assigned to a window will grab a value from that range and 127 windows would overflow the old range. The 127 limit could be increased if need be, modulo other possible problems. We could also make it a system variable. As for Bug#33364125, this patch will make it safe it increase the stack size so it could run ok: it needs 127 windows exactly. Change-Id: Id2af258d0622b4c6be70f8e498b7ccb6de260645
1 parent 686835f commit 95c3ea7

File tree

5 files changed

+24
-3
lines changed

5 files changed

+24
-3
lines changed

Diff for: share/messages_to_clients.txt

+2
Original file line numberDiff line numberDiff line change
@@ -9685,6 +9685,8 @@ ER_WARN_SF_UDF_NAME_COLLISION
96859685
ER_CANNOT_PURGE_BINLOG_WITH_BACKUP_LOCK
96869686
eng "Could not purge binary logs since another session is executing LOCK INSTANCE FOR BACKUP. Wait for that session to release the lock."
96879687

9688+
ER_TOO_MANY_WINDOWS
9689+
eng "Too many windows in SELECT: %d. Maximum allowed is %d. Use named windows to share windows between window functions."
96889690
#
96899691
# End of 8.0 error messages (server-to-client).
96909692
# Do NOT add messages intended for the error log above!

Diff for: sql/sql_opt_exec_shared.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct POSITION;
5050
before-first-table" (firstmatch_return==PRE_FIRST_PLAN_IDX) from "No
5151
FirstMatch" (firstmatch_return==NO_PLAN_IDX).
5252
*/
53-
typedef int8 plan_idx;
53+
using plan_idx = int;
5454
#define NO_PLAN_IDX (-2) ///< undefined index
5555
#define PRE_FIRST_PLAN_IDX \
5656
(-1) ///< right before the first (first's index is 0)
@@ -487,7 +487,10 @@ class QEP_shared_owner {
487487
// (before optimization).
488488
plan_idx idx() const { return m_qs->idx(); }
489489
void set_idx(plan_idx i) { return m_qs->set_idx(i); }
490-
qep_tab_map idx_map() const { return qep_tab_map{1} << m_qs->idx(); }
490+
qep_tab_map idx_map() const {
491+
assert(m_qs->idx() < static_cast<plan_idx>(CHAR_BIT * sizeof(qep_tab_map)));
492+
return qep_tab_map{1} << m_qs->idx();
493+
}
491494

492495
TABLE *table() const { return m_qs->table(); }
493496
POSITION *position() const { return m_qs->position(); }

Diff for: sql/table.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ struct TABLE_LIST;
110110
struct TABLE_SHARE;
111111
struct handlerton;
112112
struct Name_resolution_context;
113-
typedef int8 plan_idx;
113+
using plan_idx = int;
114114

115115
namespace dd {
116116
class Table;

Diff for: sql/window.cc

+6
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,12 @@ bool Window::setup_windows1(THD *thd, Query_block *select,
10861086
List<Window> *windows) {
10871087
// Only possible at resolution time.
10881088
assert(thd->lex->current_query_block()->first_execution);
1089+
1090+
if (windows->elements > kMaxWindows) {
1091+
my_error(ER_TOO_MANY_WINDOWS, MYF(0), windows->elements, kMaxWindows);
1092+
return true;
1093+
}
1094+
10891095
/*
10901096
We can encounter aggregate functions in the ORDER BY and PARTITION clauses
10911097
of window function, so make sure we allow it:

Diff for: sql/window.h

+10
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ enum class Window_retrieve_cached_row_reason {
7171
MISC_POSITIONS = 5 // NTH_VALUE, LEAD/LAG have dynamic indexes 5..N
7272
};
7373

74+
/**
75+
The number of windows is limited to avoid the stack blowing up
76+
when constructing iterators recursively. There used to be no limit, but
77+
it would be unsafe since QEP_shared::m_idx of tmp tables assigned for windows
78+
would exceed the old range of its type plan_idx (int8). It
79+
has now been widened, so the max number of windows could be increased
80+
if need be, modulo other problems. We could also make it a system variable.
81+
*/
82+
constexpr int kMaxWindows = 127;
83+
7484
/**
7585
Represents the (explicit) window of a SQL 2003 section 7.11 \<window clause\>,
7686
or the implicit (inlined) window of a window function call, or a reference to

0 commit comments

Comments
 (0)