diff --git a/go/test/endtoend/vtgate/queries/reference/reference_test.go b/go/test/endtoend/vtgate/queries/reference/reference_test.go index 9c2508a889f..0e3096e6064 100644 --- a/go/test/endtoend/vtgate/queries/reference/reference_test.go +++ b/go/test/endtoend/vtgate/queries/reference/reference_test.go @@ -83,6 +83,25 @@ func TestReferenceRouting(t *testing.T) { `[[INT64(0)]]`, ) + t.Run("Complex reference query", func(t *testing.T) { + utils.SkipIfBinaryIsBelowVersion(t, 20, "vtgate") + // Verify a complex query using reference tables with a left join having a derived table with an order by clause works as intended. + utils.AssertMatches( + t, + conn, + `SELECT t.id FROM ( + SELECT zd.id, zd.zip_id + FROM `+shardedKeyspaceName+`.zip_detail AS zd + WHERE zd.id IN (2) + ORDER BY zd.discontinued_at + LIMIT 1 + ) AS t + LEFT JOIN `+shardedKeyspaceName+`.zip_detail AS t0 ON t.zip_id = t0.zip_id + ORDER BY t.id`, + `[[INT64(2)]]`, + ) + }) + // UPDATE should route an unqualified zip_detail to unsharded keyspace. utils.Exec(t, conn, "UPDATE zip_detail SET discontinued_at = NULL WHERE id = 2") diff --git a/go/vt/vtgate/planbuilder/operators/route.go b/go/vt/vtgate/planbuilder/operators/route.go index 5742877fbe3..82aeacb20b6 100644 --- a/go/vt/vtgate/planbuilder/operators/route.go +++ b/go/vt/vtgate/planbuilder/operators/route.go @@ -656,6 +656,11 @@ func addMultipleColumnsToInput( } return derivedName, op, added, offset + case *Horizon: + // if the horizon has an alias, then it is a derived table, + // we have to add a new projection and can't build on this one + return op.Alias, op, false, nil + case selectExpressions: name := op.derivedName() if name != "" { diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json index e98f53bb4cf..f7e556956e3 100644 --- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json @@ -6249,8 +6249,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select table_name from (select table_name from `user` where 1 != 1 group by table_name) as `tables` where 1 != 1", - "Query": "select table_name from (select table_name from `user` where id = 143 group by table_name) as `tables`", + "FieldQuery": "select `tables`.table_name from (select table_name from `user` where 1 != 1 group by table_name) as `tables` where 1 != 1", + "Query": "select `tables`.table_name from (select table_name from `user` where id = 143 group by table_name) as `tables`", "Table": "`user`", "Values": [ "143" diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.json b/go/vt/vtgate/planbuilder/testdata/from_cases.json index b8292888161..491d2d526a8 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.json @@ -4216,8 +4216,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select id, col from (select id, col from `user` where 1 != 1) as u where 1 != 1", - "Query": "select distinct id, col from (select id, col from `user`) as u", + "FieldQuery": "select u.id, u.col from (select id, col from `user` where 1 != 1) as u where 1 != 1", + "Query": "select distinct u.id, u.col from (select id, col from `user`) as u", "Table": "`user`" }, { diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json index 1727e372490..09e04b47343 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json @@ -1162,8 +1162,8 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select table_name from (select table_name from information_schema.`tables` where 1 != 1) as `tables` where 1 != 1", - "Query": "select table_name from (select table_name from information_schema.`tables` where table_schema != 'information_schema' limit 1) as `tables`", + "FieldQuery": "select `tables`.table_name from (select table_name from information_schema.`tables` where 1 != 1) as `tables` where 1 != 1", + "Query": "select `tables`.table_name from (select table_name from information_schema.`tables` where table_schema != 'information_schema' limit 1) as `tables`", "Table": "information_schema.`tables`" }, { diff --git a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json index 3e15c19abc5..3df016e0aa3 100644 --- a/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json @@ -1284,8 +1284,8 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select table_name from (select table_name from information_schema.`tables` where 1 != 1) as `tables` where 1 != 1", - "Query": "select table_name from (select table_name from information_schema.`tables` where table_schema != 'information_schema' limit 1) as `tables`", + "FieldQuery": "select `tables`.table_name from (select table_name from information_schema.`tables` where 1 != 1) as `tables` where 1 != 1", + "Query": "select `tables`.table_name from (select table_name from information_schema.`tables` where table_schema != 'information_schema' limit 1) as `tables`", "Table": "information_schema.`tables`" }, { diff --git a/go/vt/vtgate/planbuilder/testdata/reference_cases.json b/go/vt/vtgate/planbuilder/testdata/reference_cases.json index 42240ce56c7..91aac12d9e9 100644 --- a/go/vt/vtgate/planbuilder/testdata/reference_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/reference_cases.json @@ -161,6 +161,50 @@ ] } }, + { + "comment": "Reference tables using left join with a derived table having a limit clause", + "query": "SELECT u.id FROM ( SELECT a.id, a.u_id FROM user.ref_with_source AS a WHERE a.id IN (3) ORDER BY a.d_at LIMIT 1) as u LEFT JOIN user.ref_with_source AS u0 ON u.u_id = u0.u_uid ORDER BY u.id", + "plan": { + "QueryType": "SELECT", + "Original": "SELECT u.id FROM ( SELECT a.id, a.u_id FROM user.ref_with_source AS a WHERE a.id IN (3) ORDER BY a.d_at LIMIT 1) as u LEFT JOIN user.ref_with_source AS u0 ON u.u_id = u0.u_uid ORDER BY u.id", + "Instructions": { + "OperatorType": "Join", + "Variant": "LeftJoin", + "JoinColumnIndexes": "L:0", + "JoinVars": { + "u_u_id": 1 + }, + "TableName": "ref_with_source_ref_with_source", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select u.id, u.u_id from (select a.id, a.u_id from ref_with_source as a where 1 != 1) as u where 1 != 1", + "Query": "select u.id, u.u_id from (select a.id, a.u_id from ref_with_source as a where a.id in (3) order by a.d_at asc limit 1) as u order by u.id asc", + "Table": "ref_with_source" + }, + { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 1 from ref_with_source as u0 where 1 != 1", + "Query": "select 1 from ref_with_source as u0 where u0.u_uid = :u_u_id", + "Table": "ref_with_source" + } + ] + }, + "TablesUsed": [ + "user.ref_with_source" + ] + } + }, { "comment": "insert into qualified ambiguous reference table routes to source", "query": "insert into user.ambiguous_ref_with_source(col) values(1)", diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index 63fba06202c..bfae85a08b2 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -5043,8 +5043,8 @@ "Name": "main", "Sharded": false }, - "FieldQuery": "select table_name from (select table_name from unsharded where 1 != 1) as `tables` where 1 != 1", - "Query": "select table_name from (select table_name from unsharded limit 1) as `tables`", + "FieldQuery": "select `tables`.table_name from (select table_name from unsharded where 1 != 1) as `tables` where 1 != 1", + "Query": "select `tables`.table_name from (select table_name from unsharded limit 1) as `tables`", "Table": "unsharded" }, {