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

Refactoring of plan building #7054

Merged
merged 11 commits into from
Nov 23, 2020
Merged

Conversation

systay
Copy link
Collaborator

@systay systay commented Nov 18, 2020

This is a rebased #7033

Today, in the planbuilding package, we have builders and a primitiveBuilder.

The primitive builder contains the current builder we are working on, the symtab, jointab and a context object that allows us to talk with the vschema during planning.

Part of the logic lives in static methods, such as buildSelectPlan et al, that create the primitive builder and control the flow during planning.
The other part of of the logic is spread out amongst the builders - methods such as PushFilter, PushSelect, MakeDistinct and others.

During planning, the current plan is represented by a tree of builders, that at the end of it all are turned into engine.Primitives.

I think we can design this so it becomes easier to understand and work with:

  • The builder interface is shock full of Liskov Substitution Principle problems - no implementor implements all interface methods. The structs implement the interface but most methods return an "not implemented" error.
  • When adding new functionality or working with a bug, we often consider one aspect across all builders - the bug is with DISTINCT, so we want to look at MakeDistinct(). Since we have 11 different builders, this means we have to jump around to a lot of files, and it's harder to get an overview of how DISTINCT is solved.
  • The PushFilter, MakeDistinct, PushSelect methods on the builder interface have very different signatures and behaviours - some change the builder in the primitiveBuilder, some return a new builder, and some are just mutating their own state.

This refactoring will try to address this by making the following changes:

  • Extract most methods from the builder structs - for example, all PushFilter logic will instead live in filtering.go in a single method. The methods that will be extracted are:
    • PushFilter
    • PushSelect
    • MakeDistinct
    • PushGroupBy
    • PushOrderBy
    • SetUpperLimit
    • PushMisc
    • PushLock
  • All extracted methods will take a primitiveBuilder and a builder as parameters (other params as needed by method), and return a builder.
  • After removing these methods from the builder interface, we can rename it to logicalPlan or something along those lines.

Introduce Inputs and Rewrite as a way to visit all nodes in the tree,
and used them to implement First and PushMisc outside the builders

Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Signed-off-by: Andres Taylor <andres@planetscale.com>
Comment on lines 68 to 74
case *mergeSort, *pulloutSubquery:
filteredInput, err := planFilter(pb, node.Inputs()[0], filter, whereType, origin)
if err != nil {
return nil, err
}
err = node.Rewrite(filteredInput)
return node, err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a test to cover this case

Comment on lines 93 to 94
case *join:
return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "unsupported: group by on cross-shard join")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a test to cover this case

Comment on lines 102 to 112
case *mergeSort, *pulloutSubquery:
inputs := node.Inputs()
input := inputs[0]

newInput, err := planDistinct(input)
if err != nil {
return nil, err
}
inputs[0] = newInput
node.Rewrite(inputs...)
return node, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a test to cover this case

Comment on lines 134 to 139
case *subquery:
return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "unsupported: distinct on cross-shard subquery")
case *concatenate:
return newDistinct(node), nil
case *join:
return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "unsupported: distinct on cross-shard join")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a test to cover these cases

Copy link
Contributor

@sougou sougou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is better than the old approach from the perspective of understanding how each SQL construct is handled. On the downside, it reduces the understanding of all the functionality that builds a primitive. A perfect code structure is not possible because we essentially have a matrix of primitives and AST constructs, and we have to provide code snippets for each of those.

However, if we have to make a choice, leaning towards grouping functions by the SQL construct (this new approach) feels better. So, I'm good with this.

Once review comments are addressed, you can push this forward.

Signed-off-by: Andres Taylor <andres@planetscale.com>
@systay systay merged commit faf2525 into vitessio:master Nov 23, 2020
@harshit-gangal harshit-gangal deleted the planner-refactor-2 branch November 23, 2020 10:17
@askdba askdba added this to the v9.0 milestone Nov 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants