-
Notifications
You must be signed in to change notification settings - Fork 110
sql/analyzer: resolve correctly GetField expressions indexes #181
sql/analyzer: resolve correctly GetField expressions indexes #181
Conversation
It seems st is failing, don't review yet |
06ebb75
to
c3e0018
Compare
@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) { |
There was a problem hiding this comment.
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?
sql/analyzer/rules.go
Outdated
@@ -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) { |
There was a problem hiding this comment.
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?
sql/analyzer/rules.go
Outdated
return n, nil | ||
} | ||
|
||
_, ok := n.(*plan.InnerJoin) |
There was a problem hiding this comment.
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?
There was a problem hiding this 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?
I changed the PR to address all cases. Now there is a rule Thus, the |
sql/analyzer/rules.go
Outdated
@@ -330,6 +326,8 @@ type column interface { | |||
sql.Expression | |||
} | |||
|
|||
const unresolvedGetFieldIndex = 2147483647 |
There was a problem hiding this comment.
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".
sql/plan/innerjoin.go
Outdated
return []sql.Expression{j.Cond} | ||
} | ||
|
||
// TransformExpressions implements the Expressioner interface. | ||
func (j *InnerJoin) TransformExpressions(f sql.TransformExprFunc) error { |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
@mcarmonaa You can do the same logic calling |
@ajnavarro, calling Having the method |
Yes, but you can do it in a rule checking the type of the node depending on the case. |
There was a problem hiding this 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.
8db045c
to
6172b02
Compare
@erizocosmico can you have a look? |
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) { |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/TransformExprssions/TransformExpressions/
There was a problem hiding this comment.
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
…umn rule. Signed-off-by: Manuel Carmona <[email protected]>
6172b02
to
cfc5c19
Compare
@erizocosmico ping |
@erizocosmico ping? |
There was a problem hiding this 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
Fixes #180
Signed-off-by: Manuel Carmona [email protected]