From 974bce9aeb169b3f8c08924d8afb95bedc4a6c53 Mon Sep 17 00:00:00 2001 From: Kirill Yukhin <kirill.yukhin@gmail.com> Date: Thu, 29 Jun 2017 21:07:41 +0300 Subject: [PATCH] sql: Limit number of terms in SELECT compoind stmts Right now SQL query compiler is run on top of fiber's stack, which is limited to 64KB by default, so maximum number of entities in compound SELECT statement should be less than 50 (verified by experiment) or stack guard will be triggered. In future we'll introduce heuristic which should understand that query is 'complex' and run compilation in separate thread with larger stack. This will also allow us not to block Tarantool while compiling the query. Closes #2548 --- src/box/sql/sqliteLimit.h | 6 ++++- test/sql/sql-select-compound-limit.lua | 37 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 test/sql/sql-select-compound-limit.lua diff --git a/src/box/sql/sqliteLimit.h b/src/box/sql/sqliteLimit.h index 0554e61581..e04401d305 100644 --- a/src/box/sql/sqliteLimit.h +++ b/src/box/sql/sqliteLimit.h @@ -77,9 +77,13 @@ ** if the number of terms is too large. In practice, most SQL ** never has more than 3 or 4 terms. Use a value of 0 to disable ** any limit on the number of terms in a compount SELECT. +** +** Tarantool: gh-2548: Fiber stack is 64KB by default, so maximum +** number of entities should be less than 50 or stack guard will be +** triggered. */ #ifndef SQLITE_MAX_COMPOUND_SELECT -# define SQLITE_MAX_COMPOUND_SELECT 500 +# define SQLITE_MAX_COMPOUND_SELECT 50 #endif /* diff --git a/test/sql/sql-select-compound-limit.lua b/test/sql/sql-select-compound-limit.lua new file mode 100644 index 0000000000..e33792598f --- /dev/null +++ b/test/sql/sql-select-compound-limit.lua @@ -0,0 +1,37 @@ + +box.cfg{wal_mode='none'} + +table_count = 51 + +for _, term in ipairs({'UNION', 'UNION ALL', 'INTERSECT', 'EXCEPT'}) do + for i = 1,table_count do + drop_string = 'DROP TABLE IF EXISTS t' .. i .. ';\n' + box.sql.execute(drop_string) + end + + for i = 1,table_count do + create_string = 'CREATE TABLE t' .. i .. ' (s1 int primary key, s2 int);\n' + box.sql.execute(create_string) + end + + for i = 1,table_count do + insert_string = 'INSERT INTO t' .. i .. ' VALUES (0,' .. i .. ');\n' + box.sql.execute(insert_string) + end + + select_string = '' + for i = 1,table_count-1 do + if i > 1 then select_string = select_string .. ' ' .. term .. ' ' end + select_string = select_string .. 'SELECT * FROM t' .. i + end + + if not pcall(function() box.sql.execute(select_string) end) then + print('not ok') + end + + select_string = select_string .. ' ' .. term ..' ' .. 'SELECT * FROM t' .. table_count + if pcall(function() box.sql.execute(select_string) end) then + print('not ok') + end +end + -- GitLab