diff --git a/go/test/endtoend/vtgate/queries/random/query_gen.go b/go/test/endtoend/vtgate/queries/random/query_gen.go index 69bf66903f3..f94f2e11209 100644 --- a/go/test/endtoend/vtgate/queries/random/query_gen.go +++ b/go/test/endtoend/vtgate/queries/random/query_gen.go @@ -395,7 +395,7 @@ func (sg *selectGenerator) createJoin(tables []tableT) { // returns 1-3 random expressions based on the last two elements of tables // tables should have at least two elements -func (sg *selectGenerator) createJoinPredicates(tables []tableT) sqlparser.Exprs { +func (sg *selectGenerator) createJoinPredicates(tables []tableT) []sqlparser.Expr { if len(tables) < 2 { log.Fatalf("tables has %d elements, needs at least 2", len(tables)) } @@ -527,7 +527,7 @@ func (sg *selectGenerator) createHavingPredicates(grouping []column) { } // returns between minExprs and maxExprs random expressions using generators -func (sg *selectGenerator) createRandomExprs(minExprs, maxExprs int, generators ...sqlparser.ExprGenerator) (predicates sqlparser.Exprs) { +func (sg *selectGenerator) createRandomExprs(minExprs, maxExprs int, generators ...sqlparser.ExprGenerator) (predicates []sqlparser.Expr) { if minExprs > maxExprs { log.Fatalf("minExprs is greater than maxExprs; minExprs: %d, maxExprs: %d\n", minExprs, maxExprs) } else if maxExprs <= 0 { diff --git a/go/vt/sqlparser/analyzer_test.go b/go/vt/sqlparser/analyzer_test.go index 0a2de52ef19..e60e10d08ca 100644 --- a/go/vt/sqlparser/analyzer_test.go +++ b/go/vt/sqlparser/analyzer_test.go @@ -195,7 +195,7 @@ func TestAndExpressions(t *testing.T) { } testcases := []struct { name string - expressions Exprs + expressions []Expr expectedOutput Expr }{ { @@ -204,7 +204,7 @@ func TestAndExpressions(t *testing.T) { expectedOutput: nil, }, { name: "two equal inputs", - expressions: Exprs{ + expressions: []Expr{ greaterThanExpr, equalExpr, equalExpr, @@ -216,7 +216,7 @@ func TestAndExpressions(t *testing.T) { }, { name: "two equal inputs", - expressions: Exprs{ + expressions: []Expr{ equalExpr, equalExpr, }, diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index 5ee96397c9f..97735c39dae 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -3566,7 +3566,9 @@ func (*JSONObjectAgg) AggrName() string { return "json_objectagg" } // Exprs represents a list of value expressions. // It's not a valid expression because it's not parenthesized. -type Exprs []Expr +type Exprs struct { + Exprs []Expr +} func (ValTuple) iColTuple() {} func (*Subquery) iColTuple() {} diff --git a/go/vt/sqlparser/ast_clone.go b/go/vt/sqlparser/ast_clone.go index d5be47a4a4b..cde83314a10 100644 --- a/go/vt/sqlparser/ast_clone.go +++ b/go/vt/sqlparser/ast_clone.go @@ -161,8 +161,8 @@ func CloneSQLNode(in SQLNode) SQLNode { return CloneRefOfExplainStmt(in) case *ExplainTab: return CloneRefOfExplainTab(in) - case Exprs: - return CloneExprs(in) + case *Exprs: + return CloneRefOfExprs(in) case *ExtractFuncExpr: return CloneRefOfExtractFuncExpr(in) case *ExtractValueExpr: @@ -1307,16 +1307,14 @@ func CloneRefOfExplainTab(n *ExplainTab) *ExplainTab { return &out } -// CloneExprs creates a deep clone of the input. -func CloneExprs(n Exprs) Exprs { +// CloneRefOfExprs creates a deep clone of the input. +func CloneRefOfExprs(n *Exprs) *Exprs { if n == nil { return nil } - res := make(Exprs, len(n)) - for i, x := range n { - res[i] = CloneExpr(x) - } - return res + out := *n + out.Exprs = CloneSliceOfExpr(n.Exprs) + return &out } // CloneRefOfExtractFuncExpr creates a deep clone of the input. diff --git a/go/vt/sqlparser/ast_copy_on_rewrite.go b/go/vt/sqlparser/ast_copy_on_rewrite.go index 286c85cb805..502c58e9a10 100644 --- a/go/vt/sqlparser/ast_copy_on_rewrite.go +++ b/go/vt/sqlparser/ast_copy_on_rewrite.go @@ -160,8 +160,8 @@ func (c *cow) copyOnRewriteSQLNode(n SQLNode, parent SQLNode) (out SQLNode, chan return c.copyOnRewriteRefOfExplainStmt(n, parent) case *ExplainTab: return c.copyOnRewriteRefOfExplainTab(n, parent) - case Exprs: - return c.copyOnRewriteExprs(n, parent) + case *Exprs: + return c.copyOnRewriteRefOfExprs(n, parent) case *ExtractFuncExpr: return c.copyOnRewriteRefOfExtractFuncExpr(n, parent) case *ExtractValueExpr: @@ -2158,22 +2158,29 @@ func (c *cow) copyOnRewriteRefOfExplainTab(n *ExplainTab, parent SQLNode) (out S } return } -func (c *cow) copyOnRewriteExprs(n Exprs, parent SQLNode) (out SQLNode, changed bool) { +func (c *cow) copyOnRewriteRefOfExprs(n *Exprs, parent SQLNode) (out SQLNode, changed bool) { if n == nil || c.cursor.stop { return n, false } out = n if c.pre == nil || c.pre(n, parent) { - res := make(Exprs, len(n)) - for x, el := range n { - this, change := c.copyOnRewriteExpr(el, n) - res[x] = this.(Expr) - if change { - changed = true + var changedExprs bool + _Exprs := make([]Expr, len(n.Exprs)) + for x, el := range n.Exprs { + this, changed := c.copyOnRewriteExpr(el, n) + _Exprs[x] = this.(Expr) + if changed { + changedExprs = true } } - if changed { - out = res + if changedExprs { + res := *n + res.Exprs = _Exprs + out = &res + if c.cloned != nil { + c.cloned(n, out) + } + changed = true } } if c.post != nil { diff --git a/go/vt/sqlparser/ast_equals.go b/go/vt/sqlparser/ast_equals.go index d8e1b55dc24..2ccd9dc1792 100644 --- a/go/vt/sqlparser/ast_equals.go +++ b/go/vt/sqlparser/ast_equals.go @@ -440,12 +440,12 @@ func (cmp *Comparator) SQLNode(inA, inB SQLNode) bool { return false } return cmp.RefOfExplainTab(a, b) - case Exprs: - b, ok := inB.(Exprs) + case *Exprs: + b, ok := inB.(*Exprs) if !ok { return false } - return cmp.Exprs(a, b) + return cmp.RefOfExprs(a, b) case *ExtractFuncExpr: b, ok := inB.(*ExtractFuncExpr) if !ok { @@ -2534,17 +2534,15 @@ func (cmp *Comparator) RefOfExplainTab(a, b *ExplainTab) bool { cmp.TableName(a.Table, b.Table) } -// Exprs does deep equals between the two objects. -func (cmp *Comparator) Exprs(a, b Exprs) bool { - if len(a) != len(b) { - return false +// RefOfExprs does deep equals between the two objects. +func (cmp *Comparator) RefOfExprs(a, b *Exprs) bool { + if a == b { + return true } - for i := 0; i < len(a); i++ { - if !cmp.Expr(a[i], b[i]) { - return false - } + if a == nil || b == nil { + return false } - return true + return cmp.SliceOfExpr(a.Exprs, b.Exprs) } // RefOfExtractFuncExpr does deep equals between the two objects. diff --git a/go/vt/sqlparser/ast_format.go b/go/vt/sqlparser/ast_format.go index 9458891e31f..03e3a044732 100644 --- a/go/vt/sqlparser/ast_format.go +++ b/go/vt/sqlparser/ast_format.go @@ -1312,9 +1312,9 @@ func (node *Where) Format(buf *TrackedBuffer) { } // Format formats the node. -func (node Exprs) Format(buf *TrackedBuffer) { +func (node *Exprs) Format(buf *TrackedBuffer) { var prefix string - for _, n := range node { + for _, n := range node.Exprs { buf.astPrintf(node, "%s%v", prefix, n) prefix = ", " } @@ -1499,7 +1499,7 @@ func (node *ColName) Format(buf *TrackedBuffer) { // Format formats the node. func (node ValTuple) Format(buf *TrackedBuffer) { - buf.astPrintf(node, "(%v)", Exprs(node)) + buf.astPrintf(node, "(%v)", NewExprs(node)) } // Format formats the node. diff --git a/go/vt/sqlparser/ast_format_fast.go b/go/vt/sqlparser/ast_format_fast.go index 73a7e038c77..7ec960acb19 100644 --- a/go/vt/sqlparser/ast_format_fast.go +++ b/go/vt/sqlparser/ast_format_fast.go @@ -1704,9 +1704,9 @@ func (node *Where) FormatFast(buf *TrackedBuffer) { } // FormatFast formats the node. -func (node Exprs) FormatFast(buf *TrackedBuffer) { +func (node *Exprs) FormatFast(buf *TrackedBuffer) { var prefix string - for _, n := range node { + for _, n := range node.Exprs { buf.WriteString(prefix) n.FormatFast(buf) prefix = ", " @@ -1937,7 +1937,7 @@ func (node *ColName) FormatFast(buf *TrackedBuffer) { // FormatFast formats the node. func (node ValTuple) FormatFast(buf *TrackedBuffer) { buf.WriteByte('(') - Exprs(node).FormatFast(buf) + NewExprs(node).FormatFast(buf) buf.WriteByte(')') } diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index ce1426ae744..ce5a4ffdc42 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -2354,7 +2354,7 @@ func ContainsAggregation(e SQLNode) bool { } // setFuncArgs sets the arguments for the aggregation function, while checking that there is only one argument -func setFuncArgs(aggr AggrFunc, exprs Exprs, name string) error { +func setFuncArgs(aggr AggrFunc, exprs []Expr, name string) error { if len(exprs) != 1 { return vterrors.VT03001(name) } @@ -3071,3 +3071,7 @@ func NewFuncExpr(name string, exprs ...Expr) *FuncExpr { Exprs: exprs, } } + +func NewExprs(exprs ...Expr) *Exprs { + return &Exprs{Exprs: exprs} +} diff --git a/go/vt/sqlparser/ast_rewrite.go b/go/vt/sqlparser/ast_rewrite.go index 3cac5bc09ad..e7342a1afa2 100644 --- a/go/vt/sqlparser/ast_rewrite.go +++ b/go/vt/sqlparser/ast_rewrite.go @@ -160,8 +160,8 @@ func (a *application) rewriteSQLNode(parent SQLNode, node SQLNode, replacer repl return a.rewriteRefOfExplainStmt(parent, node, replacer) case *ExplainTab: return a.rewriteRefOfExplainTab(parent, node, replacer) - case Exprs: - return a.rewriteExprs(parent, node, replacer) + case *Exprs: + return a.rewriteRefOfExprs(parent, node, replacer) case *ExtractFuncExpr: return a.rewriteRefOfExtractFuncExpr(parent, node, replacer) case *ExtractValueExpr: @@ -3056,7 +3056,7 @@ func (a *application) rewriteRefOfExplainTab(parent SQLNode, node *ExplainTab, r } return true } -func (a *application) rewriteExprs(parent SQLNode, node Exprs, replacer replacerFunc) bool { +func (a *application) rewriteRefOfExprs(parent SQLNode, node *Exprs, replacer replacerFunc) bool { if node == nil { return true } @@ -3073,10 +3073,10 @@ func (a *application) rewriteExprs(parent SQLNode, node Exprs, replacer replacer return true } } - for x, el := range node { + for x, el := range node.Exprs { if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { - parent.(Exprs)[idx] = newNode.(Expr) + parent.(*Exprs).Exprs[idx] = newNode.(Expr) } }(x)) { return false diff --git a/go/vt/sqlparser/ast_visit.go b/go/vt/sqlparser/ast_visit.go index 85da1abef09..fe0911037d9 100644 --- a/go/vt/sqlparser/ast_visit.go +++ b/go/vt/sqlparser/ast_visit.go @@ -160,8 +160,8 @@ func VisitSQLNode(in SQLNode, f Visit) error { return VisitRefOfExplainStmt(in, f) case *ExplainTab: return VisitRefOfExplainTab(in, f) - case Exprs: - return VisitExprs(in, f) + case *Exprs: + return VisitRefOfExprs(in, f) case *ExtractFuncExpr: return VisitRefOfExtractFuncExpr(in, f) case *ExtractValueExpr: @@ -1564,14 +1564,14 @@ func VisitRefOfExplainTab(in *ExplainTab, f Visit) error { } return nil } -func VisitExprs(in Exprs, f Visit) error { +func VisitRefOfExprs(in *Exprs, f Visit) error { if in == nil { return nil } if cont, err := f(in); err != nil || !cont { return err } - for _, el := range in { + for _, el := range in.Exprs { if err := VisitExpr(el, f); err != nil { return err } diff --git a/go/vt/sqlparser/predicate_rewriting.go b/go/vt/sqlparser/predicate_rewriting.go index 234a2f4acd5..4dd4c09556d 100644 --- a/go/vt/sqlparser/predicate_rewriting.go +++ b/go/vt/sqlparser/predicate_rewriting.go @@ -213,7 +213,7 @@ func simplifyAnd(expr *AndExpr) (Expr, bool) { // And rewrite that to WHERE (a, b) IN ((1,11), (2,12), (3,13)) func ExtractINFromOR(expr *OrExpr) []Expr { var varNames []*ColName - var values []Exprs + var values [][]Expr orSlice := orToSlice(expr) for _, expr := range orSlice { andSlice := andToSlice(expr) diff --git a/go/vt/sqlparser/random_expr.go b/go/vt/sqlparser/random_expr.go index f5b394b36fe..2442906bb8e 100644 --- a/go/vt/sqlparser/random_expr.go +++ b/go/vt/sqlparser/random_expr.go @@ -246,7 +246,9 @@ func (g *Generator) randomAggregate(genConfig ExprGeneratorConfig) Expr { options := []exprF{ func() Expr { return &CountStar{} }, - func() Expr { return &Count{Args: Exprs{g.Expression(genConfig.anyTypeConfig())}, Distinct: isDistinct} }, + func() Expr { + return &Count{Args: []Expr{g.Expression(genConfig.anyTypeConfig())}, Distinct: isDistinct} + }, func() Expr { return &Sum{Arg: g.Expression(genConfig), Distinct: isDistinct} }, func() Expr { return &Min{Arg: g.Expression(genConfig), Distinct: isDistinct} }, func() Expr { return &Max{Arg: g.Expression(genConfig), Distinct: isDistinct} }, @@ -269,7 +271,7 @@ func (g *Generator) booleanExpr(genConfig ExprGeneratorConfig) Expr { func() Expr { return g.orExpr(genConfig) }, func() Expr { return g.comparison(genConfig.intTypeConfig()) }, func() Expr { return g.comparison(genConfig.stringTypeConfig()) }, - //func() Expr { return g.comparison(genConfig) }, // this is not accepted by the parser + // func() Expr { return g.comparison(genConfig) }, // this is not accepted by the parser func() Expr { return g.inExpr(genConfig) }, func() Expr { return g.existsExpr(genConfig) }, func() Expr { return g.between(genConfig.intTypeConfig()) }, @@ -374,7 +376,7 @@ func (g *Generator) randomBool(prob float32) bool { } func (g *Generator) intLiteral() Expr { - t := fmt.Sprintf("%d", rand.IntN(100)-rand.IntN(100)) //nolint SA4000 + t := fmt.Sprintf("%d", rand.IntN(100)-rand.IntN(100)) // nolint SA4000 return NewIntLiteral(t) } diff --git a/go/vt/vtgate/evalengine/expr_env_test.go b/go/vt/vtgate/evalengine/expr_env_test.go index f75cc6f1376..1206ac42f0a 100644 --- a/go/vt/vtgate/evalengine/expr_env_test.go +++ b/go/vt/vtgate/evalengine/expr_env_test.go @@ -42,7 +42,7 @@ func TestExpressionEnvTypeOf(t *testing.T) { Type: sqltypes.Unknown, Offset: 1, Original: &sqlparser.Count{ - Args: sqlparser.Exprs{ + Args: []sqlparser.Expr{ sqlparser.NewColName("l_discount"), }, }, diff --git a/go/vt/vtgate/planbuilder/operators/info_schema_planning.go b/go/vt/vtgate/planbuilder/operators/info_schema_planning.go index f8dc9b9d281..b3c1195b132 100644 --- a/go/vt/vtgate/planbuilder/operators/info_schema_planning.go +++ b/go/vt/vtgate/planbuilder/operators/info_schema_planning.go @@ -18,7 +18,6 @@ package operators import ( "maps" - "slices" "strings" "vitess.io/vitess/go/mysql/collations" @@ -35,14 +34,14 @@ import ( // They are special because we usually don't know at plan-time // what keyspace the query go to, because we don't see normalized literal values type InfoSchemaRouting struct { - SysTableTableSchema []sqlparser.Expr + SysTableTableSchema *sqlparser.Exprs SysTableTableName map[string]sqlparser.Expr Table *QueryTable } func (isr *InfoSchemaRouting) UpdateRoutingParams(ctx *plancontext.PlanningContext, rp *engine.RoutingParameters) { rp.SysTableTableSchema = nil - for _, expr := range isr.SysTableTableSchema { + for _, expr := range isr.SysTableTableSchema.Exprs { eexpr, err := evalengine.Translate(expr, &evalengine.Config{ Collation: collations.SystemCollation.Collation, ResolveColumn: NotImplementedSchemaInfoResolver, @@ -71,7 +70,7 @@ func (isr *InfoSchemaRouting) UpdateRoutingParams(ctx *plancontext.PlanningConte func (isr *InfoSchemaRouting) Clone() Routing { return &InfoSchemaRouting{ - SysTableTableSchema: slices.Clone(isr.SysTableTableSchema), + SysTableTableSchema: sqlparser.Clone(isr.SysTableTableSchema), SysTableTableName: maps.Clone(isr.SysTableTableName), Table: isr.Table, } @@ -88,14 +87,14 @@ func (isr *InfoSchemaRouting) updateRoutingLogic(ctx *plancontext.PlanningContex } if isTableSchema { - for _, s := range isr.SysTableTableSchema { + for _, s := range isr.SysTableTableSchema.Exprs { if sqlparser.Equals.Expr(out, s) { // we already have this expression in the list // stating it again does not add value return isr } } - isr.SysTableTableSchema = append(isr.SysTableTableSchema, out) + isr.SysTableTableSchema.Exprs = append(isr.SysTableTableSchema.Exprs, out) } else { isr.SysTableTableName[bvName] = out } @@ -174,8 +173,8 @@ func tryMergeInfoSchemaRoutings(ctx *plancontext.PlanningContext, routingA, rout // we have already checked type earlier, so this should always be safe isrA := routingA.(*InfoSchemaRouting) isrB := routingB.(*InfoSchemaRouting) - emptyA := len(isrA.SysTableTableName) == 0 && len(isrA.SysTableTableSchema) == 0 - emptyB := len(isrB.SysTableTableName) == 0 && len(isrB.SysTableTableSchema) == 0 + emptyA := len(isrA.SysTableTableName) == 0 && len(isrA.SysTableTableSchema.Exprs) == 0 + emptyB := len(isrB.SysTableTableName) == 0 && len(isrB.SysTableTableSchema.Exprs) == 0 switch { // if either side has no predicates to help us route, we can merge them @@ -185,7 +184,7 @@ func tryMergeInfoSchemaRoutings(ctx *plancontext.PlanningContext, routingA, rout return m.merge(ctx, lhsRoute, rhsRoute, isrA) // if we have no schema predicates on either side, we can merge if the table info is the same - case len(isrA.SysTableTableSchema) == 0 && len(isrB.SysTableTableSchema) == 0: + case len(isrA.SysTableTableSchema.Exprs) == 0 && len(isrB.SysTableTableSchema.Exprs) == 0: for k, expr := range isrB.SysTableTableName { if e, found := isrA.SysTableTableName[k]; found && !sqlparser.Equals.Expr(expr, e) { // schema names are the same, but we have contradicting table names, so we give up @@ -196,7 +195,7 @@ func tryMergeInfoSchemaRoutings(ctx *plancontext.PlanningContext, routingA, rout return m.merge(ctx, lhsRoute, rhsRoute, isrA) // if both sides have the same schema predicate, we can safely merge them - case sqlparser.Equals.Exprs(isrA.SysTableTableSchema, isrB.SysTableTableSchema): + case sqlparser.Equals.RefOfExprs(isrA.SysTableTableSchema, isrB.SysTableTableSchema): for k, expr := range isrB.SysTableTableName { isrA.SysTableTableName[k] = expr } diff --git a/go/vt/vtgate/simplifier/expression_simplifier.go b/go/vt/vtgate/simplifier/expression_simplifier.go index b64402cfaac..8395fb26d17 100644 --- a/go/vt/vtgate/simplifier/expression_simplifier.go +++ b/go/vt/vtgate/simplifier/expression_simplifier.go @@ -29,7 +29,7 @@ type CheckF = func(sqlparser.Expr) bool func SimplifyExpr(in sqlparser.Expr, test CheckF) sqlparser.Expr { // since we can't rewrite the top level, wrap the expr in an Exprs object - smallestKnown := sqlparser.Exprs{sqlparser.Clone(in)} + smallestKnown := sqlparser.NewExprs(sqlparser.Clone(in)) alwaysVisit := func(node, parent sqlparser.SQLNode) bool { return true @@ -42,7 +42,7 @@ func SimplifyExpr(in sqlparser.Expr, test CheckF) sqlparser.Expr { for expr != nil { cursor.Replace(expr) - valid := test(smallestKnown[0]) + valid := test(smallestKnown.Exprs[0]) if valid { break // we will still continue trying to simplify other expressions at this level } else { @@ -59,12 +59,13 @@ func SimplifyExpr(in sqlparser.Expr, test CheckF) sqlparser.Expr { for { prevSmallest := sqlparser.Clone(smallestKnown) sqlparser.SafeRewrite(smallestKnown, alwaysVisit, up) - if sqlparser.Equals.Exprs(prevSmallest, smallestKnown) { + _ = prevSmallest + if sqlparser.Equals.RefOfExprs(prevSmallest, smallestKnown) { break } } - return smallestKnown[0] + return smallestKnown.Exprs[0] } type shrinker struct { diff --git a/go/vt/vtgate/vschema_manager.go b/go/vt/vtgate/vschema_manager.go index e73bff4c196..c4e40956253 100644 --- a/go/vt/vtgate/vschema_manager.go +++ b/go/vt/vtgate/vschema_manager.go @@ -276,7 +276,7 @@ func (vm *VSchemaManager) updateTableInfo(vschema *vindexes.VSchema, ks *vindexe rTbl.PrimaryKey = append(rTbl.PrimaryKey, idxCol.Column) } case sqlparser.IndexTypeUnique: - var uniqueKey sqlparser.Exprs + var uniqueKey []sqlparser.Expr for _, idxCol := range idxDef.Columns { if idxCol.Expression == nil { uniqueKey = append(uniqueKey, sqlparser.NewColName(idxCol.Column.String())) diff --git a/go/vt/vtgate/vschema_manager_test.go b/go/vt/vtgate/vschema_manager_test.go index b4b7a20804f..acd0f11fe07 100644 --- a/go/vt/vtgate/vschema_manager_test.go +++ b/go/vt/vtgate/vschema_manager_test.go @@ -89,7 +89,7 @@ func TestVSchemaUpdate(t *testing.T) { Keyspace: ks, ColumnListAuthoritative: true, PrimaryKey: sqlparser.Columns{sqlparser.NewIdentifierCI("a")}, - UniqueKeys: []sqlparser.Exprs{ + UniqueKeys: [][]sqlparser.Expr{ {sqlparser.NewColName("b")}, {sqlparser.NewColName("c"), sqlparser.NewColName("d")}, }, @@ -99,7 +99,7 @@ func TestVSchemaUpdate(t *testing.T) { Keyspace: ks, ColumnListAuthoritative: true, PrimaryKey: sqlparser.Columns{sqlparser.NewIdentifierCI("a")}, - UniqueKeys: []sqlparser.Exprs{ + UniqueKeys: [][]sqlparser.Expr{ {&sqlparser.BinaryExpr{Operator: sqlparser.DivOp, Left: sqlparser.NewColName("b"), Right: sqlparser.NewIntLiteral("2")}}, {sqlparser.NewColName("c"), &sqlparser.BinaryExpr{Operator: sqlparser.PlusOp, Left: sqlparser.NewColName("d"), Right: sqlparser.NewColName("e")}}, }, diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index e5115afe6d3..fd836c2cf8e 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -838,7 +838,7 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp // analyzeInKeyRange allows the following constructs: "in_keyrange('-80')", // "in_keyrange(col, 'hash', '-80')", "in_keyrange(col, 'local_vindex', '-80')", or // "in_keyrange(col, 'ks.external_vindex', '-80')". -func (plan *Plan) analyzeInKeyRange(vschema *localVSchema, exprs sqlparser.Exprs) error { +func (plan *Plan) analyzeInKeyRange(vschema *localVSchema, exprs []sqlparser.Expr) error { var colnames []sqlparser.IdentifierCI var krExpr sqlparser.Expr whereFilter := Filter{ @@ -879,7 +879,7 @@ func (plan *Plan) analyzeInKeyRange(vschema *localVSchema, exprs sqlparser.Exprs krExpr = exprs[len(exprs)-1] default: - return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unexpected in_keyrange parameters: %v", sqlparser.String(exprs)) + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unexpected in_keyrange parameters: %v", sqlparser.SliceString(exprs)) } var err error whereFilter.VindexColumns, err = buildVindexColumns(plan.Table, colnames)