зеркало из https://github.com/github/vitess-gh.git
Merge pull request #63 from github/arthur/backport-vindex-lock-options
Backport `read_lock` and `no_verify` VIndex options
This commit is contained in:
Коммит
a5fb1dc1e2
|
@ -41,6 +41,10 @@ var (
|
|||
id BIGINT NOT NULL,
|
||||
field BIGINT NOT NULL,
|
||||
field2 BIGINT,
|
||||
field3 BIGINT,
|
||||
field4 BIGINT,
|
||||
field5 BIGINT,
|
||||
field6 BIGINT,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=Innodb;
|
||||
|
||||
|
@ -56,6 +60,30 @@ CREATE TABLE lookup2 (
|
|||
UNIQUE KEY (field2)
|
||||
) ENGINE=Innodb;
|
||||
|
||||
CREATE TABLE lookup3 (
|
||||
field3 BIGINT NOT NULL,
|
||||
keyspace_id binary(8),
|
||||
UNIQUE KEY (field3)
|
||||
) ENGINE=Innodb;
|
||||
|
||||
CREATE TABLE lookup4 (
|
||||
field4 BIGINT NOT NULL,
|
||||
keyspace_id binary(8),
|
||||
UNIQUE KEY (field4)
|
||||
) ENGINE=Innodb;
|
||||
|
||||
CREATE TABLE lookup5 (
|
||||
field5 BIGINT NOT NULL,
|
||||
keyspace_id binary(8),
|
||||
UNIQUE KEY (field5)
|
||||
) ENGINE=Innodb;
|
||||
|
||||
CREATE TABLE lookup6 (
|
||||
field6 BIGINT NOT NULL,
|
||||
keyspace_id binary(8),
|
||||
UNIQUE KEY (field6)
|
||||
) ENGINE=Innodb;
|
||||
|
||||
CREATE TABLE thex (
|
||||
id VARBINARY(64) NOT NULL,
|
||||
field BIGINT NOT NULL,
|
||||
|
@ -88,7 +116,7 @@ CREATE TABLE thex (
|
|||
"table": "lookup1",
|
||||
"from": "field",
|
||||
"to": "keyspace_id",
|
||||
"ignore_nulls": "true"
|
||||
"ignore_nulls": "true"
|
||||
},
|
||||
"owner": "t1"
|
||||
},
|
||||
|
@ -98,7 +126,47 @@ CREATE TABLE thex (
|
|||
"table": "lookup2",
|
||||
"from": "field2",
|
||||
"to": "keyspace_id",
|
||||
"ignore_nulls": "true"
|
||||
"ignore_nulls": "true"
|
||||
},
|
||||
"owner": "t1"
|
||||
},
|
||||
"lookup3": {
|
||||
"type": "lookup",
|
||||
"params": {
|
||||
"from": "field3",
|
||||
"no_verify": "true",
|
||||
"table": "lookup3",
|
||||
"to": "keyspace_id"
|
||||
},
|
||||
"owner": "t1"
|
||||
},
|
||||
"lookup4": {
|
||||
"type": "lookup",
|
||||
"params": {
|
||||
"from": "field4",
|
||||
"read_lock": "exclusive",
|
||||
"table": "lookup4",
|
||||
"to": "keyspace_id"
|
||||
},
|
||||
"owner": "t1"
|
||||
},
|
||||
"lookup5": {
|
||||
"type": "lookup",
|
||||
"params": {
|
||||
"from": "field5",
|
||||
"read_lock": "shared",
|
||||
"table": "lookup5",
|
||||
"to": "keyspace_id"
|
||||
},
|
||||
"owner": "t1"
|
||||
},
|
||||
"lookup6": {
|
||||
"type": "lookup",
|
||||
"params": {
|
||||
"from": "field6",
|
||||
"read_lock": "none",
|
||||
"table": "lookup6",
|
||||
"to": "keyspace_id"
|
||||
},
|
||||
"owner": "t1"
|
||||
}
|
||||
|
@ -117,6 +185,22 @@ CREATE TABLE thex (
|
|||
{
|
||||
"column": "field2",
|
||||
"name": "lookup2"
|
||||
},
|
||||
{
|
||||
"column": "field3",
|
||||
"name": "lookup3"
|
||||
},
|
||||
{
|
||||
"column": "field4",
|
||||
"name": "lookup4"
|
||||
},
|
||||
{
|
||||
"column": "field5",
|
||||
"name": "lookup5"
|
||||
},
|
||||
{
|
||||
"column": "field6",
|
||||
"name": "lookup6"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -136,6 +220,38 @@ CREATE TABLE thex (
|
|||
}
|
||||
]
|
||||
},
|
||||
"lookup3": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
"column": "field3",
|
||||
"name": "binary_md5_vdx"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lookup4": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
"column": "field4",
|
||||
"name": "binary_md5_vdx"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lookup5": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
"column": "field5",
|
||||
"name": "binary_md5_vdx"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lookup6": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
"column": "field6",
|
||||
"name": "binary_md5_vdx"
|
||||
}
|
||||
]
|
||||
},
|
||||
"thex": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
|
@ -216,51 +332,51 @@ func TestVindexBindVarOverlap(t *testing.T) {
|
|||
require.Nil(t, err)
|
||||
defer conn.Close()
|
||||
|
||||
utils.Exec(t, conn, "INSERT INTO t1 (id, field, field2) VALUES "+
|
||||
"(0,1,2), "+
|
||||
"(1,2,3), "+
|
||||
"(2,3,4), "+
|
||||
"(3,4,5), "+
|
||||
"(4,5,6), "+
|
||||
"(5,6,7), "+
|
||||
"(6,7,8), "+
|
||||
"(7,8,9), "+
|
||||
"(8,9,10), "+
|
||||
"(9,10,11), "+
|
||||
"(10,11,12), "+
|
||||
"(11,12,13), "+
|
||||
"(12,13,14), "+
|
||||
"(13,14,15), "+
|
||||
"(14,15,16), "+
|
||||
"(15,16,17), "+
|
||||
"(16,17,18), "+
|
||||
"(17,18,19), "+
|
||||
"(18,19,20), "+
|
||||
"(19,20,21), "+
|
||||
"(20,21,22)")
|
||||
result := utils.Exec(t, conn, "select id, field, field2 from t1 order by id")
|
||||
utils.Exec(t, conn, "INSERT INTO t1 (id, field, field2, field3, field4, field5, field6) VALUES "+
|
||||
"(0,1,2,3,4,5,6), "+
|
||||
"(1,2,3,4,5,6,7), "+
|
||||
"(2,3,4,5,6,7,8), "+
|
||||
"(3,4,5,6,7,8,9), "+
|
||||
"(4,5,6,7,8,9,10), "+
|
||||
"(5,6,7,8,9,10,11), "+
|
||||
"(6,7,8,9,10,11,12), "+
|
||||
"(7,8,9,10,11,12,13), "+
|
||||
"(8,9,10,11,12,13,14), "+
|
||||
"(9,10,11,12,13,14,15), "+
|
||||
"(10,11,12,13,14,15,16), "+
|
||||
"(11,12,13,14,15,16,17), "+
|
||||
"(12,13,14,15,16,17,18), "+
|
||||
"(13,14,15,16,17,18,19), "+
|
||||
"(14,15,16,17,18,19,20), "+
|
||||
"(15,16,17,18,19,20,21), "+
|
||||
"(16,17,18,19,20,21,22), "+
|
||||
"(17,18,19,20,21,22,23), "+
|
||||
"(18,19,20,21,22,23,24), "+
|
||||
"(19,20,21,22,23,24,25), "+
|
||||
"(20,21,22,23,24,25,26)")
|
||||
result := utils.Exec(t, conn, "select id, field, field2, field3, field4, field5, field6 from t1 order by id")
|
||||
|
||||
expected :=
|
||||
"[[INT64(0) INT64(1) INT64(2)] " +
|
||||
"[INT64(1) INT64(2) INT64(3)] " +
|
||||
"[INT64(2) INT64(3) INT64(4)] " +
|
||||
"[INT64(3) INT64(4) INT64(5)] " +
|
||||
"[INT64(4) INT64(5) INT64(6)] " +
|
||||
"[INT64(5) INT64(6) INT64(7)] " +
|
||||
"[INT64(6) INT64(7) INT64(8)] " +
|
||||
"[INT64(7) INT64(8) INT64(9)] " +
|
||||
"[INT64(8) INT64(9) INT64(10)] " +
|
||||
"[INT64(9) INT64(10) INT64(11)] " +
|
||||
"[INT64(10) INT64(11) INT64(12)] " +
|
||||
"[INT64(11) INT64(12) INT64(13)] " +
|
||||
"[INT64(12) INT64(13) INT64(14)] " +
|
||||
"[INT64(13) INT64(14) INT64(15)] " +
|
||||
"[INT64(14) INT64(15) INT64(16)] " +
|
||||
"[INT64(15) INT64(16) INT64(17)] " +
|
||||
"[INT64(16) INT64(17) INT64(18)] " +
|
||||
"[INT64(17) INT64(18) INT64(19)] " +
|
||||
"[INT64(18) INT64(19) INT64(20)] " +
|
||||
"[INT64(19) INT64(20) INT64(21)] " +
|
||||
"[INT64(20) INT64(21) INT64(22)]]"
|
||||
"[[INT64(0) INT64(1) INT64(2) INT64(3) INT64(4) INT64(5) INT64(6)] " +
|
||||
"[INT64(1) INT64(2) INT64(3) INT64(4) INT64(5) INT64(6) INT64(7)] " +
|
||||
"[INT64(2) INT64(3) INT64(4) INT64(5) INT64(6) INT64(7) INT64(8)] " +
|
||||
"[INT64(3) INT64(4) INT64(5) INT64(6) INT64(7) INT64(8) INT64(9)] " +
|
||||
"[INT64(4) INT64(5) INT64(6) INT64(7) INT64(8) INT64(9) INT64(10)] " +
|
||||
"[INT64(5) INT64(6) INT64(7) INT64(8) INT64(9) INT64(10) INT64(11)] " +
|
||||
"[INT64(6) INT64(7) INT64(8) INT64(9) INT64(10) INT64(11) INT64(12)] " +
|
||||
"[INT64(7) INT64(8) INT64(9) INT64(10) INT64(11) INT64(12) INT64(13)] " +
|
||||
"[INT64(8) INT64(9) INT64(10) INT64(11) INT64(12) INT64(13) INT64(14)] " +
|
||||
"[INT64(9) INT64(10) INT64(11) INT64(12) INT64(13) INT64(14) INT64(15)] " +
|
||||
"[INT64(10) INT64(11) INT64(12) INT64(13) INT64(14) INT64(15) INT64(16)] " +
|
||||
"[INT64(11) INT64(12) INT64(13) INT64(14) INT64(15) INT64(16) INT64(17)] " +
|
||||
"[INT64(12) INT64(13) INT64(14) INT64(15) INT64(16) INT64(17) INT64(18)] " +
|
||||
"[INT64(13) INT64(14) INT64(15) INT64(16) INT64(17) INT64(18) INT64(19)] " +
|
||||
"[INT64(14) INT64(15) INT64(16) INT64(17) INT64(18) INT64(19) INT64(20)] " +
|
||||
"[INT64(15) INT64(16) INT64(17) INT64(18) INT64(19) INT64(20) INT64(21)] " +
|
||||
"[INT64(16) INT64(17) INT64(18) INT64(19) INT64(20) INT64(21) INT64(22)] " +
|
||||
"[INT64(17) INT64(18) INT64(19) INT64(20) INT64(21) INT64(22) INT64(23)] " +
|
||||
"[INT64(18) INT64(19) INT64(20) INT64(21) INT64(22) INT64(23) INT64(24)] " +
|
||||
"[INT64(19) INT64(20) INT64(21) INT64(22) INT64(23) INT64(24) INT64(25)] " +
|
||||
"[INT64(20) INT64(21) INT64(22) INT64(23) INT64(24) INT64(25) INT64(26)]]"
|
||||
assert.Equal(t, expected, fmt.Sprintf("%v", result.Rows))
|
||||
}
|
||||
|
|
|
@ -105,3 +105,27 @@ CREATE TABLE orders_id_lookup (
|
|||
keyspace_id varbinary(128),
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE orders_id_lookup_exclusive_read_lock (
|
||||
id int NOT NULL,
|
||||
keyspace_id varbinary(128),
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE orders_id_lookup_shared_read_lock (
|
||||
id int NOT NULL,
|
||||
keyspace_id varbinary(128),
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE orders_id_lookup_no_read_lock (
|
||||
id int NOT NULL,
|
||||
keyspace_id varbinary(128),
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE orders_id_lookup_no_verify (
|
||||
id int NOT NULL,
|
||||
keyspace_id varbinary(128),
|
||||
primary key(id)
|
||||
);
|
||||
|
|
|
@ -18,6 +18,46 @@
|
|||
},
|
||||
"owner": "orders"
|
||||
},
|
||||
"orders_id_vdx_exclusive_read_lock": {
|
||||
"type": "lookup_unique",
|
||||
"params": {
|
||||
"table": "orders_id_lookup_exclusive_read_lock",
|
||||
"from": "id",
|
||||
"to": "keyspace_id",
|
||||
"read_lock": "exclusive"
|
||||
},
|
||||
"owner": "orders"
|
||||
},
|
||||
"orders_id_vdx_shared_read_lock": {
|
||||
"type": "lookup_unique",
|
||||
"params": {
|
||||
"table": "orders_id_lookup_shared_read_lock",
|
||||
"from": "id",
|
||||
"to": "keyspace_id",
|
||||
"read_lock": "shared"
|
||||
},
|
||||
"owner": "orders"
|
||||
},
|
||||
"orders_id_vdx_no_read_lock": {
|
||||
"type": "lookup_unique",
|
||||
"params": {
|
||||
"table": "orders_id_lookup_no_read_lock",
|
||||
"from": "id",
|
||||
"to": "keyspace_id",
|
||||
"read_lock": "none"
|
||||
},
|
||||
"owner": "orders"
|
||||
},
|
||||
"orders_id_vdx_no_verify": {
|
||||
"type": "lookup_unique",
|
||||
"params": {
|
||||
"table": "orders_id_lookup_no_verify",
|
||||
"from": "id",
|
||||
"to": "keyspace_id",
|
||||
"no_verify": "true"
|
||||
},
|
||||
"owner": "orders"
|
||||
},
|
||||
"music_user_map": {
|
||||
"type": "lookup_hash_unique",
|
||||
"owner": "music",
|
||||
|
@ -164,6 +204,22 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"orders_id_lookup_no_read_lock": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
"column": "id",
|
||||
"name": "hash"
|
||||
}
|
||||
]
|
||||
},
|
||||
"orders_id_lookup_no_verify": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
"column": "id",
|
||||
"name": "hash"
|
||||
}
|
||||
]
|
||||
},
|
||||
"email_customer_map": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
|
|
|
@ -164,21 +164,24 @@ func TestUpdateFromSubQuery(t *testing.T) {
|
|||
testQueryLog(t, logChan, "TestExecute", "UPDATE", "update user set a=(select count(*) from user where id = 3) where id = 1", 2)
|
||||
}
|
||||
|
||||
func TestUpdateEqualWithWriteOnlyLookupUniqueVindex(t *testing.T) {
|
||||
func TestUpdateEqualWithNoVerifyAndWriteOnlyLookupUniqueVindexes(t *testing.T) {
|
||||
res := []*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields("id|wo_lu_col|lu_col|t2_lu_vdx", "int64|int64|int64|int64"),
|
||||
"1|2|1|0",
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col|t2_lu_vdx",
|
||||
"int64|int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|2|2|2|2|2|1|0",
|
||||
)}
|
||||
executor, sbc1, sbc2, sbcLookup := createCustomExecutorSetValues(executorVSchema, res)
|
||||
|
||||
_, err := executorExec(executor, "update t2_wo_lookup set lu_col = 5 where wo_lu_col = 2", nil)
|
||||
_, err := executorExec(executor, "update t2_lookup set lu_col = 5 where wo_lu_col = 2", nil)
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, lu_col, lu_col = 5 from t2_wo_lookup where wo_lu_col = 2 for update",
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col, lu_col = 5 from t2_lookup where wo_lu_col = 2 for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "update t2_wo_lookup set lu_col = 5 where wo_lu_col = 2",
|
||||
Sql: "update t2_lookup set lu_col = 5 where wo_lu_col = 2",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}}
|
||||
|
||||
|
@ -199,7 +202,264 @@ func TestUpdateEqualWithWriteOnlyLookupUniqueVindex(t *testing.T) {
|
|||
"lu_col_0": sqltypes.Int64BindVariable(5),
|
||||
},
|
||||
}
|
||||
lookWant := []*querypb.BoundQuery{bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2}
|
||||
lookWant := []*querypb.BoundQuery{
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
}
|
||||
assertQueries(t, sbcLookup, lookWant)
|
||||
}
|
||||
|
||||
func TestUpdateInTransactionLookupDefaultReadLock(t *testing.T) {
|
||||
res := []*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col|t2_lu_vdx",
|
||||
"int64|int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|2|2|2|2|2|1|0",
|
||||
)}
|
||||
executor, sbc1, sbc2, sbcLookup := createCustomExecutorSetValues(executorVSchema, res)
|
||||
|
||||
safeSession := NewSafeSession(&vtgatepb.Session{InTransaction: true})
|
||||
_, err := executorExecSession(
|
||||
executor,
|
||||
"update t2_lookup set lu_col = 5 where nv_lu_col = 2",
|
||||
nil,
|
||||
safeSession.Session,
|
||||
)
|
||||
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col, lu_col = 5 from t2_lookup where nv_lu_col = 2 and lu_col = 1 for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "update t2_lookup set lu_col = 5 where nv_lu_col = 2",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
},
|
||||
}
|
||||
|
||||
assertQueries(t, sbc1, wantQueries)
|
||||
assertQueries(t, sbc2, wantQueries)
|
||||
|
||||
vars, _ := sqltypes.BuildBindVariable([]any{
|
||||
sqltypes.NewInt64(2),
|
||||
})
|
||||
bq1 := &querypb.BoundQuery{
|
||||
Sql: "select nv_lu_col, keyspace_id from nv_lu_idx where nv_lu_col in ::nv_lu_col for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"nv_lu_col": vars,
|
||||
},
|
||||
}
|
||||
bq2 := &querypb.BoundQuery{
|
||||
Sql: "insert into lu_idx(lu_col, keyspace_id) values (:lu_col_0, :keyspace_id_0)",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id_0": sqltypes.Uint64BindVariable(1),
|
||||
"lu_col_0": sqltypes.Int64BindVariable(5),
|
||||
},
|
||||
}
|
||||
lookWant := []*querypb.BoundQuery{
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
}
|
||||
|
||||
assertQueries(t, sbcLookup, lookWant)
|
||||
}
|
||||
|
||||
func TestUpdateInTransactionLookupExclusiveReadLock(t *testing.T) {
|
||||
res := []*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col|t2_lu_vdx",
|
||||
"int64|int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|2|2|2|2|2|1|0",
|
||||
)}
|
||||
executor, sbc1, sbc2, sbcLookup := createCustomExecutorSetValues(executorVSchema, res)
|
||||
|
||||
safeSession := NewSafeSession(&vtgatepb.Session{InTransaction: true})
|
||||
_, err := executorExecSession(
|
||||
executor,
|
||||
"update t2_lookup set lu_col = 5 where erl_lu_col = 2",
|
||||
nil,
|
||||
safeSession.Session,
|
||||
)
|
||||
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col, lu_col = 5 from t2_lookup where nv_lu_col = 2 and lu_col = 1 for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "update t2_lookup set lu_col = 5 where erl_lu_col = 2",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
},
|
||||
}
|
||||
|
||||
assertQueries(t, sbc1, wantQueries)
|
||||
assertQueries(t, sbc2, wantQueries)
|
||||
|
||||
vars, _ := sqltypes.BuildBindVariable([]any{
|
||||
sqltypes.NewInt64(2),
|
||||
})
|
||||
bq1 := &querypb.BoundQuery{
|
||||
Sql: "select erl_lu_col, keyspace_id from erl_lu_idx where erl_lu_col in ::erl_lu_col for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"erl_lu_col": vars,
|
||||
},
|
||||
}
|
||||
bq2 := &querypb.BoundQuery{
|
||||
Sql: "insert into lu_idx(lu_col, keyspace_id) values (:lu_col_0, :keyspace_id_0)",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id_0": sqltypes.Uint64BindVariable(1),
|
||||
"lu_col_0": sqltypes.Int64BindVariable(5),
|
||||
},
|
||||
}
|
||||
lookWant := []*querypb.BoundQuery{
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
}
|
||||
|
||||
assertQueries(t, sbcLookup, lookWant)
|
||||
}
|
||||
|
||||
func TestUpdateInTransactionLookupSharedReadLock(t *testing.T) {
|
||||
res := []*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col|t2_lu_vdx",
|
||||
"int64|int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|2|2|2|2|2|1|0",
|
||||
)}
|
||||
executor, sbc1, sbc2, sbcLookup := createCustomExecutorSetValues(executorVSchema, res)
|
||||
|
||||
safeSession := NewSafeSession(&vtgatepb.Session{InTransaction: true})
|
||||
_, err := executorExecSession(
|
||||
executor,
|
||||
"update t2_lookup set lu_col = 5 where srl_lu_col = 2",
|
||||
nil,
|
||||
safeSession.Session,
|
||||
)
|
||||
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col, lu_col = 5 from t2_lookup where nv_lu_col = 2 and lu_col = 1 for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "update t2_lookup set lu_col = 5 where srl_lu_col = 2",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
},
|
||||
}
|
||||
|
||||
assertQueries(t, sbc1, wantQueries)
|
||||
assertQueries(t, sbc2, wantQueries)
|
||||
|
||||
vars, _ := sqltypes.BuildBindVariable([]any{
|
||||
sqltypes.NewInt64(2),
|
||||
})
|
||||
bq1 := &querypb.BoundQuery{
|
||||
Sql: "select srl_lu_col, keyspace_id from srl_lu_idx where srl_lu_col in ::srl_lu_col lock in share mode",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"srl_lu_col": vars,
|
||||
},
|
||||
}
|
||||
bq2 := &querypb.BoundQuery{
|
||||
Sql: "insert into lu_idx(lu_col, keyspace_id) values (:lu_col_0, :keyspace_id_0)",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id_0": sqltypes.Uint64BindVariable(1),
|
||||
"lu_col_0": sqltypes.Int64BindVariable(5),
|
||||
},
|
||||
}
|
||||
lookWant := []*querypb.BoundQuery{
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
}
|
||||
|
||||
assertQueries(t, sbcLookup, lookWant)
|
||||
}
|
||||
|
||||
func TestUpdateInTransactionLookupNoReadLock(t *testing.T) {
|
||||
res := []*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col|t2_lu_vdx",
|
||||
"int64|int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|2|2|2|2|2|1|0",
|
||||
)}
|
||||
executor, sbc1, sbc2, sbcLookup := createCustomExecutorSetValues(executorVSchema, res)
|
||||
|
||||
safeSession := NewSafeSession(&vtgatepb.Session{InTransaction: true})
|
||||
_, err := executorExecSession(
|
||||
executor,
|
||||
"update t2_lookup set lu_col = 5 where nrl_lu_col = 2",
|
||||
nil,
|
||||
safeSession.Session,
|
||||
)
|
||||
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col, lu_col = 5 from t2_lookup where nrl_lu_col = 2 and lu_col = 1 for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "update t2_lookup set lu_col = 5 where nrl_lu_col = 2",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
},
|
||||
}
|
||||
|
||||
assertQueries(t, sbc1, wantQueries)
|
||||
assertQueries(t, sbc2, wantQueries)
|
||||
|
||||
vars, _ := sqltypes.BuildBindVariable([]any{
|
||||
sqltypes.NewInt64(2),
|
||||
})
|
||||
bq1 := &querypb.BoundQuery{
|
||||
Sql: "select nrl_lu_col, keyspace_id from nrl_lu_idx where nrl_lu_col in ::nrl_lu_col",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"nrl_lu_col": vars,
|
||||
},
|
||||
}
|
||||
bq2 := &querypb.BoundQuery{
|
||||
Sql: "insert into lu_idx(lu_col, keyspace_id) values (:lu_col_0, :keyspace_id_0)",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id_0": sqltypes.Uint64BindVariable(1),
|
||||
"lu_col_0": sqltypes.Int64BindVariable(5),
|
||||
},
|
||||
}
|
||||
lookWant := []*querypb.BoundQuery{
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
bq1, bq2,
|
||||
}
|
||||
|
||||
assertQueries(t, sbcLookup, lookWant)
|
||||
}
|
||||
|
||||
|
@ -513,18 +773,21 @@ func TestUpdateEqualWithMultipleLookupVindex(t *testing.T) {
|
|||
)})
|
||||
|
||||
sbc1.SetResults([]*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields("id|wo_lu_col|lu_col|t2_lu_vdx", "int64|int64|int64|int64"),
|
||||
"1|2|1|0",
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col|t2_lu_vdx",
|
||||
"int64|int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|2|2|2|2|2|1|0",
|
||||
)})
|
||||
|
||||
_, err := executorExec(executor, "update t2_wo_lookup set lu_col = 5 where wo_lu_col = 2 and lu_col = 1", nil)
|
||||
_, err := executorExec(executor, "update t2_lookup set lu_col = 5 where wo_lu_col = 2 and lu_col = 1", nil)
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, lu_col, lu_col = 5 from t2_wo_lookup where wo_lu_col = 2 and lu_col = 1 for update",
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col, lu_col = 5 from t2_lookup where wo_lu_col = 2 and lu_col = 1 for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "update t2_wo_lookup set lu_col = 5 where wo_lu_col = 2 and lu_col = 1",
|
||||
Sql: "update t2_lookup set lu_col = 5 where wo_lu_col = 2 and lu_col = 1",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}}
|
||||
|
||||
|
@ -564,19 +827,22 @@ func TestUpdateUseHigherCostVindexIfBackfilling(t *testing.T) {
|
|||
)})
|
||||
|
||||
sbc1.SetResults([]*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields("id|wo_lu_col|lu_col|t2_lu_vdx", "int64|int64|int64|int64"),
|
||||
"1|2|1|0",
|
||||
"1|2|2|0",
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col|t2_lu_vdx",
|
||||
"int64|int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|2|2|2|2|2|1|0",
|
||||
"1|2|2|2|2|2|2|0",
|
||||
)})
|
||||
|
||||
_, err := executorExec(executor, "update t2_wo_lookup set lu_col = 5 where wo_lu_col = 2 and lu_col in (1, 2)", nil)
|
||||
_, err := executorExec(executor, "update t2_lookup set lu_col = 5 where wo_lu_col = 2 and lu_col in (1, 2)", nil)
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, lu_col, lu_col = 5 from t2_wo_lookup where wo_lu_col = 2 and lu_col in (1, 2) for update",
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col, lu_col = 5 from t2_lookup where wo_lu_col = 2 and lu_col in (1, 2) for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "update t2_wo_lookup set lu_col = 5 where wo_lu_col = 2 and lu_col in (1, 2)",
|
||||
Sql: "update t2_lookup set lu_col = 5 where wo_lu_col = 2 and lu_col in (1, 2)",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}}
|
||||
|
||||
|
@ -619,21 +885,24 @@ func TestUpdateUseHigherCostVindexIfBackfilling(t *testing.T) {
|
|||
assertQueries(t, sbc2, nil)
|
||||
}
|
||||
|
||||
func TestDeleteEqualWithWriteOnlyLookupUniqueVindex(t *testing.T) {
|
||||
func TestDeleteEqualWithNoVerifyAndWriteOnlyLookupUniqueVindex(t *testing.T) {
|
||||
res := []*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields("id|wo_lu_col|lu_col", "int64|int64|int64"),
|
||||
"1|1|1",
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col",
|
||||
"int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|1|1|1|1|1|1",
|
||||
)}
|
||||
executor, sbc1, sbc2, sbcLookup := createCustomExecutorSetValues(executorVSchema, res)
|
||||
|
||||
_, err := executorExec(executor, "delete from t2_wo_lookup where wo_lu_col = 1", nil)
|
||||
_, err := executorExec(executor, "delete from t2_lookup where wo_lu_col = 1", nil)
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, lu_col from t2_wo_lookup where wo_lu_col = 1 for update",
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col from t2_lookup where wo_lu_col = 1 for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "delete from t2_wo_lookup where wo_lu_col = 1",
|
||||
Sql: "delete from t2_lookup where wo_lu_col = 1",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}}
|
||||
|
||||
|
@ -645,13 +914,50 @@ func TestDeleteEqualWithWriteOnlyLookupUniqueVindex(t *testing.T) {
|
|||
},
|
||||
}
|
||||
bq2 := &querypb.BoundQuery{
|
||||
Sql: "delete from erl_lu_idx where erl_lu_col = :erl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"erl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}
|
||||
bq3 := &querypb.BoundQuery{
|
||||
Sql: "delete from srl_lu_idx where srl_lu_col = :srl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"srl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}
|
||||
bq4 := &querypb.BoundQuery{
|
||||
Sql: "delete from nrl_lu_idx where nrl_lu_col = :nrl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"nrl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}
|
||||
bq5 := &querypb.BoundQuery{
|
||||
Sql: "delete from nv_lu_idx where nv_lu_col = :nv_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"nv_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}
|
||||
bq6 := &querypb.BoundQuery{
|
||||
Sql: "delete from lu_idx where lu_col = :lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": sqltypes.Uint64BindVariable(1),
|
||||
"lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}
|
||||
lookWant := []*querypb.BoundQuery{bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2, bq1, bq2}
|
||||
lookWant := []*querypb.BoundQuery{
|
||||
bq1, bq2, bq3, bq4, bq5, bq6,
|
||||
bq1, bq2, bq3, bq4, bq5, bq6,
|
||||
bq1, bq2, bq3, bq4, bq5, bq6,
|
||||
bq1, bq2, bq3, bq4, bq5, bq6,
|
||||
bq1, bq2, bq3, bq4, bq5, bq6,
|
||||
bq1, bq2, bq3, bq4, bq5, bq6,
|
||||
bq1, bq2, bq3, bq4, bq5, bq6,
|
||||
bq1, bq2, bq3, bq4, bq5, bq6,
|
||||
}
|
||||
assertQueries(t, sbcLookup, lookWant)
|
||||
assertQueries(t, sbc1, wantQueries)
|
||||
assertQueries(t, sbc2, wantQueries)
|
||||
|
@ -666,18 +972,21 @@ func TestDeleteEqualWithMultipleLookupVindex(t *testing.T) {
|
|||
)})
|
||||
|
||||
sbc1.SetResults([]*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields("id|wo_lu_col|lu_col", "int64|int64|int64"),
|
||||
"1|1|1",
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col",
|
||||
"int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|1|1|1|1|1|1",
|
||||
)})
|
||||
|
||||
_, err := executorExec(executor, "delete from t2_wo_lookup where wo_lu_col = 1 and lu_col = 1", nil)
|
||||
_, err := executorExec(executor, "delete from t2_lookup where wo_lu_col = 1 and lu_col = 1", nil)
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, lu_col from t2_wo_lookup where wo_lu_col = 1 and lu_col = 1 for update",
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col from t2_lookup where wo_lu_col = 1 and lu_col = 1 for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "delete from t2_wo_lookup where wo_lu_col = 1 and lu_col = 1",
|
||||
Sql: "delete from t2_lookup where wo_lu_col = 1 and lu_col = 1",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}}
|
||||
|
||||
|
@ -695,6 +1004,30 @@ func TestDeleteEqualWithMultipleLookupVindex(t *testing.T) {
|
|||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"wo_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from erl_lu_idx where erl_lu_col = :erl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"erl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from srl_lu_idx where srl_lu_col = :srl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"srl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from nrl_lu_idx where nrl_lu_col = :nrl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"nrl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from nv_lu_idx where nv_lu_col = :nv_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"nv_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from lu_idx where lu_col = :lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
|
@ -718,19 +1051,22 @@ func TestDeleteUseHigherCostVindexIfBackfilling(t *testing.T) {
|
|||
)})
|
||||
|
||||
sbc1.SetResults([]*sqltypes.Result{sqltypes.MakeTestResult(
|
||||
sqltypes.MakeTestFields("id|wo_lu_col|lu_col", "int64|int64|int64"),
|
||||
"1|1|1",
|
||||
"1|1|2",
|
||||
sqltypes.MakeTestFields(
|
||||
"id|wo_lu_col|erl_lu_col|srl_lu_col|nrl_lu_col|nv_lu_col|lu_col",
|
||||
"int64|int64|int64|int64|int64|int64|int64",
|
||||
),
|
||||
"1|1|1|1|1|1|1",
|
||||
"1|1|1|1|1|1|2",
|
||||
)})
|
||||
|
||||
_, err := executorExec(executor, "delete from t2_wo_lookup where wo_lu_col = 1 and lu_col in (1, 2)", nil)
|
||||
_, err := executorExec(executor, "delete from t2_lookup where wo_lu_col = 1 and lu_col in (1, 2)", nil)
|
||||
require.NoError(t, err)
|
||||
wantQueries := []*querypb.BoundQuery{
|
||||
{
|
||||
Sql: "select id, wo_lu_col, lu_col from t2_wo_lookup where wo_lu_col = 1 and lu_col in (1, 2) for update",
|
||||
Sql: "select id, wo_lu_col, erl_lu_col, srl_lu_col, nrl_lu_col, nv_lu_col, lu_col from t2_lookup where wo_lu_col = 1 and lu_col in (1, 2) for update",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}, {
|
||||
Sql: "delete from t2_wo_lookup where wo_lu_col = 1 and lu_col in (1, 2)",
|
||||
Sql: "delete from t2_lookup where wo_lu_col = 1 and lu_col in (1, 2)",
|
||||
BindVariables: map[string]*querypb.BindVariable{},
|
||||
}}
|
||||
|
||||
|
@ -749,6 +1085,30 @@ func TestDeleteUseHigherCostVindexIfBackfilling(t *testing.T) {
|
|||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"wo_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from erl_lu_idx where erl_lu_col = :erl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"erl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from srl_lu_idx where srl_lu_col = :srl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"srl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from nrl_lu_idx where nrl_lu_col = :nrl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"nrl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from nv_lu_idx where nv_lu_col = :nv_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"nv_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from lu_idx where lu_col = :lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
|
@ -761,6 +1121,30 @@ func TestDeleteUseHigherCostVindexIfBackfilling(t *testing.T) {
|
|||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"wo_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from erl_lu_idx where erl_lu_col = :erl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"erl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from srl_lu_idx where srl_lu_col = :srl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"srl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from nrl_lu_idx where nrl_lu_col = :nrl_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"nrl_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from nv_lu_idx where nv_lu_col = :nv_lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
"keyspace_id": {Type: querypb.Type_VARBINARY, Value: []byte("\x16k@\xb4J\xbaK\xd6")},
|
||||
"nv_lu_col": sqltypes.Int64BindVariable(1),
|
||||
},
|
||||
}, {
|
||||
Sql: "delete from lu_idx where lu_col = :lu_col and keyspace_id = :keyspace_id",
|
||||
BindVariables: map[string]*querypb.BindVariable{
|
||||
|
|
|
@ -119,9 +119,49 @@ var executorVSchema = `
|
|||
"table": "TestUnsharded.wo_lu_idx",
|
||||
"from": "wo_lu_col",
|
||||
"to": "keyspace_id",
|
||||
"write_only": "true"
|
||||
"write_only": "true"
|
||||
},
|
||||
"owner": "t2_wo_lookup"
|
||||
"owner": "t2_lookup"
|
||||
},
|
||||
"t2_erl_lu_vdx": {
|
||||
"type": "lookup_unique",
|
||||
"params": {
|
||||
"table": "TestUnsharded.erl_lu_idx",
|
||||
"from": "erl_lu_col",
|
||||
"to": "keyspace_id",
|
||||
"read_lock": "exclusive"
|
||||
},
|
||||
"owner": "t2_lookup"
|
||||
},
|
||||
"t2_srl_lu_vdx": {
|
||||
"type": "lookup_unique",
|
||||
"params": {
|
||||
"table": "TestUnsharded.srl_lu_idx",
|
||||
"from": "srl_lu_col",
|
||||
"to": "keyspace_id",
|
||||
"read_lock": "shared"
|
||||
},
|
||||
"owner": "t2_lookup"
|
||||
},
|
||||
"t2_nrl_lu_vdx": {
|
||||
"type": "lookup_unique",
|
||||
"params": {
|
||||
"table": "TestUnsharded.nrl_lu_idx",
|
||||
"from": "nrl_lu_col",
|
||||
"to": "keyspace_id",
|
||||
"read_lock": "none"
|
||||
},
|
||||
"owner": "t2_lookup"
|
||||
},
|
||||
"t2_nv_lu_vdx": {
|
||||
"type": "lookup_unique",
|
||||
"params": {
|
||||
"table": "TestUnsharded.nv_lu_idx",
|
||||
"from": "nv_lu_col",
|
||||
"to": "keyspace_id",
|
||||
"no_verify": "true"
|
||||
},
|
||||
"owner": "t2_lookup"
|
||||
},
|
||||
"t2_lu_vdx": {
|
||||
"type": "lookup_hash_unique",
|
||||
|
@ -130,7 +170,7 @@ var executorVSchema = `
|
|||
"from": "lu_col",
|
||||
"to": "keyspace_id"
|
||||
},
|
||||
"owner": "t2_wo_lookup"
|
||||
"owner": "t2_lookup"
|
||||
},
|
||||
"regional_vdx": {
|
||||
"type": "region_experimental",
|
||||
|
@ -294,15 +334,31 @@ var executorVSchema = `
|
|||
}
|
||||
]
|
||||
},
|
||||
"t2_wo_lookup": {
|
||||
"t2_lookup": {
|
||||
"column_vindexes": [
|
||||
{
|
||||
"column": "id",
|
||||
"name": "hash_index"
|
||||
},
|
||||
{
|
||||
"column": "wo_lu_col",
|
||||
"name": "t2_wo_lu_vdx"
|
||||
"column": "wo_lu_col",
|
||||
"name": "t2_wo_lu_vdx"
|
||||
},
|
||||
{
|
||||
"column": "erl_lu_col",
|
||||
"name": "t2_erl_lu_vdx"
|
||||
},
|
||||
{
|
||||
"column": "srl_lu_col",
|
||||
"name": "t2_srl_lu_vdx"
|
||||
},
|
||||
{
|
||||
"column": "nrl_lu_col",
|
||||
"name": "t2_nrl_lu_vdx"
|
||||
},
|
||||
{
|
||||
"column": "nv_lu_col",
|
||||
"name": "t2_nv_lu_vdx"
|
||||
},
|
||||
{
|
||||
"column": "lu_col",
|
||||
|
@ -350,6 +406,10 @@ var unshardedVSchema = `
|
|||
}
|
||||
},
|
||||
"wo_lu_idx": {},
|
||||
"erl_lu_idx": {},
|
||||
"srl_lu_idx": {},
|
||||
"nrl_lu_idx": {},
|
||||
"nv_lu_idx": {},
|
||||
"lu_idx": {},
|
||||
"simple": {}
|
||||
}
|
||||
|
|
|
@ -865,8 +865,12 @@ func TestExecutorShow(t *testing.T) {
|
|||
buildVarCharRow("TestExecutor", "name_user_map", "lookup_hash", "from=name; table=name_user_map; to=user_id", "user"),
|
||||
buildVarCharRow("TestExecutor", "regional_vdx", "region_experimental", "region_bytes=1", ""),
|
||||
buildVarCharRow("TestExecutor", "t1_lkp_vdx", "consistent_lookup_unique", "from=unq_col; table=t1_lkp_idx; to=keyspace_id", "t1"),
|
||||
buildVarCharRow("TestExecutor", "t2_lu_vdx", "lookup_hash_unique", "from=lu_col; table=TestUnsharded.lu_idx; to=keyspace_id", "t2_wo_lookup"),
|
||||
buildVarCharRow("TestExecutor", "t2_wo_lu_vdx", "lookup_unique", "from=wo_lu_col; table=TestUnsharded.wo_lu_idx; to=keyspace_id; write_only=true", "t2_wo_lookup"),
|
||||
buildVarCharRow("TestExecutor", "t2_erl_lu_vdx", "lookup_unique", "from=erl_lu_col; read_lock=exclusive; table=TestUnsharded.erl_lu_idx; to=keyspace_id", "t2_lookup"),
|
||||
buildVarCharRow("TestExecutor", "t2_lu_vdx", "lookup_hash_unique", "from=lu_col; table=TestUnsharded.lu_idx; to=keyspace_id", "t2_lookup"),
|
||||
buildVarCharRow("TestExecutor", "t2_nrl_lu_vdx", "lookup_unique", "from=nrl_lu_col; read_lock=none; table=TestUnsharded.nrl_lu_idx; to=keyspace_id", "t2_lookup"),
|
||||
buildVarCharRow("TestExecutor", "t2_nv_lu_vdx", "lookup_unique", "from=nv_lu_col; no_verify=true; table=TestUnsharded.nv_lu_idx; to=keyspace_id", "t2_lookup"),
|
||||
buildVarCharRow("TestExecutor", "t2_srl_lu_vdx", "lookup_unique", "from=srl_lu_col; read_lock=shared; table=TestUnsharded.srl_lu_idx; to=keyspace_id", "t2_lookup"),
|
||||
buildVarCharRow("TestExecutor", "t2_wo_lu_vdx", "lookup_unique", "from=wo_lu_col; table=TestUnsharded.wo_lu_idx; to=keyspace_id; write_only=true", "t2_lookup"),
|
||||
buildVarCharRow("TestMultiCol", "multicol_vdx", "multicol", "column_bytes=1,3,4; column_count=3; column_vindex=hash,binary,unicode_loose_xxhash", ""),
|
||||
},
|
||||
}
|
||||
|
@ -997,13 +1001,17 @@ func TestExecutorShow(t *testing.T) {
|
|||
Fields: buildVarCharFields("Tables"),
|
||||
Rows: [][]sqltypes.Value{
|
||||
buildVarCharRow("dual"),
|
||||
buildVarCharRow("erl_lu_idx"),
|
||||
buildVarCharRow("ins_lookup"),
|
||||
buildVarCharRow("lu_idx"),
|
||||
buildVarCharRow("main1"),
|
||||
buildVarCharRow("music_user_map"),
|
||||
buildVarCharRow("name_lastname_keyspace_id_map"),
|
||||
buildVarCharRow("name_user_map"),
|
||||
buildVarCharRow("nrl_lu_idx"),
|
||||
buildVarCharRow("nv_lu_idx"),
|
||||
buildVarCharRow("simple"),
|
||||
buildVarCharRow("srl_lu_idx"),
|
||||
buildVarCharRow("user_msgs"),
|
||||
buildVarCharRow("user_seq"),
|
||||
buildVarCharRow("wo_lu_idx"),
|
||||
|
|
|
@ -180,7 +180,7 @@ func (cached *LookupHash) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
size := int64(0)
|
||||
if alloc {
|
||||
size += int64(144)
|
||||
size += int64(176)
|
||||
}
|
||||
// field name string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.name)))
|
||||
|
@ -194,7 +194,7 @@ func (cached *LookupHashUnique) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
size := int64(0)
|
||||
if alloc {
|
||||
size += int64(144)
|
||||
size += int64(176)
|
||||
}
|
||||
// field name string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.name)))
|
||||
|
@ -208,7 +208,7 @@ func (cached *LookupNonUnique) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
size := int64(0)
|
||||
if alloc {
|
||||
size += int64(144)
|
||||
size += int64(176)
|
||||
}
|
||||
// field name string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.name)))
|
||||
|
@ -222,7 +222,7 @@ func (cached *LookupUnicodeLooseMD5Hash) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
size := int64(0)
|
||||
if alloc {
|
||||
size += int64(144)
|
||||
size += int64(176)
|
||||
}
|
||||
// field name string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.name)))
|
||||
|
@ -236,7 +236,7 @@ func (cached *LookupUnicodeLooseMD5HashUnique) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
size := int64(0)
|
||||
if alloc {
|
||||
size += int64(144)
|
||||
size += int64(176)
|
||||
}
|
||||
// field name string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.name)))
|
||||
|
@ -250,7 +250,7 @@ func (cached *LookupUnique) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
size := int64(0)
|
||||
if alloc {
|
||||
size += int64(144)
|
||||
size += int64(176)
|
||||
}
|
||||
// field name string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.name)))
|
||||
|
@ -492,7 +492,7 @@ func (cached *clCommon) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
size := int64(0)
|
||||
if alloc {
|
||||
size += int64(256)
|
||||
size += int64(288)
|
||||
}
|
||||
// field name string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.name)))
|
||||
|
@ -525,7 +525,7 @@ func (cached *lookupInternal) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
size := int64(0)
|
||||
if alloc {
|
||||
size += int64(112)
|
||||
size += int64(144)
|
||||
}
|
||||
// field Table string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.Table)))
|
||||
|
@ -538,8 +538,12 @@ func (cached *lookupInternal) CachedSize(alloc bool) int64 {
|
|||
}
|
||||
// field To string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.To)))
|
||||
// field ReadLock string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.ReadLock)))
|
||||
// field sel string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.sel)))
|
||||
// field selTxDml string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.selTxDml)))
|
||||
// field ver string
|
||||
size += hack.RuntimeAllocSize(int64(len(cached.ver)))
|
||||
// field del string
|
||||
|
|
|
@ -46,6 +46,7 @@ func init() {
|
|||
type LookupNonUnique struct {
|
||||
name string
|
||||
writeOnly bool
|
||||
noVerify bool
|
||||
lkp lookupInternal
|
||||
}
|
||||
|
||||
|
@ -132,7 +133,7 @@ func (ln *LookupNonUnique) MapResult(ids []sqltypes.Value, results []*sqltypes.R
|
|||
|
||||
// Verify returns true if ids maps to ksids.
|
||||
func (ln *LookupNonUnique) Verify(ctx context.Context, vcursor VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) {
|
||||
if ln.writeOnly {
|
||||
if ln.writeOnly || ln.noVerify {
|
||||
out := make([]bool, len(ids))
|
||||
for i := range ids {
|
||||
out[i] = true
|
||||
|
@ -178,6 +179,7 @@ func (ln *LookupNonUnique) Query() (selQuery string, arguments []string) {
|
|||
//
|
||||
// autocommit: setting this to "true" will cause inserts to upsert and deletes to be ignored.
|
||||
// write_only: in this mode, Map functions return the full keyrange causing a full scatter.
|
||||
// no_verify: in this mode, Verify will always succeed.
|
||||
func NewLookup(name string, m map[string]string) (Vindex, error) {
|
||||
lookup := &LookupNonUnique{name: name}
|
||||
|
||||
|
@ -190,6 +192,11 @@ func NewLookup(name string, m map[string]string) (Vindex, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
lookup.noVerify, err = boolFromMap(m, "no_verify")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if autocommit is on for non-unique lookup, upsert should also be on.
|
||||
upsert := cc.autocommit || cc.multiShardAutocommit
|
||||
if err := lookup.lkp.Init(m, cc.autocommit, upsert, cc.multiShardAutocommit); err != nil {
|
||||
|
@ -214,6 +221,7 @@ func ksidsToValues(ksids [][]byte) []sqltypes.Value {
|
|||
type LookupUnique struct {
|
||||
name string
|
||||
writeOnly bool
|
||||
noVerify bool
|
||||
lkp lookupInternal
|
||||
}
|
||||
|
||||
|
@ -248,6 +256,11 @@ func NewLookupUnique(name string, m map[string]string) (Vindex, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
lu.noVerify, err = boolFromMap(m, "no_verify")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Don't allow upserts for unique vindexes.
|
||||
if err := lu.lkp.Init(m, cc.autocommit, false /* upsert */, cc.multiShardAutocommit); err != nil {
|
||||
return nil, err
|
||||
|
@ -312,7 +325,7 @@ func (lu *LookupUnique) MapResult(ids []sqltypes.Value, results []*sqltypes.Resu
|
|||
|
||||
// Verify returns true if ids maps to ksids.
|
||||
func (lu *LookupUnique) Verify(ctx context.Context, vcursor VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) {
|
||||
if lu.writeOnly {
|
||||
if lu.writeOnly || lu.noVerify {
|
||||
out := make([]bool, len(ids))
|
||||
for i := range ids {
|
||||
out[i] = true
|
||||
|
|
|
@ -48,7 +48,7 @@ func init() {
|
|||
// LookupHash defines a vindex that uses a lookup table.
|
||||
// The table is expected to define the id column as unique. It's
|
||||
// NonUnique and a Lookup.
|
||||
// Warning: This Vindex is being depcreated in favor of Lookup
|
||||
// Warning: This Vindex is being deprecated in favor of Lookup
|
||||
type LookupHash struct {
|
||||
name string
|
||||
writeOnly bool
|
||||
|
|
|
@ -33,17 +33,31 @@ import (
|
|||
vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
|
||||
)
|
||||
|
||||
var (
|
||||
readLockExclusive = "exclusive"
|
||||
readLockShared = "shared"
|
||||
readLockNone = "none"
|
||||
readLockDefault = readLockExclusive
|
||||
|
||||
readLockExprs map[string]string = map[string]string{
|
||||
readLockExclusive: "for update",
|
||||
readLockShared: "lock in share mode",
|
||||
readLockNone: "",
|
||||
}
|
||||
)
|
||||
|
||||
// lookupInternal implements the functions for the Lookup vindexes.
|
||||
type lookupInternal struct {
|
||||
Table string `json:"table"`
|
||||
FromColumns []string `json:"from_columns"`
|
||||
To string `json:"to"`
|
||||
Autocommit bool `json:"autocommit,omitempty"`
|
||||
MultiShardAutocommit bool `json:"multi_shard_autocommit,omitempty"`
|
||||
Upsert bool `json:"upsert,omitempty"`
|
||||
IgnoreNulls bool `json:"ignore_nulls,omitempty"`
|
||||
BatchLookup bool `json:"batch_lookup,omitempty"`
|
||||
sel, ver, del string // sel: map query, ver: verify query, del: delete query
|
||||
Table string `json:"table"`
|
||||
FromColumns []string `json:"from_columns"`
|
||||
To string `json:"to"`
|
||||
Autocommit bool `json:"autocommit,omitempty"`
|
||||
MultiShardAutocommit bool `json:"multi_shard_autocommit,omitempty"`
|
||||
Upsert bool `json:"upsert,omitempty"`
|
||||
IgnoreNulls bool `json:"ignore_nulls,omitempty"`
|
||||
BatchLookup bool `json:"batch_lookup,omitempty"`
|
||||
ReadLock string `json:"read_lock,omitempty"`
|
||||
sel, selTxDml, ver, del string // sel: map query, ver: verify query, del: delete query
|
||||
}
|
||||
|
||||
func (lkp *lookupInternal) Init(lookupQueryParams map[string]string, autocommit, upsert, multiShardAutocommit bool) error {
|
||||
|
@ -64,6 +78,12 @@ func (lkp *lookupInternal) Init(lookupQueryParams map[string]string, autocommit,
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if readLock, ok := lookupQueryParams["read_lock"]; ok {
|
||||
if _, valid := readLockExprs[readLock]; !valid {
|
||||
return fmt.Errorf("invalid read_lock value: %s", readLock)
|
||||
}
|
||||
lkp.ReadLock = readLock
|
||||
}
|
||||
|
||||
lkp.Autocommit = autocommit
|
||||
lkp.Upsert = upsert
|
||||
|
@ -76,6 +96,15 @@ func (lkp *lookupInternal) Init(lookupQueryParams map[string]string, autocommit,
|
|||
// as part of face 2 of https://github.com/vitessio/vitess/issues/3481
|
||||
// For now multi column behaves as a single column for Map and Verify operations
|
||||
lkp.sel = fmt.Sprintf("select %s, %s from %s where %s in ::%s", lkp.FromColumns[0], lkp.To, lkp.Table, lkp.FromColumns[0], lkp.FromColumns[0])
|
||||
if lkp.ReadLock != readLockNone {
|
||||
lockExpr, ok := readLockExprs[lkp.ReadLock]
|
||||
if !ok {
|
||||
lockExpr = readLockExprs[readLockDefault]
|
||||
}
|
||||
lkp.selTxDml = fmt.Sprintf("%s %s", lkp.sel, lockExpr)
|
||||
} else {
|
||||
lkp.selTxDml = lkp.sel
|
||||
}
|
||||
lkp.ver = fmt.Sprintf("select %s from %s where %s = :%s and %s = :%s", lkp.FromColumns[0], lkp.Table, lkp.FromColumns[0], lkp.FromColumns[0], lkp.To, lkp.To)
|
||||
lkp.del = lkp.initDelStmt()
|
||||
return nil
|
||||
|
@ -90,9 +119,11 @@ func (lkp *lookupInternal) Lookup(ctx context.Context, vcursor VCursor, ids []sq
|
|||
if lkp.Autocommit {
|
||||
co = vtgatepb.CommitOrder_AUTOCOMMIT
|
||||
}
|
||||
sel := lkp.sel
|
||||
var sel string
|
||||
if vcursor.InTransactionAndIsDML() {
|
||||
sel = sel + " for update"
|
||||
sel = lkp.selTxDml
|
||||
} else {
|
||||
sel = lkp.sel
|
||||
}
|
||||
if ids[0].IsIntegral() || lkp.BatchLookup {
|
||||
// for integral types, batch query all ids and then map them back to the input order
|
||||
|
|
|
@ -281,6 +281,52 @@ func TestLookupNonUniqueVerify(t *testing.T) {
|
|||
utils.MustMatch(t, []bool{true, true}, got)
|
||||
}
|
||||
|
||||
func TestLookupNonUniqueNoVerify(t *testing.T) {
|
||||
vindex, err := CreateVindex("lookup", "lookup", map[string]string{
|
||||
"table": "t",
|
||||
"from": "fromc",
|
||||
"to": "toc",
|
||||
"no_verify": "true",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
lookupNonUnique := vindex.(SingleColumn)
|
||||
vc := &vcursor{numRows: 1}
|
||||
|
||||
_, err = lookupNonUnique.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}, [][]byte{[]byte("test1"), []byte("test2")})
|
||||
require.NoError(t, err)
|
||||
|
||||
var wantqueries []*querypb.BoundQuery
|
||||
utils.MustMatch(t, vc.queries, wantqueries)
|
||||
|
||||
// Test query fail.
|
||||
vc.mustFail = true
|
||||
_, err = lookupNonUnique.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, [][]byte{[]byte("\x16k@\xb4J\xbaK\xd6")})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLookupUniqueNoVerify(t *testing.T) {
|
||||
vindex, err := CreateVindex("lookup_unique", "lookup_unique", map[string]string{
|
||||
"table": "t",
|
||||
"from": "fromc",
|
||||
"to": "toc",
|
||||
"no_verify": "true",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
lookupUnique := vindex.(SingleColumn)
|
||||
vc := &vcursor{numRows: 1}
|
||||
|
||||
_, err = lookupUnique.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}, [][]byte{[]byte("test1"), []byte("test2")})
|
||||
require.NoError(t, err)
|
||||
|
||||
var wantqueries []*querypb.BoundQuery
|
||||
utils.MustMatch(t, vc.queries, wantqueries)
|
||||
|
||||
// Test query fail.
|
||||
vc.mustFail = true
|
||||
_, err = lookupUnique.Verify(context.Background(), vc, []sqltypes.Value{sqltypes.NewInt64(1)}, [][]byte{[]byte("\x16k@\xb4J\xbaK\xd6")})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLookupNonUniqueVerifyAutocommit(t *testing.T) {
|
||||
vindex, err := CreateVindex("lookup", "lookup", map[string]string{
|
||||
"table": "t",
|
||||
|
|
Загрузка…
Ссылка в новой задаче