Repository: vitessio/vitess
Pull request #9338 (2021-12-08 14:50:24)

Multi column vindex support for DML
## Description
Changes the planner and engine primitives to use the new evalengine expressions instead of PlanValue. This is in preparation for multi column vindex support.



Patch:
diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go
index 5d9f440d23..7bd05a40af 100644
--- a/go/vt/vtgate/engine/cached_size.go
+++ b/go/vt/vtgate/engine/cached_size.go
@@ -132,11 +132,13 @@ func (cached *DML) CachedSize(alloc bool) int64 {
 	if cc, ok := cached.Vindex.(cachedObject); ok {
 		size += cc.CachedSize(true)
 	}
-	// field Values []vitess.io/vitess/go/sqltypes.PlanValue
+	// field Values []vitess.io/vitess/go/vt/vtgate/evalengine.Expr
 	{
-		size += hack.RuntimeAllocSize(int64(cap(cached.Values)) * int64(88))
+		size += hack.RuntimeAllocSize(int64(cap(cached.Values)) * int64(16))
 		for _, elem := range cached.Values {
-			size += elem.CachedSize(false)
+			if cc, ok := elem.(cachedObject); ok {
+				size += cc.CachedSize(true)
+			}
 		}
 	}
 	// field KsidVindex vitess.io/vitess/go/vt/vtgate/vindexes.SingleColumn
diff --git a/go/vt/vtgate/engine/delete.go b/go/vt/vtgate/engine/delete.go
index 4a7472bbd6..d0aa98f97a 100644
--- a/go/vt/vtgate/engine/delete.go
+++ b/go/vt/vtgate/engine/delete.go
@@ -20,6 +20,8 @@ import (
 	"fmt"
 	"time"
 
+	"vitess.io/vitess/go/vt/vtgate/evalengine"
+
 	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
 
 	"vitess.io/vitess/go/sqltypes"
@@ -122,11 +124,15 @@ func (del *Delete) execDeleteUnsharded(vcursor VCursor, bindVars map[string]*que
 }
 
 func (del *Delete) execDeleteEqual(vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) {
-	key, err := del.Values[0].ResolveValue(bindVars)
+	env := &evalengine.ExpressionEnv{
+		BindVars: bindVars,
+	}
+
+	key, err := del.Values[0].Evaluate(env)
 	if err != nil {
 		return nil, err
 	}
-	rs, ksid, err := resolveSingleShard(vcursor, del.Vindex, del.Keyspace, key)
+	rs, ksid, err := resolveSingleShard(vcursor, del.Vindex, del.Keyspace, key.Value())
 	if err != nil {
 		return nil, err
 	}
@@ -261,6 +267,10 @@ func addFieldsIfNotEmpty(dml DML, other map[string]interface{}) {
 		other["KsidVindex"] = dml.KsidVindex.String()
 	}
 	if len(dml.Values) > 0 {
-		other["Values"] = dml.Values
+		s := []string{}
+		for _, value := range dml.Values {
+			s = append(s, evalengine.FormatExpr(value))
+		}
+		other["Values"] = s
 	}
 }
diff --git a/go/vt/vtgate/engine/dml.go b/go/vt/vtgate/engine/dml.go
index 9689074155..b2e07ed846 100644
--- a/go/vt/vtgate/engine/dml.go
+++ b/go/vt/vtgate/engine/dml.go
@@ -22,6 +22,7 @@ import (
 	querypb "vitess.io/vitess/go/vt/proto/query"
 	"vitess.io/vitess/go/vt/srvtopo"
 	"vitess.io/vitess/go/vt/vterrors"
+	"vitess.io/vitess/go/vt/vtgate/evalengine"
 	"vitess.io/vitess/go/vt/vtgate/vindexes"
 )
 
@@ -44,7 +45,7 @@ type DML struct {
 
 	// Values specifies the vindex values to use for routing.
 	// For now, only one value is specified.
-	Values []sqltypes.PlanValue
+	Values []evalengine.Expr
 
 	// Keyspace Id Vindex
 	KsidVindex vindexes.SingleColumn
@@ -100,12 +101,23 @@ func (op DMLOpcode) String() string {
 	return opcodeName[op]
 }
 
-func resolveMultiValueShards(vcursor VCursor, keyspace *vindexes.Keyspace, query string, bindVars map[string]*querypb.BindVariable, pv sqltypes.PlanValue, vindex vindexes.SingleColumn) ([]*srvtopo.ResolvedShard, []*querypb.BoundQuery, error) {
-	keys, err := pv.ResolveList(bindVars)
+func resolveMultiValueShards(
+	vcursor VCursor,
+	keyspace *vindexes.Keyspace,
+	query string,
+	bindVars map[string]*querypb.BindVariable,
+	val evalengine.Expr,
+	vindex vindexes.SingleColumn,
+) ([]*srvtopo.ResolvedShard, []*querypb.BoundQuery, error) {
+	env := &evalengine.ExpressionEnv{
+		BindVars: bindVars,
+	}
+
+	keys, err := val.Evaluate(env)
 	if err != nil {
 		return nil, nil, err
 	}
-	rss, err := resolveMultiShard(vcursor, vindex, keyspace, keys)
+	rss, err := resolveMultiShard(vcursor, vindex, keyspace, keys.TupleValues())
 	if err != nil {
 		return nil, nil, err
 	}
diff --git a/go/vt/vtgate/engine/update.go b/go/vt/vtgate/engine/update.go
index 02bb3c8094..cf65d8fa64 100644
--- a/go/vt/vtgate/engine/update.go
+++ b/go/vt/vtgate/engine/update.go
@@ -135,11 +135,15 @@ func (upd *Update) execUpdateUnsharded(vcursor VCursor, bindVars map[string]*que
 }
 
 func (upd *Update) execUpdateEqual(vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) {
-	key, err := upd.Values[0].ResolveValue(bindVars)
+	env := &evalengine.ExpressionEnv{
+		BindVars: bindVars,
+	}
+
+	key, err := upd.Values[0].Evaluate(env)
 	if err != nil {
 		return nil, err
 	}
-	rs, ksid, err := resolveSingleShard(vcursor, upd.Vindex, upd.Keyspace, key)
+	rs, ksid, err := resolveSingleShard(vcursor, upd.Vindex, upd.Keyspace, key.Value())
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/vt/vtgate/evalengine/expressions.go b/go/vt/vtgate/evalengine/expressions.go
index 192c8160fc..58cd42dc53 100644
--- a/go/vt/vtgate/evalengine/expressions.go
+++ b/go/vt/vtgate/evalengine/expressions.go
@@ -79,6 +79,13 @@ type (
 	}
 )
 
+// EmptyExpressionEnv returns a new ExpressionEnv with no bind vars or row
+func EmptyExpressionEnv() *ExpressionEnv {
+	return &ExpressionEnv{
+		BindVars: make(map[string]*querypb.BindVariable),
+	}
+}
+
 // ResolveValue allows for retrieval of the value we expose for public consumption
 func (rv *RouteValue) ResolveValue(bindVars map[string]*querypb.BindVariable) (sqltypes.Value, error) {
 	env := &ExpressionEnv{
diff --git a/go/vt/vtgate/planbuilder/dml.go b/go/vt/vtgate/planbuilder/dml.go
index 3a2c893260..6f2c61d256 100644
--- a/go/vt/vtgate/planbuilder/dml.go
+++ b/go/vt/vtgate/planbuilder/dml.go
@@ -17,18 +17,26 @@ limitations under the License.
 package planbuilder
 
 import (
-	"vitess.io/vitess/go/sqltypes"
 	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
 	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
 	"vitess.io/vitess/go/vt/sqlparser"
 	"vitess.io/vitess/go/vt/vterrors"
 	"vitess.io/vitess/go/vt/vtgate/engine"
+	"vitess.io/vitess/go/vt/vtgate/evalengine"
+	"vitess.io/vitess/go/vt/vtgate/semantics"
 	"vitess.io/vitess/go/vt/vtgate/vindexes"
 )
 
 // getDMLRouting returns the vindex and values for the DML,
 // If it cannot find a unique vindex match, it returns an error.
-func getDMLRouting(where *sqlparser.Where, table *vindexes.Table) (engine.DMLOpcode, vindexes.SingleColumn, string, vindexes.SingleColumn, []sqltypes.PlanValue, error) {
+func getDMLRouting(where *sqlparser.Where, table *vindexes.Table) (
+	engine.DMLOpcode,
+	vindexes.SingleColumn,
+	string,
+	vindexes.SingleColumn,
+	[]evalengine.Expr,
+	error,
+) {
 	var ksidVindex vindexes.SingleColumn
 	var ksidCol string
 	for _, index := range table.Ordered {
@@ -47,16 +55,16 @@ func getDMLRouting(where *sqlparser.Where, table *vindexes.Table) (engine.DMLOpc
 			return engine.Scatter, ksidVindex, ksidCol, nil, nil, nil
 		}
 
-		if pv, ok := getMatch(where.Expr, index.Columns[0]); ok {
+		if expr, op := getMatch(where.Expr, index.Columns[0]); expr != nil {
 			opcode := engine.Equal
-			if pv.IsList() {
+			if op == sqlparser.InOp {
 				opcode = engine.In
 			} else if lu, isLu := single.(vindexes.LookupBackfill); isLu && lu.IsBackfilling() {
 				// Checking if the Vindex is currently backfilling or not, if it isn't we can read from the vindex table
 				// and we will be able to do a delete equal. Otherwise, we continue to look for next best vindex.
 				continue
 			}
-			return opcode, ksidVindex, ksidCol, single, []sqltypes.PlanValue{pv}, nil
+			return opcode, ksidVindex, ksidCol, single, []evalengine.Expr{expr}, nil
 		}
 	}
 	if ksidVindex == nil {
@@ -68,7 +76,7 @@ func getDMLRouting(where *sqlparser.Where, table *vindexes.Table) (engine.DMLOpc
 // getMatch returns the matched value if there is an equality
 // constraint on the specified column that can be used to
 // decide on a route.
-func getMatch(node sqlparser.Expr, col sqlparser.ColIdent) (pv sqltypes.PlanValue, ok bool) {
+func getMatch(node sqlparser.Expr, col sqlparser.ColIdent) (evalengine.Expr, sqlparser.ComparisonExprOperator) {
 	filters := sqlparser.SplitAndExpression(nil, node)
 	for _, filter := range filters {
 		comparison, ok := filter.(*sqlparser.ComparisonExpr)
@@ -90,18 +98,18 @@ func getMatch(node sqlparser.Expr, col sqlparser.ColIdent) (pv sqltypes.PlanValu
 		default:
 			continue
 		}
-		pv, err := sqlparser.NewPlanValue(comparison.Right)
+		expr, err := evalengine.Convert(comparison.Right, &noColumnLookup{semTable: semantics.EmptySemTable()})
 		if err != nil {
 			continue
 		}
-		return pv, true
+		return expr, comparison.Operator
 	}
-	return sqltypes.PlanValue{}, false
+	return nil, 0
 }
 
 func nameMatch(node sqlparser.Expr, col sqlparser.ColIdent) bool {
-	colname, ok := node.(*sqlparser.ColName)
-	return ok && colname.Name.Equal(col)
+	colName, ok := node.(*sqlparser.ColName)
+	return ok && colName.Name.Equal(col)
 }
 
 func buildDMLPlan(vschema ContextVSchema, dmlType string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, tableExprs sqlparser.TableExprs, where *sqlparser.Where, orderBy sqlparser.OrderBy, limit *sqlparser.Limit, comments sqlparser.Comments, nodes ...sqlparser.SQLNode) (*engine.DML, vindexes.SingleColumn, string, error) {
diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go
index 07033d8ba7..329ec88ff3 100644
--- a/go/vt/vtgate/semantics/semantic_state.go
+++ b/go/vt/vtgate/semantics/semantic_state.go
@@ -318,3 +318,11 @@ func (st *SemTable) CopyExprInfo(src, dest sqlparser.Expr) {
 		st.ExprTypes[dest] = srcType
 	}
 }
+
+// EmptySemTable creates a new empty SemTable
+func EmptySemTable() *SemTable {
+	return &SemTable{
+		ExprTypes: make(map[sqlparser.Expr]Type),
+		Recursive: make(map[sqlparser.Expr]TableSet),
+	}
+}


Test patch:
diff --git a/go/vt/vtgate/engine/delete_test.go b/go/vt/vtgate/engine/delete_test.go
index 02b01b308e..0032f3c52d 100644
--- a/go/vt/vtgate/engine/delete_test.go
+++ b/go/vt/vtgate/engine/delete_test.go
@@ -20,6 +20,9 @@ import (
 	"errors"
 	"testing"
 
+	"vitess.io/vitess/go/mysql/collations"
+	"vitess.io/vitess/go/vt/vtgate/evalengine"
+
 	"github.com/stretchr/testify/require"
 
 	"vitess.io/vitess/go/sqltypes"
@@ -69,7 +72,7 @@ func TestDeleteEqual(t *testing.T) {
 			},
 			Query:  "dummy_delete",
 			Vindex: vindex.(vindexes.SingleColumn),
-			Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
 		},
 	}
 
@@ -82,9 +85,10 @@ func TestDeleteEqual(t *testing.T) {
 	})
 
 	// Failure case
-	del.Values = []sqltypes.PlanValue{{Key: "aa"}}
+	expr := evalengine.NewBindVar("aa", collations.TypedCollation{})
+	del.Values = []evalengine.Expr{expr}
 	_, err = del.TryExecute(vc, map[string]*querypb.BindVariable{}, false)
-	require.EqualError(t, err, "missing bind var aa")
+	require.EqualError(t, err, "Bind variable not found")
 }
 
 func TestDeleteEqualNoRoute(t *testing.T) {
@@ -102,7 +106,7 @@ func TestDeleteEqualNoRoute(t *testing.T) {
 			},
 			Query:  "dummy_delete",
 			Vindex: vindex.(vindexes.SingleColumn),
-			Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
 		},
 	}
 
@@ -131,7 +135,7 @@ func TestDeleteEqualNoScatter(t *testing.T) {
 			},
 			Query:  "dummy_delete",
 			Vindex: vindex.(vindexes.SingleColumn),
-			Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
 		},
 	}
 
@@ -148,7 +152,7 @@ func TestDeleteOwnedVindex(t *testing.T) {
 			Keyspace:         ks.Keyspace,
 			Query:            "dummy_delete",
 			Vindex:           ks.Vindexes["hash"].(vindexes.SingleColumn),
-			Values:           []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values:           []evalengine.Expr{evalengine.NewLiteralInt(1)},
 			Table:            ks.Tables["t1"],
 			OwnedVindexQuery: "dummy_subquery",
 			KsidVindex:       ks.Vindexes["hash"].(vindexes.SingleColumn),
diff --git a/go/vt/vtgate/engine/update_test.go b/go/vt/vtgate/engine/update_test.go
index 530f4ba04a..eb59994578 100644
--- a/go/vt/vtgate/engine/update_test.go
+++ b/go/vt/vtgate/engine/update_test.go
@@ -20,6 +20,9 @@ import (
 	"errors"
 	"testing"
 
+	"vitess.io/vitess/go/mysql/collations"
+	"vitess.io/vitess/go/vt/vtgate/evalengine"
+
 	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
 
 	"github.com/stretchr/testify/require"
@@ -72,7 +75,7 @@ func TestUpdateEqual(t *testing.T) {
 			},
 			Query:  "dummy_update",
 			Vindex: vindex.(vindexes.SingleColumn),
-			Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
 		},
 	}
 
@@ -85,9 +88,9 @@ func TestUpdateEqual(t *testing.T) {
 	})
 
 	// Failure case
-	upd.Values = []sqltypes.PlanValue{{Key: "aa"}}
+	upd.Values = []evalengine.Expr{evalengine.NewBindVar("aa", collations.TypedCollation{})}
 	_, err = upd.TryExecute(vc, map[string]*querypb.BindVariable{}, false)
-	require.EqualError(t, err, `missing bind var aa`)
+	require.EqualError(t, err, `Bind variable not found`)
 }
 
 func TestUpdateScatter(t *testing.T) {
@@ -101,7 +104,7 @@ func TestUpdateScatter(t *testing.T) {
 			},
 			Query:  "dummy_update",
 			Vindex: vindex.(vindexes.SingleColumn),
-			Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
 		},
 	}
 
@@ -124,7 +127,7 @@ func TestUpdateScatter(t *testing.T) {
 			},
 			Query:                "dummy_update",
 			Vindex:               vindex.(vindexes.SingleColumn),
-			Values:               []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values:               []evalengine.Expr{evalengine.NewLiteralInt(1)},
 			MultiShardAutocommit: true,
 		},
 	}
@@ -154,7 +157,7 @@ func TestUpdateEqualNoRoute(t *testing.T) {
 			},
 			Query:  "dummy_update",
 			Vindex: vindex.(vindexes.SingleColumn),
-			Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
 		},
 	}
 
@@ -183,7 +186,7 @@ func TestUpdateEqualNoScatter(t *testing.T) {
 			},
 			Query:  "dummy_update",
 			Vindex: vindex.(vindexes.SingleColumn),
-			Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
 		},
 	}
 
