vitess.io/vitess@v0.16.2/go/test/endtoend/vtgate/queries/dml/insert_test.go (about)

     1  /*
     2  Copyright 2022 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package dml
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  
    25  	"vitess.io/vitess/go/test/endtoend/utils"
    26  )
    27  
    28  func TestSimpleInsertSelect(t *testing.T) {
    29  	if clusterInstance.HasPartialKeyspaces {
    30  		t.Skip("test uses multiple keyspaces, test framework only supports partial keyspace testing for a single keyspace")
    31  	}
    32  	mcmp, closer := start(t)
    33  	defer closer()
    34  
    35  	mcmp.Exec("insert into s_tbl(id, num) values (1,2),(3,4)")
    36  	mcmp.Exec("insert into u_tbl(id, num) values (1,2),(3,4)")
    37  
    38  	for i, mode := range []string{"oltp", "olap"} {
    39  		t.Run(mode, func(t *testing.T) {
    40  			utils.Exec(t, mcmp.VtConn, fmt.Sprintf("set workload = %s", mode))
    41  
    42  			qr := mcmp.Exec(fmt.Sprintf("insert into s_tbl(id, num) select id*%d, num*%d from s_tbl where id < 10", 10+i, 20+i))
    43  			assert.EqualValues(t, 2, qr.RowsAffected)
    44  			qr = mcmp.Exec(fmt.Sprintf("insert into u_tbl(id, num) select id*%d, num*%d from u_tbl where id < 10", 10+i, 20+i))
    45  			assert.EqualValues(t, 2, qr.RowsAffected)
    46  		})
    47  	}
    48  
    49  	mcmp.AssertMatches(`select id, num from s_tbl order by id`, `[[INT64(1) INT64(2)] [INT64(3) INT64(4)] [INT64(10) INT64(40)] [INT64(11) INT64(42)] [INT64(30) INT64(80)] [INT64(33) INT64(84)]]`)
    50  	mcmp.AssertMatches(`select id, num from u_tbl order by id`, `[[INT64(1) INT64(2)] [INT64(3) INT64(4)] [INT64(10) INT64(40)] [INT64(11) INT64(42)] [INT64(30) INT64(80)] [INT64(33) INT64(84)]]`)
    51  
    52  	utils.AssertMatches(t, mcmp.VtConn, `select num from num_vdx_tbl order by num`, `[[INT64(2)] [INT64(4)] [INT64(40)] [INT64(42)] [INT64(80)] [INT64(84)]]`)
    53  }
    54  
    55  func TestFailureInsertSelect(t *testing.T) {
    56  	if clusterInstance.HasPartialKeyspaces {
    57  		t.Skip("don't run on partial keyspaces")
    58  	}
    59  	mcmp, closer := start(t)
    60  	defer closer()
    61  
    62  	mcmp.Exec("insert into s_tbl(id, num) values (1,2),(3,4)")
    63  	mcmp.Exec("insert into u_tbl(id, num) values (1,2),(3,4)")
    64  
    65  	for _, mode := range []string{"oltp", "olap"} {
    66  		t.Run(mode, func(t *testing.T) {
    67  			utils.Exec(t, mcmp.VtConn, fmt.Sprintf("set workload = %s", mode))
    68  
    69  			// primary key same
    70  			mcmp.AssertContainsError("insert into s_tbl(id, num) select id, num*20 from s_tbl where id = 1", `AlreadyExists desc = Duplicate entry '1' for key`)
    71  			// lookup key same (does not fail on MySQL as there is no lookup, and we have not put unique contrains on num column)
    72  			utils.AssertContainsError(t, mcmp.VtConn, "insert into s_tbl(id, num) select id*20, num from s_tbl where id = 1", `lookup.Create: Code: ALREADY_EXISTS`)
    73  			// mismatch column count
    74  			mcmp.AssertContainsError("insert into s_tbl(id, num) select 100,200,300", `column count does not match value count at row 1`)
    75  			mcmp.AssertContainsError("insert into s_tbl(id, num) select 100", `column count does not match value count at row 1`)
    76  		})
    77  	}
    78  }
    79  
    80  func TestAutoIncInsertSelect(t *testing.T) {
    81  	if clusterInstance.HasPartialKeyspaces {
    82  		t.Skip("test uses multiple keyspaces, test framework only supports partial keyspace testing for a single keyspace")
    83  	}
    84  	mcmp, closer := start(t)
    85  	defer closer()
    86  
    87  	// comparison with MySQL ignored in this test as it tests auto increment
    88  	utils.Exec(t, mcmp.VtConn, "insert into user_tbl(region_id, name) values (1,'A'),(3,'C')")
    89  
    90  	tcases := []struct {
    91  		query           string
    92  		expRowsAffected uint64
    93  		expInsertID     uint64
    94  	}{{
    95  		query:           "insert into user_tbl(region_id, name) select region_id, name from user_tbl",
    96  		expRowsAffected: 2,
    97  		expInsertID:     3,
    98  	}, {
    99  		query:           "insert into user_tbl(id, region_id, name) select null, region_id, name from user_tbl where id = 1",
   100  		expRowsAffected: 1,
   101  		expInsertID:     5,
   102  	}, {
   103  		query:           "insert into user_tbl(id, region_id, name) select 100, region_id, name from user_tbl where id = 1",
   104  		expRowsAffected: 1,
   105  		expInsertID:     0,
   106  	}, {
   107  		// auto-inc column as sharding column
   108  		query:           "insert into auto_tbl(id) select 10 union select null",
   109  		expRowsAffected: 2,
   110  		expInsertID:     666,
   111  	}, {
   112  		// auto-inc column as sharding column
   113  		query:           "insert into auto_tbl(unq_col) select null",
   114  		expRowsAffected: 1,
   115  		expInsertID:     667,
   116  	}}
   117  
   118  	for _, tcase := range tcases {
   119  		t.Run(tcase.query, func(t *testing.T) {
   120  			qr := utils.Exec(t, mcmp.VtConn, tcase.query)
   121  			assert.EqualValues(t, tcase.expRowsAffected, qr.RowsAffected)
   122  			assert.EqualValues(t, tcase.expInsertID, qr.InsertID)
   123  		})
   124  	}
   125  
   126  	utils.AssertMatches(t, mcmp.VtConn, `select id from user_tbl order by id`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)] [INT64(5)] [INT64(100)]]`)
   127  }
   128  
   129  func TestAutoIncInsertSelectOlapMode(t *testing.T) {
   130  	if clusterInstance.HasPartialKeyspaces {
   131  		t.Skip("don't run on partial keyspaces")
   132  	}
   133  	mcmp, closer := start(t)
   134  	defer closer()
   135  
   136  	utils.Exec(t, mcmp.VtConn, "set workload = olap")
   137  
   138  	// comparison with MySQL ignored in this test as it tests auto increment
   139  	utils.Exec(t, mcmp.VtConn, "insert into user_tbl(region_id, name) values (1,'A'),(3,'C')")
   140  
   141  	tcases := []struct {
   142  		query           string
   143  		expRowsAffected uint64
   144  		expInsertID     uint64
   145  	}{{
   146  		query:           "insert into user_tbl(region_id, name) select region_id, name from user_tbl",
   147  		expRowsAffected: 2,
   148  		expInsertID:     8,
   149  	}, {
   150  		query:           "insert into user_tbl(id, region_id, name) select null, region_id, name from user_tbl where id = 8",
   151  		expRowsAffected: 1,
   152  		expInsertID:     10,
   153  	}, {
   154  		query:           "insert into user_tbl(id, region_id, name) select 100, region_id, name from user_tbl where id = 8",
   155  		expRowsAffected: 1,
   156  		expInsertID:     0,
   157  	}, {
   158  		// auto-inc column as sharding column
   159  		query:           "insert into auto_tbl(id) select 10 union select null",
   160  		expRowsAffected: 2,
   161  		expInsertID:     668,
   162  	}, {
   163  		// auto-inc column as sharding column
   164  		query:           "insert into auto_tbl(unq_col) select null",
   165  		expRowsAffected: 1,
   166  		expInsertID:     669,
   167  	}}
   168  
   169  	for _, tcase := range tcases {
   170  		t.Run(tcase.query, func(t *testing.T) {
   171  			qr := utils.Exec(t, mcmp.VtConn, tcase.query)
   172  			assert.EqualValues(t, tcase.expRowsAffected, qr.RowsAffected)
   173  			assert.EqualValues(t, tcase.expInsertID, qr.InsertID)
   174  		})
   175  	}
   176  
   177  	utils.AssertMatches(t, mcmp.VtConn, `select id from user_tbl order by id`, `[[INT64(6)] [INT64(7)] [INT64(8)] [INT64(9)] [INT64(10)] [INT64(100)]]`)
   178  }
   179  
   180  func TestUnownedVindexInsertSelect(t *testing.T) {
   181  	if clusterInstance.HasPartialKeyspaces {
   182  		t.Skip("test uses multiple keyspaces, test framework only supports partial keyspace testing for a single keyspace")
   183  	}
   184  	mcmp, closer := start(t)
   185  	defer closer()
   186  
   187  	utils.Exec(t, mcmp.VtConn, "insert into order_tbl(oid, region_id) values (100,1),(300,2),(600,3),(700,4)")
   188  
   189  	qr := utils.Exec(t, mcmp.VtConn, "insert into oevent_tbl(oid, ename) select oid, 'dispatched' from order_tbl")
   190  	assert.EqualValues(t, 4, qr.RowsAffected)
   191  
   192  	utils.Exec(t, mcmp.VtConn, "use `sks/-80`")
   193  	qr = utils.Exec(t, mcmp.VtConn, `select count(*) from order_tbl o join oevent_tbl oe on o.oid = oe.oid`)
   194  	assert.Equal(t, `[[INT64(3)]]`, fmt.Sprintf("%v", qr.Rows))
   195  	utils.Exec(t, mcmp.VtConn, "use `sks/80-`")
   196  	qr = utils.Exec(t, mcmp.VtConn, `select count(*) from order_tbl o join oevent_tbl oe on o.oid = oe.oid`)
   197  	assert.Equal(t, `[[INT64(1)]]`, fmt.Sprintf("%v", qr.Rows))
   198  
   199  	// resetting the target
   200  	utils.Exec(t, mcmp.VtConn, "use `sks`")
   201  
   202  	// inserting non-existing record in oevent_tbl.
   203  	utils.AssertContainsError(t, mcmp.VtConn, "insert into oevent_tbl(oid, ename) select 1000, 'dispatched'", `could not map [INT64(1000)] to a keyspace id`)
   204  
   205  	// id is the sharding column, oid is unknowned lookup which points to region_id,
   206  	// the verify step should pass as we are inserting the same region_id to id
   207  	qr = utils.Exec(t, mcmp.VtConn, "insert into oextra_tbl(id, oid) select region_id, oid from order_tbl")
   208  	assert.EqualValues(t, 4, qr.RowsAffected)
   209  
   210  	// mismatch value, verify step will fail. oid 100 is mapped to region_id 1, in this test trying to insert 100 with 2.
   211  	utils.AssertContainsError(t, mcmp.VtConn, "insert into oextra_tbl(id, oid) select 2, 100", `values [[INT64(100)]] for column [oid] does not map to keyspace ids`)
   212  
   213  	// null to oid is allowed so verify ksids will ignore it.
   214  	utils.Exec(t, mcmp.VtConn, "insert into oextra_tbl(id, oid) select 5, null")
   215  }
   216  
   217  func TestUnownedVindexInsertSelectOlapMode(t *testing.T) {
   218  	if clusterInstance.HasPartialKeyspaces {
   219  		t.Skip("don't run on partial keyspaces")
   220  	}
   221  	mcmp, closer := start(t)
   222  	defer closer()
   223  
   224  	utils.Exec(t, mcmp.VtConn, "set workload = olap")
   225  
   226  	utils.Exec(t, mcmp.VtConn, "insert into order_tbl(oid, region_id) values (100,1),(300,2),(600,3),(700,4)")
   227  
   228  	qr := utils.Exec(t, mcmp.VtConn, "insert into oevent_tbl(oid, ename) select oid, 'dispatched' from order_tbl")
   229  	assert.EqualValues(t, 4, qr.RowsAffected)
   230  
   231  	utils.Exec(t, mcmp.VtConn, "use `sks/-80`")
   232  	utils.AssertMatches(t, mcmp.VtConn, `select count(*) from order_tbl o join oevent_tbl oe on o.oid = oe.oid`, `[[INT64(3)]]`)
   233  	utils.Exec(t, mcmp.VtConn, "use `sks/80-`")
   234  	utils.AssertMatches(t, mcmp.VtConn, `select count(*) from order_tbl o join oevent_tbl oe on o.oid = oe.oid`, `[[INT64(1)]]`)
   235  
   236  	// resetting the target
   237  	utils.Exec(t, mcmp.VtConn, "use `sks`")
   238  
   239  	// inserting non-existing record in oevent_tbl.
   240  	utils.AssertContainsError(t, mcmp.VtConn, "insert into oevent_tbl(oid, ename) select 1000, 'dispatched'", `could not map [INT64(1000)] to a keyspace id`)
   241  
   242  	// id is the sharding column, oid is unknowned lookup which points to region_id,
   243  	// the verify step should pass as we are inserting the same region_id to id
   244  	qr = utils.Exec(t, mcmp.VtConn, "insert into oextra_tbl(id, oid) select region_id, oid from order_tbl")
   245  	assert.EqualValues(t, 4, qr.RowsAffected)
   246  
   247  	// mismatch value, verify step will fail. oid 100 is mapped to region_id 1, in this test trying to insert 100 with 2.
   248  	utils.AssertContainsError(t, mcmp.VtConn, "insert into oextra_tbl(id, oid) select 2, 100", `values [[INT64(100)]] for column [oid] does not map to keyspace ids`)
   249  
   250  	// null to oid is allowed so verify ksids will ignore it.
   251  	utils.Exec(t, mcmp.VtConn, "insert into oextra_tbl(id, oid) select 5, null")
   252  }
   253  
   254  func TestLookupCasesIncInsertSelect(t *testing.T) {
   255  	mcmp, closer := start(t)
   256  	defer closer()
   257  
   258  	// all lookup vdx cols present
   259  	mcmp.Exec("insert into auto_tbl(id, unq_col, nonunq_col) select 1,2,3")
   260  	// unique lookup vdx cols present
   261  	mcmp.Exec("insert into auto_tbl(id, nonunq_col) select 2,3")
   262  	// non-unique lookup vdx cols present
   263  	mcmp.Exec("insert into auto_tbl(id, unq_col) select 3,3")
   264  
   265  	mcmp.AssertMatches(`select id, unq_col, nonunq_col from auto_tbl order by id`,
   266  		`[[INT64(1) INT64(2) INT64(3)] [INT64(2) NULL INT64(3)] [INT64(3) INT64(3) NULL]]`)
   267  	utils.AssertMatches(t, mcmp.VtConn, `select unq_col from unq_idx order by unq_col`,
   268  		`[[INT64(2)] [INT64(3)]]`)
   269  	utils.AssertMatches(t, mcmp.VtConn, `select nonunq_col, id from nonunq_idx order by nonunq_col, id`,
   270  		`[[INT64(3) INT64(1)] [INT64(3) INT64(2)]]`)
   271  }
   272  
   273  func TestLookupCasesIncInsertSelectOlapMode(t *testing.T) {
   274  	mcmp, closer := start(t)
   275  	defer closer()
   276  
   277  	utils.Exec(t, mcmp.VtConn, "set workload = olap")
   278  
   279  	// all lookup vdx cols present
   280  	mcmp.Exec("insert into auto_tbl(id, unq_col, nonunq_col) select 1,2,3")
   281  	// unique lookup vdx cols present
   282  	mcmp.Exec("insert into auto_tbl(id, nonunq_col) select 2,3")
   283  	// non-unique lookup vdx cols present
   284  	mcmp.Exec("insert into auto_tbl(id, unq_col) select 3,3")
   285  
   286  	mcmp.AssertMatches(`select id, unq_col, nonunq_col from auto_tbl order by id`,
   287  		`[[INT64(1) INT64(2) INT64(3)] [INT64(2) NULL INT64(3)] [INT64(3) INT64(3) NULL]]`)
   288  	utils.AssertMatches(t, mcmp.VtConn, `select unq_col from unq_idx order by unq_col`,
   289  		`[[INT64(2)] [INT64(3)]]`)
   290  	utils.AssertMatches(t, mcmp.VtConn, `select nonunq_col, id from nonunq_idx order by nonunq_col, id`,
   291  		`[[INT64(3) INT64(1)] [INT64(3) INT64(2)]]`)
   292  }
   293  
   294  func TestIgnoreInsertSelect(t *testing.T) {
   295  	mcmp, closer := start(t)
   296  	defer closer()
   297  
   298  	mcmp.Exec("insert into order_tbl(region_id, oid, cust_no) values (1,1,100),(1,2,200),(1,3,300)")
   299  
   300  	// inserting same rows, throws error.
   301  	mcmp.AssertContainsError("insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl", `lookup.Create: Code: ALREADY_EXISTS`)
   302  	// inserting same rows with ignore
   303  	qr := mcmp.Exec("insert ignore into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl")
   304  	assert.EqualValues(t, 0, qr.RowsAffected)
   305  	mcmp.AssertMatches("select count(*) from order_tbl", `[[INT64(3)]]`)
   306  
   307  	// inserting row with ignore with cust_no non-unique
   308  	qr = mcmp.Exec("insert ignore into order_tbl(region_id, oid, cust_no) select 1, 4, 100 from order_tbl")
   309  	assert.EqualValues(t, 0, qr.RowsAffected)
   310  
   311  	// inserting row with ignore with cust_no unique
   312  	qr = mcmp.Exec("insert ignore into order_tbl(region_id, oid, cust_no) select 1, 4, 400 from order_tbl")
   313  	assert.EqualValues(t, 1, qr.RowsAffected)
   314  	mcmp.AssertMatches("select count(*) from order_tbl", `[[INT64(4)]]`)
   315  
   316  	mcmp.AssertMatches("select oid, cust_no from order_tbl where region_id = 1 order by oid", `[[INT64(1) INT64(100)] [INT64(2) INT64(200)] [INT64(3) INT64(300)] [INT64(4) INT64(400)]]`)
   317  
   318  	// inserting row with on dup with cust_no non-unique
   319  	qr = utils.Exec(t, mcmp.VtConn, "insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl where oid = 4 on duplicate key update cust_no = cust_no + 1")
   320  	assert.EqualValues(t, 2, qr.RowsAffected)
   321  	utils.AssertMatches(t, mcmp.VtConn, "select count(*) from order_tbl", `[[INT64(4)]]`)
   322  
   323  	utils.AssertMatches(t, mcmp.VtConn, "select oid, cust_no from order_tbl order by oid", `[[INT64(1) INT64(100)] [INT64(2) INT64(200)] [INT64(3) INT64(300)] [INT64(4) INT64(401)]]`)
   324  
   325  	// inserting on dup trying to update vindex throws error.
   326  	utils.AssertContainsError(t, mcmp.VtConn, "insert into order_tbl(region_id, oid, cust_no) select 1, 10, 1000 on duplicate key update region_id = region_id + 1", `unsupported: DML cannot update vindex column`)
   327  	utils.AssertContainsError(t, mcmp.VtConn, "insert into order_tbl(region_id, oid, cust_no) select 1, 10, 1000 on duplicate key update oid = oid + 100", `unsupported: DML cannot update vindex column`)
   328  }
   329  
   330  func TestIgnoreInsertSelectOlapMode(t *testing.T) {
   331  	mcmp, closer := start(t)
   332  	defer closer()
   333  
   334  	utils.Exec(t, mcmp.VtConn, "set workload = olap")
   335  
   336  	mcmp.Exec("insert into order_tbl(region_id, oid, cust_no) values (1,1,100),(1,2,200),(1,3,300)")
   337  
   338  	// inserting same rows, throws error.
   339  	mcmp.AssertContainsError("insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl", `lookup.Create: Code: ALREADY_EXISTS`)
   340  	// inserting same rows with ignore
   341  	qr := mcmp.Exec("insert ignore into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl")
   342  	assert.EqualValues(t, 0, qr.RowsAffected)
   343  	mcmp.AssertMatches("select count(*) from order_tbl", `[[INT64(3)]]`)
   344  
   345  	// inserting row with ignore with cust_no non-unique
   346  	qr = mcmp.Exec("insert ignore into order_tbl(region_id, oid, cust_no) select 1, 4, 100 from order_tbl")
   347  	assert.EqualValues(t, 0, qr.RowsAffected)
   348  
   349  	// inserting row with ignore with cust_no unique
   350  	qr = mcmp.Exec("insert ignore into order_tbl(region_id, oid, cust_no) select 1, 4, 400 from order_tbl")
   351  	assert.EqualValues(t, 1, qr.RowsAffected)
   352  	mcmp.AssertMatches("select count(*) from order_tbl", `[[INT64(4)]]`)
   353  
   354  	mcmp.AssertMatches("select oid, cust_no from order_tbl where region_id = 1 order by oid", `[[INT64(1) INT64(100)] [INT64(2) INT64(200)] [INT64(3) INT64(300)] [INT64(4) INT64(400)]]`)
   355  
   356  	// inserting row with on dup with cust_no non-unique
   357  	qr = utils.Exec(t, mcmp.VtConn, "insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl where oid = 4 on duplicate key update cust_no = cust_no + 1")
   358  	assert.EqualValues(t, 2, qr.RowsAffected)
   359  	utils.AssertMatches(t, mcmp.VtConn, "select count(*) from order_tbl", `[[INT64(4)]]`)
   360  
   361  	utils.AssertMatches(t, mcmp.VtConn, "select oid, cust_no from order_tbl order by oid", `[[INT64(1) INT64(100)] [INT64(2) INT64(200)] [INT64(3) INT64(300)] [INT64(4) INT64(401)]]`)
   362  
   363  	// inserting on dup trying to update vindex throws error.
   364  	utils.AssertContainsError(t, mcmp.VtConn, "insert into order_tbl(region_id, oid, cust_no) select 1, 10, 1000 on duplicate key update region_id = region_id + 1", `unsupported: DML cannot update vindex column`)
   365  	utils.AssertContainsError(t, mcmp.VtConn, "insert into order_tbl(region_id, oid, cust_no) select 1, 10, 1000 on duplicate key update oid = oid + 100", `unsupported: DML cannot update vindex column`)
   366  }
   367  
   368  func TestInsertSelectUnshardedUsingSharded(t *testing.T) {
   369  	if clusterInstance.HasPartialKeyspaces {
   370  		t.Skip("test uses multiple keyspaces, test framework only supports partial keyspace testing for a single keyspace")
   371  	}
   372  	mcmp, closer := start(t)
   373  	defer closer()
   374  
   375  	mcmp.Exec("insert into s_tbl(id, num) values (1,2),(3,4)")
   376  
   377  	for _, mode := range []string{"oltp", "olap"} {
   378  		t.Run(mode, func(t *testing.T) {
   379  			utils.Exec(t, mcmp.VtConn, fmt.Sprintf("set workload = %s", mode))
   380  			qr := mcmp.Exec("insert into u_tbl(id, num) select id, num from s_tbl where s_tbl.id in (1,3)")
   381  			assert.EqualValues(t, 2, qr.RowsAffected)
   382  			mcmp.AssertMatches(`select id, num from u_tbl order by id`, `[[INT64(1) INT64(2)] [INT64(3) INT64(4)]]`)
   383  			mcmp.Exec(`delete from u_tbl`)
   384  		})
   385  	}
   386  }
   387  
   388  func TestRedactDupError(t *testing.T) {
   389  	mcmp, closer := start(t)
   390  	defer closer()
   391  
   392  	mcmp.Exec("insert into order_tbl(region_id, oid, cust_no) values (1,1,100),(1,2,200),(1,3,300)")
   393  
   394  	// inserting same rows, throws error.
   395  	mcmp.AssertContainsError("insert into order_tbl(region_id, oid, cust_no) select region_id, oid, cust_no from order_tbl", `BindVars: {REDACTED}`)
   396  }