Skip to content

Commit b3a90bd

Browse files
committed
sql: disallow aggregate functions in ORDER BY in DELETE and UPDATE
This commit disallows aggregate functions in the context of an `ORDER BY` clause in a `DELETE` or `UPDATE` statement. An aggregate function in an `ORDER BY` would require a `GROUP BY` clause to group non-aggregate columns. A `GROUP BY` is not allowed in `DELETE` or `UPDATE` statements as it's not obvious how grouping in these statements would behave. So we simply disallow aggregates in `ORDER BY` instead. Fixes cockroachdb#107634 Release note (bug fix): A bug has been fixed that caused internal errors when using an aggregate function in an `ORDER BY` clause of a `DELETE` or `UPDATE` statement. Aggregate functions are no longer allowed in these contexts. The bug has been present since at least version 20.2.
1 parent 9db3a0e commit b3a90bd

File tree

8 files changed

+52
-7
lines changed

8 files changed

+52
-7
lines changed

pkg/sql/logictest/testdata/logic_test/delete

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,3 +565,14 @@ false
565565
query I
566566
SELECT a FROM t99630a@idx WHERE a > 0
567567
----
568+
569+
# Regression test for #107634. Do not allow aggregate functions in ORDER BY.
570+
subtest regression_107634
571+
572+
statement ok
573+
CREATE TABLE t107634 (a INT)
574+
575+
statement error pgcode 42803 sum\(\): aggregate functions are not allowed in ORDER BY in DELETE
576+
DELETE FROM t107634 ORDER BY sum(a) LIMIT 1;
577+
578+
subtest end

pkg/sql/logictest/testdata/logic_test/update

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,3 +661,14 @@ SELECT * FROM generated_as_id_t ORDER BY a;
661661
7 4 4
662662
8 5 5
663663
9 6 6
664+
665+
# Regression test for #107634. Do not allow aggregate functions in ORDER BY.
666+
subtest regression_107634
667+
668+
statement ok
669+
CREATE TABLE t107634 (a INT)
670+
671+
statement error pgcode 42803 sum\(\): aggregate functions are not allowed in ORDER BY in UPDATE
672+
UPDATE t107634 SET a = 1 ORDER BY sum(a) LIMIT 1;
673+
674+
subtest end