@@ -200,7 +203,7 @@ func TestUpdateEqualChangedVindex(t *testing.T) {
 			Keyspace:         ks.Keyspace,
 			Query:            "dummy_update",
 			Vindex:           ks.Vindexes["hash"].(vindexes.SingleColumn),
-			Values:           []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}},
+			Values:           []evalengine.Expr{evalengine.NewLiteralInt(1)},
 			Table:            ks.Tables["t1"],
 			OwnedVindexQuery: "dummy_subquery",
 			KsidVindex:       ks.Vindexes["hash"].(vindexes.SingleColumn),
@@ -449,12 +452,10 @@ func TestUpdateIn(t *testing.T) {
 		Keyspace: ks.Keyspace,
 		Query:    "dummy_update",
 		Vindex:   ks.Vindexes["hash"].(vindexes.SingleColumn),
-		Values: []sqltypes.PlanValue{{
-			Values: []sqltypes.PlanValue{
-				{Value: sqltypes.NewInt64(1)},
-				{Value: sqltypes.NewInt64(2)},
-			}},
-		}},
+		Values: []evalengine.Expr{&evalengine.TupleExpr{
+			evalengine.NewLiteralInt(1),
+			evalengine.NewLiteralInt(2),
+		}}},
 	}
 
 	vc := newDMLTestVCursor("-20", "20-")
