diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.json b/go/vt/vtgate/planbuilder/testdata/from_cases.json index 8cdf4630655..b2f254369ac 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.json @@ -964,6 +964,31 @@ ] } }, + { + "comment": "Ambiguous column is not a problem when we can merge and push down", + "query": "select foobar from user join music on user.id = music.user_id order by foobar", + "plan": { + "QueryType": "SELECT", + "Original": "select foobar from user join music on user.id = music.user_id order by foobar", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select foobar, weight_string(foobar) from `user`, music where 1 != 1", + "OrderBy": "(0|1) ASC", + "Query": "select foobar, weight_string(foobar) from `user`, music where `user`.id = music.user_id order by foobar asc", + "ResultColumns": 1, + "Table": "`user`, music" + }, + "TablesUsed": [ + "user.music", + "user.user" + ] + } + }, { "comment": "index hints, make sure they are not stripped.", "query": "select user.col from user use index(a)", diff --git a/go/vt/vtgate/semantics/early_rewriter.go b/go/vt/vtgate/semantics/early_rewriter.go index ce47005c1d8..a32455d7585 100644 --- a/go/vt/vtgate/semantics/early_rewriter.go +++ b/go/vt/vtgate/semantics/early_rewriter.go @@ -605,7 +605,15 @@ func (r *earlyRewriter) fillInQualifiers(cursor *sqlparser.CopyOnWriteCursor) { if !found { panic("uh oh") } - tbl := r.tables.Tables[ts.TableOffset()] + offset := ts.TableOffset() + if offset < 0 { + // this is a column that is not coming from a table - it's an alias introduced in a SELECT expression + // Example: select (1+1) as foo from bar order by foo + // we don't want to add a qualifier to foo here + cursor.Replace(sqlparser.NewColName(col.Name.String())) + return + } + tbl := r.tables.Tables[offset] tblName, err := tbl.Name() if err != nil { panic(err) diff --git a/go/vt/vtgate/semantics/early_rewriter_test.go b/go/vt/vtgate/semantics/early_rewriter_test.go index 13823e5351f..5286b0798a4 100644 --- a/go/vt/vtgate/semantics/early_rewriter_test.go +++ b/go/vt/vtgate/semantics/early_rewriter_test.go @@ -735,6 +735,33 @@ func TestOrderByColumnName(t *testing.T) { } } +func TestOrderByNotAllColumnsAuthoritative(t *testing.T) { + schemaInfo := fakeSchemaInfo() + cDB := "db" + tcases := []struct { + sql string + expSQL string + deps TableSet + }{{ + sql: "select foo from t3 join t order by foo", + expSQL: "select foo from t3 join t order by foo asc", + deps: None, + }} + for _, tcase := range tcases { + t.Run(tcase.sql, func(t *testing.T) { + ast, err := sqlparser.Parse(tcase.sql) + require.NoError(t, err) + selectStatement := ast.(sqlparser.SelectStatement) + semTable, err := Analyze(selectStatement, cDB, schemaInfo) + + require.NoError(t, err) + assert.Equal(t, tcase.expSQL, sqlparser.String(selectStatement)) + orderByExpr := selectStatement.GetOrderBy()[0].Expr + assert.Equal(t, tcase.deps, semTable.RecursiveDeps(orderByExpr)) + }) + } +} + func TestSemTableDependenciesAfterExpandStar(t *testing.T) { schemaInfo := &FakeSI{Tables: map[string]*vindexes.Table{ "t1": {