Skip to content

Commit f311379

Browse files
committed
Fix for issue #5390
1 parent 8448267 commit f311379

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

enginetest/queries/procedure_queries.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,56 @@ END;`,
268268
},
269269
},
270270
},
271+
{
272+
Name: "REPEAT loop over user variable",
273+
SetUpScript: []string{
274+
`CREATE PROCEDURE p1(p1 INT)
275+
BEGIN
276+
SET @x = 0;
277+
REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
278+
END`,
279+
},
280+
Assertions: []ScriptTestAssertion{
281+
{
282+
Query: "CALL p1(0)",
283+
Expected: []sql.Row{},
284+
},
285+
{
286+
Query: "CALL p1(1)",
287+
Expected: []sql.Row{{}, {}}, // Next calls return an empty row, but progress the loop
288+
},
289+
{
290+
Query: "CALL p1(2)",
291+
Expected: []sql.Row{{}, {}, {}},
292+
},
293+
},
294+
},
295+
{
296+
Name: "WHILE loop over user variable",
297+
SetUpScript: []string{
298+
`CREATE PROCEDURE p1(p1 INT)
299+
BEGIN
300+
SET @x = 0;
301+
WHILE @x <= p1 DO
302+
SET @x = @x + 1;
303+
END WHILE;
304+
END`,
305+
},
306+
Assertions: []ScriptTestAssertion{
307+
{
308+
Query: "CALL p1(0)",
309+
Expected: []sql.Row{{}},
310+
},
311+
{
312+
Query: "CALL p1(1)",
313+
Expected: []sql.Row{{}, {}},
314+
},
315+
{
316+
Query: "CALL p1(2)",
317+
Expected: []sql.Row{{}, {}, {}},
318+
},
319+
},
320+
},
271321
{
272322
Name: "CASE statements",
273323
SetUpScript: []string{

sql/analyzer/stored_procedures.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,15 @@ func analyzeProcedureBodies(ctx *sql.Context, a *Analyzer, node sql.Node, skipCa
130130
var newChild sql.Node
131131
switch child := child.(type) {
132132
case plan.RepresentsBlock:
133+
// Many analyzer rules only check the top-level node, so we have to recursively analyze each child
133134
newChild, _, err = analyzeProcedureBodies(ctx, a, child, skipCall, scope, sel)
135+
if err != nil {
136+
return nil, transform.SameTree, err
137+
}
138+
// Blocks may have expressions declared directly on them, so we explicitly check the block node for variables
139+
newChild, _, err = a.analyzeWithSelector(ctx, newChild, scope, SelectAllBatches, func(id RuleId) bool {
140+
return id == resolveVariablesId
141+
})
134142
case *plan.Call:
135143
if skipCall {
136144
newChild = child

sql/types/typecheck.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ func IsBlobType(t sql.Type) bool {
3232

3333
// IsBinaryType checks if t is BINARY, VARBINARY, or BLOB
3434
func IsBinaryType(t sql.Type) bool {
35+
if t == nil {
36+
return false
37+
}
3538
switch t.Type() {
3639
case sqltypes.Binary, sqltypes.VarBinary, sqltypes.Blob:
3740
return true

0 commit comments

Comments
 (0)