@@ -474,12 +475,10 @@ func TestUpdateInStreamExecute(t *testing.T) {
 		Keyspace: ks.Keyspace,
 		Query:    "dummy_update",
 		Vindex:   ks.Vindexes["hash"].(vindexes.SingleColumn),
-		Values: []sqltypes.PlanValue{{
-			Values: []sqltypes.PlanValue{
-				{Value: sqltypes.NewInt64(1)},
-				{Value: sqltypes.NewInt64(2)},
-			}},
-		}},
+		Values: []evalengine.Expr{&evalengine.TupleExpr{
+			evalengine.NewLiteralInt(1),
+			evalengine.NewLiteralInt(2),
+		}}},
 	}
 
 	vc := newDMLTestVCursor("-20", "20-")
@@ -502,12 +501,10 @@ func TestUpdateInChangedVindex(t *testing.T) {
 			Keyspace: ks.Keyspace,
 			Query:    "dummy_update",
 			Vindex:   ks.Vindexes["hash"].(vindexes.SingleColumn),
-			Values: []sqltypes.PlanValue{{
-				Values: []sqltypes.PlanValue{
-					{Value: sqltypes.NewInt64(1)},
-					{Value: sqltypes.NewInt64(2)},
-				}},
-			},
+			Values: []evalengine.Expr{&evalengine.TupleExpr{
+				evalengine.NewLiteralInt(1),
+				evalengine.NewLiteralInt(2),
+			}},
 			Table:            ks.Tables["t1"],
 			OwnedVindexQuery: "dummy_subquery",
 			KsidVindex:       ks.Vindexes["hash"].(vindexes.SingleColumn),
diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.txt b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt
index a04303a687..45c4b31072 100644
--- a/go/vt/vtgate/planbuilder/testdata/dml_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt
@@ -139,7 +139,7 @@ Gen4 plan same as above
     "Query": "update `user` as route1 set a = 1 where id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -201,7 +201,7 @@ Gen4 plan same as above
     "Query": "update `user` set val = 1 where id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -225,7 +225,7 @@ Gen4 plan same as above
     "Query": "update `user` as user_alias set val = 1 where user_alias.id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -249,7 +249,7 @@ Gen4 plan same as above
     "Query": "update `user` set val = 1 where id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -273,7 +273,7 @@ Gen4 plan same as above
     "Query": "update `user` set val = 1 where `name` = 'foo' and id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -302,7 +302,7 @@ Gen4 plan same as above
     "Query": "update user_metadata set email = 'juan@vitess.io' where user_id = 1",
     "Table": "user_metadata",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -337,7 +337,7 @@ Gen4 plan same as above
     "Query": "update user_metadata set email = 'juan@vitess.io', address = '155 5th street' where user_id = 1",
     "Table": "user_metadata",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -366,7 +366,7 @@ Gen4 plan same as above
     "Query": "update user_metadata set email = 'juan@vitess.io' where user_id = 1 order by user_id asc limit 10",
     "Table": "user_metadata",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -390,7 +390,7 @@ Gen4 plan same as above
     "Query": "update `user` set val = 1 where id = id2 and id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -414,7 +414,7 @@ Gen4 plan same as above
     "Query": "update `user` set val = 1 where id = 18446744073709551616 and id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -440,7 +440,7 @@ Gen4 plan same as above
     "Query": "delete from `user` where id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -523,7 +523,7 @@ Gen4 plan same as above
     "Query": "delete from `user` as route1 where id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -566,7 +566,7 @@ Gen4 plan same as above
     "Query": "update music set val = 1 where id = 1",
     "Table": "music",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "music_user_map"
   }
