Skip to content

Commit 82109df

Browse files
committed
sql/sem/tree: do not Restore SemaRejectFlags during semantic analysis
This commit fixes a bug introduced in cockroachdb#105582 that caused SemaRejectFlags to be restored during semantic analysis, preventing the analysis from detecting some forms of invalid expressions. Fixes cockroachdb#108166 There is no release note because the related bug does not exist in any releases. Release note: None
1 parent b61e511 commit 82109df

File tree

5 files changed

+47
-21
lines changed

5 files changed

+47
-21
lines changed

pkg/sql/logictest/testdata/logic_test/delete

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,3 +576,15 @@ statement error pgcode 42803 sum\(\): aggregate functions are not allowed in ORD
576576
DELETE FROM t107634 ORDER BY sum(a) LIMIT 1;
577577

578578
subtest end
579+
580+
# Regression test for #108166. Do not allow aggregate functions in ORDER BY when
581+
# the function is wrapped by a conditional expression.
582+
subtest regression_108166
583+
584+
statement ok
585+
CREATE TABLE t108166 (a INT)
586+
587+
statement error pgcode 42803 sum\(\): aggregate functions are not allowed in ORDER BY in DELETE
588+
DELETE FROM t108166 ORDER BY COALESCE(sum(a), 1) LIMIT 1;
589+
590+
subtest end

pkg/sql/logictest/testdata/logic_test/srfs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,16 +1322,16 @@ subtest generator-syntax
13221322

13231323
# Regression test for #97119 and #94890 - return syntax error when CASE or
13241324
# COALESCE is used with a set-generating function as argument.
1325-
statement error pq: set-returning functions are not allowed in CASE
1325+
statement error pq: set-returning functions are not allowed in conditional expressions
13261326
SELECT CASE generate_series(1, 3) WHEN 3 THEN 0 ELSE 1 END;
13271327

1328-
statement error pq: set-returning functions are not allowed in CASE
1328+
statement error pq: set-returning functions are not allowed in conditional expressions
13291329
SELECT CASE WHEN true THEN generate_series(1, 3) ELSE 1 END;
13301330

1331-
statement error pq: set-returning functions are not allowed in CASE
1331+
statement error pq: set-returning functions are not allowed in conditional expressions
13321332
SELECT CASE WHEN false THEN 1 ELSE generate_series(1, 3) END;
13331333

1334-
statement error pq: set-returning functions are not allowed in COALESCE
1334+
statement error pq: set-returning functions are not allowed in conditional expressions
13351335
SELECT COALESCE(generate_series(1, 10));
13361336

13371337
# A subquery with a generator function is allowed within CASE and COALESCE.
@@ -1376,12 +1376,12 @@ SELECT COALESCE(sum(x) OVER ()) FROM xy;
13761376
15
13771377

13781378
# IF does not allow generator functions.
1379-
statement error pq: set-returning functions are not allowed in IF
1379+
statement error pq: set-returning functions are not allowed in conditional expressions
13801380
SELECT IF(x > y, generate_series(1, 3), 0) FROM xy;
13811381

13821382
# IFNULL does not allow generator functions. Note that the error mentions
13831383
# COALESCE because IFNULL is parsed directly as a COALESCE expression.
1384-
statement error pq: set-returning functions are not allowed in COALESCE
1384+
statement error pq: set-returning functions are not allowed in conditional expressions
13851385
SELECT IFNULL(1, generate_series(1, 2));
13861386

13871387
# NULLIF allows generator functions.

pkg/sql/logictest/testdata/logic_test/update

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,3 +672,15 @@ statement error pgcode 42803 sum\(\): aggregate functions are not allowed in ORD
672672
UPDATE t107634 SET a = 1 ORDER BY sum(a) LIMIT 1;
673673

674674
subtest end
675+
676+
# Regression test for #108166. Do not allow aggregate functions in ORDER BY when
677+
# the function is wrapped by a conditional expression.
678+
subtest regression_108166
679+
680+
statement ok
681+
CREATE TABLE t108166 (a INT)
682+
683+
statement error pgcode 42803 sum\(\): aggregate functions are not allowed in ORDER BY in UPDATE
684+
UPDATE t108166 SET a = 1 ORDER BY COALESCE(sum(a), 1) LIMIT 1;
685+
686+
subtest end

