From 58bb702355e1eae9337ed005682a23f0222f3443 Mon Sep 17 00:00:00 2001
From: Armand Parajon <83522714+aparajon@users.noreply.github.com>
Date: Wed, 24 Jan 2024 09:31:45 -0800
Subject: [PATCH] Mark non-unique lookup vindex as backfill to ignore vindex
 selection (#14227)

Signed-off-by: Armand Parajon <armand@squareup.com>
---
 go/vt/vtgate/planbuilder/plan_test_vindex.go  | 17 +++++++++++---
 .../planbuilder/testdata/select_cases.json    | 22 +++++++++++++++++++
 .../planbuilder/testdata/vschemas/schema.json | 14 ++++++++++++
 go/vt/vtgate/vindexes/consistent_lookup.go    |  2 +-
 go/vt/vtgate/vindexes/lookup.go               |  5 +++++
 5 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/go/vt/vtgate/planbuilder/plan_test_vindex.go b/go/vt/vtgate/planbuilder/plan_test_vindex.go
index 432ef7b8479..30d72f8c03a 100644
--- a/go/vt/vtgate/planbuilder/plan_test_vindex.go
+++ b/go/vt/vtgate/planbuilder/plan_test_vindex.go
@@ -72,7 +72,10 @@ func newLookupIndex(name string, _ map[string]string) (vindexes.Vindex, error) {
 var _ vindexes.Lookup = (*lookupIndex)(nil)
 
 // nameLkpIndex satisfies Lookup, NonUnique.
-type nameLkpIndex struct{ name string }
+type nameLkpIndex struct {
+	name       string
+	inBackfill bool
+}
 
 func (v *nameLkpIndex) String() string                     { return v.name }
 func (*nameLkpIndex) Cost() int                            { return 3 }
@@ -102,13 +105,21 @@ func (*nameLkpIndex) Query() (string, []string) {
 func (*nameLkpIndex) MapResult([]sqltypes.Value, []*sqltypes.Result) ([]key.Destination, error) {
 	return nil, nil
 }
-func newNameLkpIndex(name string, _ map[string]string) (vindexes.Vindex, error) {
-	return &nameLkpIndex{name: name}, nil
+
+func (v *nameLkpIndex) IsBackfilling() bool { return v.inBackfill }
+
+func newNameLkpIndex(name string, m map[string]string) (vindexes.Vindex, error) {
+	vdx := &nameLkpIndex{name: name}
+	if val, ok := m["write_only"]; ok {
+		vdx.inBackfill = val == "true"
+	}
+	return vdx, nil
 }
 
 var _ vindexes.Vindex = (*nameLkpIndex)(nil)
 var _ vindexes.Lookup = (*nameLkpIndex)(nil)
 var _ vindexes.LookupPlanable = (*nameLkpIndex)(nil)
+var _ vindexes.LookupBackfill = (*nameLkpIndex)(nil)
 
 // costlyIndex satisfies Lookup, NonUnique.
 type costlyIndex struct{ name string }
diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json
index f7f15d6c127..db8230d8f7b 100644
--- a/go/vt/vtgate/planbuilder/testdata/select_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json
@@ -4598,6 +4598,28 @@
       ]
     }
   },
+  {
+    "comment": "name is in backfill vindex - not selected for vindex lookup",
+    "query": "select * from customer where name = 'x'",
+    "plan": {
+      "QueryType": "SELECT",
+      "Original": "select * from customer where name = 'x'",
+      "Instructions": {
+        "OperatorType": "Route",
+        "Variant": "Scatter",
+        "Keyspace": {
+          "Name": "user",
+          "Sharded": true
+        },
+        "FieldQuery": "select * from customer where 1 != 1",
+        "Query": "select * from customer where `name` = 'x'",
+        "Table": "customer"
+      },
+      "TablesUsed": [
+        "user.customer"
+      ]
+    }
+  },
   {
     "comment": "email vindex is costly than phone vindex - but phone vindex is backfiling hence ignored",
     "query": "select * from customer where email = 'a@mail.com' and phone = 123456",
diff --git a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json
index 34a3d904f4f..6f274413fbe 100644
--- a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json
+++ b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json
@@ -166,6 +166,16 @@
               "to": "keyspace_id",
               "cost": "300"
             }
+        },
+        "lkp_bf_vdx": {
+          "type": "name_lkp_test",
+          "owner": "customer",
+          "params": {
+            "table": "lkp_shard_vdx",
+            "from": " ",
+            "to": "keyspace_id",
+            "write_only": "true"
+          }
         }
       },
       "tables": {
@@ -476,6 +486,10 @@
             {
               "column": "phone",
               "name": "unq_lkp_bf_vdx"
+            },
+            {
+              "column": "name",
+              "name": "lkp_bf_vdx"
             }
           ]
         },
diff --git a/go/vt/vtgate/vindexes/consistent_lookup.go b/go/vt/vtgate/vindexes/consistent_lookup.go
index f065bfca5e0..f32adc0f772 100644
--- a/go/vt/vtgate/vindexes/consistent_lookup.go
+++ b/go/vt/vtgate/vindexes/consistent_lookup.go
@@ -489,7 +489,7 @@ func (lu *clCommon) GetCommitOrder() vtgatepb.CommitOrder {
 }
 
 // IsBackfilling implements the LookupBackfill interface
-func (lu *ConsistentLookupUnique) IsBackfilling() bool {
+func (lu *clCommon) IsBackfilling() bool {
 	return lu.writeOnly
 }
 
diff --git a/go/vt/vtgate/vindexes/lookup.go b/go/vt/vtgate/vindexes/lookup.go
index b3e14fa01f6..33462470010 100644
--- a/go/vt/vtgate/vindexes/lookup.go
+++ b/go/vt/vtgate/vindexes/lookup.go
@@ -181,6 +181,11 @@ func (ln *LookupNonUnique) MarshalJSON() ([]byte, error) {
 	return json.Marshal(ln.lkp)
 }
 
+// IsBackfilling implements the LookupBackfill interface
+func (ln *LookupNonUnique) IsBackfilling() bool {
+	return ln.writeOnly
+}
+
 // Query implements the LookupPlanable interface
 func (ln *LookupNonUnique) Query() (selQuery string, arguments []string) {
 	return ln.lkp.query()