1. Create a function, which selects data from any table. It is not enough to just return some constant value.
2. Create a view, which uses the function created in step 1.
3. Create a procedure, which runs for-loop. This for loop must query view created on step 2. However, it should not use any columns returned from the query, but a constant, eg. 1, for each row.
4. Call procedure twice from the same connection. First run success normally. The second one crashes the server without any explanation.
Minimal Reproducible Example is on attachment server_crash.sql.
All these details seem to be required to cause the server to crash. Interestingly enough, dropping some of them causes a different issue. If I select any value on cursor definition or skip the view and call the function directly, the first run results an error Table 'test_table' doesn't exist. Example of this is on file table_does_not_exist.sql.
on debug build: fails a debug assertion on the first execution of the SP, which didn't happen before,
on non-debug build: fails same way as it did before, crashing in check_grant.
Also, it's not exactly specific to a view – as often happens, the view in that test case can be replaced with a subquery with the same effect, as in
declare _cur cursorforselect 1 from (select get_name(id) from t1) sq;
So the patch may indeed need further improvement.
Elena Stepanova
added a comment - - edited With the patch the test case with views
on debug build: fails a debug assertion on the first execution of the SP, which didn't happen before,
on non-debug build: fails same way as it did before, crashing in check_grant.
Also, it's not exactly specific to a view – as often happens, the view in that test case can be replaced with a subquery with the same effect, as in
declare _cur cursor for select 1 from ( select get_name(id) from t1) sq;
So the patch may indeed need further improvement.
JFYI rewritten without FOR it still cause error where should not (but does not crash)
CREATE TABLE t1 ( id int, name varchar(24));
INSERT INTO t1 values (1, 'x'), (2, 'y'), (3, 'z');
create function get_name(_id int) returns varchar(24)
return (select name from t1 where id = _id);
select get_name(id) from t1;
delimiter ^^;
create procedure test_proc()
begin
DECLARE done INT DEFAULT FALSE;
DECLARE rec ROW TYPE OF _cur;
declare _cur cursor for select get_name(id) from t1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open _cur;
read_loop: LOOP
fetch _cur into rec;
IF done THEN
LEAVE read_loop;
END IF;
select 1;
end LOOP;
end;
^^
delimiter ;^^
--error 1146
call test_proc();
--error 1146
call test_proc();
Oleksandr Byelkin
added a comment - JFYI rewritten without FOR it still cause error where should not (but does not crash)
CREATE TABLE t1 ( id int, name varchar(24));
INSERT INTO t1 values (1, 'x'), (2, 'y'), (3, 'z');
create function get_name(_id int) returns varchar(24)
return (select name from t1 where id = _id);
select get_name(id) from t1;
delimiter ^^;
create procedure test_proc()
begin
DECLARE done INT DEFAULT FALSE;
DECLARE rec ROW TYPE OF _cur;
declare _cur cursor for select get_name(id) from t1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open _cur;
read_loop: LOOP
fetch _cur into rec;
IF done THEN
LEAVE read_loop;
END IF;
select 1;
end LOOP;
end;
^^
delimiter ;^^
--error 1146
call test_proc();
--error 1146
call test_proc();
My first patch does not work with views because view also add tables. So I come up with one lined fix which work with views.
Oleksandr Byelkin
added a comment - My first patch does not work with views because view also add tables. So I come up with one lined fix which work with views.
MDEV-26009 Server crash when calling twice procedure using FOR-loop
The problem was that instructions sp_instr_cursor_copy_struct and
sp_instr_copen uses the same lex, adding and removing "tail" of
prelocked tables and forgetting that tail of all tables is kept in
LEX::query_tables_last. If the LEX used only by one instruction
or the query do not have prelocked tables it is not important.
But to work correctly in all cases LEX::query_tables_last should
be reset to make new tables added in the correct list (after last
table in the LEX instead after last table of the prelocking "tail"
which was cut).
Oleksandr Byelkin
added a comment -
commit d8e915a88fcdebd0b42f10b2f6d2165296056dd1 (HEAD -> bb-10.3-MDEV-26009, origin/bb-10.3-MDEV-26009)
Author: Oleksandr Byelkin <sanja@mariadb.com>
Date: Fri Mar 18 11:13:09 2022 +0100
MDEV-26009 Server crash when calling twice procedure using FOR-loop
The problem was that instructions sp_instr_cursor_copy_struct and
sp_instr_copen uses the same lex, adding and removing "tail" of
prelocked tables and forgetting that tail of all tables is kept in
LEX::query_tables_last. If the LEX used only by one instruction
or the query do not have prelocked tables it is not important.
But to work correctly in all cases LEX::query_tables_last should
be reset to make new tables added in the correct list (after last
table in the LEX instead after last table of the prelocking "tail"
which was cut).
People
Oleksandr Byelkin
Paulus Limma
Votes:
0Vote for this issue
Watchers:
9Start watching this issue
Dates
Created:
Updated:
Resolved:
Git Integration
Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.
{"report":{"fcp":944.9000000953674,"ttfb":137.20000004768372,"pageVisibility":"visible","entityId":100783,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":0.5,"journeyId":"2e9ea1b1-3152-4e9c-a662-dd466c6ae555","navigationType":0,"readyForUser":1019.7999999523163,"redirectCount":0,"resourceLoadedEnd":778.4000000953674,"resourceLoadedStart":143.20000004768372,"resourceTiming":[{"duration":284.89999985694885,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2bu7/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":143.20000004768372,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":143.20000004768372,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":428.09999990463257,"responseStart":0,"secureConnectionStart":0},{"duration":284.69999980926514,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2bu7/820016/12ta74/8679b4946efa1a0bb029a3a22206fb5d/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":143.40000009536743,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":143.40000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":428.09999990463257,"responseStart":0,"secureConnectionStart":0},{"duration":293.7999999523163,"initiatorType":"script","name":"https://jira.mariadb.org/s/fbf975c0cce4b1abf04784eeae9ba1f4-CDN/lu2bu7/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":143.5,"connectEnd":143.5,"connectStart":143.5,"domainLookupEnd":143.5,"domainLookupStart":143.5,"fetchStart":143.5,"redirectEnd":0,"redirectStart":0,"requestStart":143.5,"responseEnd":437.2999999523163,"responseStart":437.2999999523163,"secureConnectionStart":143.5},{"duration":488,"initiatorType":"script","name":"https://jira.mariadb.org/s/099b33461394b8015fc36c0a4b96e19f-CDN/lu2bu7/820016/12ta74/8679b4946efa1a0bb029a3a22206fb5d/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true","startTime":143.59999990463257,"connectEnd":143.59999990463257,"connectStart":143.59999990463257,"domainLookupEnd":143.59999990463257,"domainLookupStart":143.59999990463257,"fetchStart":143.59999990463257,"redirectEnd":0,"redirectStart":0,"requestStart":143.59999990463257,"responseEnd":631.5999999046326,"responseStart":631.5999999046326,"secureConnectionStart":143.59999990463257},{"duration":491.39999985694885,"initiatorType":"script","name":"https://jira.mariadb.org/s/94c15bff32baef80f4096a08aceae8bc-CDN/lu2bu7/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":143.70000004768372,"connectEnd":143.70000004768372,"connectStart":143.70000004768372,"domainLookupEnd":143.70000004768372,"domainLookupStart":143.70000004768372,"fetchStart":143.70000004768372,"redirectEnd":0,"redirectStart":0,"requestStart":143.70000004768372,"responseEnd":635.0999999046326,"responseStart":635.0999999046326,"secureConnectionStart":143.70000004768372},{"duration":491.69999980926514,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":143.90000009536743,"connectEnd":143.90000009536743,"connectStart":143.90000009536743,"domainLookupEnd":143.90000009536743,"domainLookupStart":143.90000009536743,"fetchStart":143.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":143.90000009536743,"responseEnd":635.5999999046326,"responseStart":635.5999999046326,"secureConnectionStart":143.90000009536743},{"duration":492.19999980926514,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":143.90000009536743,"connectEnd":143.90000009536743,"connectStart":143.90000009536743,"domainLookupEnd":143.90000009536743,"domainLookupStart":143.90000009536743,"fetchStart":143.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":143.90000009536743,"responseEnd":636.0999999046326,"responseStart":636.0999999046326,"secureConnectionStart":143.90000009536743},{"duration":492.59999990463257,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2bu7/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":144,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":144,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":636.5999999046326,"responseStart":0,"secureConnectionStart":0},{"duration":492.59999990463257,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":144.20000004768372,"connectEnd":144.20000004768372,"connectStart":144.20000004768372,"domainLookupEnd":144.20000004768372,"domainLookupStart":144.20000004768372,"fetchStart":144.20000004768372,"redirectEnd":0,"redirectStart":0,"requestStart":144.20000004768372,"responseEnd":636.7999999523163,"responseStart":636.7999999523163,"secureConnectionStart":144.20000004768372},{"duration":493,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2bu7/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":144.29999995231628,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":144.29999995231628,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":637.2999999523163,"responseStart":0,"secureConnectionStart":0},{"duration":492.89999985694885,"initiatorType":"script","name":"https://jira.mariadb.org/s/3339d87fa2538a859872f2df449bf8d0-CDN/lu2bu7/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":144.40000009536743,"connectEnd":144.40000009536743,"connectStart":144.40000009536743,"domainLookupEnd":144.40000009536743,"domainLookupStart":144.40000009536743,"fetchStart":144.40000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":144.40000009536743,"responseEnd":637.2999999523163,"responseStart":637.2999999523163,"secureConnectionStart":144.40000009536743},{"duration":517.6999998092651,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":144.90000009536743,"connectEnd":144.90000009536743,"connectStart":144.90000009536743,"domainLookupEnd":144.90000009536743,"domainLookupStart":144.90000009536743,"fetchStart":144.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":144.90000009536743,"responseEnd":662.5999999046326,"responseStart":662.5999999046326,"secureConnectionStart":144.90000009536743},{"duration":584.7000000476837,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":149.59999990463257,"connectEnd":149.59999990463257,"connectStart":149.59999990463257,"domainLookupEnd":149.59999990463257,"domainLookupStart":149.59999990463257,"fetchStart":149.59999990463257,"redirectEnd":0,"redirectStart":0,"requestStart":149.59999990463257,"responseEnd":734.2999999523163,"responseStart":734.2000000476837,"secureConnectionStart":149.59999990463257},{"duration":59.200000047683716,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":584.7999999523163,"connectEnd":584.7999999523163,"connectStart":584.7999999523163,"domainLookupEnd":584.7999999523163,"domainLookupStart":584.7999999523163,"fetchStart":584.7999999523163,"redirectEnd":0,"redirectStart":0,"requestStart":584.7999999523163,"responseEnd":644,"responseStart":644,"secureConnectionStart":584.7999999523163},{"duration":117.89999985694885,"initiatorType":"link","name":"https://jira.mariadb.org/s/d5715adaadd168a9002b108b2b039b50-CDN/lu2bu7/820016/12ta74/be4b45e9cec53099498fa61c8b7acba4/_/download/contextbatch/css/jira.project.sidebar,-_super,-project.issue.navigator,-jira.general,-jira.browse.project,-jira.view.issue,-jira.global,-atl.general,-com.atlassian.jira.projects.sidebar.init/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":660.4000000953674,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":660.4000000953674,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":778.2999999523163,"responseStart":0,"secureConnectionStart":0},{"duration":117.5,"initiatorType":"link","name":"https://jira.mariadb.org/s/50bc9be5bfead1a25e72c1a9338c94f6-CDN/lu2bu7/820016/12ta74/e108c7645258ccb43280ed3404e3e949/_/download/contextbatch/css/com.atlassian.jira.plugins.jira-development-integration-plugin:0,-_super,-jira.view.issue,-jira.global,-jira.general,-jira.browse.project,-project.issue.navigator,-atl.general/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":660.9000000953674,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":660.9000000953674,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":778.4000000953674,"responseStart":0,"secureConnectionStart":0}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":12,"responseStart":138,"responseEnd":142,"domLoading":141,"domInteractive":1089,"domContentLoadedEventStart":1089,"domContentLoadedEventEnd":1148,"domComplete":1755,"loadEventStart":1755,"loadEventEnd":1756,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":1053},{"name":"bigPipe.sidebar-id.end","time":1053.9000000953674},{"name":"bigPipe.activity-panel-pipe-id.start","time":1054.0999999046326},{"name":"bigPipe.activity-panel-pipe-id.end","time":1058.0999999046326},{"name":"activityTabFullyLoaded","time":1163.2999999523163}],"measures":[],"correlationId":"b7a3d7ffd20237","effectiveType":"4g","downlink":10,"rtt":0,"serverDuration":80,"dbReadsTimeInMs":12,"dbConnsTimeInMs":18,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}
This fixes suite without view, but test suite with a view crashes by other cause (maybe other bug or this patch should be impruved):
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 57ab31d9edf..7f9e15d8dc9 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -4584,6 +4584,7 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp)
if (!row->arguments())
{
sp_cursor tmp(thd, &m_lex_keeper, true);
+ TABLE_LIST **query_tables_last_save= m_lex_keeper.get_query_tables_last();
// Open the cursor without copying data
if (!(ret= tmp.open(thd)))
{
@@ -4605,6 +4606,7 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp)
thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena);
tmp.close(thd);
}
+ m_lex_keeper.set_query_tables_last(query_tables_last_save);
}
*nextp= m_ip + 1;
DBUG_RETURN(ret);
diff --git a/sql/sp_head.h b/sql/sp_head.h
index e1cfbb484ad..1fa9232b0d9 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -1214,6 +1214,17 @@ class sp_lex_keeper
m_lex->safe_to_cache_query= 0;
}
+ TABLE_LIST **get_query_tables_last()
+ {
+ return m_lex->query_tables_last;
+ }
+
+ void set_query_tables_last(TABLE_LIST ** t)
+ {
+ m_lex->query_tables_last= t;
+ }
+
+
private:
LEX *m_lex;