Skip to content

Commit 29d8f65

Browse files
MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
Problem: When an SP instruction fails during execution, it is re-parsed. During this process, the items created on-behalf of the SP instruction are cleaned up, re-parsed and SP instruction state is updated. The clean up step frees the default parameters and the update step partially updates the SP instruction state, leaving the `default_value` in `sp_variable` pointing to the dangling reference. Fix: The SP instruction state is updated correctly, making the `default_value` in `sp_variable` ponit to the re-parsed item.
1 parent 8cca0f1 commit 29d8f65

File tree

5 files changed

+366
-0
lines changed

5 files changed

+366
-0
lines changed

mysql-test/main/sp-default-param.result

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,85 @@ SET p2 = p2 + 1;
130130
END;
131131
DELIMITER ;$$
132132
ERROR 42000: This version of MariaDB doesn't yet support 'IN sparam1 <type> DEFAULT <expr>, OUT spparam2 <type>'
133+
#
134+
# MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
135+
#
136+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
137+
BEGIN
138+
SELECT x;
139+
END;
140+
//
141+
SET SESSION max_session_mem_used=8192;
142+
CALL p0();
143+
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
144+
SET @@max_session_mem_used=DEFAULT;
145+
CALL p0();
146+
ERROR 42000: FUNCTION test.func does not exist
147+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
148+
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
149+
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
150+
# with func() defined
151+
CREATE FUNCTION func(x INT DEFAULT 10) RETURNS INT
152+
BEGIN
153+
RETURN x;
154+
END;
155+
//
156+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
157+
BEGIN
158+
SELECT x;
159+
END;
160+
//
161+
SET SESSION max_session_mem_used=8192;
162+
CALL p0();
163+
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
164+
SET @@max_session_mem_used=DEFAULT;
165+
CALL p0();
166+
x
167+
10
168+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
169+
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
170+
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
171+
# with multiple functions
172+
CREATE FUNCTION func2(x INT DEFAULT 10) RETURNS INT
173+
BEGIN
174+
RETURN x;
175+
END;
176+
//
177+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
178+
BEGIN
179+
SELECT x, y;
180+
END;
181+
//
182+
SET SESSION max_session_mem_used=8192;
183+
CALL p0();
184+
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
185+
SET @@max_session_mem_used=DEFAULT;
186+
CALL p0();
187+
x y
188+
10 10
189+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
190+
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
191+
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
192+
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
193+
# with function and constant default param
194+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
195+
BEGIN
196+
SELECT x, y, z;
197+
END;
198+
//
199+
SET SESSION max_session_mem_used=8192;
200+
CALL p0();
201+
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
202+
SET @@max_session_mem_used=DEFAULT;
203+
CALL p0();
204+
x y z
205+
10 10 10
206+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
207+
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
208+
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
209+
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
210+
def test p0 3 IN z int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
211+
DROP PROCEDURE p0;
212+
DROP FUNCTION func;
213+
DROP FUNCTION func2;
133214
# End of 11.8 tests

mysql-test/main/sp-default-param.test

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,96 @@ BEGIN
139139
END;
140140
DELIMITER ;$$
141141

142+
--echo #
143+
--echo # MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
144+
--echo #
145+
146+
--DELIMITER //
147+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
148+
BEGIN
149+
SELECT x;
150+
END;
151+
//
152+
--DELIMITER ;
153+
154+
SET SESSION max_session_mem_used=8192;
155+
--ERROR ER_OPTION_PREVENTS_STATEMENT
156+
CALL p0();
157+
158+
SET @@max_session_mem_used=DEFAULT;
159+
--ERROR ER_SP_DOES_NOT_EXIST
160+
CALL p0();
161+
162+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
163+
164+
--echo # with func() defined
165+
--DELIMITER //
166+
CREATE FUNCTION func(x INT DEFAULT 10) RETURNS INT
167+
BEGIN
168+
RETURN x;
169+
END;
170+
//
171+
172+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
173+
BEGIN
174+
SELECT x;
175+
END;
176+
//
177+
--DELIMITER ;
178+
179+
SET SESSION max_session_mem_used=8192;
180+
--ERROR ER_OPTION_PREVENTS_STATEMENT
181+
CALL p0();
182+
183+
SET @@max_session_mem_used=DEFAULT;
184+
CALL p0();
185+
186+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
187+
188+
--echo # with multiple functions
189+
--DELIMITER //
190+
CREATE FUNCTION func2(x INT DEFAULT 10) RETURNS INT
191+
BEGIN
192+
RETURN x;
193+
END;
194+
//
195+
196+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
197+
BEGIN
198+
SELECT x, y;
199+
END;
200+
//
201+
--DELIMITER ;
202+
203+
SET SESSION max_session_mem_used=8192;
204+
--ERROR ER_OPTION_PREVENTS_STATEMENT
205+
CALL p0();
206+
207+
SET @@max_session_mem_used=DEFAULT;
208+
CALL p0();
209+
210+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
211+
212+
--echo # with function and constant default param
213+
--DELIMITER //
214+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
215+
BEGIN
216+
SELECT x, y, z;
217+
END;
218+
//
219+
--DELIMITER ;
220+
221+
SET SESSION max_session_mem_used=8192;
222+
--ERROR ER_OPTION_PREVENTS_STATEMENT
223+
CALL p0();
224+
225+
SET @@max_session_mem_used=DEFAULT;
226+
CALL p0();
227+
228+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
229+
230+
DROP PROCEDURE p0;
231+
DROP FUNCTION func;
232+
DROP FUNCTION func2;
233+
142234
--echo # End of 11.8 tests

