Skip to content

Commit

Permalink
refactor: change the planner to use the new AST
Browse files Browse the repository at this point in the history
Signed-off-by: Andres Taylor <andres@planetscale.com>
  • Loading branch information
systay committed Jan 13, 2025
1 parent 39ef5fb commit 37ac77f
Show file tree
Hide file tree
Showing 21 changed files with 91 additions and 61 deletions.
2 changes: 1 addition & 1 deletion go/vt/schemadiff/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,6 @@ func (c *CreateViewEntity) identicalOtherThanName(other *CreateViewEntity) bool
c.IsReplace == other.IsReplace &&
sqlparser.Equals.RefOfDefiner(c.Definer, other.Definer) &&
sqlparser.Equals.Columns(c.Columns, other.Columns) &&
sqlparser.Equals.SelectStatement(c.Select, other.Select) &&
sqlparser.Equals.Statement(c.Select, other.Select) &&
sqlparser.Equals.RefOfParsedComments(c.Comments, other.Comments)
}
8 changes: 6 additions & 2 deletions go/vt/sqlparser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ type (
SetWith(with *With)
}

Distinctable interface {
MakeDistinct()
IsDistinct() bool
}

// SelectStatement any SELECT statement.
SelectStatement interface {
Statement
Expand All @@ -90,12 +95,11 @@ type (
Commented
ColumnResults
Withable
Distinctable
iSelectStatement()
GetLock() Lock
SetLock(lock Lock)
SetInto(into *SelectInto)
MakeDistinct()
IsDistinct() bool
}

// DDLStatement represents any DDL Statement
Expand Down
2 changes: 1 addition & 1 deletion go/vt/sqlparser/ast_rewriting.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ func (er *astRewriter) existsRewrite(cursor *Cursor, node *ExistsExpr) {
sel.GroupBy = nil
}

// rewriteDistinctableAggr removed Distinct from Max and Min Aggregations as it does not impact the result. But, makes the plan simpler.
// rewriteDistinctableAggr removed Distinctable from Max and Min Aggregations as it does not impact the result. But, makes the plan simpler.
func (er *astRewriter) rewriteDistinctableAggr(cursor *Cursor, node DistinctableAggr) {
if !node.IsDistinct() {
return
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func buildCreateViewCommon(
vschema plancontext.VSchema,
reservedVars *sqlparser.ReservedVars,
cfg dynamicconfig.DDL,
ddlSelect sqlparser.SelectStatement,
ddlSelect sqlparser.TableSubquery,
ddl sqlparser.DDLStatement,
) (key.Destination, *vindexes.Keyspace, error) {
// For Create View, we require that the keyspace exist and the select query can be satisfied within the keyspace itself
Expand Down
26 changes: 17 additions & 9 deletions go/vt/vtgate/planbuilder/operators/SQL_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ type (
}
)

func (qb *queryBuilder) asSelectStatement() sqlparser.SelectStatement {
return qb.stmt.(sqlparser.SelectStatement)
func (qb *queryBuilder) asSelectStatement() sqlparser.TableSubquery {
return qb.stmt.(sqlparser.TableSubquery)

}
func (qb *queryBuilder) asOrderAndLimit() sqlparser.OrderAndLimit {
return qb.stmt.(sqlparser.OrderAndLimit)
Expand Down Expand Up @@ -191,7 +192,8 @@ func (qb *queryBuilder) pushUnionInsideDerived() {
As: sqlparser.NewIdentifierCS("dt"),
}},
}
sel.SelectExprs = unionSelects(sqlparser.GetFirstSelect(selStmt).SelectExprs)
firstSelect := getFirstSelect(selStmt)
sel.SelectExprs = unionSelects(firstSelect.SelectExprs)
qb.stmt = sel
}

Expand All @@ -208,9 +210,10 @@ func unionSelects(exprs sqlparser.SelectExprs) (selectExprs sqlparser.SelectExpr
return
}

func checkUnionColumnByName(column *sqlparser.ColName, sel sqlparser.SelectStatement) {
func checkUnionColumnByName(column *sqlparser.ColName, sel sqlparser.TableSubquery) {
colName := column.Name.String()
exprs := sqlparser.GetFirstSelect(sel).SelectExprs
firstSelect := getFirstSelect(sel)
exprs := firstSelect.SelectExprs
offset := slices.IndexFunc(exprs, func(expr sqlparser.SelectExpr) bool {
switch ae := expr.(type) {
case *sqlparser.StarExpr:
Expand Down Expand Up @@ -244,8 +247,8 @@ func (qb *queryBuilder) unionWith(other *queryBuilder, distinct bool) {

func (qb *queryBuilder) recursiveCteWith(other *queryBuilder, name, alias string, distinct bool, columns sqlparser.Columns) {
cteUnion := &sqlparser.Union{
Left: qb.stmt.(sqlparser.SelectStatement),
Right: other.stmt.(sqlparser.SelectStatement),
Left: qb.stmt.(sqlparser.TableSubquery),
Right: other.stmt.(sqlparser.TableSubquery),
Distinct: distinct,
}

Expand Down Expand Up @@ -393,7 +396,7 @@ func removeKeyspaceFromSelectExpr(expr sqlparser.SelectExpr) {
}
}

func stripDownQuery(from, to sqlparser.SelectStatement) {
func stripDownQuery(from, to sqlparser.TableSubquery) {
switch node := from.(type) {
case *sqlparser.Select:
toNode, ok := to.(*sqlparser.Select)
Expand Down Expand Up @@ -450,7 +453,12 @@ func buildQuery(op Operator, qb *queryBuilder) {
buildUnion(op, qb)
case *Distinct:
buildQuery(op.Source, qb)
qb.asSelectStatement().MakeDistinct()
statement := qb.asSelectStatement()
d, ok := statement.(sqlparser.Distinctable)
if !ok {
panic(vterrors.VT13001("expected a select statement with distinct"))
}
d.MakeDistinct()
case *Update:
buildUpdate(op, qb)
case *Delete:
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/aggregation_pushing.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ func splitAggrColumnsToLeftAndRight(

canPushDistinctAggr, distinctExprs := checkIfWeCanPush(ctx, aggregator)

// Distinct aggregation cannot be pushed down in the join.
// Distinctable aggregation cannot be pushed down in the join.
// We keep node of the distinct aggregation expression to be used later for ordering.
if !canPushDistinctAggr {
if len(distinctExprs) != 1 {
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/ast_to_op.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func createOperatorFromUnion(ctx *plancontext.PlanningContext, node *sqlparser.U
return newHorizon(union, node)
}

func translateQueryToOpForUnion(ctx *plancontext.PlanningContext, node sqlparser.SelectStatement) Operator {
func translateQueryToOpForUnion(ctx *plancontext.PlanningContext, node sqlparser.TableSubquery) Operator {
op := translateQueryToOp(ctx, node)
if hz, ok := op.(*Horizon); ok {
hz.Truncate = true
Expand Down
11 changes: 11 additions & 0 deletions go/vt/vtgate/planbuilder/operators/expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ limitations under the License.
package operators

import (
"fmt"

"vitess.io/vitess/go/vt/sqlparser"
"vitess.io/vitess/go/vt/vterrors"
"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
"vitess.io/vitess/go/vt/vtgate/semantics"
)
Expand Down Expand Up @@ -121,3 +124,11 @@ func simplifyPredicates(ctx *plancontext.PlanningContext, in sqlparser.Expr) sql
}
return output
}

func getFirstSelect(selStmt sqlparser.TableSubquery) *sqlparser.Select {
firstSelect, err := sqlparser.GetFirstSelect(selStmt)
if err != nil {
panic(vterrors.VT12001(fmt.Sprintf("first UNION part not a SELECT: %v", err)))
}
return firstSelect
}
10 changes: 5 additions & 5 deletions go/vt/vtgate/planbuilder/operators/horizon.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Horizon struct {
// QP contains the QueryProjection for this op
QP *QueryProjection

Query sqlparser.SelectStatement
Query sqlparser.TableSubquery

// Columns needed to feed other plans
Columns []*sqlparser.ColName
Expand All @@ -54,7 +54,7 @@ type Horizon struct {
Truncate bool
}

func newHorizon(src Operator, query sqlparser.SelectStatement) *Horizon {
func newHorizon(src Operator, query sqlparser.TableSubquery) *Horizon {
return &Horizon{
unaryOperator: newUnaryOp(src),
Query: query,
Expand Down Expand Up @@ -148,7 +148,7 @@ func (h *Horizon) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr,
return -1
}

for idx, se := range sqlparser.GetFirstSelect(h.Query).SelectExprs {
for idx, se := range getFirstSelect(h.Query).SelectExprs {
ae, ok := se.(*sqlparser.AliasedExpr)
if !ok {
panic(vterrors.VT09015())
Expand All @@ -174,7 +174,7 @@ func (h *Horizon) GetColumns(ctx *plancontext.PlanningContext) (exprs []*sqlpars
}

func (h *Horizon) GetSelectExprs(*plancontext.PlanningContext) sqlparser.SelectExprs {
return sqlparser.GetFirstSelect(h.Query).SelectExprs
return getFirstSelect(h.Query).SelectExprs
}

func (h *Horizon) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy {
Expand All @@ -185,7 +185,7 @@ func (h *Horizon) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy {
}

// TODO: REMOVE
func (h *Horizon) selectStatement() sqlparser.SelectStatement {
func (h *Horizon) selectStatement() sqlparser.TableSubquery {
return h.Query
}

Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/horizon_expanding.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel

if qp.NeedsDistinct() {
op = newDistinct(op, qp, true)
extracted = append(extracted, "Distinct")
extracted = append(extracted, "Distinctable")
}

if sel.Having != nil {
Expand Down
8 changes: 4 additions & 4 deletions go/vt/vtgate/planbuilder/operators/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ func createInsertOperator(ctx *plancontext.PlanningContext, insStmt *sqlparser.I
case sqlparser.Values:
op = route
route.Source = insertRowsPlan(ctx, insOp, insStmt, rows)
case sqlparser.SelectStatement:
case sqlparser.TableSubquery:
op = insertSelectPlan(ctx, insOp, route, insStmt, rows)
}
if insStmt.Comments != nil {
Expand All @@ -408,7 +408,7 @@ func insertSelectPlan(
insOp *Insert,
routeOp *Route,
ins *sqlparser.Insert,
sel sqlparser.SelectStatement,
sel sqlparser.TableSubquery,
) *InsertSelection {
if columnMismatch(insOp.AutoIncrement, ins, sel) {
panic(vterrors.VT03006())
Expand Down Expand Up @@ -457,7 +457,7 @@ func insertSelectPlan(
return insertSelect
}

func columnMismatch(gen *Generate, ins *sqlparser.Insert, sel sqlparser.SelectStatement) bool {
func columnMismatch(gen *Generate, ins *sqlparser.Insert, sel sqlparser.TableSubquery) bool {
origColCount := len(ins.Columns)
if gen != nil && gen.added {
// One column got added to the insert query ast for auto increment column.
Expand All @@ -468,7 +468,7 @@ func columnMismatch(gen *Generate, ins *sqlparser.Insert, sel sqlparser.SelectSt
return true
}
if origColCount > sel.GetColumnCount() {
sel := sqlparser.GetFirstSelect(sel)
sel := getFirstSelect(sel)
var hasStarExpr bool
for _, sExpr := range sel.SelectExprs {
if _, hasStarExpr = sExpr.(*sqlparser.StarExpr); hasStarExpr {
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/phases.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (p Phase) String() string {
case addAggrOrdering:
return "optimize aggregations with ORDER BY"
case cleanOutPerfDistinct:
return "optimize Distinct operations"
return "optimize Distinctable operations"
case subquerySettling:
return "settle subqueries"
case dmlWithInput:
Expand Down
13 changes: 10 additions & 3 deletions go/vt/vtgate/planbuilder/operators/query_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (
func planQuery(ctx *plancontext.PlanningContext, root Operator) Operator {
var selExpr sqlparser.SelectExprs
if horizon, isHorizon := root.(*Horizon); isHorizon {
sel := sqlparser.GetFirstSelect(horizon.Query)
sel := getFirstSelect(horizon.Query)
selExpr = sqlparser.Clone(sel.SelectExprs)
}

Expand Down Expand Up @@ -207,7 +207,7 @@ func pushOrExpandHorizon(ctx *plancontext.PlanningContext, in *Horizon) (Operato
!hasHaving &&
!needsOrdering &&
!qp.NeedsAggregation() &&
!in.selectStatement().IsDistinct() &&
!isDistinctAST(in.selectStatement()) &&
in.selectStatement().GetLimit() == nil

if canPush {
Expand Down Expand Up @@ -784,14 +784,21 @@ func isDistinct(op Operator) bool {
case *Union:
return op.distinct
case *Horizon:
return op.Query.IsDistinct()
return isDistinctAST(op.Query)
case *Limit:
return isDistinct(op.Source)
default:
return false
}
}

func isDistinctAST(s sqlparser.Statement) bool {
if d, ok := s.(sqlparser.Distinctable); ok {
return d.IsDistinct()
}
return false
}

func tryPushUnion(ctx *plancontext.PlanningContext, op *Union) (Operator, *ApplyResult) {
if res := compactUnion(op); res != NoRewrite {
return op, res
Expand Down
4 changes: 2 additions & 2 deletions go/vt/vtgate/planbuilder/operators/queryprojection.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (qp *QueryProjection) addSelectExpressions(ctx *plancontext.PlanningContext
func createQPFromUnion(ctx *plancontext.PlanningContext, union *sqlparser.Union) *QueryProjection {
qp := &QueryProjection{}

sel := sqlparser.GetFirstSelect(union)
sel := getFirstSelect(union)
qp.addSelectExpressions(ctx, sel)
qp.addOrderBy(ctx, union.OrderBy)

Expand Down Expand Up @@ -714,7 +714,7 @@ func CompareRefInt(a *int, b *int) bool {
return *a < *b
}

func CreateQPFromSelectStatement(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement) *QueryProjection {
func CreateQPFromSelectStatement(ctx *plancontext.PlanningContext, stmt sqlparser.TableSubquery) *QueryProjection {
switch sel := stmt.(type) {
case *sqlparser.Select:
return createQPFromSelect(ctx, sel)
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/subquery_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func createSubqueryOp(
// inspectStatement goes through all the predicates contained in the AST
// and extracts subqueries into operators
func (sqb *SubQueryBuilder) inspectStatement(ctx *plancontext.PlanningContext,
stmt sqlparser.SelectStatement,
stmt sqlparser.TableSubquery,
) (sqlparser.Exprs, []applyJoinColumn) {
switch stmt := stmt.(type) {
case *sqlparser.Select:
Expand Down
6 changes: 3 additions & 3 deletions go/vt/vtgate/planbuilder/operators/subquery_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
"vitess.io/vitess/go/vt/vtgate/semantics"
)

func isMergeable(ctx *plancontext.PlanningContext, query sqlparser.SelectStatement, op Operator) bool {
func isMergeable(ctx *plancontext.PlanningContext, query sqlparser.TableSubquery, op Operator) bool {
validVindex := func(expr sqlparser.Expr) bool {
sc := findColumnVindex(ctx, op, expr)
return sc != nil && sc.IsUnique()
Expand Down Expand Up @@ -672,7 +672,7 @@ func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningCont
if err != nil {
panic(err)
}
subqStmt, ok := stmt.(sqlparser.SelectStatement)
subqStmt, ok := stmt.(sqlparser.TableSubquery)
if !ok {
panic(vterrors.VT13001("subqueries should only be select statement"))
}
Expand Down Expand Up @@ -700,7 +700,7 @@ func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningCont
if !deps.IsSolvedBy(subqID) {
cursor.Replace(exprFound)
}
}, nil).(sqlparser.SelectStatement)
}, nil).(sqlparser.TableSubquery)
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/union.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (u *Union) GetSelectFor(source int) *sqlparser.Select {
for {
switch op := src.(type) {
case *Horizon:
return sqlparser.GetFirstSelect(op.Query)
return getFirstSelect(op.Query)
case *Route:
src = op.Source
default:
Expand Down
Loading

0 comments on commit 37ac77f

Please sign in to comment.