diff --git a/go/vt/sqlparser/ast_rewriting.go b/go/vt/sqlparser/ast_rewriting.go index 90bbd7ccc0c..5ecdea8896b 100644 --- a/go/vt/sqlparser/ast_rewriting.go +++ b/go/vt/sqlparser/ast_rewriting.go @@ -541,6 +541,14 @@ func (er *astRewriter) unnestSubQueries(cursor *Cursor, subquery *Subquery) { if !ok { return } + _, isColName := expr.Expr.(*ColName) + if isColName { + // If we find a single col-name in a `dual` subquery, we can be pretty sure the user is returning a column + // already projected. + // `select 1 as x, (select x)` + // is perfectly valid - any aliased columns to the left are available inside subquery scopes + return + } er.bindVars.NoteRewrite() // we need to make sure that the inner expression also gets rewritten, // so we fire off another rewriter traversal here diff --git a/go/vt/sqlparser/ast_rewriting_test.go b/go/vt/sqlparser/ast_rewriting_test.go index 957128e473c..95e84ae8c20 100644 --- a/go/vt/sqlparser/ast_rewriting_test.go +++ b/go/vt/sqlparser/ast_rewriting_test.go @@ -96,6 +96,10 @@ func TestRewrites(in *testing.T) { in: "select (select database() from dual) from dual", expected: "select :__vtdbname as `(select database() from dual)` from dual", db: true, + }, { + // don't unnest solo columns + in: "select 1 as foobar, (select foobar)", + expected: "select 1 as foobar, (select foobar from dual) from dual", }, { in: "select id from user where database()", expected: "select id from user where database()", diff --git a/go/vt/vtgate/planbuilder/physical/filter.go b/go/vt/vtgate/planbuilder/physical/filter.go index 67cc84809ee..4647740faac 100644 --- a/go/vt/vtgate/planbuilder/physical/filter.go +++ b/go/vt/vtgate/planbuilder/physical/filter.go @@ -37,11 +37,6 @@ func (f *Filter) TableID() semantics.TableSet { return f.Source.TableID() } -// PushPredicate implements the PhysicalOperator interface -func (f *Filter) PushPredicate(expr sqlparser.Expr, semTable *semantics.SemTable) error { - panic("unimplemented") -} - // UnsolvedPredicates implements the PhysicalOperator interface func (f *Filter) UnsolvedPredicates(semTable *semantics.SemTable) []sqlparser.Expr { panic("implement me") diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt index 9259e15688c..3072533565c 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.txt @@ -7694,3 +7694,39 @@ Gen4 error: unsupported: JOIN not supported between derived tables "user.music" ] } + +# Earlier columns are in scope in subqueries https://github.com/vitessio/vitess/issues/11246 +"SELECT 1 as x, (SELECT x)" +{ + "QueryType": "SELECT", + "Original": "SELECT 1 as x, (SELECT x)", + "Instructions": { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select 1 as x, (select x from dual where 1 != 1) from dual where 1 != 1", + "Query": "select 1 as x, (select x from dual) from dual", + "Table": "dual" + } +} +{ + "QueryType": "SELECT", + "Original": "SELECT 1 as x, (SELECT x)", + "Instructions": { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select 1 as x, (select x from dual where 1 != 1) from dual where 1 != 1", + "Query": "select 1 as x, (select x from dual) from dual", + "Table": "dual" + }, + "TablesUsed": [ + "main.dual" + ] +}