Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/gen4_planner.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ func planHorizon(ctx *plancontext.PlanningContext, plan logicalPlan, in sqlparse
return nil, ctx.SemTable.NotSingleRouteErr
}
if isRoute && rb.isSingleShard() {
err = planSingleShardRoutePlan(node, rb)
err = planSingleRoutePlan(node, rb)
} else {
plan, err = planOrderByOnUnion(ctx, plan, node)
}
Expand Down
6 changes: 3 additions & 3 deletions go/vt/vtgate/planbuilder/horizon_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (hp *horizonPlanning) planHorizon(ctx *plancontext.PlanningContext, plan lo
}

if isRoute && rb.isSingleShard() {
err := planSingleShardRoutePlan(hp.sel, rb)
err := planSingleRoutePlan(hp.sel, rb)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -88,7 +88,7 @@ func (hp *horizonPlanning) planHorizon(ctx *plancontext.PlanningContext, plan lo
// if we already did sorting, we don't need to do it again
needsOrdering = needsOrdering && !hp.qp.CanPushDownSorting
case canShortcut:
err = planSingleShardRoutePlan(hp.sel, rb)
err = planSingleRoutePlan(hp.sel, rb)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1097,7 +1097,7 @@ func exprHasVindex(semTable *semantics.SemTable, expr sqlparser.Expr, hasToBeUni
return false
}

func planSingleShardRoutePlan(sel sqlparser.SelectStatement, rb *routeGen4) error {
func planSingleRoutePlan(sel sqlparser.SelectStatement, rb *routeGen4) error {
err := stripDownQuery(sel, rb.Select)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operator_transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func transformHorizon(ctx *plancontext.PlanningContext, op *operators.Horizon, i
}
var plan logicalPlan
if isRoute && rb.isSingleShard() {
err = planSingleShardRoutePlan(node, rb)
err = planSingleRoutePlan(node, rb)
plan = rb
} else {
plan, err = planOrderByOnUnion(ctx, source, node)
Expand Down
43 changes: 34 additions & 9 deletions go/vt/vtgate/planbuilder/operators/horizon_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,25 @@ limitations under the License.
package operators

import (
"vitess.io/vitess/go/vt/sqlparser"
"vitess.io/vitess/go/vt/vterrors"
"vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite"
"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"

"vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops"
)

var errNotHorizonPlanned = vterrors.VT12001("query cannot be fully operator planned")

func planHorizons(in ops.Operator) (ops.Operator, error) {
func planHorizons(ctx *plancontext.PlanningContext, in ops.Operator) (ops.Operator, error) {
return rewrite.TopDown(in, func(in ops.Operator) (ops.Operator, rewrite.TreeIdentity, rewrite.VisitRule, error) {
switch in := in.(type) {
case *Horizon:
op, err := planHorizon(in)
op, visit, err := planHorizon(ctx, in)
if err != nil {
return nil, rewrite.SameTree, rewrite.SkipChildren, err
}
return op, rewrite.NewTree, rewrite.VisitChildren, nil
return op, rewrite.NewTree, visit, nil
case *Route:
return in, rewrite.SameTree, rewrite.SkipChildren, nil
default:
Expand All @@ -42,18 +44,41 @@ func planHorizons(in ops.Operator) (ops.Operator, error) {
})
}

func planHorizon(in *Horizon) (ops.Operator, error) {
func planHorizon(ctx *plancontext.PlanningContext, in *Horizon) (ops.Operator, rewrite.VisitRule, error) {
rb, isRoute := in.Source.(*Route)
if !isRoute {
return in, nil
return in, rewrite.VisitChildren, nil
}
if isRoute && rb.IsSingleShard() && in.Select.GetLimit() == nil {
return planSingleShardRoute(rb, in)
return planSingleRoute(rb, in)
}

return nil, errNotHorizonPlanned
sel, isSel := in.Select.(*sqlparser.Select)
if !isSel {
return nil, rewrite.VisitChildren, errNotHorizonPlanned
}

qp, err := CreateQPFromSelect(ctx, sel)
if err != nil {
return nil, rewrite.VisitChildren, err
}

needsOrdering := len(qp.OrderExprs) > 0
canShortcut := isRoute && sel.Having == nil && !needsOrdering

// If we still have a HAVING clause, it's because it could not be pushed to the WHERE,
// so it probably has aggregations
switch {
case qp.NeedsAggregation() || sel.Having != nil:
return nil, rewrite.VisitChildren, errNotHorizonPlanned
case canShortcut && !needsOrdering && !qp.NeedsDistinct() && in.Select.GetLimit() == nil:
return planSingleRoute(rb, in)
default:
return nil, rewrite.VisitChildren, errNotHorizonPlanned
}
Comment thread
frouioui marked this conversation as resolved.
Outdated
}
func planSingleShardRoute(rb *Route, horizon *Horizon) (ops.Operator, error) {

func planSingleRoute(rb *Route, horizon *Horizon) (ops.Operator, rewrite.VisitRule, error) {
rb.Source, horizon.Source = horizon, rb.Source
return rb, nil
return rb, rewrite.SkipChildren, nil
}
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func PlanQuery(ctx *plancontext.PlanningContext, selStmt sqlparser.Statement) (o

backup := Clone(op)

op, err = planHorizons(op)
op, err = planHorizons(ctx, op)
if err == errNotHorizonPlanned {
op = backup
} else if err != nil {
Expand Down