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

sql/analyzer: resolve correctly GetField expressions indexes #181

Merged
merged 1 commit into from
May 22, 2018

Conversation

mcarmonaa
Copy link
Contributor

Fixes #180

Signed-off-by: Manuel Carmona [email protected]

@mcarmonaa mcarmonaa requested review from jfontan, ajnavarro, erizocosmico and kuba-- and removed request for jfontan, erizocosmico and kuba-- May 4, 2018 12:00
@mcarmonaa
Copy link
Contributor Author

It seems st is failing, don't review yet

@mcarmonaa mcarmonaa force-pushed the fix/rows-indexes-in-getfield branch 2 times, most recently from 06ebb75 to c3e0018 Compare May 4, 2018 14:02
@mcarmonaa
Copy link
Contributor Author

@ajnavarro now CI passes, it's ready to review!

engine_test.go Outdated
@@ -206,6 +206,32 @@ func TestQueries(t *testing.T) {
}
}

func TestJoinsFields(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add the query to the queries slice instead of create a new test for this?

@@ -809,3 +810,49 @@ func fixFieldIndexes(schema sql.Schema, exp sql.Expression) (sql.Expression, err
return e, nil
})
}

func fixJoinFields(ctx *sql.Context, a *Analyzer, node sql.Node) (sql.Node, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add some comments to this function explaining why this is needed and adding a TODO to fix it in a proper way?

return n, nil
}

_, ok := n.(*plan.InnerJoin)
Copy link
Contributor

Choose a reason for hiding this comment

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

Only for inner joins? should be for all kind of joins, right?

@ajnavarro ajnavarro requested a review from erizocosmico May 4, 2018 14:48
Copy link
Contributor

@erizocosmico erizocosmico left a comment

Choose a reason for hiding this comment

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

Overall, except for what @ajnavarro said it looks good to me. Just a question, isn't it possible to fix this without a rule? Can you add a bit of context in the issue description about why does this happen and why it cannot be solved without a rule?

@mcarmonaa
Copy link
Contributor Author

@ajnavarro @erizocosmico

I changed the PR to address all cases. Now there is a rule resolveGetFieldIndexes in charge of set the correct index for the GetField expressions referencing this value to the sql.Node that contains that expression.

Thus, the resolveColumns rule doesn't set these indexes anymore and we avoid the usage of the global row's indexes based on the final schema.

@mcarmonaa mcarmonaa changed the title sql/analyzer: add rule to fix field's indexes in inner joins sql/analyzer: add rule to fix GetField's indexes May 7, 2018
@@ -330,6 +326,8 @@ type column interface {
sql.Expression
}

const unresolvedGetFieldIndex = 2147483647
Copy link
Contributor

@erizocosmico erizocosmico May 7, 2018

Choose a reason for hiding this comment

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

-1 would do the trick and then you can do index >= 0 to know if it's resolved. Plus, I think it's a more obvious value for "unresolved".

return []sql.Expression{j.Cond}
}

// TransformExpressions implements the Expressioner interface.
func (j *InnerJoin) TransformExpressions(f sql.TransformExprFunc) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

why add this method when nodes already have TransformExpressionsUp?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because TransformExpressionsUp transforms expressions for this node and its childrens meanwhile this method only transform the expressions for this node.

Copy link
Contributor

@erizocosmico erizocosmico May 7, 2018

Choose a reason for hiding this comment

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

Ok. In any case, all nodes should be immutable, so they would need to return new instances, just as TransformExpressionsUp and TransformUp do.

@ajnavarro
Copy link
Contributor

@mcarmonaa You can do the same logic calling Expressions() method on the nodes that you need into a rule. I cannot see the need of TransformExpression() method.

@mcarmonaa
Copy link
Contributor Author

@ajnavarro, calling Expressions you will get the expressions for this node, but you must add a different implementation to generate a new node with its expressions changed for each node subtype(inner join, project, etc) in the rule.

Having the method TransformExpressions you have that specific implementation done in each node, which I think it's better.

@ajnavarro
Copy link
Contributor

Yes, but you can do it in a rule checking the type of the node depending on the case.

Copy link
Collaborator

@smola smola 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 that it would be better to resolve unresolved column to get field in a single step. Instead of generating unresolved get field first and then get field.

In a rule iteration, if the children nodes are not resolved, you just skip it and it will be called.

@mcarmonaa mcarmonaa force-pushed the fix/rows-indexes-in-getfield branch from 8db045c to 6172b02 Compare May 10, 2018 10:24
@ajnavarro
Copy link
Contributor

@erizocosmico can you have a look?

@mcarmonaa mcarmonaa changed the title sql/analyzer: add rule to fix GetField's indexes sql/analyzer: resolve correctly GetField expressions indexes May 10, 2018
sql/type.go Outdated
return true
// Contains returns whether the schema contains a column with the given name
// and the index of that column in the schema.
func (s Schema) Contains(column string, source string) (int, bool) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of making contains return an int, which feels weird, maybe we could have a ColumnIndex or IndexOf method that returns the index or -1 when it's not found and the following Contains:

func (s Schema) Contains(column string, source string) bool {
        return s.IndexOf(column, source) >= 0
}

WDYT?

sql/core.go Outdated
@@ -110,6 +110,10 @@ type Node interface {
type Expressioner interface {
// Expressions returns the list of expressions contained by the node.
Expressions() []Expression
// TransformExprssions applies for each expression in this node
Copy link
Contributor

Choose a reason for hiding this comment

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

s/TransformExprssions/TransformExpressions/

Copy link
Member

@eiso eiso May 11, 2018

Choose a reason for hiding this comment

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

Sounds like something that an intelligent code review bot should be able to detect, hint

@mcarmonaa mcarmonaa force-pushed the fix/rows-indexes-in-getfield branch from 6172b02 to cfc5c19 Compare May 10, 2018 12:52
@ajnavarro
Copy link
Contributor

@erizocosmico ping

@ajnavarro
Copy link
Contributor

@erizocosmico ping?

Copy link
Contributor

@erizocosmico erizocosmico left a comment

Choose a reason for hiding this comment

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

Oops, sorry, didn't see this before

@ajnavarro ajnavarro merged commit 6dacde8 into src-d:master May 22, 2018
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.

5 participants