diff --git a/pkg/sql/logictest/testdata/logic_test/explain b/pkg/sql/logictest/testdata/logic_test/explain index 163b23b89f1e..347bc23239c9 100644 --- a/pkg/sql/logictest/testdata/logic_test/explain +++ b/pkg/sql/logictest/testdata/logic_test/explain @@ -22,3 +22,36 @@ Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJyUUF9L6zAUf7-fI # needed to make the physical plan is rejected. See #40677. statement error running EXPLAIN \(DISTSQL\) on this query is unsupported because of the presence of subqueries EXPLAIN (DISTSQL) SELECT avg(a) OVER (ROWS (SELECT count(*) FROM t) PRECEDING) FROM t + +# Regression test for #88037 - don't require an ordering on non-output columns +# from the enclosed expression of an EXPLAIN. +statement ok +CREATE TABLE t88037 AS +SELECT g, g % 2 = 1 AS _bool, '0.0.0.0'::INET + g AS _inet +FROM generate_series(1, 5) AS g; + +query T +SELECT info FROM [ + EXPLAIN + SELECT NULL AS col_1372 + FROM t88037@[0] AS tab_489 + WHERE tab_489._bool + ORDER BY tab_489._inet, tab_489._bool ASC + LIMIT 92:::INT8 +] WHERE info NOT LIKE 'vectorized%' +---- +distribution: local +· +• render +│ +└── • top-k + │ order: +_inet + │ k: 92 + │ + └── • filter + │ filter: _bool + │ + └── • scan + missing stats + table: t88037@t88037_pkey + spans: FULL SCAN diff --git a/pkg/sql/opt/ordering/statement.go b/pkg/sql/opt/ordering/statement.go index 57b1e73a126e..aad679d5977e 100644 --- a/pkg/sql/opt/ordering/statement.go +++ b/pkg/sql/opt/ordering/statement.go @@ -13,82 +13,104 @@ package ordering import ( "github.com/cockroachdb/cockroach/pkg/sql/opt/memo" "github.com/cockroachdb/cockroach/pkg/sql/opt/props" + "github.com/cockroachdb/errors" ) +// statementBuildChildReqOrdering removes columns from the ordering that are not +// returned by the expression enclosed by the current statement. If this is not +// possible, statementBuildChildReqOrdering panics. +func statementBuildChildReqOrdering( + statement memo.RelExpr, childIdx int, ordering props.OrderingChoice, +) props.OrderingChoice { + if childIdx != 0 { + return props.OrderingChoice{} + } + child := statement.Child(0).(memo.RelExpr) + childCols := child.Relational().OutputCols + if ordering.SubsetOfCols(childCols) { + return ordering + } + if !ordering.CanProjectCols(childCols) { + panic(errors.AssertionFailedf( + "%s ordering %s requires non-output cols from %s", + statement.Op(), + ordering.String(), + child.Op(), + )) + } + projectedOrdering := ordering.Copy() + projectedOrdering.ProjectCols(childCols) + return projectedOrdering +} + func explainBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - return parent.(*memo.ExplainExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.ExplainExpr).Props.Ordering, + ) } func alterTableSplitBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - if childIdx != 0 { - return props.OrderingChoice{} - } - return parent.(*memo.AlterTableSplitExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.AlterTableSplitExpr).Props.Ordering, + ) } func alterTableUnsplitBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - if childIdx != 0 { - return props.OrderingChoice{} - } - return parent.(*memo.AlterTableUnsplitExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.AlterTableUnsplitExpr).Props.Ordering, + ) } func alterTableRelocateBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - if childIdx != 0 { - return props.OrderingChoice{} - } - return parent.(*memo.AlterTableRelocateExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.AlterTableRelocateExpr).Props.Ordering, + ) } func alterRangeRelocateBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - if childIdx != 0 { - return props.OrderingChoice{} - } - return parent.(*memo.AlterRangeRelocateExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.AlterRangeRelocateExpr).Props.Ordering, + ) } func controlJobsBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - if childIdx != 0 { - return props.OrderingChoice{} - } - return parent.(*memo.ControlJobsExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.ControlJobsExpr).Props.Ordering, + ) } func cancelQueriesBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - if childIdx != 0 { - return props.OrderingChoice{} - } - return parent.(*memo.CancelQueriesExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.CancelQueriesExpr).Props.Ordering, + ) } func cancelSessionsBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - if childIdx != 0 { - return props.OrderingChoice{} - } - return parent.(*memo.CancelSessionsExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.CancelSessionsExpr).Props.Ordering, + ) } func exportBuildChildReqOrdering( parent memo.RelExpr, required *props.OrderingChoice, childIdx int, ) props.OrderingChoice { - if childIdx != 0 { - return props.OrderingChoice{} - } - return parent.(*memo.ExportExpr).Props.Ordering + return statementBuildChildReqOrdering( + parent, childIdx, parent.(*memo.ExportExpr).Props.Ordering, + ) }