pkg/sql/opt/optbuilder/srfs.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ func (s *srf) TypeCheck(
5050
// invalid usage here.
5151
return nil, tree.NewInvalidFunctionUsageError(tree.GeneratorClass, ctx.TypeCheckContext())
5252
}
53+
if ctx.Properties.Ancestors.Has(tree.ConditionalAncestor) {
54+
return nil, tree.NewInvalidFunctionUsageError(tree.GeneratorClass, "conditional expressions")
55+
}
5356
if ctx.Properties.Derived.SeenGenerator {
5457
// This error happens if this srf struct is nested inside a raw srf that
5558
// has not yet been replaced. This is possible since scope.replaceSRF first

pkg/sql/sem/tree/type_check.go

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ const (
209209
// checking the parameters of a window function in order to reject nested
210210
// window functions.
211211
WindowFuncAncestor
212+
213+
// ConditionalAncestor is temporarily added to ScalarAncestors while type
214+
// checking condition expressions CASE, COALESCE, and IF. Used to reject
215+
// set-returning functions within conditional expressions.
216+
ConditionalAncestor
212217
)
213218

214219
// Push adds the given ancestor to s.
@@ -424,11 +429,8 @@ func (expr *CaseExpr) TypeCheck(
424429
ctx context.Context, semaCtx *SemaContext, desired *types.T,
425430
) (TypedExpr, error) {
426431
if semaCtx != nil {
427-
// We need to save and restore the previous value of the field in
428-
// semaCtx in case we are recursively called within a subquery
429-
// context.
430-
defer semaCtx.Properties.Restore(semaCtx.Properties)
431-
semaCtx.Properties.Require("CASE", RejectGenerators)
432+
defer semaCtx.Properties.Ancestors.PopTo(semaCtx.Properties.Ancestors)
433+
semaCtx.Properties.Ancestors.Push(ConditionalAncestor)
432434
}
433435
var err error
434436
tmpExprs := make([]Expr, 0, len(expr.Whens)+1)
@@ -877,11 +879,8 @@ func (expr *CoalesceExpr) TypeCheck(
877879
ctx context.Context, semaCtx *SemaContext, desired *types.T,
878880
) (TypedExpr, error) {
879881
if semaCtx != nil {
880-
// We need to save and restore the previous value of the field in
881-
// semaCtx in case we are recursively called within a subquery
882-
// context.
883-
defer semaCtx.Properties.Restore(semaCtx.Properties)
884-
semaCtx.Properties.Require("COALESCE", RejectGenerators)
882+
defer semaCtx.Properties.Ancestors.PopTo(semaCtx.Properties.Ancestors)
883+
semaCtx.Properties.Ancestors.Push(ConditionalAncestor)
885884
}
886885
typedSubExprs, retType, err := typeCheckSameTypedExprs(ctx, semaCtx, desired, expr.Exprs...)
887886
if err != nil {
@@ -1029,6 +1028,9 @@ func (sc *SemaContext) checkFunctionUsage(expr *FuncExpr, def *ResolvedFunctionD
10291028
if sc.Properties.IsSet(RejectGenerators) {
10301029
return NewInvalidFunctionUsageError(GeneratorClass, sc.Properties.required.context)
10311030
}
1031+
if sc.Properties.Ancestors.Has(ConditionalAncestor) {
1032+
return NewInvalidFunctionUsageError(GeneratorClass, "conditional expressions")
1033+
}
10321034
sc.Properties.Derived.SeenGenerator = true
10331035
}
10341036
return nil
@@ -1355,11 +1357,8 @@ func (expr *IfExpr) TypeCheck(
13551357
ctx context.Context, semaCtx *SemaContext, desired *types.T,
13561358
) (TypedExpr, error) {
13571359
if semaCtx != nil {
1358-
// We need to save and restore the previous value of the field in
1359-
// semaCtx in case we are recursively called within a subquery
1360-
// context.
1361-
defer semaCtx.Properties.Restore(semaCtx.Properties)
1362-
semaCtx.Properties.Require("IF", RejectGenerators)
1360+
defer semaCtx.Properties.Ancestors.PopTo(semaCtx.Properties.Ancestors)
1361+
semaCtx.Properties.Ancestors.Push(ConditionalAncestor)
13631362
}
13641363
typedCond, err := typeCheckAndRequireBoolean(ctx, semaCtx, expr.Cond, "IF condition")
13651364
if err != nil {

0 commit comments

Comments
 (0)