Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release-22.1: opt: project required ordering for EXPLAIN to input columns #88686

Merged
merged 1 commit into from
Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/explain
Original file line number Diff line number Diff line change
Expand Up @@ -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
88 changes: 55 additions & 33 deletions pkg/sql/opt/ordering/statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
}