github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/sqlinsert_test.go (about) 1 // Copyright 2020 Dolthub, Inc. 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 sqle 16 17 import ( 18 "context" 19 "testing" 20 21 "github.com/dolthub/go-mysql-server/sql" 22 "github.com/google/uuid" 23 "github.com/stretchr/testify/assert" 24 "github.com/stretchr/testify/require" 25 26 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 27 "github.com/dolthub/dolt/go/libraries/doltcore/doltdocs" 28 "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils" 29 "github.com/dolthub/dolt/go/libraries/doltcore/env" 30 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 31 . "github.com/dolthub/dolt/go/libraries/doltcore/sql/sqltestutil" 32 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables" 33 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil" 34 "github.com/dolthub/dolt/go/store/types" 35 ) 36 37 // Set to the name of a single test to run just that test, useful for debugging 38 const singleInsertQueryTest = "" //"Natural join with join clause" 39 40 // Set to false to run tests known to be broken 41 const skipBrokenInsert = true 42 43 // Structure for a test of a insert query 44 type InsertTest struct { 45 // The name of this test. Names should be unique and descriptive. 46 Name string 47 // The insert query to run 48 InsertQuery string 49 // The select query to run to verify the results 50 SelectQuery string 51 // The schema of the result of the query, nil if an error is expected 52 ExpectedSchema schema.Schema 53 // The rows this query should return, nil if an error is expected 54 ExpectedRows []sql.Row 55 // An expected error string 56 ExpectedErr string 57 // Setup logic to run before executing this test, after initial tables have been created and populated 58 AdditionalSetup SetupFn 59 // Whether to skip this test on SqlEngine (go-mysql-server) execution. 60 // Over time, this should become false for every query. 61 SkipOnSqlEngine bool 62 } 63 64 // BasicInsertTests cover basic insert statement features and error handling 65 var BasicInsertTests = []InsertTest{ 66 { 67 Name: "insert no columns", 68 InsertQuery: "insert into people values (2, 'Bart', 'Simpson', false, 10, 9, '00000000-0000-0000-0000-000000000002', 222)", 69 SelectQuery: "select * from people where id = 2 ORDER BY id", 70 ExpectedRows: ToSqlRows(PeopleTestSchema, Bart), 71 ExpectedSchema: CompressSchema(PeopleTestSchema), 72 }, 73 { 74 Name: "insert no columns too few values", 75 InsertQuery: "insert into people values (2, 'Bart', 'Simpson', false, 10, 9, '00000000-0000-0000-0000-000000000002')", 76 ExpectedErr: "too few values", 77 }, 78 { 79 Name: "insert no columns too many values", 80 InsertQuery: "insert into people values (2, 'Bart', 'Simpson', false, 10, 9, '00000000-0000-0000-0000-000000000002', 222, 'abc')", 81 ExpectedErr: "too many values", 82 }, 83 { 84 Name: "insert full columns", 85 InsertQuery: "insert into people (id, first_name, last_name, is_married, age, rating, uuid, num_episodes) values (2, 'Bart', 'Simpson', false, 10, 9, '00000000-0000-0000-0000-000000000002', 222)", 86 SelectQuery: "select * from people where id = 2 ORDER BY id", 87 ExpectedRows: ToSqlRows(PeopleTestSchema, Bart), 88 ExpectedSchema: CompressSchema(PeopleTestSchema), 89 }, 90 { 91 Name: "insert full columns mixed order", 92 InsertQuery: "insert into people (num_episodes, uuid, rating, age, is_married, last_name, first_name, id) values (222, '00000000-0000-0000-0000-000000000002', 9, 10, false, 'Simpson', 'Bart', 2)", 93 SelectQuery: "select * from people where id = 2 ORDER BY id", 94 ExpectedRows: ToSqlRows(PeopleTestSchema, Bart), 95 ExpectedSchema: CompressSchema(PeopleTestSchema), 96 }, 97 { 98 Name: "insert full columns negative values", 99 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating, uuid, num_episodes) values 100 (-7, "Maggie", "Simpson", false, -1, -5.1, '00000000-0000-0000-0000-000000000005', 677)`, 101 SelectQuery: "select * from people where id = -7 ORDER BY id", 102 ExpectedRows: ToSqlRows(PeopleTestSchema, NewPeopleRowWithOptionalFields(-7, "Maggie", "Simpson", false, -1, -5.1, uuid.MustParse("00000000-0000-0000-0000-000000000005"), 677)), 103 ExpectedSchema: CompressSchema(PeopleTestSchema), 104 }, 105 { 106 Name: "insert full columns null values", 107 InsertQuery: "insert into people (id, first_name, last_name, is_married, age, rating, uuid, num_episodes) values (2, 'Bart', 'Simpson', null, null, null, null, null)", 108 SelectQuery: "select * from people where id = 2 ORDER BY id", 109 ExpectedRows: ToSqlRows(CompressSchema(PeopleTestSchema), NewResultSetRow(types.Int(2), types.String("Bart"), types.String("Simpson"))), 110 ExpectedSchema: CompressSchema(PeopleTestSchema), 111 }, 112 { 113 Name: "insert partial columns", 114 InsertQuery: "insert into people (id, first_name, last_name) values (2, 'Bart', 'Simpson')", 115 SelectQuery: "select id, first_name, last_name from people where id = 2 ORDER BY id", 116 ExpectedRows: ToSqlRows( 117 NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 118 NewResultSetRow(types.Int(2), types.String("Bart"), types.String("Simpson")), 119 ), 120 ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 121 }, 122 { 123 Name: "insert partial columns mixed order", 124 InsertQuery: "insert into people (last_name, first_name, id) values ('Simpson', 'Bart', 2)", 125 SelectQuery: "select id, first_name, last_name from people where id = 2 ORDER BY id", 126 ExpectedRows: ToSqlRows( 127 NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 128 NewResultSetRow(types.Int(2), types.String("Bart"), types.String("Simpson")), 129 ), 130 ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 131 }, 132 { 133 Name: "insert partial columns duplicate column", 134 InsertQuery: "insert into people (id, first_name, last_name, first_name) values (2, 'Bart', 'Simpson', 'Bart')", 135 ExpectedErr: "duplicate column", 136 }, 137 { 138 Name: "insert partial columns invalid column", 139 InsertQuery: "insert into people (id, first_name, last_name, middle) values (2, 'Bart', 'Simpson', 'Nani')", 140 ExpectedErr: "duplicate column", 141 }, 142 { 143 Name: "insert missing non-nullable column", 144 InsertQuery: "insert into people (id, first_name) values (2, 'Bart')", 145 ExpectedErr: "column <last_name> received nil but is non-nullable", 146 }, 147 { 148 Name: "insert partial columns mismatch too many values", 149 InsertQuery: "insert into people (id, first_name, last_name) values (2, 'Bart', 'Simpson', false)", 150 ExpectedErr: "too many values", 151 }, 152 { 153 Name: "insert partial columns mismatch too few values", 154 InsertQuery: "insert into people (id, first_name, last_name) values (2, 'Bart')", 155 ExpectedErr: "too few values", 156 }, 157 { 158 Name: "insert partial columns functions", 159 InsertQuery: "insert into people (id, first_name, last_name) values (2, UPPER('Bart'), 'Simpson')", 160 SelectQuery: "select id, first_name, last_name from people where id = 2 ORDER BY id", 161 ExpectedRows: ToSqlRows( 162 NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 163 NewResultSetRow(types.Int(2), types.String("BART"), types.String("Simpson")), 164 ), 165 ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 166 }, 167 { 168 Name: "insert partial columns multiple rows 2", 169 InsertQuery: "insert into people (id, first_name, last_name) values (0, 'Bart', 'Simpson'), (1, 'Homer', 'Simpson')", 170 SelectQuery: "select id, first_name, last_name from people where id < 2 order by id", 171 ExpectedRows: ToSqlRows( 172 NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 173 NewResultSetRow(types.Int(0), types.String("Bart"), types.String("Simpson")), 174 NewResultSetRow(types.Int(1), types.String("Homer"), types.String("Simpson")), 175 ), 176 ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 177 }, 178 { 179 Name: "insert partial columns multiple rows 5", 180 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 181 (7, "Maggie", "Simpson", false, 1, 5.1), 182 (8, "Milhouse", "Van Houten", false, 8, 3.5), 183 (9, "Jacqueline", "Bouvier", true, 80, 2), 184 (10, "Patty", "Bouvier", false, 40, 7), 185 (11, "Selma", "Bouvier", false, 40, 7)`, 186 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id > 6 ORDER BY id", 187 ExpectedRows: ToSqlRows(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating"), 188 NewPeopleRow(7, "Maggie", "Simpson", false, 1, 5.1), 189 NewPeopleRow(8, "Milhouse", "Van Houten", false, 8, 3.5), 190 NewPeopleRow(9, "Jacqueline", "Bouvier", true, 80, 2), 191 NewPeopleRow(10, "Patty", "Bouvier", false, 40, 7), 192 NewPeopleRow(11, "Selma", "Bouvier", false, 40, 7), 193 ), 194 ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind, 195 "is_married", types.BoolKind, "age", types.IntKind, "rating", types.FloatKind), 196 }, 197 { 198 Name: "insert ignore partial columns multiple rows null constraint failure", 199 InsertQuery: `insert ignore into people (id, first_name, last_name, is_married, age, rating) values 200 (7, "Maggie", null, false, 1, 5.1), 201 (8, "Milhouse", "Van Houten", false, 8, 3.5)`, 202 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id > 6 ORDER BY id", 203 ExpectedRows: ToSqlRows(PeopleTestSchema, NewPeopleRow(8, "Milhouse", "Van Houten", false, 8, 3.5)), 204 ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind, 205 "is_married", types.BoolKind, "age", types.IntKind, "rating", types.FloatKind), 206 SkipOnSqlEngine: true, 207 }, 208 { 209 Name: "insert ignore partial columns multiple rows existing pk", 210 InsertQuery: `insert ignore into people (id, first_name, last_name, is_married, age, rating) values 211 (0, "Homer", "Simpson", true, 45, 100), 212 (8, "Milhouse", "Van Houten", false, 8, 8.5)`, 213 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where rating = 8.5 order by id", 214 ExpectedRows: ToSqlRows(PeopleTestSchema, 215 Homer, 216 NewPeopleRow(8, "Milhouse", "Van Houten", false, 8, 8.5), 217 ), 218 ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind, 219 "is_married", types.BoolKind, "age", types.IntKind, "rating", types.FloatKind), 220 SkipOnSqlEngine: true, 221 }, 222 { 223 Name: "insert ignore partial columns multiple rows duplicate pk", 224 InsertQuery: `insert ignore into people (id, first_name, last_name, is_married, age, rating) values 225 (7, "Maggie", "Simpson", false, 1, 5.1), 226 (7, "Milhouse", "Van Houten", false, 8, 3.5)`, 227 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 228 ExpectedRows: ToSqlRows(PeopleTestSchema, NewPeopleRow(7, "Maggie", "Simpson", false, 1, 5.1)), 229 ExpectedSchema: NewResultSetSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind, 230 "is_married", types.BoolKind, "age", types.IntKind, "rating", types.FloatKind), 231 SkipOnSqlEngine: true, 232 }, 233 { 234 Name: "insert partial columns multiple rows null pk", 235 InsertQuery: "insert into people (id, first_name, last_name) values (0, 'Bart', 'Simpson'), (1, 'Homer', null)", 236 ExpectedErr: "column <last_name> received nil but is non-nullable", 237 }, 238 { 239 Name: "insert partial columns multiple rows duplicate", 240 InsertQuery: "insert into people (id, first_name, last_name) values (2, 'Bart', 'Simpson'), (2, 'Bart', 'Simpson')", 241 ExpectedErr: "duplicate primary key", 242 }, 243 { 244 Name: "insert partial columns existing pk", 245 AdditionalSetup: CreateTableWithRowsFn("temppeople", 246 NewSchema("id", types.IntKind, "first_name", types.StringKind, "last_name", types.StringKind), 247 []types.Value{types.Int(2), types.String("Bart"), types.String("Simpson")}), 248 InsertQuery: "insert into temppeople (id, first_name, last_name) values (2, 'Bart', 'Simpson')", 249 ExpectedErr: "duplicate primary key", 250 }, 251 { 252 Name: "type mismatch int -> string", 253 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 254 (7, "Maggie", 100, false, 1, 5.1)`, 255 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 256 ExpectedRows: ToSqlRows( 257 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 258 NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("100"), types.Bool(false), types.Int(1), types.Float(5.1)), 259 ), 260 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 261 }, 262 { 263 Name: "type mismatch int -> bool", 264 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 265 (7, "Maggie", "Simpson", 1, 1, 5.1)`, 266 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 267 ExpectedRows: ToSqlRows( 268 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 269 NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Bool(true), types.Int(1), types.Float(5.1)), 270 ), 271 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 272 }, 273 { 274 Name: "type mismatch int -> uuid", 275 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, uuid) values 276 (7, "Maggie", "Simpson", false, 1, 100)`, 277 ExpectedErr: "Type mismatch", 278 }, 279 { 280 Name: "type mismatch string -> int", 281 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 282 ("7", "Maggie", "Simpson", false, 1, 5.1)`, 283 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 284 ExpectedRows: ToSqlRows( 285 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 286 NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Bool(false), types.Int(1), types.Float(5.1)), 287 ), 288 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 289 }, 290 { 291 Name: "type mismatch string -> float", 292 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 293 (7, "Maggie", "Simpson", false, 1, "5.1")`, 294 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 295 ExpectedRows: ToSqlRows( 296 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 297 NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Bool(false), types.Int(1), types.Float(5.1)), 298 ), 299 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 300 }, 301 { 302 Name: "type mismatch string -> uint", 303 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, num_episodes) values 304 (7, "Maggie", "Simpson", false, 1, "100")`, 305 SelectQuery: "select id, first_name, last_name, is_married, age, num_episodes from people where id = 7 ORDER BY id", 306 ExpectedRows: ToSqlRows( 307 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "num_episodes")), 308 NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Bool(false), types.Int(1), types.Uint(100)), 309 ), 310 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "num_episodes")), 311 }, 312 { 313 Name: "type mismatch string -> uuid", 314 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, uuid) values 315 (7, "Maggie", "Simpson", false, 1, "a uuid but idk what im doing")`, 316 ExpectedErr: "Type mismatch", 317 }, 318 { 319 Name: "type mismatch float -> string", 320 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 321 (7, 8.1, "Simpson", false, 1, 5.1)`, 322 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 323 ExpectedRows: ToSqlRows( 324 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 325 NewResultSetRow(types.Int(7), types.String("8.1"), types.String("Simpson"), types.Bool(false), types.Int(1), types.Float(5.1)), 326 ), 327 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 328 }, 329 { 330 Name: "type mismatch float -> bool", 331 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 332 (7, "Maggie", "Simpson", 0.5, 1, 5.1)`, 333 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 334 ExpectedRows: ToSqlRows( 335 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 336 NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Bool(false), types.Int(1), types.Float(5.1)), 337 ), 338 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 339 }, 340 { 341 Name: "type mismatch float -> int", 342 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 343 (7, "Maggie", "Simpson", false, 1.0, 5.1)`, 344 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 345 ExpectedRows: ToSqlRows( 346 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 347 NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Bool(false), types.Int(1), types.Float(5.1)), 348 ), 349 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 350 }, 351 { 352 Name: "type mismatch bool -> int", 353 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 354 (true, "Maggie", "Simpson", false, 1, 5.1)`, 355 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 1 ORDER BY id", 356 ExpectedRows: ToSqlRows( 357 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 358 NewResultSetRow(types.Int(1), types.String("Maggie"), types.String("Simpson"), types.Bool(false), types.Int(1), types.Float(5.1)), 359 ), 360 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 361 }, 362 { 363 Name: "type mismatch bool -> float", 364 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 365 (7, "Maggie", "Simpson", false, 1, true)`, 366 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 367 ExpectedRows: ToSqlRows( 368 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 369 NewResultSetRow(types.Int(7), types.String("Maggie"), types.String("Simpson"), types.Bool(false), types.Int(1), types.Float(1.0)), 370 ), 371 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 372 }, 373 { 374 Name: "type mismatch bool -> string", 375 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, rating) values 376 (7, true, "Simpson", false, 1, 5.1)`, 377 SelectQuery: "select id, first_name, last_name, is_married, age, rating from people where id = 7 ORDER BY id", 378 ExpectedRows: ToSqlRows( 379 CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 380 NewResultSetRow(types.Int(7), types.String("true"), types.String("Simpson" /*"West"*/), types.Bool(false), types.Int(1), types.Float(5.1)), 381 ), 382 ExpectedSchema: CompressSchema(SubsetSchema(PeopleTestSchema, "id", "first_name", "last_name", "is_married", "age", "rating")), 383 }, 384 { 385 Name: "type mismatch bool -> uuid", 386 InsertQuery: `insert into people (id, first_name, last_name, is_married, age, uuid) values 387 (7, "Maggie", "Simpson", false, 1, true)`, 388 ExpectedErr: "Type mismatch", 389 }, 390 } 391 392 func TestExecuteInsert(t *testing.T) { 393 for _, test := range BasicInsertTests { 394 t.Run(test.Name, func(t *testing.T) { 395 testInsertQuery(t, test) 396 }) 397 } 398 } 399 400 var systemTableInsertTests = []InsertTest{ 401 { 402 Name: "insert into dolt_docs", 403 AdditionalSetup: CreateTableFn("dolt_docs", 404 doltdocs.Schema, 405 NewRow(types.String("LICENSE.md"), types.String("A license"))), 406 InsertQuery: "insert into dolt_docs (doc_name, doc_text) values ('README.md', 'Some text')", 407 ExpectedErr: "cannot insert into table", 408 }, 409 { 410 Name: "insert into dolt_query_catalog", 411 AdditionalSetup: CreateTableFn(doltdb.DoltQueryCatalogTableName, 412 dtables.DoltQueryCatalogSchema, 413 NewRowWithSchema(dtables.DoltQueryCatalogSchema, 414 types.String("existingEntry"), 415 types.Uint(2), 416 types.String("example"), 417 types.String("select 2+2 from dual"), 418 types.String("description"))), 419 InsertQuery: "insert into dolt_query_catalog (id, display_order, name, query, description) values ('abc123', 1, 'example', 'select 1+1 from dual', 'description')", 420 SelectQuery: "select * from dolt_query_catalog ORDER BY id", 421 ExpectedRows: ToSqlRows(CompressSchema(dtables.DoltQueryCatalogSchema), 422 NewRow(types.String("abc123"), types.Uint(1), types.String("example"), types.String("select 1+1 from dual"), types.String("description")), 423 NewRow(types.String("existingEntry"), types.Uint(2), types.String("example"), types.String("select 2+2 from dual"), types.String("description")), 424 ), 425 ExpectedSchema: CompressSchema(dtables.DoltQueryCatalogSchema), 426 }, 427 { 428 Name: "insert into dolt_schemas", 429 AdditionalSetup: CreateTableFn(doltdb.SchemasTableName, schemasTableDoltSchema()), 430 InsertQuery: "insert into dolt_schemas (id, type, name, fragment) values (1, 'view', 'name', 'select 2+2 from dual')", 431 SelectQuery: "select * from dolt_schemas ORDER BY id", 432 ExpectedRows: ToSqlRows(CompressSchema(schemasTableDoltSchema()), 433 NewRow(types.String("view"), types.String("name"), types.String("select 2+2 from dual"), types.Int(1)), 434 ), 435 ExpectedSchema: CompressSchema(schemasTableDoltSchema()), 436 }, 437 } 438 439 func mustGetDoltSchema(sch sql.Schema, tableName string, testEnv *env.DoltEnv) schema.Schema { 440 wrt, err := testEnv.WorkingRoot(context.Background()) 441 if err != nil { 442 panic(err) 443 } 444 445 doltSchema, err := sqlutil.ToDoltSchema(context.Background(), wrt, tableName, sch, nil) 446 if err != nil { 447 panic(err) 448 } 449 return doltSchema 450 } 451 452 func TestInsertIntoSystemTables(t *testing.T) { 453 for _, test := range systemTableInsertTests { 454 t.Run(test.Name, func(t *testing.T) { 455 testInsertQuery(t, test) 456 }) 457 } 458 } 459 460 // Tests the given query on a freshly created dataset, asserting that the result has the given schema and rows. If 461 // expectedErr is set, asserts instead that the execution returns an error that matches. 462 func testInsertQuery(t *testing.T, test InsertTest) { 463 if (test.ExpectedRows == nil) != (test.ExpectedSchema == nil) { 464 require.Fail(t, "Incorrect test setup: schema and rows must both be provided if one is") 465 } 466 467 if len(singleInsertQueryTest) > 0 && test.Name != singleInsertQueryTest { 468 t.Skip("Skipping tests until " + singleInsertQueryTest) 469 } 470 471 if len(singleInsertQueryTest) == 0 && test.SkipOnSqlEngine && skipBrokenInsert { 472 t.Skip("Skipping test broken on SQL engine") 473 } 474 475 dEnv := dtestutils.CreateTestEnv() 476 CreateEmptyTestDatabase(dEnv, t) 477 478 if test.AdditionalSetup != nil { 479 test.AdditionalSetup(t, dEnv) 480 } 481 482 var err error 483 root, _ := dEnv.WorkingRoot(context.Background()) 484 root, err = executeModify(context.Background(), dEnv, root, test.InsertQuery) 485 if len(test.ExpectedErr) > 0 { 486 require.Error(t, err) 487 return 488 } else { 489 require.NoError(t, err) 490 } 491 492 actualRows, sch, err := executeSelect(context.Background(), dEnv, root, test.SelectQuery) 493 require.NoError(t, err) 494 495 assert.Equal(t, test.ExpectedRows, actualRows) 496 assertSchemasEqual(t, mustSqlSchema(test.ExpectedSchema), sch) 497 }