@@ -630,7 +630,7 @@ Gen4 plan same as above
     "Query": "delete from music where id = 1",
     "Table": "music",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "music_user_map"
   }
@@ -654,7 +654,7 @@ Gen4 plan same as above
     "Query": "delete from music_extra where user_id = 1",
     "Table": "music_extra",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -1506,7 +1506,7 @@ Gen4 plan same as above
     "Query": "delete from multicolvin where kid = 1",
     "Table": "multicolvin",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "kid_index"
   }
@@ -1535,7 +1535,7 @@ Gen4 plan same as above
     "Query": "update multicolvin set column_b = 1, column_c = 2 where kid = 1",
     "Table": "multicolvin",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "kid_index"
   }
@@ -1565,7 +1565,7 @@ Gen4 plan same as above
     "Query": "update multicolvin set column_a = 0, column_b = 1, column_c = 2 where kid = 1",
     "Table": "multicolvin",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "kid_index"
   }
@@ -1690,10 +1690,7 @@ Gen4 plan same as above
     "Query": "update user_extra set val = 1 where user_id in (1, 2)",
     "Table": "user_extra",
     "Values": [
-      [
-        1,
-        2
-      ]
+      "(INT64(1), INT64(2))"
     ],
     "Vindex": "user_index"
   }
@@ -1898,10 +1895,7 @@ Gen4 plan same as above
     "Query": "delete from user_extra where user_id in (1, 2)",
     "Table": "user_extra",
     "Values": [
-      [
-        1,
-        2
-      ]
+      "(INT64(1), INT64(2))"
     ],
     "Vindex": "user_index"
   }
