Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

sql: implement new API for node transformation #773

Merged
merged 1 commit into from
Jul 4, 2019

Conversation

erizocosmico
Copy link
Contributor

Close #772

Instead of having TransformUp and TransformExpressionsUp in each
node, which was really error prone, now we have a different API.

Each node will have a WithChildren method that will receive
the children from which a new node of the same type will be created.
These nodes must come in the same number and order as the ones
returned by the Children method.

Expressioner nodes will also have WithExpressions method, which is
the same, except it will create a new node with its expressions
changed, instead of the children nodes.

The plan package will expose 3 new helpers:

  • TransformUp: which transforms a node from the bottom-up.
  • TransformExpressionsUp: which transforms expressions of a node from
    the bottom up.
  • TransformExpressions: which transforms the expressions of just the
    given node.

Just like with nodes, expressions will also have a new WithChildren
method that does the exact same thing as it does in the nodes.

The expression package will expose a new helper:

  • TransformUp: which transforms an expression from the bottom up.

The sql package now has one interface more: OpaqueNode. An opaque node is a node that acts as a black box and their children will not be transformed using the aforementioned helpers. SubqueryAlias node, for example, requires being opaque.

Caveats and limitations:

One thing that may seem odd is the limitation that WithChildren and
WithExpressions must receive the children in the exact same order and
number as they were returned from Expressions or Children.

This is because without this limitation there is no way to build
certain nodes. If we force this limitation on one, it would feel odd
not to have it elsewhere.

For example, take Case expression into account. It may or may not have
Expr, it has a list of branches (each having 2 expressions) and it
may or may not have an Else expression. If WithChildren receives N
children, how do we know where to put all these expressions?
This limitation allows us to build the node beacause we know the shape
of children must match the current shape.

@erizocosmico erizocosmico requested a review from a team June 26, 2019 14:53
sql/core.go Show resolved Hide resolved
Copy link
Contributor

@juanjux juanjux left a comment

Choose a reason for hiding this comment

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

I solemnly declare here that I read everything.

Copy link
Contributor

@kuba-- kuba-- left a comment

Choose a reason for hiding this comment

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

For me personally all transformations are very fragile (if sth. mysterious happens, it's most likely in some transformation).
This PR is huge, but for the first insight, it reduces a little bit number of possible mistakes (even shadowed nodes).

@ajnavarro
Copy link
Contributor

@erizocosmico could you rebase please?

@erizocosmico erizocosmico force-pushed the feature/new-transforms branch from 2c7cd89 to 5fbc7f1 Compare July 3, 2019 14:54
@erizocosmico
Copy link
Contributor Author

Done

Instead of having TransformUp and TransformExpressionsUp in each
node, which was really error prone, now we have a different API.

Each node will have a WithChildren method that will receive
the children from which a new node of the same type will be created.
These nodes must come in the same number and order as the ones
returned by the Children method.

Expressioner nodes will also have WithExpressions method, which is
the same, except it will create a new node with its expressions
changed, instead of the children nodes.

The plan package will expose 3 new helpers:

- TransformUp: which transforms a node from the bottom-up.
- TransformExpressionsUp: which transforms expressions of a node from
  the bottom up.
- TransformExpressions: which transforms the expressions of just the
  given node.

Just like with nodes, expressions will also have a new WithChildren
method that does the exact same thing as it does in the nodes.

The expression package will expose a new helper:

- TransformUp: which transforms an expression from the bottom up.

Caveats and limitations:

One thing that may seem odd is the limitation that WithChildren and
WithExpressions must receive the children in the exact same order and
number as they were returned from Expressions or Children.

This is because without this limitation there is no way to build
certain nodes. If we force this limitation on one, it would feel odd
not to have it elsewhere.

For example, take Case expression into account. It may or may not have
Expr, it has a list of branches (each having 2 expressions) and it
may or may not have an Else expression. If WithChildren receives N
children, how do we know where to put all these expressions?
This limitation allows us to build the node beacause we know the shape
of children must match the current shape.

Signed-off-by: Miguel Molina <miguel@erizocosmi.co>
@erizocosmico erizocosmico force-pushed the feature/new-transforms branch from 5fbc7f1 to 128924a Compare July 3, 2019 14:59
@erizocosmico
Copy link
Contributor Author

Updated so that resolve_having can take advantage of the new WithChildren API

@ajnavarro ajnavarro merged commit 409efb9 into src-d:master Jul 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reduce amount of implemented code on Expressions
4 participants