Skip to content

Commit 524c86f

Browse files
authored
fix infinite recursion with recursive stored procedures (#2962)
1 parent e23900e commit 524c86f

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

enginetest/queries/procedure_queries.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,6 +2192,70 @@ END;`,
21922192
},
21932193
},
21942194
},
2195+
{
2196+
Name: "recursive procedure",
2197+
SetUpScript: []string{
2198+
`
2199+
create procedure recursive_proc(in counter int)
2200+
begin
2201+
set counter := counter + 1;
2202+
if counter > 3 then
2203+
select concat('ended with value: ', counter) as result;
2204+
else
2205+
call recursive_proc(counter);
2206+
end if;
2207+
end;`,
2208+
},
2209+
Assertions: []ScriptTestAssertion{
2210+
{
2211+
Query: "call recursive_proc(1);",
2212+
Expected: []sql.Row{
2213+
{"ended with value: 4"},
2214+
},
2215+
},
2216+
},
2217+
},
2218+
{
2219+
Name: "multi recursive procedures",
2220+
SetUpScript: []string{
2221+
`
2222+
create procedure procA(in counter int)
2223+
begin
2224+
set counter := counter + 1;
2225+
if counter > 3 then
2226+
select concat('ended in procA with value: ', counter) as result;
2227+
else
2228+
call procB(counter);
2229+
end if;
2230+
end;
2231+
`,
2232+
`
2233+
create procedure procB(in counter int)
2234+
begin
2235+
set counter := counter + 1;
2236+
if counter > 3 then
2237+
select concat('ended in procB with value: ', counter) as result;
2238+
else
2239+
call procA(counter);
2240+
end if;
2241+
end;
2242+
`,
2243+
},
2244+
Assertions: []ScriptTestAssertion{
2245+
{
2246+
Query: "call procA(1);",
2247+
Expected: []sql.Row{
2248+
{"ended in procA with value: 4"},
2249+
},
2250+
},
2251+
{
2252+
Query: "call procB(1);",
2253+
Expected: []sql.Row{
2254+
{"ended in procB with value: 4"},
2255+
},
2256+
},
2257+
},
2258+
},
21952259
}
21962260

21972261
var ProcedureCallTests = []ScriptTest{

sql/core.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ type StoredProcParam struct {
894894
func (s *StoredProcParam) SetValue(val any) {
895895
s.Value = val
896896
s.HasBeenSet = true
897-
if s.Reference != nil {
897+
if s.Reference != nil && s != s.Reference {
898898
s.Reference.SetValue(val)
899899
}
900900
}

sql/rowexec/proc.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ func (b *BaseBuilder) buildCall(ctx *sql.Context, n *plan.Call, row sql.Row) (sq
223223
paramName := strings.ToLower(param.Name)
224224
for spp := ctx.Session.GetStoredProcParam(paramName); spp != nil; {
225225
spp.Value = paramVal
226+
if spp.Reference == spp {
227+
break
228+
}
226229
spp = spp.Reference
227230
}
228231
}

0 commit comments

Comments
 (0)