pkg/sql/opt/optbuilder/mutation_builder.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ func (mb *mutationBuilder) buildInputForUpdate(
336336
// SELECT + ORDER BY (which may add projected expressions)
337337
projectionsScope := mb.outScope.replace()
338338
projectionsScope.appendColumnsFromScope(mb.outScope)
339-
orderByScope := mb.b.analyzeOrderBy(orderBy, mb.outScope, projectionsScope, tree.RejectGenerators)
339+
orderByScope := mb.b.analyzeOrderBy(orderBy, mb.outScope, projectionsScope,
340+
exprKindOrderByUpdate, tree.RejectGenerators|tree.RejectAggregates)
340341
mb.b.buildOrderBy(mb.outScope, projectionsScope, orderByScope)
341342
mb.b.constructProjectForScope(mb.outScope, projectionsScope)
342343

@@ -448,7 +449,8 @@ func (mb *mutationBuilder) buildInputForDelete(
448449
// SELECT + ORDER BY (which may add projected expressions)
449450
projectionsScope := mb.outScope.replace()
450451
projectionsScope.appendColumnsFromScope(mb.outScope)
451-
orderByScope := mb.b.analyzeOrderBy(orderBy, mb.outScope, projectionsScope, tree.RejectGenerators)
452+
orderByScope := mb.b.analyzeOrderBy(orderBy, mb.outScope, projectionsScope,
453+
exprKindOrderByDelete, tree.RejectGenerators|tree.RejectAggregates)
452454
mb.b.buildOrderBy(mb.outScope, projectionsScope, orderByScope)
453455
mb.b.constructProjectForScope(mb.outScope, projectionsScope)
454456

pkg/sql/opt/optbuilder/orderby.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ import (
2828
// analyzeOrderBy analyzes an Ordering physical property from the ORDER BY
2929
// clause and adds the resulting typed expressions to orderByScope.
3030
func (b *Builder) analyzeOrderBy(
31-
orderBy tree.OrderBy, inScope, projectionsScope *scope, rejectFlags tree.SemaRejectFlags,
31+
orderBy tree.OrderBy,
32+
inScope, projectionsScope *scope,
33+
kind exprKind,
34+
rejectFlags tree.SemaRejectFlags,
3235
) (orderByScope *scope) {
3336
if orderBy == nil {
3437
return nil
@@ -41,8 +44,8 @@ func (b *Builder) analyzeOrderBy(
4144
// semaCtx in case we are recursively called within a subquery
4245
// context.
4346
defer b.semaCtx.Properties.Restore(b.semaCtx.Properties)
44-
b.semaCtx.Properties.Require(exprKindOrderBy.String(), rejectFlags)
45-
inScope.context = exprKindOrderBy
47+
b.semaCtx.Properties.Require(kind.String(), rejectFlags)
48+
inScope.context = kind
4649

4750
for i := range orderBy {
4851
b.analyzeOrderByArg(orderBy[i], inScope, projectionsScope, orderByScope)

pkg/sql/opt/optbuilder/scope.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ const (
132132
exprKindOffset
133133
exprKindOn
134134
exprKindOrderBy
135+
exprKindOrderByDelete
136+
exprKindOrderByUpdate
135137
exprKindReturning
136138
exprKindSelect
137139
exprKindStoreID
@@ -153,6 +155,8 @@ var exprKindName = [...]string{
153155
exprKindOffset: "OFFSET",
154156
exprKindOn: "ON",
155157
exprKindOrderBy: "ORDER BY",
158+
exprKindOrderByDelete: "ORDER BY in DELETE",
159+
exprKindOrderByUpdate: "ORDER BY in UPDATE",
156160
exprKindReturning: "RETURNING",
157161
exprKindSelect: "SELECT",
158162
exprKindStoreID: "RELOCATE STORE ID",

pkg/sql/opt/optbuilder/select.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,8 @@ func (b *Builder) buildSelectStmtWithoutParens(
11061106
col := projectionsScope.addColumn(scopeColName(""), expr)
11071107
b.buildScalar(expr, outScope, projectionsScope, col, nil)
11081108
}
1109-
orderByScope := b.analyzeOrderBy(orderBy, outScope, projectionsScope, tree.RejectGenerators|tree.RejectAggregates|tree.RejectWindowApplications)
1109+
orderByScope := b.analyzeOrderBy(orderBy, outScope, projectionsScope, exprKindOrderBy,
1110+
tree.RejectGenerators|tree.RejectAggregates|tree.RejectWindowApplications)
11101111
b.buildOrderBy(outScope, projectionsScope, orderByScope)
11111112
b.constructProjectForScope(outScope, projectionsScope)
11121113
outScope = projectionsScope
@@ -1151,7 +1152,8 @@ func (b *Builder) buildSelectClause(
11511152
// Any aggregates in the HAVING, ORDER BY and DISTINCT ON clauses (if they
11521153
// exist) will be added here.
11531154
havingExpr := b.analyzeHaving(sel.Having, fromScope)
1154-
orderByScope := b.analyzeOrderBy(orderBy, fromScope, projectionsScope, tree.RejectGenerators)
1155+
orderByScope := b.analyzeOrderBy(orderBy, fromScope, projectionsScope,
1156+
exprKindOrderBy, tree.RejectGenerators)
11551157
distinctOnScope := b.analyzeDistinctOnArgs(sel.DistinctOn, fromScope, projectionsScope)
11561158

11571159
var having opt.ScalarExpr

pkg/sql/opt/optbuilder/testdata/delete

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ DELETE FROM abcde WHERE b=1 ORDER BY c
299299
----
300300
error (42601): DELETE statement requires LIMIT when ORDER BY is used
301301

302+
# Aggregate functions are not allowed in ORDER BY.
303+
build
304+
DELETE FROM abcde WHERE b=1 ORDER BY sum(c) LIMIT 1
305+
----
306+
error (42803): sum(): aggregate functions are not allowed in ORDER BY in DELETE
307+
302308
# ------------------------------------------------------------------------------
303309
# Test RETURNING.
304310
# ------------------------------------------------------------------------------

pkg/sql/opt/optbuilder/testdata/update

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,12 @@ UPDATE abcde SET b=1 ORDER BY c
617617
----
618618
error (42601): UPDATE statement requires LIMIT when ORDER BY is used
619619

620+
# Aggregate functions are not allowed in ORDER BY.
621+
build
622+
UPDATE abcde SET b=1 ORDER BY sum(c) LIMIT 1
623+
----
624+
error (42803): sum(): aggregate functions are not allowed in ORDER BY in UPDATE
625+
620626
# ------------------------------------------------------------------------------
621627
# Test RETURNING.
622628
# ------------------------------------------------------------------------------

0 commit comments

Comments
 (0)