mysql-test/suite/compat/oracle/r/sp-default-param.result

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,91 @@ SET p2 = p2 + 1;
222222
END;
223223
DELIMITER ;$$
224224
ERROR 42000: This version of MariaDB doesn't yet support 'sparam1 IN <type> DEFAULT <expr>, spparam2 OUT <type>'
225+
#
226+
# MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
227+
#
228+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
229+
AS
230+
BEGIN
231+
SELECT x;
232+
END;
233+
//
234+
SET SESSION max_session_mem_used=8192;
235+
CALL p0();
236+
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
237+
SET @@max_session_mem_used=DEFAULT;
238+
CALL p0();
239+
ERROR 42000: FUNCTION test.func does not exist
240+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
241+
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
242+
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
243+
# with func() defined
244+
CREATE FUNCTION func(x INT DEFAULT 10) RETURN INT
245+
AS
246+
BEGIN
247+
RETURN x;
248+
END;
249+
//
250+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
251+
AS
252+
BEGIN
253+
SELECT x;
254+
END;
255+
//
256+
SET SESSION max_session_mem_used=8192;
257+
CALL p0();
258+
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
259+
SET @@max_session_mem_used=DEFAULT;
260+
CALL p0();
261+
x
262+
10
263+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
264+
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
265+
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
266+
# with multiple functions
267+
CREATE FUNCTION func2(x INT DEFAULT 10) RETURN INT
268+
AS
269+
BEGIN
270+
RETURN x;
271+
END;
272+
//
273+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
274+
AS
275+
BEGIN
276+
SELECT x, y;
277+
END;
278+
//
279+
SET SESSION max_session_mem_used=8192;
280+
CALL p0();
281+
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
282+
SET @@max_session_mem_used=DEFAULT;
283+
CALL p0();
284+
x y
285+
10 10
286+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
287+
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
288+
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
289+
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
290+
# with function and constant default param
291+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
292+
AS
293+
BEGIN
294+
SELECT x, y, z;
295+
END;
296+
//
297+
SET SESSION max_session_mem_used=8192;
298+
CALL p0();
299+
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
300+
SET @@max_session_mem_used=DEFAULT;
301+
CALL p0();
302+
x y z
303+
10 10 10
304+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
305+
SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE
306+
def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
307+
def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
308+
def test p0 3 IN z int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE
309+
DROP PROCEDURE p0;
310+
DROP FUNCTION func;
311+
DROP FUNCTION func2;
225312
# End of 11.8 tests

mysql-test/suite/compat/oracle/t/sp-default-param.test

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,102 @@ BEGIN
244244
END;
245245
DELIMITER ;$$
246246

247+
--echo #
248+
--echo # MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params
249+
--echo #
250+
251+
--DELIMITER //
252+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
253+
AS
254+
BEGIN
255+
SELECT x;
256+
END;
257+
//
258+
--DELIMITER ;
259+
260+
SET SESSION max_session_mem_used=8192;
261+
--ERROR ER_OPTION_PREVENTS_STATEMENT
262+
CALL p0();
263+
264+
SET @@max_session_mem_used=DEFAULT;
265+
--ERROR ER_SP_DOES_NOT_EXIST
266+
CALL p0();
267+
268+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
269+
270+
--echo # with func() defined
271+
--DELIMITER //
272+
CREATE FUNCTION func(x INT DEFAULT 10) RETURN INT
273+
AS
274+
BEGIN
275+
RETURN x;
276+
END;
277+
//
278+
279+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func())
280+
AS
281+
BEGIN
282+
SELECT x;
283+
END;
284+
//
285+
--DELIMITER ;
286+
287+
SET SESSION max_session_mem_used=8192;
288+
--ERROR ER_OPTION_PREVENTS_STATEMENT
289+
CALL p0();
290+
291+
SET @@max_session_mem_used=DEFAULT;
292+
CALL p0();
293+
294+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
295+
296+
--echo # with multiple functions
297+
--DELIMITER //
298+
CREATE FUNCTION func2(x INT DEFAULT 10) RETURN INT
299+
AS
300+
BEGIN
301+
RETURN x;
302+
END;
303+
//
304+
305+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2())
306+
AS
307+
BEGIN
308+
SELECT x, y;
309+
END;
310+
//
311+
--DELIMITER ;
312+
313+
SET SESSION max_session_mem_used=8192;
314+
--ERROR ER_OPTION_PREVENTS_STATEMENT
315+
CALL p0();
316+
317+
SET @@max_session_mem_used=DEFAULT;
318+
CALL p0();
319+
320+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
321+
322+
--echo # with function and constant default param
323+
--DELIMITER //
324+
CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10)
325+
AS
326+
BEGIN
327+
SELECT x, y, z;
328+
END;
329+
//
330+
--DELIMITER ;
331+
332+
SET SESSION max_session_mem_used=8192;
333+
--ERROR ER_OPTION_PREVENTS_STATEMENT
334+
CALL p0();
335+
336+
SET @@max_session_mem_used=DEFAULT;
337+
CALL p0();
338+
339+
SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0';
340+
341+
DROP PROCEDURE p0;
342+
DROP FUNCTION func;
343+
DROP FUNCTION func2;
344+
247345
--echo # End of 11.8 tests

sql/sp_instr.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,14 @@ class sp_instr_set : public sp_lex_instr,
655655
m_value= thd->lex->current_select->item_list.head();
656656
DBUG_ASSERT(m_value != nullptr);
657657

658+
/*
659+
In case there is a default value, update the dangling pointer
660+
left after clean up of item before re-parsing of SP instruction
661+
*/
662+
sp_variable *spvar= m_ctx->find_variable(offset());
663+
if (spvar->default_value)
664+
spvar->default_value= m_value;
665+
658666
// Return error in release version if m_value == nullptr
659667
return m_value == nullptr;
660668
}

0 commit comments

Comments
 (0)