Skip to content

Commit

Permalink
fix: insert on duplicate key update missing BindVars (#14728)
Browse files Browse the repository at this point in the history
Co-authored-by: wlx5575 <[email protected]>
  • Loading branch information
wlx5575 and wlx5575 authored Dec 12, 2023
1 parent 21b490a commit 56aba1f
Show file tree
Hide file tree
Showing 10 changed files with 327 additions and 102 deletions.
10 changes: 10 additions & 0 deletions go/test/endtoend/vtgate/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ import (
"github.com/stretchr/testify/require"
)

func TestInsertOnDuplicateKey(t *testing.T) {
conn, closer := start(t)
defer closer()

utils.Exec(t, conn, "insert into t11(id, sharding_key, col1, col2, col3) values(1, 2, 'a', 1, 2)")
utils.Exec(t, conn, "insert into t11(id, sharding_key, col1, col2, col3) values(1, 2, 'a', 1, 2) on duplicate key update id=10;")
utils.AssertMatches(t, conn, "select id, sharding_key from t11 where id=10", "[[INT64(10) INT64(2)]]")

}

func TestInsertNeg(t *testing.T) {
conn, closer := start(t)
defer closer()
Expand Down
10 changes: 10 additions & 0 deletions go/test/endtoend/vtgate/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,13 @@ create table t10_id_to_keyspace_id_idx
keyspace_id varbinary(10),
primary key (id)
) Engine = InnoDB;

create table t11
(
id bigint,
sharding_key bigint,
col1 varchar(50),
col2 int,
col3 int,
primary key (id)
) Engine = InnoDB;
23 changes: 18 additions & 5 deletions go/test/endtoend/vtgate/vschema.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@

{
"sharded": true,
"vindexes": {
"unicode_loose_xxhash" : {
"unicode_loose_xxhash": {
"type": "unicode_loose_xxhash"
},
"unicode_loose_md5" : {
"unicode_loose_md5": {
"type": "unicode_loose_md5"
},
"hash": {
Expand Down Expand Up @@ -159,7 +158,10 @@
"name": "hash"
},
{
"columns": ["id2", "id1"],
"columns": [
"id2",
"id1"
],
"name": "t4_id2_vdx"
}
]
Expand All @@ -179,7 +181,10 @@
"name": "hash"
},
{
"columns": ["id2", "id1"],
"columns": [
"id2",
"id1"
],
"name": "t6_id2_vdx"
}
]
Expand Down Expand Up @@ -301,6 +306,14 @@
"name": "hash"
}
]
},
"t11": {
"column_vindexes": [
{
"column": "sharding_key",
"name": "hash"
}
]
}
}
}
13 changes: 9 additions & 4 deletions go/vt/vtgate/engine/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 17 additions & 12 deletions go/vt/vtgate/engine/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func newInsert(
table *vindexes.Table,
prefix string,
mid sqlparser.Values,
suffix string,
suffix sqlparser.OnDup,
) *Insert {
ins := &Insert{
InsertCommon: InsertCommon{
Expand Down Expand Up @@ -265,25 +265,30 @@ func (ins *Insert) getInsertShardedQueries(
for _, indexValue := range indexesPerRss[i] {
index, _ := strconv.ParseInt(string(indexValue.Value), 0, 64)
if keyspaceIDs[index] != nil {
walkFunc := func(node sqlparser.SQLNode) (kontinue bool, err error) {
if arg, ok := node.(*sqlparser.Argument); ok {
bv, exists := bindVars[arg.Name]
if !exists {
return false, vterrors.VT03026(arg.Name)
}
shardBindVars[arg.Name] = bv
}
return true, nil
}
mids = append(mids, sqlparser.String(ins.Mid[index]))
for _, expr := range ins.Mid[index] {
err = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) {
if arg, ok := node.(*sqlparser.Argument); ok {
bv, exists := bindVars[arg.Name]
if !exists {
return false, vterrors.VT03026(arg.Name)
}
shardBindVars[arg.Name] = bv
}
return true, nil
}, expr, nil)
err = sqlparser.Walk(walkFunc, expr, nil)
if err != nil {
return nil, nil, err
}
}
err = sqlparser.Walk(walkFunc, ins.Suffix, nil)
if err != nil {
return nil, nil, err
}
}
}
rewritten := ins.Prefix + strings.Join(mids, ",") + ins.Suffix
rewritten := ins.Prefix + strings.Join(mids, ",") + sqlparser.String(ins.Suffix)
queries[i] = &querypb.BoundQuery{
Sql: rewritten,
BindVariables: shardBindVars,
Expand Down
4 changes: 3 additions & 1 deletion go/vt/vtgate/engine/insert_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"strconv"
"strings"

"vitess.io/vitess/go/vt/sqlparser"

"vitess.io/vitess/go/sqltypes"
"vitess.io/vitess/go/vt/key"
querypb "vitess.io/vitess/go/vt/proto/query"
Expand Down Expand Up @@ -73,7 +75,7 @@ type (

// Prefix, Suffix are for sharded insert plans.
Prefix string
Suffix string
Suffix sqlparser.OnDup

// Insert needs tx handling
txNeeded
Expand Down
6 changes: 3 additions & 3 deletions go/vt/vtgate/engine/insert_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func newInsertSelect(
keyspace *vindexes.Keyspace,
table *vindexes.Table,
prefix string,
suffix string,
suffix sqlparser.OnDup,
vv [][]int,
input Primitive,
) *InsertSelect {
Expand Down Expand Up @@ -172,7 +172,7 @@ func (ins *InsertSelect) getInsertUnshardedQuery(rows []sqltypes.Row, bindVars m
}
mids = append(mids, row)
}
return ins.Prefix + sqlparser.String(mids) + ins.Suffix
return ins.Prefix + sqlparser.String(mids) + sqlparser.String(ins.Suffix)
}

func (ins *InsertSelect) insertIntoShardedTable(
Expand Down Expand Up @@ -270,7 +270,7 @@ func (ins *InsertSelect) getInsertShardedQueries(
mids = append(mids, row)
}
}
rewritten := ins.Prefix + sqlparser.String(mids) + ins.Suffix
rewritten := ins.Prefix + sqlparser.String(mids) + sqlparser.String(ins.Suffix)
queries[i] = &querypb.BoundQuery{
Sql: rewritten,
BindVariables: bvs,
Expand Down
Loading

0 comments on commit 56aba1f

Please sign in to comment.