github.com/XiaoMi/Gaea@v1.2.5/proxy/plan/plan_explain_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 TestExplainMycatShardSimpleInsert(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: "explain 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: "explain 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: "explain 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: "explain 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: "explain 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: "explain 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: "explain 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: "explain 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: "explain 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: "explain insert into tbl_mycat (a) values ('hi')", 110 hasErr: true, // sharding column not found 111 }, 112 { 113 db: "db_mycat", 114 sql: "explain 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: "explain 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: "explain 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: "explain 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: "explain 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: "explain 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: "explain insert into tbl_mycat () values ()", 157 hasErr: true, // insert or replace must specify columns 158 }, 159 { 160 db: "db_mycat", 161 sql: "explain insert into tbl_mycat values (6, 'hi')", 162 hasErr: true, // insert or replace must specify columns 163 }, 164 { 165 db: "db_mycat", 166 sql: "explain 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: "explain 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 TestExplainUnshardInsert(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: "explain insert into tbl_unshard (id, a) values (0, 'hi')", 190 sqls: map[string]map[string][]string{ 191 "slice-0": { 192 "db_mycat_0": {"INSERT INTO `tbl_unshard` (`id`,`a`) VALUES (0,'hi')"}, 193 }, 194 }, 195 }, 196 } 197 for _, test := range tests { 198 t.Run(test.sql, getTestFunc(ns, test)) 199 } 200 } 201 202 func TestExplainUnshardInsertWithDb(t *testing.T) { 203 ns, err := preparePlanInfo() 204 if err != nil { 205 t.Fatalf("prepare namespace error: %v", err) 206 } 207 208 tests := []SQLTestcase{ 209 { 210 db: "db_mycat", 211 sql: "explain insert into db_mycat.tbl_unshard (id, a) values (0, 'hi')", 212 sqls: map[string]map[string][]string{ 213 "slice-0": { 214 "db_mycat_0": {"INSERT INTO `db_mycat_0`.`tbl_unshard` (`id`,`a`) VALUES (0,'hi')"}, 215 }, 216 }, 217 }, 218 } 219 for _, test := range tests { 220 t.Run(test.sql, getTestFunc(ns, test)) 221 } 222 }