github.com/dolthub/go-mysql-server@v0.18.0/enginetest/queries/charset_collation_engine.go (about) 1 // Copyright 2022 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 queries 16 17 import ( 18 "gopkg.in/src-d/go-errors.v1" 19 20 "github.com/dolthub/go-mysql-server/sql/types" 21 22 "github.com/dolthub/go-mysql-server/sql" 23 ) 24 25 // CharsetCollationEngineTest is used to test character sets. 26 type CharsetCollationEngineTest struct { 27 Name string 28 SetUpScript []string 29 Queries []CharsetCollationEngineTestQuery 30 } 31 32 // CharsetCollationEngineTestQuery is a query within a CharsetCollationEngineTest. If `Error` is true but `ErrKind` is 33 // nil, then just tests that an error has occurred. If `ErrKind` is not nil, then tests that an error is returned and 34 // matches the stated kind (has higher precedence than the `Error` field). Only checks the `Expected` rows when both 35 // `Error` and `ErrKind` are nil. 36 type CharsetCollationEngineTestQuery struct { 37 Query string 38 Expected []sql.Row 39 Error bool 40 ErrKind *errors.Kind 41 } 42 43 // CharsetCollationEngineTests are used to ensure that character sets and collations have the correct behavior over the 44 // engine. Return values should all have the `utf8mb4` encoding, as it's returning the internal encoding type. 45 var CharsetCollationEngineTests = []CharsetCollationEngineTest{ 46 { 47 Name: "Uppercase and lowercase collations", 48 Queries: []CharsetCollationEngineTestQuery{ 49 { 50 Query: "CREATE TABLE test1 (v1 VARCHAR(255) COLLATE utf16_unicode_ci, v2 VARCHAR(255) COLLATE UTF16_UNICODE_CI);", 51 Expected: []sql.Row{{types.NewOkResult(0)}}, 52 }, 53 { 54 Query: "CREATE TABLE test2 (v1 VARCHAR(255) CHARACTER SET utf16, v2 VARCHAR(255) CHARACTER SET UTF16);", 55 Expected: []sql.Row{{types.NewOkResult(0)}}, 56 }, 57 }, 58 }, 59 { 60 Name: "Insert multiple character sets", 61 SetUpScript: []string{ 62 "CREATE TABLE test (v1 VARCHAR(255) COLLATE utf16_unicode_ci);", 63 }, 64 Queries: []CharsetCollationEngineTestQuery{ 65 { 66 Query: "INSERT INTO test VALUES ('hey');", 67 Expected: []sql.Row{{types.NewOkResult(1)}}, 68 }, 69 { 70 Query: "INSERT INTO test VALUES (_utf16'\x00h\x00i');", 71 Expected: []sql.Row{{types.NewOkResult(1)}}, 72 }, 73 { 74 Query: "INSERT INTO test VALUES (_utf8mb4'\x68\x65\x6c\x6c\x6f');", 75 Expected: []sql.Row{{types.NewOkResult(1)}}, 76 }, 77 { 78 Query: "SELECT * FROM test ORDER BY 1;", 79 Expected: []sql.Row{{"hello"}, {"hey"}, {"hi"}}, 80 }, 81 }, 82 }, 83 { 84 Name: "Sorting differences", 85 SetUpScript: []string{ 86 "CREATE TABLE test1 (v1 VARCHAR(255) COLLATE utf8mb4_0900_bin);", 87 "CREATE TABLE test2 (v1 VARCHAR(255) COLLATE utf16_unicode_ci);", 88 }, 89 Queries: []CharsetCollationEngineTestQuery{ 90 { 91 Query: "INSERT INTO test1 VALUES ('HEY2'), ('hey1');", 92 Expected: []sql.Row{{types.NewOkResult(2)}}, 93 }, 94 { 95 Query: "INSERT INTO test2 VALUES ('HEY2'), ('hey1');", 96 Expected: []sql.Row{{types.NewOkResult(2)}}, 97 }, 98 { 99 Query: "SELECT * FROM test1 ORDER BY 1;", 100 Expected: []sql.Row{{"HEY2"}, {"hey1"}}, 101 }, 102 { 103 Query: "SELECT * FROM test2 ORDER BY 1;", 104 Expected: []sql.Row{{"hey1"}, {"HEY2"}}, 105 }, 106 }, 107 }, 108 { 109 Name: "Character set introducer with invalid collate", 110 Queries: []CharsetCollationEngineTestQuery{ 111 { 112 Query: "SELECT _utf16'\x00a' COLLATE utf8mb4_0900_bin;", 113 Error: true, 114 }, 115 { 116 Query: "SELECT _utf16'\x00a' COLLATE binary;", 117 Error: true, 118 }, 119 }, 120 }, 121 { 122 Name: "Properly block using not-yet-implemented character sets/collations", 123 Queries: []CharsetCollationEngineTestQuery{ 124 { 125 Query: "CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255) CHARACTER SET utf16le);", 126 ErrKind: sql.ErrCharSetNotYetImplementedTemp, 127 }, 128 { 129 Query: "CREATE TABLE test2 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255) COLLATE utf16le_general_ci);", 130 ErrKind: sql.ErrCharSetNotYetImplementedTemp, 131 }, 132 { 133 Query: "CREATE TABLE test3 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255) CHARACTER SET utf8mb4);", 134 Expected: []sql.Row{{types.NewOkResult(0)}}, 135 }, 136 { 137 Query: "ALTER TABLE test3 MODIFY COLUMN v1 VARCHAR(255) COLLATE utf8mb4_sr_latn_0900_as_cs;", 138 ErrKind: sql.ErrCollationNotYetImplementedTemp, 139 }, 140 }, 141 }, 142 { 143 Name: "Order by behaves differently according to case-sensitivity", 144 SetUpScript: []string{ 145 "CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255) COLLATE utf16_unicode_ci, INDEX(v1));", 146 "CREATE TABLE test2 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255) COLLATE utf8mb4_0900_bin, INDEX(v1));", 147 "INSERT INTO test1 VALUES (1, 'abc'), (2, 'ABC'), (3, 'aBc'), (4, 'AbC');", 148 "INSERT INTO test2 VALUES (1, 'abc'), (2, 'ABC'), (3, 'aBc'), (4, 'AbC');", 149 }, 150 Queries: []CharsetCollationEngineTestQuery{ 151 { 152 Query: "SELECT v1, pk FROM test1 ORDER BY pk;", 153 Expected: []sql.Row{ 154 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 155 }, 156 }, 157 { 158 Query: "SELECT v1, pk FROM test1 ORDER BY v1, pk;", 159 Expected: []sql.Row{ 160 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 161 }, 162 }, 163 { 164 Query: "SELECT v1, pk FROM test2 ORDER BY pk;", 165 Expected: []sql.Row{ 166 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 167 }, 168 }, 169 { 170 Query: "SELECT v1, pk FROM test2 ORDER BY v1, pk;", 171 Expected: []sql.Row{ 172 {"ABC", int64(2)}, {"AbC", int64(4)}, {"aBc", int64(3)}, {"abc", int64(1)}, 173 }, 174 }, 175 }, 176 }, 177 { 178 Name: "Proper index access", 179 SetUpScript: []string{ 180 "CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255) COLLATE utf16_unicode_ci, INDEX(v1));", 181 "CREATE TABLE test2 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255) COLLATE utf8mb4_0900_bin, INDEX(v1));", 182 "INSERT INTO test1 VALUES (1, 'abc'), (2, 'ABC'), (3, 'aBc'), (4, 'AbC');", 183 "INSERT INTO test2 VALUES (1, 'abc'), (2, 'ABC'), (3, 'aBc'), (4, 'AbC');", 184 }, 185 Queries: []CharsetCollationEngineTestQuery{ 186 { 187 Query: "SELECT v1, pk FROM test1 WHERE v1 > 'AbC' ORDER BY v1, pk;", 188 Expected: []sql.Row(nil), 189 }, 190 { 191 Query: "SELECT v1, pk FROM test1 WHERE v1 >= 'AbC' ORDER BY v1, pk;", 192 Expected: []sql.Row{ 193 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 194 }, 195 }, 196 { 197 Query: "SELECT v1, pk FROM test1 WHERE v1 <= 'aBc' ORDER BY v1, pk;", 198 Expected: []sql.Row{ 199 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 200 }, 201 }, 202 { 203 Query: "SELECT v1, pk FROM test1 WHERE v1 = 'ABC' ORDER BY v1, pk;", 204 Expected: []sql.Row{ 205 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 206 }, 207 }, 208 { 209 Query: "SELECT v1, pk FROM test1 WHERE v1 BETWEEN 'ABC' AND 'AbC' ORDER BY v1, pk;", 210 Expected: []sql.Row{ 211 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 212 }, 213 }, 214 { 215 Query: "SELECT v1, pk FROM test1 WHERE v1 IN ('abc') ORDER BY v1, pk;", 216 Expected: []sql.Row{ 217 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 218 }, 219 }, 220 { 221 Query: "SELECT v1, pk FROM test2 WHERE v1 > 'AbC' ORDER BY v1, pk;", 222 Expected: []sql.Row{ 223 {"aBc", int64(3)}, {"abc", int64(1)}, 224 }, 225 }, 226 { 227 Query: "SELECT v1, pk FROM test2 WHERE v1 >= 'AbC' ORDER BY v1, pk;", 228 Expected: []sql.Row{ 229 {"AbC", int64(4)}, {"aBc", int64(3)}, {"abc", int64(1)}, 230 }, 231 }, 232 { 233 Query: "SELECT v1, pk FROM test2 WHERE v1 <= 'aBc' ORDER BY v1, pk;", 234 Expected: []sql.Row{ 235 {"ABC", int64(2)}, {"AbC", int64(4)}, {"aBc", int64(3)}, 236 }, 237 }, 238 { 239 Query: "SELECT v1, pk FROM test2 WHERE v1 = 'ABC' ORDER BY v1, pk;", 240 Expected: []sql.Row{ 241 {"ABC", int64(2)}, 242 }, 243 }, 244 { 245 Query: "SELECT v1, pk FROM test2 WHERE v1 BETWEEN 'ABC' AND 'AbC' ORDER BY v1, pk;", 246 Expected: []sql.Row{ 247 {"ABC", int64(2)}, {"AbC", int64(4)}, 248 }, 249 }, 250 { 251 Query: "SELECT v1, pk FROM test2 WHERE v1 IN ('abc') ORDER BY v1, pk;", 252 Expected: []sql.Row{ 253 {"abc", int64(1)}, 254 }, 255 }, 256 }, 257 }, 258 { 259 Name: "Table collation is respected", 260 SetUpScript: []string{ 261 "CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255)) COLLATE utf16_unicode_ci;", 262 "CREATE TABLE test2 (pk BIGINT PRIMARY KEY, v1 VARCHAR(255)) COLLATE utf8mb4_unicode_ci;", 263 "CREATE TABLE test3 LIKE test2;", 264 "INSERT INTO test1 VALUES (1, 'abc'), (2, 'ABC'), (3, 'aBc'), (4, 'AbC');", 265 "INSERT INTO test2 VALUES (1, 'abc'), (2, 'ABC'), (3, 'aBc'), (4, 'AbC');", 266 "INSERT INTO test3 VALUES (1, 'abc'), (2, 'ABC'), (3, 'aBc'), (4, 'AbC');", 267 "CREATE TABLE test4 AS SELECT * FROM test2;", 268 }, 269 Queries: []CharsetCollationEngineTestQuery{ 270 { 271 Query: "SELECT v1, pk FROM test1 WHERE v1 <= 'aBc' ORDER BY v1, pk;", 272 Expected: []sql.Row{ 273 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 274 }, 275 }, 276 { 277 Query: "SELECT v1, pk FROM test2 WHERE v1 <= 'aBc' ORDER BY v1, pk;", 278 Expected: []sql.Row{ 279 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 280 }, 281 }, 282 { 283 Query: "ALTER TABLE test2 MODIFY COLUMN v1 VARCHAR(100);", 284 Expected: []sql.Row{ 285 {types.NewOkResult(0)}, 286 }, 287 }, 288 { 289 Query: "SELECT v1, pk FROM test2 WHERE v1 <= 'aBc' ORDER BY v1, pk;", 290 Expected: []sql.Row{ 291 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 292 }, 293 }, 294 { 295 Query: "SELECT v1, pk FROM test3 WHERE v1 <= 'aBc' ORDER BY v1, pk;", 296 Expected: []sql.Row{ 297 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 298 }, 299 }, 300 { 301 Query: "SELECT v1, pk FROM test4 WHERE v1 <= 'aBc' ORDER BY v1, pk;", 302 Expected: []sql.Row{ 303 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 304 }, 305 }, 306 { 307 Query: "SHOW CREATE TABLE test1;", 308 Expected: []sql.Row{ 309 {"test1", "CREATE TABLE `test1` (\n `pk` bigint NOT NULL,\n `v1` varchar(255),\n PRIMARY KEY (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci"}, 310 }, 311 }, 312 { 313 Query: "SHOW CREATE TABLE test2;", 314 Expected: []sql.Row{ 315 {"test2", "CREATE TABLE `test2` (\n `pk` bigint NOT NULL,\n `v1` varchar(100),\n PRIMARY KEY (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"}, 316 }, 317 }, 318 { 319 Query: "SHOW CREATE TABLE test3;", 320 Expected: []sql.Row{ 321 {"test3", "CREATE TABLE `test3` (\n `pk` bigint NOT NULL,\n `v1` varchar(255),\n PRIMARY KEY (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"}, 322 }, 323 }, 324 { 325 Query: "SHOW CREATE TABLE test4;", 326 Expected: []sql.Row{ 327 {"test4", "CREATE TABLE `test4` (\n `pk` bigint NOT NULL,\n `v1` varchar(255) COLLATE utf8mb4_unicode_ci\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, 328 }, 329 }, 330 { 331 Query: "ALTER TABLE test3 ADD COLUMN v2 VARCHAR(255);", 332 Expected: []sql.Row{ 333 {types.NewOkResult(0)}, 334 }, 335 }, 336 { 337 Query: "SHOW CREATE TABLE test3;", 338 Expected: []sql.Row{ 339 {"test3", "CREATE TABLE `test3` (\n `pk` bigint NOT NULL,\n `v1` varchar(255),\n `v2` varchar(255),\n PRIMARY KEY (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"}, 340 }, 341 }, 342 { 343 Query: "ALTER TABLE test2 CHANGE COLUMN v1 v1 VARCHAR(220);", 344 Expected: []sql.Row{ 345 {types.NewOkResult(0)}, 346 }, 347 }, 348 { 349 Query: "SHOW CREATE TABLE test2;", 350 Expected: []sql.Row{ 351 {"test2", "CREATE TABLE `test2` (\n `pk` bigint NOT NULL,\n `v1` varchar(220),\n PRIMARY KEY (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"}, 352 }, 353 }, 354 { 355 Query: "ALTER TABLE test2 CHARACTER SET latin1 COLLATE utf8mb4_bin;", 356 Error: true, 357 }, 358 { 359 Query: "ALTER TABLE test2 COLLATE utf8mb4_bin;", 360 Expected: []sql.Row{ 361 {types.NewOkResult(0)}, 362 }, 363 }, 364 { 365 Query: "ALTER TABLE test2 ADD COLUMN v2 VARCHAR(255);", 366 Expected: []sql.Row{ 367 {types.NewOkResult(0)}, 368 }, 369 }, 370 { 371 Query: "REPLACE INTO test2 VALUES (1, 'abc', 'abc'), (2, 'ABC', 'ABC'), (3, 'aBc', 'aBc'), (4, 'AbC', 'AbC');", 372 Expected: []sql.Row{ 373 {types.NewOkResult(8)}, 374 }, 375 }, 376 { 377 Query: "SELECT v1, pk FROM test2 WHERE v1 <= 'aBc' ORDER BY v1, pk;", 378 Expected: []sql.Row{ 379 {"abc", int64(1)}, {"ABC", int64(2)}, {"aBc", int64(3)}, {"AbC", int64(4)}, 380 }, 381 }, 382 { 383 Query: "SELECT v2, pk FROM test2 WHERE v2 <= 'aBc' ORDER BY v2, pk;", 384 Expected: []sql.Row{ 385 {"ABC", int64(2)}, {"AbC", int64(4)}, {"aBc", int64(3)}, 386 }, 387 }, 388 { 389 Query: "SHOW CREATE TABLE test2;", 390 Expected: []sql.Row{ 391 {"test2", "CREATE TABLE `test2` (\n `pk` bigint NOT NULL,\n `v1` varchar(220) COLLATE utf8mb4_unicode_ci,\n `v2` varchar(255),\n PRIMARY KEY (`pk`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"}, 392 }, 393 }, 394 }, 395 }, 396 { 397 Name: "SET NAMES does not interfere with column charset", 398 SetUpScript: []string{ 399 "SET NAMES utf8mb3;", 400 "CREATE TABLE test(pk BIGINT PRIMARY KEY, v1 VARCHAR(100) COLLATE utf8mb4_0900_bin);", 401 "INSERT INTO test VALUES (1, 'a'), (2, 'b');", 402 }, 403 Queries: []CharsetCollationEngineTestQuery{ 404 { 405 Query: "SELECT * FROM test ORDER BY v1 COLLATE utf8mb4_bin ASC;", 406 Expected: []sql.Row{{int64(1), "a"}, {int64(2), "b"}}, 407 }, 408 { 409 Query: "SELECT * FROM test ORDER BY v1 COLLATE utf8mb3_bin ASC;", 410 ErrKind: sql.ErrCollationInvalidForCharSet, 411 }, 412 { 413 Query: "SELECT 'a' COLLATE utf8mb3_bin;", 414 Expected: []sql.Row{{"a"}}, 415 }, 416 { 417 Query: "SELECT 'a' COLLATE utf8mb4_bin;", 418 ErrKind: sql.ErrCollationInvalidForCharSet, 419 }, 420 }, 421 }, 422 { 423 Name: "SET validates character set and collation variables", 424 Queries: []CharsetCollationEngineTestQuery{ 425 { 426 Query: "SET character_set_client = 'am_i_wrong';", 427 ErrKind: sql.ErrCharSetUnknown, 428 }, 429 { 430 Query: "SET character_set_connection = 'to_believe';", 431 ErrKind: sql.ErrCharSetUnknown, 432 }, 433 { 434 Query: "SET character_set_results = 'in_crusty_cheese';", 435 ErrKind: sql.ErrCharSetUnknown, 436 }, 437 { 438 Query: "SET collation_connection = 'is_it_wrong';", 439 ErrKind: sql.ErrCollationUnknown, 440 }, 441 { 442 Query: "SET collation_database = 'to_believe';", 443 ErrKind: sql.ErrCollationUnknown, 444 }, 445 { 446 Query: "SET collation_server = 'in_deez';", 447 ErrKind: sql.ErrCollationUnknown, 448 }, 449 { 450 Query: "SET NAMES things;", 451 ErrKind: sql.ErrCharSetUnknown, 452 }, 453 }, 454 }, 455 { 456 Name: "ENUM collation handling", 457 SetUpScript: []string{ 458 "CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 ENUM('abc','def','ghi') COLLATE utf16_unicode_ci);", 459 "CREATE TABLE test2 (pk BIGINT PRIMARY KEY, v1 ENUM('abc','def','ghi') COLLATE utf8mb4_0900_bin);", 460 }, 461 Queries: []CharsetCollationEngineTestQuery{ 462 { 463 Query: "INSERT INTO test1 VALUES (1, 'ABC');", 464 Expected: []sql.Row{ 465 {types.NewOkResult(1)}, 466 }, 467 }, 468 { 469 Query: "INSERT INTO test2 VALUES (1, 'ABC');", 470 Error: true, 471 }, 472 { 473 Query: "INSERT INTO test1 VALUES (2, _utf16'\x00d\x00e\x00f' COLLATE utf16_unicode_ci);", 474 Expected: []sql.Row{ 475 {types.NewOkResult(1)}, 476 }, 477 }, 478 { 479 Query: "INSERT INTO test2 VALUES (2, _utf16'\x00d\x00e\x00f' COLLATE utf16_unicode_ci);", 480 Expected: []sql.Row{ 481 {types.NewOkResult(1)}, 482 }, 483 }, 484 { 485 Query: "SELECT * FROM test1 ORDER BY pk;", 486 Expected: []sql.Row{ 487 {int64(1), uint16(1)}, {int64(2), uint16(2)}, 488 }, 489 }, 490 { 491 Query: "SELECT * FROM test2 ORDER BY pk;", 492 Expected: []sql.Row{ 493 {int64(2), uint16(2)}, 494 }, 495 }, 496 }, 497 }, 498 { 499 Name: "SET collation handling", 500 SetUpScript: []string{ 501 "CREATE TABLE test1 (pk BIGINT PRIMARY KEY, v1 SET('a','b','c') COLLATE utf16_unicode_ci);", 502 "CREATE TABLE test2 (pk BIGINT PRIMARY KEY, v1 SET('a','b','c') COLLATE utf8mb4_0900_bin);", 503 }, 504 Queries: []CharsetCollationEngineTestQuery{ 505 { 506 Query: "INSERT INTO test1 VALUES (1, 'A');", 507 Expected: []sql.Row{ 508 {types.NewOkResult(1)}, 509 }, 510 }, 511 { 512 Query: "INSERT INTO test2 VALUES (1, 'A');", 513 Error: true, 514 }, 515 { 516 Query: "INSERT INTO test1 VALUES (2, _utf16'\x00b\x00,\x00c' COLLATE utf16_unicode_ci);", 517 Expected: []sql.Row{ 518 {types.NewOkResult(1)}, 519 }, 520 }, 521 { 522 Query: "INSERT INTO test2 VALUES (2, _utf16'\x00b\x00,\x00c' COLLATE utf16_unicode_ci);", 523 Expected: []sql.Row{ 524 {types.NewOkResult(1)}, 525 }, 526 }, 527 { 528 Query: "SELECT * FROM test1 ORDER BY pk;", 529 Expected: []sql.Row{ 530 {int64(1), uint64(1)}, {int64(2), uint64(6)}, 531 }, 532 }, 533 { 534 Query: "SELECT * FROM test2 ORDER BY pk;", 535 Expected: []sql.Row{ 536 {int64(2), uint64(6)}, 537 }, 538 }, 539 }, 540 }, 541 { 542 Name: "LIKE respects table collations", 543 SetUpScript: []string{ 544 "SET NAMES utf8mb4;", 545 "CREATE TABLE test(v1 VARCHAR(100) COLLATE utf8mb4_0900_bin, v2 VARCHAR(100) COLLATE utf8mb4_0900_ai_ci);", 546 "INSERT INTO test VALUES ('abc', 'abc'), ('ABC', 'ABC');", 547 }, 548 Queries: []CharsetCollationEngineTestQuery{ 549 { 550 Query: "SELECT COUNT(*) FROM test WHERE v1 LIKE 'ABC';", 551 Expected: []sql.Row{ 552 {int64(1)}, 553 }, 554 }, 555 { 556 Query: "SELECT COUNT(*) FROM test WHERE v2 LIKE 'ABC';", 557 Expected: []sql.Row{ 558 {int64(2)}, 559 }, 560 }, 561 { 562 Query: "SELECT COUNT(*) FROM test WHERE v1 LIKE 'A%';", 563 Expected: []sql.Row{ 564 {int64(1)}, 565 }, 566 }, 567 { 568 Query: "SELECT COUNT(*) FROM test WHERE v2 LIKE 'A%';", 569 Expected: []sql.Row{ 570 {int64(2)}, 571 }, 572 }, 573 { 574 Query: "SELECT COUNT(*) FROM test WHERE v1 LIKE '%C';", 575 Expected: []sql.Row{ 576 {int64(1)}, 577 }, 578 }, 579 { 580 Query: "SELECT COUNT(*) FROM test WHERE v2 LIKE '%C';", 581 Expected: []sql.Row{ 582 {int64(2)}, 583 }, 584 }, 585 { 586 Query: "SET collation_connection = 'utf8mb4_0900_bin';", 587 Expected: []sql.Row{{}}, 588 }, 589 { 590 Query: "SELECT COUNT(*) FROM test WHERE v1 LIKE 'ABC';", 591 Expected: []sql.Row{ 592 {int64(1)}, 593 }, 594 }, 595 { 596 Query: "SELECT COUNT(*) FROM test WHERE v2 LIKE 'ABC';", 597 Expected: []sql.Row{ 598 {int64(2)}, 599 }, 600 }, 601 { 602 Query: "SELECT COUNT(*) FROM test WHERE v1 LIKE 'ABC' COLLATE utf8mb4_0900_ai_ci;", 603 Expected: []sql.Row{ 604 {int64(2)}, 605 }, 606 }, 607 }, 608 }, 609 { 610 Name: "LIKE respects connection collation", 611 SetUpScript: []string{ 612 "SET NAMES utf8mb4;", 613 }, 614 Queries: []CharsetCollationEngineTestQuery{ 615 { 616 Query: "SELECT 'abc' LIKE 'ABC';", 617 Expected: []sql.Row{ 618 {true}, 619 }, 620 }, 621 { 622 Query: "SELECT 'abc' COLLATE utf8mb4_0900_bin LIKE 'ABC';", 623 Expected: []sql.Row{ 624 {false}, 625 }, 626 }, 627 { 628 Query: "SELECT 'abc' LIKE 'ABC' COLLATE utf8mb4_0900_bin;", 629 Expected: []sql.Row{ 630 {false}, 631 }, 632 }, 633 { 634 Query: "SELECT 'abc' COLLATE utf8mb4_0900_ai_ci LIKE 'ABC';", 635 Expected: []sql.Row{ 636 {true}, 637 }, 638 }, 639 { 640 Query: "SELECT 'abc' LIKE 'ABC' COLLATE utf8mb4_0900_ai_ci;", 641 Expected: []sql.Row{ 642 {true}, 643 }, 644 }, 645 { 646 Query: "SET collation_connection = 'utf8mb4_0900_bin';", 647 Expected: []sql.Row{{}}, 648 }, 649 { 650 Query: "SELECT 'abc' LIKE 'ABC';", 651 Expected: []sql.Row{ 652 {false}, 653 }, 654 }, 655 { 656 Query: "SELECT 'abc' COLLATE utf8mb4_0900_ai_ci LIKE 'ABC';", 657 Expected: []sql.Row{ 658 {true}, 659 }, 660 }, 661 { 662 Query: "SELECT 'abc' LIKE 'ABC' COLLATE utf8mb4_0900_ai_ci;", 663 Expected: []sql.Row{ 664 {true}, 665 }, 666 }, 667 { 668 Query: "SELECT 'abc' COLLATE utf8mb4_0900_bin LIKE 'ABC';", 669 Expected: []sql.Row{ 670 {false}, 671 }, 672 }, 673 { 674 Query: "SELECT 'abc' LIKE 'ABC' COLLATE utf8mb4_0900_bin;", 675 Expected: []sql.Row{ 676 {false}, 677 }, 678 }, 679 { 680 Query: "SELECT _utf8mb4'abc' LIKE 'ABC';", 681 Expected: []sql.Row{ 682 {false}, 683 }, 684 }, 685 { 686 Query: "SELECT 'abc' LIKE _utf8mb4'ABC';", 687 Expected: []sql.Row{ 688 {false}, 689 }, 690 }, 691 }, 692 }, 693 { 694 Name: "STRCMP() function", 695 Queries: []CharsetCollationEngineTestQuery{ 696 // TODO: returning different results from MySQL 697 /*{ 698 // collation with the lowest coercibility is used 699 Query: "SELECT STRCMP(_utf8mb4'A' COLLATE utf8mb4_0900_ai_ci, 'a')", 700 Expected: []sql.Row{ 701 {int(0)}, 702 }, 703 }, 704 { 705 // same coercibility, both unicode 706 Query: "SELECT STRCMP(_utf8mb4'A' COLLATE utf8mb4_0900_ai_ci, _utf8mb4'a' COLLATE utf8mb4_0900_as_cs)", 707 ErrKind: sql.ErrCollationIllegalMix, 708 }, 709 { 710 // same coercibility, both not unicode 711 Query: "SELECT STRCMP(_latin1'A' COLLATE latin1_general_ci, _latin1'a' COLLATE latin1_german1_ci)", 712 ErrKind: sql.ErrCollationIllegalMix, 713 },*/ 714 { 715 // same coercibility, one unicode and one not unicode 716 Query: "SELECT STRCMP(_utf8mb4'A' COLLATE utf8mb4_0900_ai_ci, _latin1'b' COLLATE latin1_general_cs)", 717 Expected: []sql.Row{ 718 {int(-1)}, 719 }, 720 }, 721 }, 722 }, 723 { 724 Name: "LENGTH() function", 725 Queries: []CharsetCollationEngineTestQuery{ 726 { 727 Query: "SELECT LENGTH(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci);", 728 Expected: []sql.Row{ 729 {int32(6)}, 730 }, 731 }, 732 { 733 Query: "SELECT LENGTH(_utf8mb4'abc' COLLATE utf8mb4_0900_bin);", 734 Expected: []sql.Row{ 735 {int32(3)}, 736 }, 737 }, 738 { 739 Query: "SELECT LENGTH(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin);", 740 Expected: []sql.Row{ 741 {int32(6)}, 742 }, 743 }, 744 }, 745 }, 746 { 747 Name: "CHAR_LENGTH() function", 748 Queries: []CharsetCollationEngineTestQuery{ 749 { 750 Query: "SELECT CHAR_LENGTH(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci);", 751 Expected: []sql.Row{ 752 {int32(3)}, 753 }, 754 }, 755 { 756 Query: "SELECT CHAR_LENGTH(_utf8mb4'abc' COLLATE utf8mb4_0900_bin);", 757 Expected: []sql.Row{ 758 {int32(3)}, 759 }, 760 }, 761 { 762 Query: "SELECT CHAR_LENGTH(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin);", 763 Expected: []sql.Row{ 764 {int32(6)}, 765 }, 766 }, 767 }, 768 }, 769 { 770 Name: "UPPER() function", 771 Queries: []CharsetCollationEngineTestQuery{ 772 { 773 Query: "SELECT UPPER(_utf16'\x00a\x00B\x00c' COLLATE utf16_unicode_ci);", 774 Expected: []sql.Row{ 775 {"ABC"}, 776 }, 777 }, 778 { 779 Query: "SELECT UPPER(_utf8mb4'aBc' COLLATE utf8mb4_0900_bin);", 780 Expected: []sql.Row{ 781 {"ABC"}, 782 }, 783 }, 784 { 785 Query: "SELECT UPPER(_utf8mb4'\x00a\x00B\x00c' COLLATE utf8mb4_0900_bin);", 786 Expected: []sql.Row{ 787 {"\x00A\x00B\x00C"}, 788 }, 789 }, 790 }, 791 }, 792 { 793 Name: "LOWER() function", 794 Queries: []CharsetCollationEngineTestQuery{ 795 { 796 Query: "SELECT LOWER(_utf16'\x00A\x00b\x00C' COLLATE utf16_unicode_ci);", 797 Expected: []sql.Row{ 798 {"abc"}, 799 }, 800 }, 801 { 802 Query: "SELECT LOWER(_utf8mb4'AbC' COLLATE utf8mb4_0900_bin);", 803 Expected: []sql.Row{ 804 {"abc"}, 805 }, 806 }, 807 { 808 Query: "SELECT LOWER(_utf8mb4'\x00A\x00b\x00C' COLLATE utf8mb4_0900_bin);", 809 Expected: []sql.Row{ 810 {"\x00a\x00b\x00c"}, 811 }, 812 }, 813 }, 814 }, 815 { 816 Name: "RPAD() function", 817 Queries: []CharsetCollationEngineTestQuery{ 818 { 819 Query: "SELECT RPAD(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci, 6, 'z');", 820 Expected: []sql.Row{ 821 {"abczzz"}, 822 }, 823 }, 824 { 825 Query: "SELECT RPAD(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci, 6, _utf8mb4'z' COLLATE utf8mb4_0900_bin);", 826 Expected: []sql.Row{ 827 {"abczzz"}, 828 }, 829 }, 830 { 831 Query: "SELECT RPAD(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci, 6, _utf16'\x00z' COLLATE utf16_unicode_ci);", 832 Expected: []sql.Row{ 833 {"abczzz"}, 834 }, 835 }, 836 { 837 Query: "SELECT RPAD(_utf8mb4'abc' COLLATE utf8mb4_0900_bin, 6, _utf8mb4'z' COLLATE utf8mb4_0900_bin);", 838 Expected: []sql.Row{ 839 {"abczzz"}, 840 }, 841 }, 842 { 843 Query: "SELECT RPAD(_utf8mb4'abc' COLLATE utf8mb4_0900_bin, 6, _utf16'\x00z' COLLATE utf16_unicode_ci);", 844 Expected: []sql.Row{ 845 {"abczzz"}, 846 }, 847 }, 848 { 849 Query: "SELECT RPAD(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin, 6, _utf16'\x00z' COLLATE utf16_unicode_ci);", 850 Expected: []sql.Row{ 851 {"\x00a\x00b\x00c"}, 852 }, 853 }, 854 { 855 Query: "SELECT RPAD(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin, 9, _utf16'\x00z' COLLATE utf16_unicode_ci);", 856 Expected: []sql.Row{ 857 {"\x00a\x00b\x00czzz"}, 858 }, 859 }, 860 }, 861 }, 862 { 863 Name: "LPAD() function", 864 Queries: []CharsetCollationEngineTestQuery{ 865 { 866 Query: "SELECT LPAD(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci, 6, 'z');", 867 Expected: []sql.Row{ 868 {"zzzabc"}, 869 }, 870 }, 871 { 872 Query: "SELECT LPAD(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci, 6, _utf8mb4'z' COLLATE utf8mb4_0900_bin);", 873 Expected: []sql.Row{ 874 {"zzzabc"}, 875 }, 876 }, 877 { 878 Query: "SELECT LPAD(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci, 6, _utf16'\x00z' COLLATE utf16_unicode_ci);", 879 Expected: []sql.Row{ 880 {"zzzabc"}, 881 }, 882 }, 883 { 884 Query: "SELECT LPAD(_utf8mb4'abc' COLLATE utf8mb4_0900_bin, 6, _utf8mb4'z' COLLATE utf8mb4_0900_bin);", 885 Expected: []sql.Row{ 886 {"zzzabc"}, 887 }, 888 }, 889 { 890 Query: "SELECT LPAD(_utf8mb4'abc' COLLATE utf8mb4_0900_bin, 6, _utf16'\x00z' COLLATE utf16_unicode_ci);", 891 Expected: []sql.Row{ 892 {"zzzabc"}, 893 }, 894 }, 895 { 896 Query: "SELECT LPAD(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin, 6, _utf16'\x00z' COLLATE utf16_unicode_ci);", 897 Expected: []sql.Row{ 898 {"\x00a\x00b\x00c"}, 899 }, 900 }, 901 { 902 Query: "SELECT LPAD(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin, 9, _utf16'\x00z' COLLATE utf16_unicode_ci);", 903 Expected: []sql.Row{ 904 {"zzz\x00a\x00b\x00c"}, 905 }, 906 }, 907 }, 908 }, 909 { 910 Name: "HEX() function", 911 Queries: []CharsetCollationEngineTestQuery{ 912 { 913 Query: "SELECT HEX(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci);", 914 Expected: []sql.Row{ 915 {"006100620063"}, 916 }, 917 }, 918 { 919 Query: "SELECT HEX(_utf8mb4'abc' COLLATE utf8mb4_0900_bin);", 920 Expected: []sql.Row{ 921 {"616263"}, 922 }, 923 }, 924 { 925 Query: "SELECT HEX(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin);", 926 Expected: []sql.Row{ 927 {"006100620063"}, 928 }, 929 }, 930 }, 931 }, 932 { 933 Name: "UNHEX() function", 934 Queries: []CharsetCollationEngineTestQuery{ 935 { 936 Query: "SELECT UNHEX(_utf16'\x006\x001\x006\x002\x006\x003' COLLATE utf16_unicode_ci);", 937 Expected: []sql.Row{ 938 {[]byte("abc")}, 939 }, 940 }, 941 { 942 Query: "SELECT UNHEX(_utf8mb4'616263' COLLATE utf8mb4_0900_bin);", 943 Expected: []sql.Row{ 944 {[]byte("abc")}, 945 }, 946 }, 947 }, 948 }, 949 { 950 Name: "SUBSTRING() function", 951 Queries: []CharsetCollationEngineTestQuery{ 952 { 953 Query: "SELECT SUBSTRING(_utf16'\x00a\x00b\x00c\x00d' COLLATE utf16_unicode_ci, 2, 2);", 954 Expected: []sql.Row{ 955 {"bc"}, 956 }, 957 }, 958 { 959 Query: "SELECT SUBSTRING(_utf8mb4'abcd' COLLATE utf8mb4_0900_bin, 2, 2);", 960 Expected: []sql.Row{ 961 {"bc"}, 962 }, 963 }, 964 { 965 Query: "SELECT SUBSTRING(_utf8mb4'\x00a\x00b\x00c\x00d' COLLATE utf8mb4_0900_bin, 2, 2);", 966 Expected: []sql.Row{ 967 {"a\x00"}, 968 }, 969 }, 970 }, 971 }, 972 { 973 Name: "TO_BASE64() function", 974 Queries: []CharsetCollationEngineTestQuery{ 975 { 976 Query: "SELECT TO_BASE64(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci);", 977 Expected: []sql.Row{ 978 {"AGEAYgBj"}, 979 }, 980 }, 981 { 982 Query: "SELECT TO_BASE64(_utf8mb4'abc' COLLATE utf8mb4_0900_bin);", 983 Expected: []sql.Row{ 984 {"YWJj"}, 985 }, 986 }, 987 { 988 Query: "SELECT TO_BASE64(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin);", 989 Expected: []sql.Row{ 990 {"AGEAYgBj"}, 991 }, 992 }, 993 }, 994 }, 995 { 996 Name: "FROM_BASE64() function", 997 Queries: []CharsetCollationEngineTestQuery{ 998 { 999 Query: "SELECT FROM_BASE64(_utf16'\x00Y\x00W\x00J\x00j' COLLATE utf16_unicode_ci);", 1000 Expected: []sql.Row{ 1001 {[]byte("abc")}, 1002 }, 1003 }, 1004 { 1005 Query: "SELECT FROM_BASE64(_utf8mb4'YWJj' COLLATE utf8mb4_0900_bin);", 1006 Expected: []sql.Row{ 1007 {[]byte("abc")}, 1008 }, 1009 }, 1010 }, 1011 }, 1012 { 1013 Name: "TRIM() function", 1014 Queries: []CharsetCollationEngineTestQuery{ 1015 { 1016 Query: "SELECT TRIM(_utf16'\x00 \x00a\x00b\x00c\x00 ' COLLATE utf16_unicode_ci);", 1017 Expected: []sql.Row{ 1018 {"abc"}, 1019 }, 1020 }, 1021 { 1022 Query: "SELECT TRIM(_utf8mb4' abc ' COLLATE utf8mb4_0900_bin);", 1023 Expected: []sql.Row{ 1024 {"abc"}, 1025 }, 1026 }, 1027 { 1028 Query: "SELECT TRIM(_utf8mb4'\x00 \x00a\x00b\x00c\x00 ' COLLATE utf8mb4_0900_bin);", 1029 Expected: []sql.Row{ 1030 {"\x00 \x00a\x00b\x00c\x00"}, 1031 }, 1032 }, 1033 }, 1034 }, 1035 { 1036 Name: "RTRIM() function", 1037 Queries: []CharsetCollationEngineTestQuery{ 1038 { 1039 Query: "SELECT RTRIM(_utf16'\x00 \x00a\x00b\x00c\x00 ' COLLATE utf16_unicode_ci);", 1040 Expected: []sql.Row{ 1041 {" abc"}, 1042 }, 1043 }, 1044 { 1045 Query: "SELECT RTRIM(_utf8mb4' abc ' COLLATE utf8mb4_0900_bin);", 1046 Expected: []sql.Row{ 1047 {" abc"}, 1048 }, 1049 }, 1050 { 1051 Query: "SELECT RTRIM(_utf8mb4'\x00 \x00a\x00b\x00c\x00 ' COLLATE utf8mb4_0900_bin);", 1052 Expected: []sql.Row{ 1053 {"\x00 \x00a\x00b\x00c\x00"}, 1054 }, 1055 }, 1056 }, 1057 }, 1058 { 1059 Name: "LTRIM() function", 1060 Queries: []CharsetCollationEngineTestQuery{ 1061 { 1062 Query: "SELECT LTRIM(_utf16'\x00 \x00a\x00b\x00c\x00 ' COLLATE utf16_unicode_ci);", 1063 Expected: []sql.Row{ 1064 {"abc "}, 1065 }, 1066 }, 1067 { 1068 Query: "SELECT LTRIM(_utf8mb4' abc ' COLLATE utf8mb4_0900_bin);", 1069 Expected: []sql.Row{ 1070 {"abc "}, 1071 }, 1072 }, 1073 { 1074 Query: "SELECT LTRIM(_utf8mb4'\x00 \x00a\x00b\x00c\x00 ' COLLATE utf8mb4_0900_bin);", 1075 Expected: []sql.Row{ 1076 {"\x00 \x00a\x00b\x00c\x00 "}, 1077 }, 1078 }, 1079 }, 1080 }, 1081 { 1082 Name: "BINARY() function", 1083 Queries: []CharsetCollationEngineTestQuery{ 1084 { 1085 Query: "SELECT BINARY(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci);", 1086 Expected: []sql.Row{ 1087 {[]byte("\x00a\x00b\x00c")}, 1088 }, 1089 }, 1090 { 1091 Query: "SELECT BINARY(_utf8mb4'abc' COLLATE utf8mb4_0900_bin);", 1092 Expected: []sql.Row{ 1093 {[]byte("abc")}, 1094 }, 1095 }, 1096 { 1097 Query: "SELECT BINARY(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin);", 1098 Expected: []sql.Row{ 1099 {[]byte("\x00a\x00b\x00c")}, 1100 }, 1101 }, 1102 }, 1103 }, 1104 { 1105 Name: "CAST(... AS BINARY) function", 1106 Queries: []CharsetCollationEngineTestQuery{ 1107 { 1108 Query: "SELECT CAST(_utf16'\x00a\x00b\x00c' COLLATE utf16_unicode_ci AS BINARY);", 1109 Expected: []sql.Row{ 1110 {[]byte("\x00a\x00b\x00c")}, 1111 }, 1112 }, 1113 { 1114 Query: "SELECT CAST(_utf8mb4'abc' COLLATE utf8mb4_0900_bin AS BINARY);", 1115 Expected: []sql.Row{ 1116 {[]byte("abc")}, 1117 }, 1118 }, 1119 { 1120 Query: "SELECT CAST(_utf8mb4'\x00a\x00b\x00c' COLLATE utf8mb4_0900_bin AS BINARY);", 1121 Expected: []sql.Row{ 1122 {[]byte("\x00a\x00b\x00c")}, 1123 }, 1124 }, 1125 }, 1126 }, 1127 { 1128 Name: "Issue #5482", 1129 Queries: []CharsetCollationEngineTestQuery{ 1130 { 1131 Query: `SELECT T.TABLE_NAME AS label, 'connection.table' as type, T.TABLE_SCHEMA AS 'schema', 1132 T.TABLE_SCHEMA AS 'database', T.TABLE_CATALOG AS 'catalog', 1133 0 AS isView FROM INFORMATION_SCHEMA.TABLES AS T WHERE T.TABLE_CATALOG = 'def' AND 1134 UPPER(T.TABLE_TYPE) = 'BASE TABLE' ORDER BY T.TABLE_NAME;`, 1135 Expected: []sql.Row(nil), 1136 }, 1137 }, 1138 }, 1139 }