@@ -1968,7 +1962,7 @@ Gen4 plan same as above
     "Query": "update `user` set `name` = null where id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -2017,11 +2011,7 @@ Gen4 plan same as above
     "Query": "update `user` set `name` = null where id in (1, 2, 3)",
     "Table": "user",
     "Values": [
-      [
-        1,
-        2,
-        3
-      ]
+      "(INT64(1), INT64(2), INT64(3))"
     ],
     "Vindex": "user_index"
   }
@@ -2097,11 +2087,7 @@ Gen4 plan same as above
     "Query": "delete from `user` where id in (1, 2, 3)",
     "Table": "user",
     "Values": [
-      [
-        1,
-        2,
-        3
-      ]
+      "(INT64(1), INT64(2), INT64(3))"
     ],
     "Vindex": "user_index"
   }
@@ -2171,7 +2157,7 @@ Gen4 plan same as above
     "Query": "delete from music where id = 1",
     "Table": "music",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "music_user_map"
   }
@@ -2242,7 +2228,7 @@ Gen4 plan same as above
     "Query": "update multicolvin set column_c = 2 where kid = 1",
     "Table": "multicolvin",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "kid_index"
   }
@@ -2271,7 +2257,7 @@ Gen4 plan same as above
     "Query": "update `user` set `name` = _binary 'abc' where id = 1",
     "Table": "user",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "user_index"
   }
