diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index 60f844ed05c..469a75f203e 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -3031,7 +3031,22 @@ "TableName": "user_privacy_consents" } }, - "gen4-plan": "unsupported: unable to split predicates to derived table: not :__sq_has_values1" + "gen4-plan": { + "QueryType": "INSERT", + "Original": "INSERT INTO main.user_privacy_consents (user_id, accepted_at) SELECT user_id, accepted_at FROM (SELECT 1 as user_id, 1629194864 as accepted_at) AS tmp WHERE NOT EXISTS (SELECT user_id FROM main.user_privacy_consents WHERE user_id = 1)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "MultiShardAutocommit": false, + "Query": "insert into user_privacy_consents(user_id, accepted_at) select user_id, accepted_at from (select 1 as user_id, 1629194864 as accepted_at from dual) as tmp where not exists (select 1 from user_privacy_consents where user_id = 1 limit 1) for update", + "TableName": "user_privacy_consents" + } + } }, { "comment": "Delete on backfilling unique lookup vindex should be a scatter", diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index eee9dda7dc9..667f974a1c7 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -5479,5 +5479,39 @@ "Vindex": "user_index" } } + }, + { + "comment": "query with a derived table and dual table in unsharded keyspace", + "query": "SELECT * FROM unsharded_a AS t1 JOIN (SELECT trim((SELECT MAX(name) FROM unsharded_a)) AS name) AS t2 WHERE t1.name >= t2.name ORDER BY t1.name ASC LIMIT 1;", + "v3-plan": { + "QueryType": "SELECT", + "Original": "SELECT * FROM unsharded_a AS t1 JOIN (SELECT trim((SELECT MAX(name) FROM unsharded_a)) AS name) AS t2 WHERE t1.name >= t2.name ORDER BY t1.name ASC LIMIT 1;", + "Instructions": { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select * from unsharded_a as t1 join (select trim((select MAX(`name`) from unsharded_a where 1 != 1)) as `name` from dual where 1 != 1) as t2 where 1 != 1", + "Query": "select * from unsharded_a as t1 join (select trim((select MAX(`name`) from unsharded_a)) as `name` from dual) as t2 where t1.`name` >= t2.`name` order by t1.`name` asc limit 1", + "Table": "unsharded_a, dual" + } + }, + "gen4-plan": { + "QueryType": "SELECT", + "Original": "SELECT * FROM unsharded_a AS t1 JOIN (SELECT trim((SELECT MAX(name) FROM unsharded_a)) AS name) AS t2 WHERE t1.name >= t2.name ORDER BY t1.name ASC LIMIT 1;", + "Instructions": { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select * from unsharded_a as t1 join (select trim((select MAX(`name`) from unsharded_a where 1 != 1)) as `name` from dual where 1 != 1) as t2 where 1 != 1", + "Query": "select * from unsharded_a as t1 join (select trim((select MAX(`name`) from unsharded_a)) as `name` from dual) as t2 where t1.`name` >= t2.`name` order by t1.`name` asc limit 1", + "Table": "dual, unsharded_a" + } + } } ] diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index 4fe0ce75371..72e0835ad12 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -370,7 +370,8 @@ func (st *SemTable) SingleUnshardedKeyspace() *vindexes.Keyspace { var ks *vindexes.Keyspace for _, table := range st.Tables { vindexTable := table.GetVindexTable() - if vindexTable == nil || vindexTable.Type != "" { + + if vindexTable == nil { _, isDT := table.getExpr().Expr.(*sqlparser.DerivedTable) if isDT { // derived tables are ok, as long as all real tables are from the same unsharded keyspace @@ -379,6 +380,13 @@ func (st *SemTable) SingleUnshardedKeyspace() *vindexes.Keyspace { } return nil } + if vindexTable.Type != "" { + // A reference table is not an issue when seeing if a query is going to an unsharded keyspace + if vindexTable.Type == vindexes.TypeReference { + continue + } + return nil + } name, ok := table.getExpr().Expr.(sqlparser.TableName) if !ok { return nil