diff --git a/pkg/sql/opt/ordering/project.go b/pkg/sql/opt/ordering/project.go index 3a87400f2bb8..927c8dacf779 100644 --- a/pkg/sql/opt/ordering/project.go +++ b/pkg/sql/opt/ordering/project.go @@ -22,18 +22,15 @@ func projectCanProvideOrdering(expr memo.RelExpr, required *physical.OrderingCho proj := expr.(*memo.ProjectExpr) inputCols := proj.Input.Relational().OutputCols - if required.CanProjectCols(inputCols) { - return true - } - - // We may be able to "remap" columns using the internal FD set. - if fdSet := proj.InternalFDs(); required.CanSimplify(fdSet) { - simplified := required.Copy() + // Use a simplified ordering if it exists. This must be kept consistent with + // projectBuildChildReqOrdering, which always simplifies the ordering if + // possible. + simplified := *required + if fdSet := proj.InternalFDs(); simplified.CanSimplify(fdSet) { + simplified = required.Copy() simplified.Simplify(fdSet) - return simplified.CanProjectCols(inputCols) } - - return false + return simplified.CanProjectCols(inputCols) } func projectBuildChildReqOrdering( diff --git a/pkg/sql/opt/ordering/project_test.go b/pkg/sql/opt/ordering/project_test.go index 73f043765856..7001bbb65b03 100644 --- a/pkg/sql/opt/ordering/project_test.go +++ b/pkg/sql/opt/ordering/project_test.go @@ -39,7 +39,7 @@ func TestProject(t *testing.T) { input := &testexpr.Instance{ Rel: &props.Relational{ - OutputCols: opt.MakeColSet(1, 2, 3, 4), + OutputCols: opt.MakeColSet(1, 2, 3, 4, 6), FuncDeps: fds, }, } @@ -73,6 +73,14 @@ func TestProject(t *testing.T) { req: "+5", exp: "no", }, + { + // Regression test for #64399. projectCanProvideOrdering should not + // return true when the columns remaining in the ordering after + // simplification cannot be provided. This causes + // projectBuildChildReqOrdering to panic. + req: "+(5|6)", + exp: "no", + }, } for _, tc := range testCases { req := physical.ParseOrderingChoice(tc.req)