-
-
Notifications
You must be signed in to change notification settings - Fork 213
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
resolve aliases in subqueries in function arguments #1838
Changes from 10 commits
022e9f1
92a4f5b
16e5875
ecc0288
1f55fd8
7959322
d23334a
272b830
f593e33
96d84d5
868ca07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -188,6 +188,28 @@ func TestHandlerOutput(t *testing.T) { | |
require.Equal(t, sqltypes.Float64, result.Rows[0][0].Type()) | ||
require.Equal(t, []byte("1"), result.Rows[0][0].ToBytes()) | ||
}) | ||
|
||
t.Run("if() type is correct", func(t *testing.T) { | ||
handler.ComInitDB(dummyConn, "test") | ||
var result *sqltypes.Result | ||
err := handler.ComQuery(dummyConn, "select if(1, 123, 'def')", func(res *sqltypes.Result, more bool) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The old code had |
||
result = res | ||
return nil | ||
}) | ||
require.NoError(t, err) | ||
require.Equal(t, 1, len(result.Rows)) | ||
require.Equal(t, sqltypes.Text, result.Rows[0][0].Type()) | ||
require.Equal(t, []byte("123"), result.Rows[0][0].ToBytes()) | ||
|
||
err = handler.ComQuery(dummyConn, "select if(0, 123, 456)", func(res *sqltypes.Result, more bool) error { | ||
result = res | ||
return nil | ||
}) | ||
require.NoError(t, err) | ||
require.Equal(t, 1, len(result.Rows)) | ||
require.Equal(t, sqltypes.Int64, result.Rows[0][0].Type()) | ||
require.Equal(t, []byte("456"), result.Rows[0][0].ToBytes()) | ||
}) | ||
} | ||
|
||
func TestHandlerComPrepare(t *testing.T) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,6 +123,30 @@ func reorderProjection(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Sc | |
}) | ||
} | ||
|
||
// findDeferredColumns is a function that searches through a projection's expressions and checks if there are any | ||
// subqueries that reference the deferred column. Additionally, we have to check for subqueries in functions arguments | ||
func findDeferredColumns(exprs ...sql.Expression) []column { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there any reason not to just |
||
var deferredColumns []column | ||
for _, e := range exprs { | ||
if a, ok := e.(*expression.Alias); ok { | ||
e = a.Child | ||
} | ||
|
||
switch e := e.(type) { | ||
case *plan.Subquery: | ||
deferredColumns = append(deferredColumns, findDeferredColumnsAndAliasReferences(e.Query)...) | ||
case sql.FunctionExpression: | ||
for _, arg := range e.Children() { | ||
innerCols := findDeferredColumns(arg) | ||
if len(innerCols) > 0 { | ||
deferredColumns = append(deferredColumns, innerCols...) | ||
} | ||
} | ||
} | ||
} | ||
return deferredColumns | ||
} | ||
|
||
func addIntermediateProjections( | ||
project *plan.Project, | ||
projectedAliases map[string]sql.Expression, | ||
|
@@ -194,19 +218,7 @@ func addIntermediateProjections( | |
// like a child node in this respect -- it draws its outer scope schema from the child of the node in which it's | ||
// embedded. We identify any missing subquery columns by their being deferred or marked as an AliasReference | ||
// from a previous analyzer step. | ||
var deferredColumns []column | ||
for _, e := range project.Projections { | ||
if a, ok := e.(*expression.Alias); ok { | ||
e = a.Child | ||
} | ||
s, ok := e.(*plan.Subquery) | ||
if !ok { | ||
continue | ||
} | ||
|
||
deferredColumns = append(deferredColumns, findDeferredColumnsAndAliasReferences(s.Query)...) | ||
} | ||
|
||
deferredColumns := findDeferredColumns(project.Projections...) | ||
if len(deferredColumns) > 0 { | ||
schema := child.Schema() | ||
var projections = make([]sql.Expression, 0, len(schema)+len(deferredColumns)) | ||
|
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.
This should be a string, but the TestEvaluation doesn't go through the schema[0].Convert code path.
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.
should we move to brokenQueries?
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.
or is it just bad test setup
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 it's just bad test setup, when the results are written to the shell we use the writerIters, but not for evaluation.
I can add it in a separate PR, and see how many failures we get