Skip to content

Commit

Permalink
sql: implement ConstructPlan by new factory
Browse files Browse the repository at this point in the history
This commit extracts the logic of `execFactory.ConstructPlan` into the
function to be used by both factories. It also extracts out another
small helper.

Release note: None
  • Loading branch information
yuzefovich committed Jun 2, 2020
1 parent dc5e82a commit 1071544
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 50 deletions.
2 changes: 1 addition & 1 deletion pkg/sql/distsql_spec_exec_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (e *distSQLSpecExecFactory) RenameColumns(
func (e *distSQLSpecExecFactory) ConstructPlan(
root exec.Node, subqueries []exec.Subquery, cascades []exec.Cascade, checks []exec.Node,
) (exec.Plan, error) {
return nil, unimplemented.NewWithIssue(47473, "experimental opt-driven distsql planning")
return constructPlan(e.planner, root, subqueries, cascades, checks, false /* usesPlanNodeRepresentation */)
}

func (e *distSQLSpecExecFactory) ConstructExplainOpt(
Expand Down
78 changes: 78 additions & 0 deletions pkg/sql/exec_factory_util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package sql

import (
"github.com/cockroachdb/cockroach/pkg/sql/opt/exec"
"github.com/cockroachdb/cockroach/pkg/sql/rowexec"
"github.com/cockroachdb/errors"
)

func constructPlan(
planner *planner,
root exec.Node,
subqueries []exec.Subquery,
cascades []exec.Cascade,
checks []exec.Node,
usesPlanNodeRepresentation bool,
) (exec.Plan, error) {
res := &planTop{
// TODO(radu): these fields can be modified by planning various opaque
// statements. We should have a cleaner way of plumbing these.
avoidBuffering: planner.curPlan.avoidBuffering,
auditEvents: planner.curPlan.auditEvents,
instrumentation: planner.curPlan.instrumentation,
}
assignPlan := func(plan *planMaybePhysical, node exec.Node) {
if usesPlanNodeRepresentation {
plan.planNode = node.(planNode)
} else {
*plan = node.(planMaybePhysical)
}
}
assignPlan(&res.main, root)
if len(subqueries) > 0 {
res.subqueryPlans = make([]subquery, len(subqueries))
for i := range subqueries {
in := &subqueries[i]
out := &res.subqueryPlans[i]
out.subquery = in.ExprNode
switch in.Mode {
case exec.SubqueryExists:
out.execMode = rowexec.SubqueryExecModeExists
case exec.SubqueryOneRow:
out.execMode = rowexec.SubqueryExecModeOneRow
case exec.SubqueryAnyRows:
out.execMode = rowexec.SubqueryExecModeAllRowsNormalized
case exec.SubqueryAllRows:
out.execMode = rowexec.SubqueryExecModeAllRows
default:
return nil, errors.Errorf("invalid SubqueryMode %d", in.Mode)
}
out.expanded = true
assignPlan(&out.plan, in.Root)
}
}
if len(cascades) > 0 {
res.cascades = make([]cascadeMetadata, len(cascades))
for i := range cascades {
res.cascades[i].Cascade = cascades[i]
}
}
if len(checks) > 0 {
res.checkPlans = make([]checkPlan, len(checks))
for i := range checks {
assignPlan(&res.checkPlans[i].plan, checks[i])
}
}

return res, nil
}
52 changes: 3 additions & 49 deletions pkg/sql/opt_exec_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/opt/constraint"
"github.com/cockroachdb/cockroach/pkg/sql/opt/exec"
"github.com/cockroachdb/cockroach/pkg/sql/row"
"github.com/cockroachdb/cockroach/pkg/sql/rowexec"
"github.com/cockroachdb/cockroach/pkg/sql/sem/builtins"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/span"
Expand Down Expand Up @@ -131,10 +130,8 @@ func (ef *execFactory) ConstructScan(
scan.isFull = len(scan.spans) == 1 && scan.spans[0].EqualValue(
scan.desc.IndexSpan(ef.planner.ExecCfg().Codec, scan.index.ID),
)
for i := range reqOrdering {
if reqOrdering[i].ColIdx >= len(colCfg.wantedColumns) {
return nil, errors.Errorf("invalid reqOrdering: %v", reqOrdering)
}
if err = colCfg.assertValidReqOrdering(reqOrdering); err != nil {
return nil, err
}
scan.reqOrdering = ReqOrdering(reqOrdering)
scan.estimatedRowCount = uint64(rowCount)
Expand Down Expand Up @@ -1048,50 +1045,7 @@ func (ef *execFactory) ConstructPlan(
if spool, ok := root.(*spoolNode); ok {
root = spool.source
}
res := &planTop{
// TODO(radu): these fields can be modified by planning various opaque
// statements. We should have a cleaner way of plumbing these.
avoidBuffering: ef.planner.curPlan.avoidBuffering,
auditEvents: ef.planner.curPlan.auditEvents,
instrumentation: ef.planner.curPlan.instrumentation,
}
res.main.planNode = root.(planNode)
if len(subqueries) > 0 {
res.subqueryPlans = make([]subquery, len(subqueries))
for i := range subqueries {
in := &subqueries[i]
out := &res.subqueryPlans[i]
out.subquery = in.ExprNode
switch in.Mode {
case exec.SubqueryExists:
out.execMode = rowexec.SubqueryExecModeExists
case exec.SubqueryOneRow:
out.execMode = rowexec.SubqueryExecModeOneRow
case exec.SubqueryAnyRows:
out.execMode = rowexec.SubqueryExecModeAllRowsNormalized
case exec.SubqueryAllRows:
out.execMode = rowexec.SubqueryExecModeAllRows
default:
return nil, errors.Errorf("invalid SubqueryMode %d", in.Mode)
}
out.expanded = true
out.plan.planNode = in.Root.(planNode)
}
}
if len(cascades) > 0 {
res.cascades = make([]cascadeMetadata, len(cascades))
for i := range cascades {
res.cascades[i].Cascade = cascades[i]
}
}
if len(checks) > 0 {
res.checkPlans = make([]checkPlan, len(checks))
for i := range checks {
res.checkPlans[i].plan.planNode = checks[i].(planNode)
}
}

return res, nil
return constructPlan(ef.planner, root, subqueries, cascades, checks, true /* usesPlanNodeRepresentation */)
}

// urlOutputter handles writing strings into an encoded URL for EXPLAIN (OPT,
Expand Down
10 changes: 10 additions & 0 deletions pkg/sql/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/roachpb"
"github.com/cockroachdb/cockroach/pkg/sql/execinfra"
"github.com/cockroachdb/cockroach/pkg/sql/execinfrapb"
"github.com/cockroachdb/cockroach/pkg/sql/opt/exec"
"github.com/cockroachdb/cockroach/pkg/sql/privilege"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
Expand Down Expand Up @@ -133,6 +134,15 @@ type scanColumnsConfig struct {
visibility execinfrapb.ScanVisibility
}

func (cfg scanColumnsConfig) assertValidReqOrdering(reqOrdering exec.OutputOrdering) error {
for i := range reqOrdering {
if reqOrdering[i].ColIdx >= len(cfg.wantedColumns) {
return errors.Errorf("invalid reqOrdering: %v", reqOrdering)
}
}
return nil
}

var publicColumnsCfg = scanColumnsConfig{}

func (p *planner) Scan() *scanNode {
Expand Down

0 comments on commit 1071544

Please sign in to comment.