@@ -2489,7 +2475,7 @@ Gen4 plan same as above
     "Query": "delete from t1 where c2 = 10 and c3 = 20",
     "Table": "t1",
     "Values": [
-      20
+      "INT64(20)"
     ],
     "Vindex": "lookup_t1_2"
   }
@@ -2518,7 +2504,7 @@ Gen4 plan same as above
     "Query": "update t1 set c2 = 1 where c2 = 10 and c3 = 20",
     "Table": "t1",
     "Values": [
-      20
+      "INT64(20)"
     ],
     "Vindex": "lookup_t1_2"
   }
@@ -2544,10 +2530,7 @@ Gen4 plan same as above
     "Query": "delete from t1 where c2 = 10 and c3 in (20, 21)",
     "Table": "t1",
     "Values": [
-      [
-        20,
-        21
-      ]
+      "(INT64(20), INT64(21))"
     ],
     "Vindex": "lookup_t1_2"
   }
@@ -2576,10 +2559,7 @@ Gen4 plan same as above
     "Query": "update t1 set c2 = 1 where c2 = 10 and c3 in (20, 21)",
     "Table": "t1",
     "Values": [
-      [
-        20,
-        21
-      ]
+      "(INT64(20), INT64(21))"
     ],
     "Vindex": "lookup_t1_2"
   }
