github.com/XiaoMi/Gaea@v1.2.5/proxy/plan/plan_insert_test.go (about)

     1  // Copyright 2019 The Gaea Authors. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package plan
    16  
    17  import "testing"
    18  
    19  func TestMycatShardSimpleInsert(t *testing.T) {
    20  	ns, err := preparePlanInfo()
    21  	if err != nil {
    22  		t.Fatalf("prepare namespace error: %v", err)
    23  	}
    24  
    25  	tests := []SQLTestcase{
    26  		{
    27  			db:  "db_mycat",
    28  			sql: "insert into tbl_mycat (id, a) values (0, 'hi')",
    29  			sqls: map[string]map[string][]string{
    30  				"slice-0": {
    31  					"db_mycat_0": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (0,'hi')"},
    32  				},
    33  			},
    34  		},
    35  		{
    36  			db:  "db_mycat",
    37  			sql: "insert into tbl_mycat (id, a) values (1, 'hi')",
    38  			sqls: map[string]map[string][]string{
    39  				"slice-0": {
    40  					"db_mycat_1": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (1,'hi')"},
    41  				},
    42  			},
    43  		},
    44  		{
    45  			db:  "db_mycat",
    46  			sql: "insert into tbl_mycat (id, a) values (2, 'hi')",
    47  			sqls: map[string]map[string][]string{
    48  				"slice-1": {
    49  					"db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (2,'hi')"},
    50  				},
    51  			},
    52  		},
    53  		{
    54  			db:  "db_mycat",
    55  			sql: "insert into tbl_mycat (id, a) values (3, 'hi')",
    56  			sqls: map[string]map[string][]string{
    57  				"slice-1": {
    58  					"db_mycat_3": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (3,'hi')"},
    59  				},
    60  			},
    61  		},
    62  		{
    63  			db:  "db_mycat",
    64  			sql: "insert into tbl_mycat (id, a) values (4, 'hi')",
    65  			sqls: map[string]map[string][]string{
    66  				"slice-0": {
    67  					"db_mycat_0": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (4,'hi')"},
    68  				},
    69  			},
    70  		},
    71  		{
    72  			db:  "db_mycat",
    73  			sql: "insert into tbl_mycat (id, a) values (6, 'hi')",
    74  			sqls: map[string]map[string][]string{
    75  				"slice-1": {
    76  					"db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi')"},
    77  				},
    78  			},
    79  		},
    80  		{
    81  			db:  "db_mycat",
    82  			sql: "insert into tbl_mycat (tbl_mycat.id, tbl_mycat.a) values (6, 'hi')", // table name is removed in columns
    83  			sqls: map[string]map[string][]string{
    84  				"slice-1": {
    85  					"db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi')"},
    86  				},
    87  			},
    88  		},
    89  		{
    90  			db:  "db_mycat",
    91  			sql: "insert into db_mycat.tbl_mycat (db_mycat.tbl_mycat.id, db_mycat.tbl_mycat.a) values (6, 'hi')", // db name is removed in columns, but rewritten in table
    92  			sqls: map[string]map[string][]string{
    93  				"slice-1": {
    94  					"db_mycat_2": {"INSERT INTO `db_mycat_2`.`tbl_mycat` (`id`,`a`) VALUES (6,'hi')"},
    95  				},
    96  			},
    97  		},
    98  		{
    99  			db:  "db_mycat",
   100  			sql: "insert into tbl_mycat (id,id,a) values (6,6,'hi')",
   101  			sqls: map[string]map[string][]string{
   102  				"slice-1": {
   103  					"db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`id`,`a`) VALUES (6,6,'hi')"}, // invalid syntax, but gaea does not handle
   104  				},
   105  			},
   106  		},
   107  		{
   108  			db:     "db_mycat",
   109  			sql:    "insert into tbl_mycat (a) values ('hi')",
   110  			hasErr: true, // sharding column not found
   111  		},
   112  		{
   113  			db:  "db_mycat",
   114  			sql: "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update a = 'hello'",
   115  			sqls: map[string]map[string][]string{
   116  				"slice-1": {
   117  					"db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi') ON DUPLICATE KEY UPDATE `a`='hello'"},
   118  				},
   119  			},
   120  		},
   121  		{
   122  			db:  "db_mycat",
   123  			sql: "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update a = 'hello'+'hi'",
   124  			sqls: map[string]map[string][]string{
   125  				"slice-1": {
   126  					"db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi') ON DUPLICATE KEY UPDATE `a`='hello'+'hi'"},
   127  				},
   128  			},
   129  		},
   130  		{
   131  			db:  "db_mycat",
   132  			sql: "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update a = left('hello',3)",
   133  			sqls: map[string]map[string][]string{
   134  				"slice-1": {
   135  					"db_mycat_2": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (6,'hi') ON DUPLICATE KEY UPDATE `a`=LEFT('hello', 3)"},
   136  				},
   137  			},
   138  		},
   139  		{
   140  			db:     "db_mycat",
   141  			sql:    "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update id = 5",
   142  			hasErr: true, // routing key in update expression
   143  		},
   144  		{
   145  			db:     "db_mycat",
   146  			sql:    "insert into tbl_mycat (id, a) values (6, 'hi') on duplicate key update id = id+3",
   147  			hasErr: true, // routing key in update expression
   148  		},
   149  		{
   150  			db:     "db_mycat",
   151  			sql:    "insert into tbl_mycat select * from tbl_mycat_child",
   152  			hasErr: true, // select in insert not allowed
   153  		},
   154  		{
   155  			db:     "db_mycat",
   156  			sql:    "insert into tbl_mycat () values ()",
   157  			hasErr: true, // insert or replace must specify columns
   158  		},
   159  		{
   160  			db:     "db_mycat",
   161  			sql:    "insert into tbl_mycat values (6, 'hi')",
   162  			hasErr: true, // insert or replace must specify columns
   163  		},
   164  		{
   165  			db:     "db_mycat",
   166  			sql:    "insert into tbl_mycat (id) values (6, 'hi')",
   167  			hasErr: true, // column count doesn't match value count
   168  		},
   169  		{
   170  			db:     "db_mycat",
   171  			sql:    "insert into tbl_mycat (id, a) values (6)",
   172  			hasErr: true, // column count doesn't match value count
   173  		},
   174  	}
   175  	for _, test := range tests {
   176  		t.Run(test.sql, getTestFunc(ns, test))
   177  	}
   178  }
   179  
   180  func TestMycatShardBatchInsert(t *testing.T) {
   181  	ns, err := preparePlanInfo()
   182  	if err != nil {
   183  		t.Fatalf("prepare namespace error: %v", err)
   184  	}
   185  
   186  	tests := []SQLTestcase{
   187  		{
   188  			db:  "db_mycat",
   189  			sql: "insert into tbl_mycat (id, a) values (0, 'hi'), (4, 'hi')",
   190  			sqls: map[string]map[string][]string{
   191  				"slice-0": {
   192  					"db_mycat_0": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (0,'hi'),(4,'hi')"},
   193  				},
   194  			},
   195  		},
   196  		{
   197  			db:     "db_mycat",
   198  			sql:    "insert into tbl_mycat (id, a) values (0, 'hi'), (1, 'hi'), (4, 'hi')",
   199  			hasErr: true, // batch insert has cross slice values
   200  		},
   201  		{
   202  			db:     "db_mycat",
   203  			sql:    "insert into tbl_mycat (id, a) values (6, 'hi'), (5, 'hello')",
   204  			hasErr: true, // batch insert has cross slice values
   205  		},
   206  	}
   207  	for _, test := range tests {
   208  		t.Run(test.sql, getTestFunc(ns, test))
   209  	}
   210  }
   211  
   212  func TestMycatShardSimpleInsertSet(t *testing.T) {
   213  	ns, err := preparePlanInfo()
   214  	if err != nil {
   215  		t.Fatalf("prepare namespace error: %v", err)
   216  	}
   217  
   218  	tests := []SQLTestcase{
   219  		{
   220  			db:  "db_mycat",
   221  			sql: "insert into tbl_mycat set id = 0, a = 'hi'",
   222  			sqls: map[string]map[string][]string{
   223  				"slice-0": {
   224  					"db_mycat_0": {"INSERT INTO `tbl_mycat` SET `id`=0,`a`='hi'"},
   225  				},
   226  			},
   227  		},
   228  	}
   229  	for _, test := range tests {
   230  		t.Run(test.sql, getTestFunc(ns, test))
   231  	}
   232  }
   233  
   234  func TestSimpleWriteDMLShardMycatMurmur(t *testing.T) {
   235  	ns, err := preparePlanInfo()
   236  	if err != nil {
   237  		t.Fatalf("prepare namespace error: %v", err)
   238  	}
   239  
   240  	tests := []SQLTestcase{
   241  		{
   242  			db:  "db_mycat",
   243  			sql: "insert into tbl_mycat_murmur (id, a) values (0, 'hi')",
   244  			sqls: map[string]map[string][]string{
   245  				"slice-1": {
   246  					"db_mycat_2": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (0,'hi')"},
   247  				},
   248  			},
   249  		},
   250  		{
   251  			db:  "db_mycat",
   252  			sql: "update tbl_mycat_murmur set a = 'h' where id = 0",
   253  			sqls: map[string]map[string][]string{
   254  				"slice-1": {
   255  					"db_mycat_2": {"UPDATE `tbl_mycat_murmur` SET `a`='h' WHERE `id`=0"},
   256  				},
   257  			},
   258  		},
   259  		{
   260  			db:  "db_mycat",
   261  			sql: "delete from tbl_mycat_murmur where id = 0",
   262  			sqls: map[string]map[string][]string{
   263  				"slice-1": {
   264  					"db_mycat_2": {"DELETE FROM `tbl_mycat_murmur` WHERE `id`=0"},
   265  				},
   266  			},
   267  		},
   268  		{
   269  			db:  "db_mycat",
   270  			sql: "insert into tbl_mycat_murmur (id, a) values (1, 'hi')",
   271  			sqls: map[string]map[string][]string{
   272  				"slice-0": {
   273  					"db_mycat_1": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (1,'hi')"},
   274  				},
   275  			},
   276  		},
   277  		{
   278  			db:  "db_mycat",
   279  			sql: "update tbl_mycat_murmur set a = 'h' where id = 1",
   280  			sqls: map[string]map[string][]string{
   281  				"slice-0": {
   282  					"db_mycat_1": {"UPDATE `tbl_mycat_murmur` SET `a`='h' WHERE `id`=1"},
   283  				},
   284  			},
   285  		},
   286  		{
   287  			db:  "db_mycat",
   288  			sql: "delete from tbl_mycat_murmur where id = 1",
   289  			sqls: map[string]map[string][]string{
   290  				"slice-0": {
   291  					"db_mycat_1": {"DELETE FROM `tbl_mycat_murmur` WHERE `id`=1"},
   292  				},
   293  			},
   294  		},
   295  		{
   296  			db:  "db_mycat",
   297  			sql: "insert into tbl_mycat_murmur (id, a) values (2, 'hi')",
   298  			sqls: map[string]map[string][]string{
   299  				"slice-0": {
   300  					"db_mycat_1": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (2,'hi')"},
   301  				},
   302  			},
   303  		},
   304  		{
   305  			db:  "db_mycat",
   306  			sql: "update tbl_mycat_murmur set a = 'h' where id = 2",
   307  			sqls: map[string]map[string][]string{
   308  				"slice-0": {
   309  					"db_mycat_1": {"UPDATE `tbl_mycat_murmur` SET `a`='h' WHERE `id`=2"},
   310  				},
   311  			},
   312  		},
   313  		{
   314  			db:  "db_mycat",
   315  			sql: "delete from tbl_mycat_murmur where id = 2",
   316  			sqls: map[string]map[string][]string{
   317  				"slice-0": {
   318  					"db_mycat_1": {"DELETE FROM `tbl_mycat_murmur` WHERE `id`=2"},
   319  				},
   320  			},
   321  		},
   322  		{
   323  			db:  "db_mycat",
   324  			sql: "insert into tbl_mycat_murmur (id, a) values (3, 'hi')",
   325  			sqls: map[string]map[string][]string{
   326  				"slice-0": {
   327  					"db_mycat_1": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (3,'hi')"},
   328  				},
   329  			},
   330  		},
   331  		{
   332  			db:  "db_mycat",
   333  			sql: "insert into tbl_mycat_murmur (id, a) values (4, 'hi')",
   334  			sqls: map[string]map[string][]string{
   335  				"slice-1": {
   336  					"db_mycat_2": {"INSERT INTO `tbl_mycat_murmur` (`id`,`a`) VALUES (4,'hi')"},
   337  				},
   338  			},
   339  		},
   340  		{
   341  			db:  "db_mycat",
   342  			sql: "update tbl_mycat_murmur set a = 'h' where id = 4",
   343  			sqls: map[string]map[string][]string{
   344  				"slice-1": {
   345  					"db_mycat_2": {"UPDATE `tbl_mycat_murmur` SET `a`='h' WHERE `id`=4"},
   346  				},
   347  			},
   348  		},
   349  		{
   350  			db:  "db_mycat",
   351  			sql: "delete from tbl_mycat_murmur where id = 4",
   352  			sqls: map[string]map[string][]string{
   353  				"slice-1": {
   354  					"db_mycat_2": {"DELETE FROM `tbl_mycat_murmur` WHERE `id`=4"},
   355  				},
   356  			},
   357  		},
   358  	}
   359  	for _, test := range tests {
   360  		t.Run(test.sql, getTestFunc(ns, test))
   361  	}
   362  }
   363  
   364  func TestSimpleWriteDMLShardMycatModLong(t *testing.T) {
   365  	ns, err := preparePlanInfo()
   366  	if err != nil {
   367  		t.Fatalf("prepare namespace error: %v", err)
   368  	}
   369  
   370  	tests := []SQLTestcase{
   371  		{
   372  			db:  "db_mycat",
   373  			sql: "insert into tbl_mycat_long (id, a) values (0, 'hi')",
   374  			sqls: map[string]map[string][]string{
   375  				"slice-0": {
   376  					"db_mycat_0": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (0,'hi')"},
   377  				},
   378  			},
   379  		},
   380  		{
   381  			db:  "db_mycat",
   382  			sql: "update tbl_mycat_long set a = 'h' where id = 0",
   383  			sqls: map[string]map[string][]string{
   384  				"slice-0": {
   385  					"db_mycat_0": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=0"},
   386  				},
   387  			},
   388  		},
   389  		{
   390  			db:  "db_mycat",
   391  			sql: "delete from tbl_mycat_long where id = 0",
   392  			sqls: map[string]map[string][]string{
   393  				"slice-0": {
   394  					"db_mycat_0": {"DELETE FROM `tbl_mycat_long` WHERE `id`=0"},
   395  				},
   396  			},
   397  		},
   398  		{
   399  			db:  "db_mycat",
   400  			sql: "insert into tbl_mycat_long (id, a) values (1, 'hi')",
   401  			sqls: map[string]map[string][]string{
   402  				"slice-0": {
   403  					"db_mycat_0": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (1,'hi')"},
   404  				},
   405  			},
   406  		},
   407  		{
   408  			db:  "db_mycat",
   409  			sql: "update tbl_mycat_long set a = 'h' where id = 1",
   410  			sqls: map[string]map[string][]string{
   411  				"slice-0": {
   412  					"db_mycat_0": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=1"},
   413  				},
   414  			},
   415  		},
   416  		{
   417  			db:  "db_mycat",
   418  			sql: "delete from tbl_mycat_long where id = 1",
   419  			sqls: map[string]map[string][]string{
   420  				"slice-0": {
   421  					"db_mycat_0": {"DELETE FROM `tbl_mycat_long` WHERE `id`=1"},
   422  				},
   423  			},
   424  		},
   425  		{
   426  			db:  "db_mycat",
   427  			sql: "insert into tbl_mycat_long (id, a) values (256, 'hi')",
   428  			sqls: map[string]map[string][]string{
   429  				"slice-0": {
   430  					"db_mycat_1": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (256,'hi')"},
   431  				},
   432  			},
   433  		},
   434  		{
   435  			db:  "db_mycat",
   436  			sql: "update tbl_mycat_long set a = 'h' where id = 256",
   437  			sqls: map[string]map[string][]string{
   438  				"slice-0": {
   439  					"db_mycat_1": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=256"},
   440  				},
   441  			},
   442  		},
   443  		{
   444  			db:  "db_mycat",
   445  			sql: "delete from tbl_mycat_long where id = 256",
   446  			sqls: map[string]map[string][]string{
   447  				"slice-0": {
   448  					"db_mycat_1": {"DELETE FROM `tbl_mycat_long` WHERE `id`=256"},
   449  				},
   450  			},
   451  		},
   452  		{
   453  			db:  "db_mycat",
   454  			sql: "insert into tbl_mycat_long (id, a) values (257, 'hi')",
   455  			sqls: map[string]map[string][]string{
   456  				"slice-0": {
   457  					"db_mycat_1": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (257,'hi')"},
   458  				},
   459  			},
   460  		},
   461  		{
   462  			db:  "db_mycat",
   463  			sql: "update tbl_mycat_long set a = 'h' where id = 257",
   464  			sqls: map[string]map[string][]string{
   465  				"slice-0": {
   466  					"db_mycat_1": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=257"},
   467  				},
   468  			},
   469  		},
   470  		{
   471  			db:  "db_mycat",
   472  			sql: "delete from tbl_mycat_long where id = 257",
   473  			sqls: map[string]map[string][]string{
   474  				"slice-0": {
   475  					"db_mycat_1": {"DELETE FROM `tbl_mycat_long` WHERE `id`=257"},
   476  				},
   477  			},
   478  		},
   479  		{
   480  			db:  "db_mycat",
   481  			sql: "insert into tbl_mycat_long (id, a) values (512, 'hi')",
   482  			sqls: map[string]map[string][]string{
   483  				"slice-1": {
   484  					"db_mycat_2": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (512,'hi')"},
   485  				},
   486  			},
   487  		},
   488  		{
   489  			db:  "db_mycat",
   490  			sql: "update tbl_mycat_long set a = 'h' where id = 512",
   491  			sqls: map[string]map[string][]string{
   492  				"slice-1": {
   493  					"db_mycat_2": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=512"},
   494  				},
   495  			},
   496  		},
   497  		{
   498  			db:  "db_mycat",
   499  			sql: "delete from tbl_mycat_long where id = 512",
   500  			sqls: map[string]map[string][]string{
   501  				"slice-1": {
   502  					"db_mycat_2": {"DELETE FROM `tbl_mycat_long` WHERE `id`=512"},
   503  				},
   504  			},
   505  		},
   506  		{
   507  			db:  "db_mycat",
   508  			sql: "insert into tbl_mycat_long (id, a) values (513, 'hi')",
   509  			sqls: map[string]map[string][]string{
   510  				"slice-1": {
   511  					"db_mycat_2": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (513,'hi')"},
   512  				},
   513  			},
   514  		},
   515  		{
   516  			db:  "db_mycat",
   517  			sql: "update tbl_mycat_long set a = 'h' where id = 513",
   518  			sqls: map[string]map[string][]string{
   519  				"slice-1": {
   520  					"db_mycat_2": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=513"},
   521  				},
   522  			},
   523  		},
   524  		{
   525  			db:  "db_mycat",
   526  			sql: "delete from tbl_mycat_long where id = 513",
   527  			sqls: map[string]map[string][]string{
   528  				"slice-1": {
   529  					"db_mycat_2": {"DELETE FROM `tbl_mycat_long` WHERE `id`=513"},
   530  				},
   531  			},
   532  		},
   533  		{
   534  			db:  "db_mycat",
   535  			sql: "insert into tbl_mycat_long (id, a) values (768, 'hi')",
   536  			sqls: map[string]map[string][]string{
   537  				"slice-1": {
   538  					"db_mycat_3": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (768,'hi')"},
   539  				},
   540  			},
   541  		},
   542  		{
   543  			db:  "db_mycat",
   544  			sql: "update tbl_mycat_long set a = 'h' where id = 768",
   545  			sqls: map[string]map[string][]string{
   546  				"slice-1": {
   547  					"db_mycat_3": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=768"},
   548  				},
   549  			},
   550  		},
   551  		{
   552  			db:  "db_mycat",
   553  			sql: "delete from tbl_mycat_long where id = 768",
   554  			sqls: map[string]map[string][]string{
   555  				"slice-1": {
   556  					"db_mycat_3": {"DELETE FROM `tbl_mycat_long` WHERE `id`=768"},
   557  				},
   558  			},
   559  		},
   560  		{
   561  			db:  "db_mycat",
   562  			sql: "insert into tbl_mycat_long (id, a) values (769, 'hi')",
   563  			sqls: map[string]map[string][]string{
   564  				"slice-1": {
   565  					"db_mycat_3": {"INSERT INTO `tbl_mycat_long` (`id`,`a`) VALUES (769,'hi')"},
   566  				},
   567  			},
   568  		},
   569  		{
   570  			db:  "db_mycat",
   571  			sql: "update tbl_mycat_long set a = 'h' where id = 769",
   572  			sqls: map[string]map[string][]string{
   573  				"slice-1": {
   574  					"db_mycat_3": {"UPDATE `tbl_mycat_long` SET `a`='h' WHERE `id`=769"},
   575  				},
   576  			},
   577  		},
   578  		{
   579  			db:  "db_mycat",
   580  			sql: "delete from tbl_mycat_long where id = 769",
   581  			sqls: map[string]map[string][]string{
   582  				"slice-1": {
   583  					"db_mycat_3": {"DELETE FROM `tbl_mycat_long` WHERE `id`=769"},
   584  				},
   585  			},
   586  		},
   587  	}
   588  	for _, test := range tests {
   589  		t.Run(test.sql, getTestFunc(ns, test))
   590  	}
   591  }
   592  
   593  func TestMycatInsertGlobalTable(t *testing.T) {
   594  	ns, err := preparePlanInfo()
   595  	if err != nil {
   596  		t.Fatalf("prepare namespace error: %v", err)
   597  	}
   598  
   599  	tests := []SQLTestcase{
   600  		{
   601  			db:  "db_mycat",
   602  			sql: "insert into tbl_mycat_global_one set id = 0, a = 'hi'",
   603  			sqls: map[string]map[string][]string{
   604  				"slice-0": {
   605  					"db_mycat_0": {"INSERT INTO `tbl_mycat_global_one` SET `id`=0,`a`='hi'"},
   606  					"db_mycat_1": {"INSERT INTO `tbl_mycat_global_one` SET `id`=0,`a`='hi'"},
   607  				},
   608  				"slice-1": {
   609  					"db_mycat_2": {"INSERT INTO `tbl_mycat_global_one` SET `id`=0,`a`='hi'"},
   610  					"db_mycat_3": {"INSERT INTO `tbl_mycat_global_one` SET `id`=0,`a`='hi'"},
   611  				},
   612  			},
   613  		},
   614  		{
   615  			db:  "db_mycat",
   616  			sql: "insert into db_mycat.tbl_mycat_global_one set id = 0, a = 'hi'",
   617  			sqls: map[string]map[string][]string{
   618  				"slice-0": {
   619  					"db_mycat_0": {"INSERT INTO `db_mycat_0`.`tbl_mycat_global_one` SET `id`=0,`a`='hi'"},
   620  					"db_mycat_1": {"INSERT INTO `db_mycat_1`.`tbl_mycat_global_one` SET `id`=0,`a`='hi'"},
   621  				},
   622  				"slice-1": {
   623  					"db_mycat_2": {"INSERT INTO `db_mycat_2`.`tbl_mycat_global_one` SET `id`=0,`a`='hi'"},
   624  					"db_mycat_3": {"INSERT INTO `db_mycat_3`.`tbl_mycat_global_one` SET `id`=0,`a`='hi'"},
   625  				},
   626  			},
   627  		},
   628  	}
   629  	for _, test := range tests {
   630  		t.Run(test.sql, getTestFunc(ns, test))
   631  	}
   632  }
   633  
   634  // 注意这一组各个测试用例之前有关联, 因为都用到了同一个全局序列号
   635  func TestMycatInsertSequenceShardKey(t *testing.T) {
   636  	ns, err := preparePlanInfo()
   637  	if err != nil {
   638  		t.Fatalf("prepare namespace error: %v", err)
   639  	}
   640  
   641  	tests := []SQLTestcase{
   642  		{
   643  			db:  "db_mycat",
   644  			sql: "insert into tbl_mycat set id = nextval(), a = 'hi'",
   645  			sqls: map[string]map[string][]string{
   646  				"slice-0": {
   647  					"db_mycat_1": {"INSERT INTO `tbl_mycat` SET `id`=1,`a`='hi'"},
   648  				},
   649  			},
   650  		},
   651  		{
   652  			db:  "db_mycat",
   653  			sql: "insert into tbl_mycat set id = nextval(), a = 'hi'",
   654  			sqls: map[string]map[string][]string{
   655  				"slice-1": {
   656  					"db_mycat_2": {"INSERT INTO `tbl_mycat` SET `id`=2,`a`='hi'"}, // next val
   657  				},
   658  			},
   659  		},
   660  		{
   661  			db:  "db_mycat",
   662  			sql: "insert into tbl_mycat (id, a) values (nextval(), 'hi')",
   663  			sqls: map[string]map[string][]string{
   664  				"slice-1": {
   665  					"db_mycat_3": {"INSERT INTO `tbl_mycat` (`id`,`a`) VALUES (3,'hi')"},
   666  				},
   667  			},
   668  		},
   669  		{
   670  			db:  "db_mycat",
   671  			sql: "insert into tbl_mycat (ID, a) values (nextval(), 'hi')",
   672  			sqls: map[string]map[string][]string{
   673  				"slice-0": {
   674  					"db_mycat_0": {"INSERT INTO `tbl_mycat` (`ID`,`a`) VALUES (4,'hi')"},
   675  				},
   676  			},
   677  		},
   678  		{
   679  			db:  "db_mycat",
   680  			sql: "insert into tbl_mycat set ID = nextval(), a = 'hi'",
   681  			sqls: map[string]map[string][]string{
   682  				"slice-0": {
   683  					"db_mycat_1": {"INSERT INTO `tbl_mycat` SET `ID`=5,`a`='hi'"},
   684  				},
   685  			},
   686  		},
   687  	}
   688  	for _, test := range tests {
   689  		t.Run(test.sql, getTestFunc(ns, test))
   690  	}
   691  }
   692  
   693  // 注意这一组各个测试用例之前有关联, 因为都用到了同一个全局序列号
   694  func TestMycatInsertSequenceUnshardKey(t *testing.T) {
   695  	ns, err := preparePlanInfo()
   696  	if err != nil {
   697  		t.Fatalf("prepare namespace error: %v", err)
   698  	}
   699  
   700  	tests := []SQLTestcase{
   701  		{
   702  			db:  "db_ks",
   703  			sql: "insert into tbl_ks set id = 0, user_id = nextval(), a = 'hi'",
   704  			sqls: map[string]map[string][]string{
   705  				"slice-0": {
   706  					"db_ks": {"INSERT INTO `tbl_ks_0000` SET `id`=0,`user_id`=1,`a`='hi'"},
   707  				},
   708  			},
   709  		},
   710  		{
   711  			db:  "db_ks",
   712  			sql: "insert into tbl_ks set id = 0, user_id = nextval(), a = 'hi'",
   713  			sqls: map[string]map[string][]string{
   714  				"slice-0": {
   715  					"db_ks": {"INSERT INTO `tbl_ks_0000` SET `id`=0,`user_id`=2,`a`='hi'"},
   716  				},
   717  			},
   718  		},
   719  		{
   720  			db:  "db_ks",
   721  			sql: "insert into tbl_ks (id, user_id) values (3,nextval()),(3,nextval()),(3, nextval())",
   722  			sqls: map[string]map[string][]string{
   723  				"slice-1": {
   724  					"db_ks": {"INSERT INTO `tbl_ks_0003` (`id`,`user_id`) VALUES (3,3),(3,4),(3,5)"},
   725  				},
   726  			},
   727  		},
   728  	}
   729  	for _, test := range tests {
   730  		t.Run(test.sql, getTestFunc(ns, test))
   731  	}
   732  }
   733  
   734  func TestEscapeBackslashShard(t *testing.T) {
   735  	ns, err := preparePlanInfo()
   736  	if err != nil {
   737  		t.Fatalf("prepare namespace error: %v", err)
   738  	}
   739  
   740  	tests := []SQLTestcase{
   741  		{
   742  			db:  "db_ks",
   743  			sql: `insert into tbl_ks (id,name) values (1,'hello\\"world')`,
   744  			sqls: map[string]map[string][]string{
   745  				"slice-0": {
   746  					"db_ks": {"INSERT INTO `tbl_ks_0001` (`id`,`name`) VALUES (1,'hello\\\\\"world')"},
   747  				},
   748  			},
   749  		},
   750  	}
   751  	for _, test := range tests {
   752  		t.Run(test.sql, getTestFunc(ns, test))
   753  	}
   754  }
   755  
   756  func TestMycatShardSimpleInsertColumnCaseInsensitive(t *testing.T) {
   757  	ns, err := preparePlanInfo()
   758  	if err != nil {
   759  		t.Fatalf("prepare namespace error: %v", err)
   760  	}
   761  
   762  	tests := []SQLTestcase{
   763  		{
   764  			db:  "db_mycat",
   765  			sql: "insert into tbl_mycat (ID, a) values (0, 'hi')",
   766  			sqls: map[string]map[string][]string{
   767  				"slice-0": {
   768  					"db_mycat_0": {"INSERT INTO `tbl_mycat` (`ID`,`a`) VALUES (0,'hi')"},
   769  				},
   770  			},
   771  		},
   772  		{
   773  			db:  "db_mycat",
   774  			sql: "insert into tbl_mycat set ID = 0, a = 'hi'",
   775  			sqls: map[string]map[string][]string{
   776  				"slice-0": {
   777  					"db_mycat_0": {"INSERT INTO `tbl_mycat` SET `ID`=0,`a`='hi'"},
   778  				},
   779  			},
   780  		},
   781  		{
   782  			db:     "db_mycat",
   783  			sql:    "insert into tbl_mycat (ID, a) values (6, 'hi') on duplicate key update ID = 5",
   784  			hasErr: true, // routing key in update expression
   785  		},
   786  	}
   787  	for _, test := range tests {
   788  		t.Run(test.sql, getTestFunc(ns, test))
   789  	}
   790  }
   791  
   792  func TestInserTableNameColumnCaseInsensitive(t *testing.T) {
   793  	ns, err := preparePlanInfo()
   794  	if err != nil {
   795  		t.Fatalf("prepare namespace error: %v", err)
   796  	}
   797  
   798  	tests := []SQLTestcase{
   799  		{
   800  			db:  "db_mycat",
   801  			sql: "insert into TBL_MYCAT (ID, a) values (0, 'hi')",
   802  			sqls: map[string]map[string][]string{
   803  				"slice-0": {
   804  					"db_mycat_0": {"INSERT INTO `TBL_MYCAT` (`ID`,`a`) VALUES (0,'hi')"},
   805  				},
   806  			},
   807  		},
   808  		{
   809  			db:  "db_ks",
   810  			sql: "insert into tbl_ks_uppercase_child (ID, a) values (0, 'hi')",
   811  			sqls: map[string]map[string][]string{
   812  				"slice-0": {
   813  					"db_ks": {"INSERT INTO `tbl_ks_uppercase_child_0000` (`ID`,`a`) VALUES (0,'hi')"},
   814  				},
   815  			},
   816  		},
   817  	}
   818  	for _, test := range tests {
   819  		t.Run(test.sql, getTestFunc(ns, test))
   820  	}
   821  }