diff --git a/go/vt/vtgate/planbuilder/testdata/oltp_cases.txt b/go/vt/vtgate/planbuilder/testdata/oltp_cases.txt
index 7510afbd53..ef53626fd5 100644
--- a/go/vt/vtgate/planbuilder/testdata/oltp_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/oltp_cases.txt
@@ -207,7 +207,7 @@ Gen4 plan same as above
     "Query": "update sbtest6 set k = k + 1 where id = 5",
     "Table": "sbtest6",
     "Values": [
-      5
+      "INT64(5)"
     ],
     "Vindex": "hash"
   }
@@ -231,7 +231,7 @@ Gen4 plan same as above
     "Query": "update sbtest9 set c = 7 where id = 8",
     "Table": "sbtest9",
     "Values": [
-      8
+      "INT64(8)"
     ],
     "Vindex": "hash"
   }
@@ -255,7 +255,7 @@ Gen4 plan same as above
     "Query": "delete from sbtest15 where id = 7525",
     "Table": "sbtest15",
     "Values": [
-      7525
+      "INT64(7525)"
     ],
     "Vindex": "hash"
   }
diff --git a/go/vt/vtgate/planbuilder/testdata/tpcc_cases.txt b/go/vt/vtgate/planbuilder/testdata/tpcc_cases.txt
index 853485f767..c765f019c9 100644
--- a/go/vt/vtgate/planbuilder/testdata/tpcc_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/tpcc_cases.txt
@@ -89,7 +89,7 @@
     "Query": "update district1 set d_next_o_id = 56 where d_id = 9842 and d_w_id = 8546",
     "Table": "district1",
     "Values": [
-      8546
+      "INT64(8546)"
     ],
     "Vindex": "hash"
   }
@@ -227,7 +227,7 @@ Gen4 plan same as above
     "Query": "update stock1 set s_quantity = 894 where s_i_id = 156 and s_w_id = 6",
     "Table": "stock1",
     "Values": [
-      6
+      "INT64(6)"
     ],
     "Vindex": "hash"
   }
@@ -271,7 +271,7 @@ Gen4 plan same as above
     "Query": "update warehouse1 set w_ytd = w_ytd + 946879 where w_id = 3",
     "Table": "warehouse1",
     "Values": [
-      3
+      "INT64(3)"
     ],
     "Vindex": "hash"
   }
@@ -332,7 +332,7 @@ Gen4 plan same as above
     "Query": "update district1 set d_ytd = d_ytd + 2 where d_w_id = 89 and d_id = 9",
     "Table": "district1",
     "Values": [
-      89
+      "INT64(89)"
     ],
     "Vindex": "hash"
   }
@@ -541,7 +541,7 @@ Gen4 plan same as above
     "Query": "update customer1 set c_balance = 508.98, c_ytd_payment = 48941.980301, c_data = 'i am data' where c_w_id = 20 and c_d_id = 387 and c_id = 98",
     "Table": "customer1",
     "Values": [
-      20
+      "INT64(20)"
     ],
     "Vindex": "hash"
   }
@@ -565,7 +565,7 @@ Gen4 plan same as above
     "Query": "update customer1 set c_balance = 508.98, c_ytd_payment = 48941.980301 where c_w_id = 20 and c_d_id = 387 and c_id = 98",
     "Table": "customer1",
     "Values": [
-      20
+      "INT64(20)"
     ],
     "Vindex": "hash"
   }
@@ -831,7 +831,7 @@ Gen4 plan same as above
     "Query": "delete from new_orders1 where no_o_id = 2218 and no_d_id = 358 and no_w_id = 98465",
     "Table": "new_orders1",
     "Values": [
-      98465
+      "INT64(98465)"
     ],
     "Vindex": "hash"
   }
@@ -892,7 +892,7 @@ Gen4 plan same as above
     "Query": "update orders1 set o_carrier_id = 9 where o_id = 56 and o_d_id = 98 and o_w_id = 897",
     "Table": "orders1",
     "Values": [
-      897
+      "INT64(897)"
     ],
     "Vindex": "hash"
   }
@@ -916,7 +916,7 @@ Gen4 plan same as above
     "Query": "update order_line1 set ol_delivery_d = NOW() where ol_o_id = 235 and ol_d_id = 315 and ol_w_id = 8",
     "Table": "order_line1",
     "Values": [
-      8
+      "INT64(8)"
     ],
     "Vindex": "hash"
   }
@@ -977,7 +977,7 @@ Gen4 plan same as above
     "Query": "update customer1 set c_balance = c_balance + 988.01, c_delivery_cnt = c_delivery_cnt + 1 where c_id = 6 and c_d_id = 5 and c_w_id = 160",
     "Table": "customer1",
     "Values": [
-      160
+      "INT64(160)"
     ],
     "Vindex": "hash"
   }
@@ -1216,7 +1216,7 @@ Gen4 plan same as above
     "Query": "delete from order_line1 where ol_w_id = 178 and ol_d_id = 1 and ol_o_id = 84",
     "Table": "order_line1",
     "Values": [
-      178
+      "INT64(178)"
     ],
     "Vindex": "hash"
   }
@@ -1240,7 +1240,7 @@ Gen4 plan same as above
     "Query": "delete from orders1 where o_w_id = 1 and o_d_id = 3 and o_id = 384",
     "Table": "orders1",
     "Values": [
-      1
+      "INT64(1)"
     ],
     "Vindex": "hash"
   }
@@ -1264,7 +1264,7 @@ Gen4 plan same as above
     "Query": "delete from history1 where h_w_id = 75 and h_d_id = 102 limit 10",
     "Table": "history1",
     "Values": [
-      75
+      "INT64(75)"
     ],
     "Vindex": "hash"
   }