github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/sqle/enginetest/dolt_engine_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 enginetest 16 17 import ( 18 "context" 19 "fmt" 20 "io" 21 "os" 22 "runtime" 23 "sync" 24 "testing" 25 "time" 26 27 "github.com/dolthub/go-mysql-server/enginetest" 28 "github.com/dolthub/go-mysql-server/enginetest/queries" 29 "github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup" 30 "github.com/dolthub/go-mysql-server/server" 31 "github.com/dolthub/go-mysql-server/sql" 32 "github.com/dolthub/go-mysql-server/sql/memo" 33 "github.com/dolthub/go-mysql-server/sql/mysql_db" 34 "github.com/dolthub/go-mysql-server/sql/plan" 35 "github.com/dolthub/go-mysql-server/sql/transform" 36 gmstypes "github.com/dolthub/go-mysql-server/sql/types" 37 "github.com/dolthub/vitess/go/mysql" 38 "github.com/stretchr/testify/assert" 39 "github.com/stretchr/testify/require" 40 41 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 42 "github.com/dolthub/dolt/go/libraries/doltcore/dtestutils" 43 "github.com/dolthub/dolt/go/libraries/doltcore/env" 44 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 45 "github.com/dolthub/dolt/go/libraries/doltcore/sqle" 46 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" 47 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/statspro" 48 "github.com/dolthub/dolt/go/libraries/utils/config" 49 "github.com/dolthub/dolt/go/store/datas" 50 "github.com/dolthub/dolt/go/store/types" 51 ) 52 53 var skipPrepared bool 54 55 // SkipPreparedsCount is used by the "ci-check-repo CI workflow 56 // as a reminder to consider prepareds when adding a new 57 // enginetest suite. 58 const SkipPreparedsCount = 83 59 60 const skipPreparedFlag = "DOLT_SKIP_PREPARED_ENGINETESTS" 61 62 func init() { 63 sqle.MinRowsPerPartition = 8 64 sqle.MaxRowsPerPartition = 1024 65 66 if v := os.Getenv(skipPreparedFlag); v != "" { 67 skipPrepared = true 68 } 69 } 70 71 func TestQueries(t *testing.T) { 72 h := newDoltHarness(t) 73 defer h.Close() 74 enginetest.TestQueries(t, h) 75 } 76 77 func TestSingleQuery(t *testing.T) { 78 t.Skip() 79 80 harness := newDoltHarness(t) 81 harness.Setup(setup.SimpleSetup...) 82 engine, err := harness.NewEngine(t) 83 if err != nil { 84 panic(err) 85 } 86 87 setupQueries := []string{ 88 // "create table t1 (pk int primary key, c int);", 89 // "insert into t1 values (1,2), (3,4)", 90 // "call dolt_add('.')", 91 // "set @Commit1 = dolt_commit('-am', 'initial table');", 92 // "insert into t1 values (5,6), (7,8)", 93 // "set @Commit2 = dolt_commit('-am', 'two more rows');", 94 } 95 96 for _, q := range setupQueries { 97 enginetest.RunQueryWithContext(t, engine, harness, nil, q) 98 } 99 100 // engine.EngineAnalyzer().Debug = true 101 // engine.EngineAnalyzer().Verbose = true 102 103 var test queries.QueryTest 104 test = queries.QueryTest{ 105 Query: `show create table mytable`, 106 Expected: []sql.Row{ 107 {"mytable", 108 "CREATE TABLE `mytable` (\n" + 109 " `i` bigint NOT NULL,\n" + 110 " `s` varchar(20) NOT NULL COMMENT 'column s',\n" + 111 " PRIMARY KEY (`i`),\n" + 112 " KEY `idx_si` (`s`,`i`),\n" + 113 " KEY `mytable_i_s` (`i`,`s`),\n" + 114 " UNIQUE KEY `mytable_s` (`s`)\n" + 115 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, 116 }, 117 } 118 119 enginetest.TestQueryWithEngine(t, harness, engine, test) 120 } 121 122 func TestSchemaOverrides(t *testing.T) { 123 tcc := &testCommitClock{} 124 cleanup := installTestCommitClock(tcc) 125 defer cleanup() 126 127 for _, script := range SchemaOverrideTests { 128 sql.RunWithNowFunc(tcc.Now, func() error { 129 harness := newDoltHarness(t) 130 harness.Setup(setup.MydbData) 131 132 engine, err := harness.NewEngine(t) 133 if err != nil { 134 panic(err) 135 } 136 // engine.EngineAnalyzer().Debug = true 137 // engine.EngineAnalyzer().Verbose = true 138 139 enginetest.TestScriptWithEngine(t, engine, harness, script) 140 return nil 141 }) 142 } 143 } 144 145 // Convenience test for debugging a single query. Unskip and set to the desired query. 146 func TestSingleScript(t *testing.T) { 147 t.Skip() 148 149 var scripts = []queries.ScriptTest{ 150 { 151 Name: "Delayed foreign key resolution: update", 152 SetUpScript: []string{ 153 "set foreign_key_checks=0;", 154 "create table delayed_parent(pk int primary key);", 155 "create table delayed_child(pk int primary key, foreign key(pk) references delayed_parent(pk));", 156 "insert into delayed_parent values (10), (20);", 157 "insert into delayed_child values (1), (20);", 158 "set foreign_key_checks=1;", 159 }, 160 Assertions: []queries.ScriptTestAssertion{ 161 { 162 // No-op update bad to bad should not cause constraint violation 163 Skip: true, 164 Query: "update delayed_child set pk=1 where pk=1;", 165 Expected: []sql.Row{ 166 {gmstypes.OkResult{RowsAffected: 0, Info: plan.UpdateInfo{Matched: 1, Updated: 0}}}, 167 }, 168 }, 169 { 170 // Update on non-existent row should not cause constraint violation 171 Query: "update delayed_child set pk=3 where pk=3;", 172 Expected: []sql.Row{ 173 {gmstypes.OkResult{RowsAffected: 0, Info: plan.UpdateInfo{Matched: 0, Updated: 0}}}, 174 }, 175 }, 176 { 177 // No-op update good to good should not cause constraint violation 178 Query: "update delayed_child set pk=20 where pk=20;", 179 Expected: []sql.Row{ 180 {gmstypes.OkResult{RowsAffected: 0, Info: plan.UpdateInfo{Matched: 1, Updated: 0}}}, 181 }, 182 }, 183 { 184 // Updating bad value to good value still fails 185 Query: "update delayed_child set pk=10 where pk=1;", 186 Expected: []sql.Row{ 187 {gmstypes.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}, 188 }, 189 }, 190 }, 191 }, 192 } 193 194 tcc := &testCommitClock{} 195 cleanup := installTestCommitClock(tcc) 196 defer cleanup() 197 198 for _, script := range scripts { 199 sql.RunWithNowFunc(tcc.Now, func() error { 200 harness := newDoltHarness(t) 201 harness.Setup(setup.MydbData) 202 203 engine, err := harness.NewEngine(t) 204 if err != nil { 205 panic(err) 206 } 207 // engine.EngineAnalyzer().Debug = true 208 // engine.EngineAnalyzer().Verbose = true 209 210 enginetest.TestScriptWithEngine(t, engine, harness, script) 211 return nil 212 }) 213 } 214 } 215 216 func newUpdateResult(matched, updated int) gmstypes.OkResult { 217 return gmstypes.OkResult{ 218 RowsAffected: uint64(updated), 219 Info: plan.UpdateInfo{Matched: matched, Updated: updated}, 220 } 221 } 222 223 func TestAutoIncrementTrackerLockMode(t *testing.T) { 224 for _, lockMode := range []int64{0, 1, 2} { 225 t.Run(fmt.Sprintf("lock mode %d", lockMode), func(t *testing.T) { 226 testAutoIncrementTrackerWithLockMode(t, lockMode) 227 }) 228 } 229 } 230 231 // testAutoIncrementTrackerWithLockMode tests that interleaved inserts don't cause deadlocks, regardless of the value of innodb_autoinc_lock_mode. 232 // In a real use case, these interleaved operations would be happening in different sessions on different threads. 233 // In order to make the test behave predictably, we manually interleave the two iterators. 234 func testAutoIncrementTrackerWithLockMode(t *testing.T, lockMode int64) { 235 236 err := sql.SystemVariables.AssignValues(map[string]interface{}{"innodb_autoinc_lock_mode": lockMode}) 237 require.NoError(t, err) 238 239 setupScripts := []setup.SetupScript{[]string{ 240 "CREATE TABLE test1 (pk int NOT NULL PRIMARY KEY AUTO_INCREMENT,c0 int,index t1_c_index (c0));", 241 "CREATE TABLE test2 (pk int NOT NULL PRIMARY KEY AUTO_INCREMENT,c0 int,index t2_c_index (c0));", 242 "CREATE TABLE timestamps (pk int NOT NULL PRIMARY KEY AUTO_INCREMENT, t int);", 243 "CREATE TRIGGER t1 AFTER INSERT ON test1 FOR EACH ROW INSERT INTO timestamps VALUES (0, 1);", 244 "CREATE TRIGGER t2 AFTER INSERT ON test2 FOR EACH ROW INSERT INTO timestamps VALUES (0, 2);", 245 "CREATE VIEW bin AS SELECT 0 AS v UNION ALL SELECT 1;", 246 "CREATE VIEW sequence5bit AS SELECT b1.v + 2*b2.v + 4*b3.v + 8*b4.v + 16*b5.v AS v from bin b1, bin b2, bin b3, bin b4, bin b5;", 247 }} 248 249 harness := newDoltHarness(t) 250 defer harness.Close() 251 harness.Setup(setup.MydbData, setupScripts) 252 e := mustNewEngine(t, harness) 253 254 defer e.Close() 255 ctx := enginetest.NewContext(harness) 256 257 // Confirm that the system variable was correctly set. 258 _, iter, err := e.Query(ctx, "select @@innodb_autoinc_lock_mode") 259 require.NoError(t, err) 260 rows, err := sql.RowIterToRows(ctx, iter) 261 require.NoError(t, err) 262 assert.Equal(t, rows, []sql.Row{{lockMode}}) 263 264 // Ordinarily QueryEngine.query manages transactions. 265 // Since we can't use that for this test, we manually start a new transaction. 266 ts := ctx.Session.(sql.TransactionSession) 267 tx, err := ts.StartTransaction(ctx, sql.ReadWrite) 268 require.NoError(t, err) 269 ctx.SetTransaction(tx) 270 271 getTriggerIter := func(query string) sql.RowIter { 272 root, err := e.AnalyzeQuery(ctx, query) 273 require.NoError(t, err) 274 275 var triggerNode *plan.TriggerExecutor 276 transform.Node(root, func(n sql.Node) (sql.Node, transform.TreeIdentity, error) { 277 if triggerNode != nil { 278 return n, transform.SameTree, nil 279 } 280 if t, ok := n.(*plan.TriggerExecutor); ok { 281 triggerNode = t 282 } 283 return n, transform.NewTree, nil 284 }) 285 iter, err := e.EngineAnalyzer().ExecBuilder.Build(ctx, triggerNode, nil) 286 require.NoError(t, err) 287 return iter 288 } 289 290 iter1 := getTriggerIter("INSERT INTO test1 (c0) select v from sequence5bit;") 291 iter2 := getTriggerIter("INSERT INTO test2 (c0) select v from sequence5bit;") 292 293 // Alternate the iterators until they're exhausted. 294 var err1 error 295 var err2 error 296 for err1 != io.EOF || err2 != io.EOF { 297 if err1 != io.EOF { 298 var row1 sql.Row 299 require.NoError(t, err1) 300 row1, err1 = iter1.Next(ctx) 301 _ = row1 302 } 303 if err2 != io.EOF { 304 require.NoError(t, err2) 305 _, err2 = iter2.Next(ctx) 306 } 307 } 308 err = iter1.Close(ctx) 309 require.NoError(t, err) 310 err = iter2.Close(ctx) 311 require.NoError(t, err) 312 313 dsess.DSessFromSess(ctx.Session).CommitTransaction(ctx, ctx.GetTransaction()) 314 315 // Verify that the inserts are seen by the engine. 316 { 317 _, iter, err := e.Query(ctx, "select count(*) from timestamps") 318 require.NoError(t, err) 319 rows, err := sql.RowIterToRows(ctx, iter) 320 require.NoError(t, err) 321 assert.Equal(t, rows, []sql.Row{{int64(64)}}) 322 } 323 324 // Verify that the insert operations are actually interleaved by inspecting the order that values were added to `timestamps` 325 { 326 _, iter, err := e.Query(ctx, "select (select min(pk) from timestamps where t = 1) < (select max(pk) from timestamps where t = 2)") 327 require.NoError(t, err) 328 rows, err := sql.RowIterToRows(ctx, iter) 329 require.NoError(t, err) 330 assert.Equal(t, rows, []sql.Row{{true}}) 331 } 332 333 { 334 _, iter, err := e.Query(ctx, "select (select min(pk) from timestamps where t = 2) < (select max(pk) from timestamps where t = 1)") 335 require.NoError(t, err) 336 rows, err := sql.RowIterToRows(ctx, iter) 337 require.NoError(t, err) 338 assert.Equal(t, rows, []sql.Row{{true}}) 339 } 340 } 341 342 // Convenience test for debugging a single query. Unskip and set to the desired query. 343 func TestSingleMergeScript(t *testing.T) { 344 t.Skip() 345 var scripts = []MergeScriptTest{ 346 { 347 Name: "adding generated column to one side, non-generated column to other side", 348 AncSetUpScript: []string{ 349 "create table t (pk int primary key);", 350 "insert into t values (1), (2);", 351 }, 352 RightSetUpScript: []string{ 353 "alter table t add column col2 varchar(100);", 354 "insert into t (pk, col2) values (3, '3hello'), (4, '4hello');", 355 "alter table t add index (col2);", 356 }, 357 LeftSetUpScript: []string{ 358 "alter table t add column col1 int default (pk + 100);", 359 "insert into t (pk) values (5), (6);", 360 "alter table t add index (col1);", 361 }, 362 Assertions: []queries.ScriptTestAssertion{ 363 { 364 Query: "call dolt_merge('right');", 365 Expected: []sql.Row{{doltCommit, 0, 0}}, 366 }, 367 { 368 Query: "select pk, col1, col2 from t;", 369 Expected: []sql.Row{ 370 {1, 101, nil}, 371 {2, 102, nil}, 372 {3, 103, "3hello"}, 373 {4, 104, "4hello"}, 374 {5, 105, nil}, 375 {6, 106, nil}, 376 }, 377 }, 378 }, 379 }, 380 // { 381 // Name: "adding generated columns to both sides", 382 // AncSetUpScript: []string{ 383 // "create table t (pk int primary key);", 384 // "insert into t values (1), (2);", 385 // }, 386 // RightSetUpScript: []string{ 387 // "alter table t add column col2 varchar(100) as (concat(pk, 'hello'));", 388 // "insert into t (pk) values (3), (4);", 389 // "alter table t add index (col2);", 390 // }, 391 // LeftSetUpScript: []string{ 392 // "alter table t add column col1 int as (pk + 100) stored;", 393 // "insert into t (pk) values (5), (6);", 394 // "alter table t add index (col1);", 395 // }, 396 // Assertions: []queries.ScriptTestAssertion{ 397 // { 398 // Query: "call dolt_merge('right');", 399 // Expected: []sql.Row{{doltCommit, 0, 0}}, 400 // }, 401 // { 402 // Query: "select pk, col1, col2 from t;", 403 // Expected: []sql.Row{ 404 // {1, 101, "1hello"}, 405 // {2, 102, "2hello"}, 406 // {3, 103, "3hello"}, 407 // {4, 104, "4hello"}, 408 // {5, 105, "5hello"}, 409 // {6, 106, "6hello"}, 410 // }, 411 // }, 412 // }, 413 // }, 414 // { 415 // Name: "adding a column with a literal default value", 416 // AncSetUpScript: []string{ 417 // "CREATE table t (pk int primary key);", 418 // "INSERT into t values (1);", 419 // }, 420 // RightSetUpScript: []string{ 421 // "alter table t add column c1 varchar(100) default ('hello');", 422 // "insert into t values (2, 'hi');", 423 // "alter table t add index idx1 (c1, pk);", 424 // }, 425 // LeftSetUpScript: []string{ 426 // "insert into t values (3);", 427 // }, 428 // Assertions: []queries.ScriptTestAssertion{ 429 // { 430 // Query: "call dolt_merge('right');", 431 // Expected: []sql.Row{{doltCommit, 0, 0}}, 432 // }, 433 // { 434 // Query: "select * from t;", 435 // Expected: []sql.Row{{1, "hello"}, {2, "hi"}, {3, "hello"}}, 436 // }, 437 // }, 438 // }, 439 // { 440 // Name: "check constraint violation - right side violates new check constraint", 441 // AncSetUpScript: []string{ 442 // "set autocommit = 0;", 443 // "CREATE table t (pk int primary key, col00 int, col01 int, col1 varchar(100) default ('hello'));", 444 // "INSERT into t values (1, 0, 0, 'hi');", 445 // "alter table t add index idx1 (col1);", 446 // }, 447 // RightSetUpScript: []string{ 448 // "insert into t values (2, 0, 0, DEFAULT);", 449 // }, 450 // LeftSetUpScript: []string{ 451 // "alter table t drop column col00;", 452 // "alter table t drop column col01;", 453 // "alter table t add constraint CHECK (col1 != concat('he', 'llo'))", 454 // }, 455 // Assertions: []queries.ScriptTestAssertion{ 456 // { 457 // Query: "call dolt_merge('right');", 458 // Expected: []sql.Row{{"", 0, 1}}, 459 // }, 460 // { 461 // Query: "select * from dolt_constraint_violations;", 462 // Expected: []sql.Row{{"t", uint64(1)}}, 463 // }, 464 // { 465 // Query: `select violation_type, pk, col1, violation_info like "\%NOT((col1 = concat('he','llo')))\%" from dolt_constraint_violations_t;`, 466 // Expected: []sql.Row{{uint64(3), 2, "hello", true}}, 467 // }, 468 // }, 469 // }, 470 } 471 for _, test := range scripts { 472 // t.Run("merge right into left", func(t *testing.T) { 473 // enginetest.TestScript(t, newDoltHarness(t), convertMergeScriptTest(test, false)) 474 // }) 475 t.Run("merge left into right", func(t *testing.T) { 476 enginetest.TestScript(t, newDoltHarness(t), convertMergeScriptTest(test, true)) 477 }) 478 } 479 } 480 481 func TestSingleQueryPrepared(t *testing.T) { 482 t.Skip() 483 484 harness := newDoltHarness(t) 485 //engine := enginetest.NewEngine(t, harness) 486 //enginetest.CreateIndexes(t, harness, engine) 487 //engine := enginetest.NewSpatialEngine(t, harness) 488 engine, err := harness.NewEngine(t) 489 if err != nil { 490 panic(err) 491 } 492 493 setupQueries := []string{ 494 "create table t1 (pk int primary key, c int);", 495 "call dolt_add('.')", 496 "insert into t1 values (1,2), (3,4)", 497 "set @Commit1 = dolt_commit('-am', 'initial table');", 498 "insert into t1 values (5,6), (7,8)", 499 "set @Commit2 = dolt_commit('-am', 'two more rows');", 500 } 501 502 for _, q := range setupQueries { 503 enginetest.RunQueryWithContext(t, engine, harness, nil, q) 504 } 505 506 //engine.Analyzer.Debug = true 507 //engine.Analyzer.Verbose = true 508 509 var test queries.QueryTest 510 test = queries.QueryTest{ 511 Query: "explain select pk, c from dolt_history_t1 where pk = 3 and committer = 'someguy'", 512 Expected: []sql.Row{ 513 {"Exchange"}, 514 {" └─ Project(dolt_history_t1.pk, dolt_history_t1.c)"}, 515 {" └─ Filter((dolt_history_t1.pk = 3) AND (dolt_history_t1.committer = 'someguy'))"}, 516 {" └─ IndexedTableAccess(dolt_history_t1)"}, 517 {" ├─ index: [dolt_history_t1.pk]"}, 518 {" ├─ filters: [{[3, 3]}]"}, 519 {" └─ columns: [pk c committer]"}, 520 }, 521 } 522 523 enginetest.TestPreparedQuery(t, harness, test.Query, test.Expected, nil) 524 } 525 526 func TestSingleScriptPrepared(t *testing.T) { 527 t.Skip() 528 529 var script = queries.ScriptTest{ 530 Name: "dolt_history table filter correctness", 531 SetUpScript: []string{ 532 "create table xy (x int primary key, y int);", 533 "call dolt_add('.');", 534 "call dolt_commit('-m', 'creating table');", 535 "insert into xy values (0, 1);", 536 "call dolt_commit('-am', 'add data');", 537 "insert into xy values (2, 3);", 538 "call dolt_commit('-am', 'add data');", 539 "insert into xy values (4, 5);", 540 "call dolt_commit('-am', 'add data');", 541 }, 542 Assertions: []queries.ScriptTestAssertion{ 543 { 544 Query: "select * from dolt_history_xy where commit_hash = (select dolt_log.commit_hash from dolt_log limit 1 offset 1) order by 1", 545 Expected: []sql.Row{ 546 sql.Row{0, 1, "itt2nrlkbl7jis4gt9aov2l32ctt08th", "billy bob", time.Date(1970, time.January, 1, 19, 0, 0, 0, time.Local)}, 547 sql.Row{2, 3, "itt2nrlkbl7jis4gt9aov2l32ctt08th", "billy bob", time.Date(1970, time.January, 1, 19, 0, 0, 0, time.Local)}, 548 }, 549 }, 550 { 551 Query: "select count(*) from dolt_history_xy where commit_hash = (select dolt_log.commit_hash from dolt_log limit 1 offset 1)", 552 Expected: []sql.Row{ 553 {2}, 554 }, 555 }, 556 { 557 Query: "select count(*) from dolt_history_xy where commit_hash = 'itt2nrlkbl7jis4gt9aov2l32ctt08th'", 558 Expected: []sql.Row{ 559 {2}, 560 }, 561 }, 562 }, 563 } 564 565 tcc := &testCommitClock{} 566 cleanup := installTestCommitClock(tcc) 567 defer cleanup() 568 569 sql.RunWithNowFunc(tcc.Now, func() error { 570 harness := newDoltHarness(t) 571 enginetest.TestScriptPrepared(t, harness, script) 572 return nil 573 }) 574 } 575 576 func TestVersionedQueries(t *testing.T) { 577 h := newDoltHarness(t) 578 defer h.Close() 579 enginetest.TestVersionedQueries(t, h) 580 } 581 582 func TestAnsiQuotesSqlMode(t *testing.T) { 583 enginetest.TestAnsiQuotesSqlMode(t, newDoltHarness(t)) 584 } 585 586 func TestAnsiQuotesSqlModePrepared(t *testing.T) { 587 enginetest.TestAnsiQuotesSqlModePrepared(t, newDoltHarness(t)) 588 } 589 590 // Tests of choosing the correct execution plan independent of result correctness. Mostly useful for confirming that 591 // the right indexes are being used for joining tables. 592 func TestQueryPlans(t *testing.T) { 593 // Dolt supports partial keys, so the index matched is different for some plans 594 // TODO: Fix these differences by implementing partial key matching in the memory tables, or the engine itself 595 skipped := []string{ 596 "SELECT pk,pk1,pk2 FROM one_pk LEFT JOIN two_pk ON pk=pk1", 597 "SELECT pk,pk1,pk2 FROM one_pk JOIN two_pk ON pk=pk1", 598 "SELECT one_pk.c5,pk1,pk2 FROM one_pk JOIN two_pk ON pk=pk1 ORDER BY 1,2,3", 599 "SELECT opk.c5,pk1,pk2 FROM one_pk opk JOIN two_pk tpk ON opk.pk=tpk.pk1 ORDER BY 1,2,3", 600 "SELECT opk.c5,pk1,pk2 FROM one_pk opk JOIN two_pk tpk ON pk=pk1 ORDER BY 1,2,3", 601 "SELECT pk,pk1,pk2 FROM one_pk LEFT JOIN two_pk ON pk=pk1 ORDER BY 1,2,3", 602 "SELECT pk,pk1,pk2 FROM one_pk t1, two_pk t2 WHERE pk=1 AND pk2=1 AND pk1=1 ORDER BY 1,2", 603 } 604 // Parallelism introduces Exchange nodes into the query plans, so disable. 605 // TODO: exchange nodes should really only be part of the explain plan under certain debug settings 606 harness := newDoltHarness(t).WithSkippedQueries(skipped) 607 harness.configureStats = true 608 if !types.IsFormat_DOLT(types.Format_Default) { 609 // only new format supports reverse IndexTableAccess 610 reverseIndexSkip := []string{ 611 "SELECT * FROM one_pk ORDER BY pk", 612 "SELECT * FROM two_pk ORDER BY pk1, pk2", 613 "SELECT * FROM two_pk ORDER BY pk1", 614 "SELECT pk1 AS one, pk2 AS two FROM two_pk ORDER BY pk1, pk2", 615 "SELECT pk1 AS one, pk2 AS two FROM two_pk ORDER BY one, two", 616 "SELECT i FROM (SELECT i FROM mytable ORDER BY i DESC LIMIT 1) sq WHERE i = 3", 617 "SELECT i FROM (SELECT i FROM (SELECT i FROM mytable ORDER BY DES LIMIT 1) sql1)sql2 WHERE i = 3", 618 "SELECT s,i FROM mytable order by i DESC", 619 "SELECT s,i FROM mytable as a order by i DESC", 620 "SELECT pk1, pk2 FROM two_pk order by pk1 asc, pk2 asc", 621 "SELECT pk1, pk2 FROM two_pk order by pk1 desc, pk2 desc", 622 "SELECT i FROM (SELECT i FROM (SELECT i FROM mytable ORDER BY i DESC LIMIT 1) sq1) sq2 WHERE i = 3", 623 } 624 harness = harness.WithSkippedQueries(reverseIndexSkip) 625 } 626 627 defer harness.Close() 628 enginetest.TestQueryPlans(t, harness, queries.PlanTests) 629 } 630 631 func TestIntegrationQueryPlans(t *testing.T) { 632 harness := newDoltHarness(t) 633 harness.configureStats = true 634 defer harness.Close() 635 enginetest.TestIntegrationPlans(t, harness) 636 } 637 638 func TestDoltDiffQueryPlans(t *testing.T) { 639 if !types.IsFormat_DOLT(types.Format_Default) { 640 t.Skip("only new format support system table indexing") 641 } 642 643 harness := newDoltHarness(t).WithParallelism(2) // want Exchange nodes 644 defer harness.Close() 645 harness.Setup(setup.SimpleSetup...) 646 e, err := harness.NewEngine(t) 647 require.NoError(t, err) 648 defer e.Close() 649 650 for _, tt := range append(DoltDiffPlanTests, DoltCommitPlanTests...) { 651 enginetest.TestQueryPlanWithName(t, tt.Query, harness, e, tt.Query, tt.ExpectedPlan, sql.DescribeOptions{}) 652 } 653 } 654 655 func TestBranchPlans(t *testing.T) { 656 for _, script := range BranchPlanTests { 657 t.Run(script.Name, func(t *testing.T) { 658 harness := newDoltHarness(t) 659 defer harness.Close() 660 661 e := mustNewEngine(t, harness) 662 defer e.Close() 663 664 for _, statement := range script.SetUpScript { 665 ctx := enginetest.NewContext(harness).WithQuery(statement) 666 enginetest.RunQueryWithContext(t, e, harness, ctx, statement) 667 } 668 for _, tt := range script.Queries { 669 t.Run(tt.Query, func(t *testing.T) { 670 TestIndexedAccess(t, e, harness, tt.Query, tt.Index) 671 }) 672 } 673 }) 674 } 675 } 676 677 func TestQueryErrors(t *testing.T) { 678 h := newDoltHarness(t) 679 defer h.Close() 680 enginetest.TestQueryErrors(t, h) 681 } 682 683 func TestInfoSchema(t *testing.T) { 684 h := newDoltHarness(t) 685 defer h.Close() 686 enginetest.TestInfoSchema(t, h) 687 688 for _, script := range DoltInfoSchemaScripts { 689 func() { 690 harness := newDoltHarness(t) 691 defer harness.Close() 692 enginetest.TestScript(t, harness, script) 693 }() 694 } 695 } 696 697 func TestColumnAliases(t *testing.T) { 698 h := newDoltHarness(t) 699 defer h.Close() 700 enginetest.TestColumnAliases(t, h) 701 } 702 703 func TestOrderByGroupBy(t *testing.T) { 704 h := newDoltHarness(t) 705 defer h.Close() 706 enginetest.TestOrderByGroupBy(t, h) 707 } 708 709 func TestAmbiguousColumnResolution(t *testing.T) { 710 h := newDoltHarness(t) 711 defer h.Close() 712 enginetest.TestAmbiguousColumnResolution(t, h) 713 } 714 715 func TestInsertInto(t *testing.T) { 716 h := newDoltHarness(t) 717 defer h.Close() 718 enginetest.TestInsertInto(t, h) 719 } 720 721 func TestInsertIgnoreInto(t *testing.T) { 722 h := newDoltHarness(t) 723 defer h.Close() 724 enginetest.TestInsertIgnoreInto(t, h) 725 } 726 727 // TODO: merge this into the above test when we remove old format 728 func TestInsertDuplicateKeyKeyless(t *testing.T) { 729 if !types.IsFormat_DOLT(types.Format_Default) { 730 t.Skip() 731 } 732 enginetest.TestInsertDuplicateKeyKeyless(t, newDoltHarness(t)) 733 } 734 735 // TODO: merge this into the above test when we remove old format 736 func TestInsertDuplicateKeyKeylessPrepared(t *testing.T) { 737 if !types.IsFormat_DOLT(types.Format_Default) { 738 t.Skip() 739 } 740 enginetest.TestInsertDuplicateKeyKeylessPrepared(t, newDoltHarness(t)) 741 } 742 743 // TODO: merge this into the above test when we remove old format 744 func TestIgnoreIntoWithDuplicateUniqueKeyKeyless(t *testing.T) { 745 if !types.IsFormat_DOLT(types.Format_Default) { 746 t.Skip() 747 } 748 h := newDoltHarness(t) 749 defer h.Close() 750 enginetest.TestIgnoreIntoWithDuplicateUniqueKeyKeyless(t, h) 751 } 752 753 // TODO: merge this into the above test when we remove old format 754 func TestIgnoreIntoWithDuplicateUniqueKeyKeylessPrepared(t *testing.T) { 755 if !types.IsFormat_DOLT(types.Format_Default) { 756 t.Skip() 757 } 758 enginetest.TestIgnoreIntoWithDuplicateUniqueKeyKeylessPrepared(t, newDoltHarness(t)) 759 } 760 761 func TestInsertIntoErrors(t *testing.T) { 762 h := newDoltHarness(t) 763 defer h.Close() 764 h = h.WithSkippedQueries([]string{ 765 "create table bad (vb varbinary(65535))", 766 "insert into bad values (repeat('0', 65536))", 767 }) 768 enginetest.TestInsertIntoErrors(t, h) 769 } 770 771 func TestGeneratedColumns(t *testing.T) { 772 enginetest.TestGeneratedColumns(t, 773 // virtual indexes are failing for certain lookups on this test 774 newDoltHarness(t).WithSkippedQueries([]string{"create table t (pk int primary key, col1 int as (pk + 1));"})) 775 776 for _, script := range GeneratedColumnMergeTestScripts { 777 func() { 778 h := newDoltHarness(t) 779 defer h.Close() 780 enginetest.TestScript(t, h, script) 781 }() 782 } 783 } 784 785 func TestGeneratedColumnPlans(t *testing.T) { 786 enginetest.TestGeneratedColumnPlans(t, newDoltHarness(t)) 787 } 788 789 func TestSpatialQueries(t *testing.T) { 790 h := newDoltHarness(t) 791 defer h.Close() 792 enginetest.TestSpatialQueries(t, h) 793 } 794 795 func TestReplaceInto(t *testing.T) { 796 h := newDoltHarness(t) 797 defer h.Close() 798 enginetest.TestReplaceInto(t, h) 799 } 800 801 func TestReplaceIntoErrors(t *testing.T) { 802 h := newDoltHarness(t) 803 defer h.Close() 804 enginetest.TestReplaceIntoErrors(t, h) 805 } 806 807 func TestUpdate(t *testing.T) { 808 h := newDoltHarness(t) 809 defer h.Close() 810 enginetest.TestUpdate(t, h) 811 } 812 813 func TestUpdateIgnore(t *testing.T) { 814 h := newDoltHarness(t) 815 defer h.Close() 816 enginetest.TestUpdateIgnore(t, h) 817 } 818 819 func TestUpdateErrors(t *testing.T) { 820 h := newDoltHarness(t) 821 defer h.Close() 822 enginetest.TestUpdateErrors(t, h) 823 } 824 825 func TestDeleteFrom(t *testing.T) { 826 h := newDoltHarness(t) 827 defer h.Close() 828 enginetest.TestDelete(t, h) 829 } 830 831 func TestDeleteFromErrors(t *testing.T) { 832 h := newDoltHarness(t) 833 defer h.Close() 834 enginetest.TestDeleteErrors(t, h) 835 } 836 837 func TestSpatialDelete(t *testing.T) { 838 h := newDoltHarness(t) 839 defer h.Close() 840 enginetest.TestSpatialDelete(t, h) 841 } 842 843 func TestSpatialScripts(t *testing.T) { 844 h := newDoltHarness(t) 845 defer h.Close() 846 enginetest.TestSpatialScripts(t, h) 847 } 848 849 func TestSpatialScriptsPrepared(t *testing.T) { 850 enginetest.TestSpatialScriptsPrepared(t, newDoltHarness(t)) 851 } 852 853 func TestSpatialIndexScripts(t *testing.T) { 854 skipOldFormat(t) 855 enginetest.TestSpatialIndexScripts(t, newDoltHarness(t)) 856 } 857 858 func TestSpatialIndexScriptsPrepared(t *testing.T) { 859 skipOldFormat(t) 860 enginetest.TestSpatialIndexScriptsPrepared(t, newDoltHarness(t)) 861 } 862 863 func TestSpatialIndexPlans(t *testing.T) { 864 skipOldFormat(t) 865 enginetest.TestSpatialIndexPlans(t, newDoltHarness(t)) 866 } 867 868 func TestTruncate(t *testing.T) { 869 h := newDoltHarness(t) 870 defer h.Close() 871 enginetest.TestTruncate(t, h) 872 } 873 874 func TestConvert(t *testing.T) { 875 if types.IsFormat_LD(types.Format_Default) { 876 t.Skip("noms format has outdated type enforcement") 877 } 878 h := newDoltHarness(t) 879 defer h.Close() 880 enginetest.TestConvertPrepared(t, h) 881 } 882 883 func TestConvertPrepared(t *testing.T) { 884 if types.IsFormat_LD(types.Format_Default) { 885 t.Skip("noms format has outdated type enforcement") 886 } 887 h := newDoltHarness(t) 888 defer h.Close() 889 enginetest.TestConvertPrepared(t, h) 890 } 891 892 func TestScripts(t *testing.T) { 893 var skipped []string 894 if types.IsFormat_DOLT(types.Format_Default) { 895 skipped = append(skipped, newFormatSkippedScripts...) 896 } 897 h := newDoltHarness(t).WithSkippedQueries(skipped) 898 defer h.Close() 899 enginetest.TestScripts(t, h) 900 } 901 902 // TestDoltUserPrivileges tests Dolt-specific code that needs to handle user privilege checking 903 func TestDoltUserPrivileges(t *testing.T) { 904 harness := newDoltHarness(t) 905 defer harness.Close() 906 for _, script := range DoltUserPrivTests { 907 t.Run(script.Name, func(t *testing.T) { 908 harness.Setup(setup.MydbData) 909 engine, err := harness.NewEngine(t) 910 require.NoError(t, err) 911 defer engine.Close() 912 913 ctx := enginetest.NewContextWithClient(harness, sql.Client{ 914 User: "root", 915 Address: "localhost", 916 }) 917 918 engine.EngineAnalyzer().Catalog.MySQLDb.AddRootAccount() 919 engine.EngineAnalyzer().Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) 920 921 for _, statement := range script.SetUpScript { 922 if sh, ok := interface{}(harness).(enginetest.SkippingHarness); ok { 923 if sh.SkipQueryTest(statement) { 924 t.Skip() 925 } 926 } 927 enginetest.RunQueryWithContext(t, engine, harness, ctx, statement) 928 } 929 for _, assertion := range script.Assertions { 930 if sh, ok := interface{}(harness).(enginetest.SkippingHarness); ok { 931 if sh.SkipQueryTest(assertion.Query) { 932 t.Skipf("Skipping query %s", assertion.Query) 933 } 934 } 935 936 user := assertion.User 937 host := assertion.Host 938 if user == "" { 939 user = "root" 940 } 941 if host == "" { 942 host = "localhost" 943 } 944 ctx := enginetest.NewContextWithClient(harness, sql.Client{ 945 User: user, 946 Address: host, 947 }) 948 949 if assertion.ExpectedErr != nil { 950 t.Run(assertion.Query, func(t *testing.T) { 951 enginetest.AssertErrWithCtx(t, engine, harness, ctx, assertion.Query, assertion.ExpectedErr) 952 }) 953 } else if assertion.ExpectedErrStr != "" { 954 t.Run(assertion.Query, func(t *testing.T) { 955 enginetest.AssertErrWithCtx(t, engine, harness, ctx, assertion.Query, nil, assertion.ExpectedErrStr) 956 }) 957 } else { 958 t.Run(assertion.Query, func(t *testing.T) { 959 enginetest.TestQueryWithContext(t, ctx, engine, harness, assertion.Query, assertion.Expected, nil, nil) 960 }) 961 } 962 } 963 }) 964 } 965 } 966 967 func TestJoinOps(t *testing.T) { 968 if types.IsFormat_LD(types.Format_Default) { 969 t.Skip("DOLT_LD keyless indexes are not sorted") 970 } 971 972 h := newDoltHarness(t) 973 defer h.Close() 974 enginetest.TestJoinOps(t, h, enginetest.DefaultJoinOpTests) 975 } 976 977 func TestJoinPlanning(t *testing.T) { 978 if types.IsFormat_LD(types.Format_Default) { 979 t.Skip("DOLT_LD keyless indexes are not sorted") 980 } 981 h := newDoltHarness(t) 982 h.configureStats = true 983 defer h.Close() 984 enginetest.TestJoinPlanning(t, h) 985 } 986 987 func TestJoinQueries(t *testing.T) { 988 h := newDoltHarness(t) 989 defer h.Close() 990 enginetest.TestJoinQueries(t, h) 991 } 992 993 func TestJoinQueriesPrepared(t *testing.T) { 994 h := newDoltHarness(t) 995 defer h.Close() 996 enginetest.TestJoinQueriesPrepared(t, h) 997 } 998 999 // TestJSONTableQueries runs the canonical test queries against a single threaded index enabled harness. 1000 func TestJSONTableQueries(t *testing.T) { 1001 h := newDoltHarness(t) 1002 defer h.Close() 1003 enginetest.TestJSONTableQueries(t, h) 1004 } 1005 1006 // TestJSONTableQueriesPrepared runs the canonical test queries against a single threaded index enabled harness. 1007 func TestJSONTableQueriesPrepared(t *testing.T) { 1008 h := newDoltHarness(t) 1009 defer h.Close() 1010 enginetest.TestJSONTableQueriesPrepared(t, h) 1011 } 1012 1013 // TestJSONTableScripts runs the canonical test queries against a single threaded index enabled harness. 1014 func TestJSONTableScripts(t *testing.T) { 1015 h := newDoltHarness(t) 1016 defer h.Close() 1017 enginetest.TestJSONTableScripts(t, h) 1018 } 1019 1020 // TestJSONTableScriptsPrepared runs the canonical test queries against a single threaded index enabled harness. 1021 func TestJSONTableScriptsPrepared(t *testing.T) { 1022 h := newDoltHarness(t) 1023 defer h.Close() 1024 enginetest.TestJSONTableScriptsPrepared(t, h) 1025 } 1026 1027 func TestUserPrivileges(t *testing.T) { 1028 h := newDoltHarness(t) 1029 h.setupTestProcedures = true 1030 h.configureStats = true 1031 defer h.Close() 1032 enginetest.TestUserPrivileges(t, h) 1033 } 1034 1035 func TestUserAuthentication(t *testing.T) { 1036 t.Skip("Unexpected panic, need to fix") 1037 h := newDoltHarness(t) 1038 defer h.Close() 1039 enginetest.TestUserAuthentication(t, h) 1040 } 1041 1042 func TestComplexIndexQueries(t *testing.T) { 1043 h := newDoltHarness(t) 1044 defer h.Close() 1045 enginetest.TestComplexIndexQueries(t, h) 1046 } 1047 1048 func TestCreateTable(t *testing.T) { 1049 h := newDoltHarness(t) 1050 defer h.Close() 1051 enginetest.TestCreateTable(t, h) 1052 } 1053 1054 func TestRowLimit(t *testing.T) { 1055 h := newDoltHarness(t) 1056 defer h.Close() 1057 enginetest.TestRowLimit(t, h) 1058 } 1059 1060 func TestBranchDdl(t *testing.T) { 1061 for _, script := range DdlBranchTests { 1062 func() { 1063 h := newDoltHarness(t) 1064 defer h.Close() 1065 enginetest.TestScript(t, h, script) 1066 }() 1067 } 1068 } 1069 1070 func TestBranchDdlPrepared(t *testing.T) { 1071 for _, script := range DdlBranchTests { 1072 func() { 1073 h := newDoltHarness(t) 1074 defer h.Close() 1075 enginetest.TestScriptPrepared(t, h, script) 1076 }() 1077 } 1078 } 1079 1080 func TestPkOrdinalsDDL(t *testing.T) { 1081 h := newDoltHarness(t) 1082 defer h.Close() 1083 enginetest.TestPkOrdinalsDDL(t, h) 1084 } 1085 1086 func TestPkOrdinalsDML(t *testing.T) { 1087 h := newDoltHarness(t) 1088 defer h.Close() 1089 enginetest.TestPkOrdinalsDML(t, h) 1090 } 1091 1092 func TestDropTable(t *testing.T) { 1093 h := newDoltHarness(t) 1094 defer h.Close() 1095 enginetest.TestDropTable(t, h) 1096 } 1097 1098 func TestRenameTable(t *testing.T) { 1099 h := newDoltHarness(t) 1100 defer h.Close() 1101 enginetest.TestRenameTable(t, h) 1102 } 1103 1104 func TestRenameColumn(t *testing.T) { 1105 h := newDoltHarness(t) 1106 defer h.Close() 1107 enginetest.TestRenameColumn(t, h) 1108 } 1109 1110 func TestAddColumn(t *testing.T) { 1111 h := newDoltHarness(t) 1112 defer h.Close() 1113 enginetest.TestAddColumn(t, h) 1114 } 1115 1116 func TestModifyColumn(t *testing.T) { 1117 h := newDoltHarness(t) 1118 defer h.Close() 1119 enginetest.TestModifyColumn(t, h) 1120 } 1121 1122 func TestDropColumn(t *testing.T) { 1123 h := newDoltHarness(t) 1124 defer h.Close() 1125 enginetest.TestDropColumn(t, h) 1126 } 1127 1128 func TestCreateDatabase(t *testing.T) { 1129 h := newDoltHarness(t) 1130 defer h.Close() 1131 enginetest.TestCreateDatabase(t, h) 1132 } 1133 1134 func TestBlobs(t *testing.T) { 1135 skipOldFormat(t) 1136 h := newDoltHarness(t) 1137 defer h.Close() 1138 enginetest.TestBlobs(t, h) 1139 } 1140 1141 func TestIndexes(t *testing.T) { 1142 harness := newDoltHarness(t) 1143 defer harness.Close() 1144 enginetest.TestIndexes(t, harness) 1145 } 1146 1147 func TestIndexPrefix(t *testing.T) { 1148 skipOldFormat(t) 1149 harness := newDoltHarness(t) 1150 defer harness.Close() 1151 enginetest.TestIndexPrefix(t, harness) 1152 for _, script := range DoltIndexPrefixScripts { 1153 enginetest.TestScript(t, harness, script) 1154 } 1155 } 1156 1157 func TestBigBlobs(t *testing.T) { 1158 skipOldFormat(t) 1159 1160 h := newDoltHarness(t) 1161 defer h.Close() 1162 h.Setup(setup.MydbData, setup.BlobData) 1163 for _, tt := range BigBlobQueries { 1164 enginetest.RunWriteQueryTest(t, h, tt) 1165 } 1166 } 1167 1168 func TestDropDatabase(t *testing.T) { 1169 func() { 1170 h := newDoltHarness(t) 1171 defer h.Close() 1172 enginetest.TestScript(t, h, queries.ScriptTest{ 1173 Name: "Drop database engine tests for Dolt only", 1174 SetUpScript: []string{ 1175 "CREATE DATABASE Test1db", 1176 "CREATE DATABASE TEST2db", 1177 }, 1178 Assertions: []queries.ScriptTestAssertion{ 1179 { 1180 Query: "DROP DATABASE TeSt2DB", 1181 Expected: []sql.Row{{gmstypes.OkResult{RowsAffected: 1}}}, 1182 }, 1183 { 1184 Query: "USE test2db", 1185 ExpectedErr: sql.ErrDatabaseNotFound, 1186 }, 1187 { 1188 Query: "USE TEST1DB", 1189 Expected: []sql.Row{}, 1190 }, 1191 { 1192 Query: "DROP DATABASE IF EXISTS test1DB", 1193 Expected: []sql.Row{{gmstypes.OkResult{RowsAffected: 1}}}, 1194 }, 1195 { 1196 Query: "USE Test1db", 1197 ExpectedErr: sql.ErrDatabaseNotFound, 1198 }, 1199 }, 1200 }) 1201 }() 1202 1203 t.Skip("Dolt doesn't yet support dropping the primary database, which these tests do") 1204 h := newDoltHarness(t) 1205 defer h.Close() 1206 enginetest.TestDropDatabase(t, h) 1207 } 1208 1209 func TestCreateForeignKeys(t *testing.T) { 1210 h := newDoltHarness(t) 1211 defer h.Close() 1212 enginetest.TestCreateForeignKeys(t, h) 1213 } 1214 1215 func TestDropForeignKeys(t *testing.T) { 1216 h := newDoltHarness(t) 1217 defer h.Close() 1218 enginetest.TestDropForeignKeys(t, h) 1219 } 1220 1221 func TestForeignKeys(t *testing.T) { 1222 h := newDoltHarness(t) 1223 defer h.Close() 1224 enginetest.TestForeignKeys(t, h) 1225 } 1226 1227 func TestForeignKeyBranches(t *testing.T) { 1228 setupPrefix := []string{ 1229 "call dolt_branch('b1')", 1230 "use mydb/b1", 1231 } 1232 assertionsPrefix := []queries.ScriptTestAssertion{ 1233 { 1234 Query: "use mydb/b1", 1235 SkipResultsCheck: true, 1236 }, 1237 } 1238 for _, script := range queries.ForeignKeyTests { 1239 // New harness for every script because we create branches 1240 h := newDoltHarness(t) 1241 h.Setup(setup.MydbData, setup.Parent_childData) 1242 modifiedScript := script 1243 modifiedScript.SetUpScript = append(setupPrefix, modifiedScript.SetUpScript...) 1244 modifiedScript.Assertions = append(assertionsPrefix, modifiedScript.Assertions...) 1245 enginetest.TestScript(t, h, modifiedScript) 1246 } 1247 1248 for _, script := range ForeignKeyBranchTests { 1249 // New harness for every script because we create branches 1250 h := newDoltHarness(t) 1251 h.Setup(setup.MydbData, setup.Parent_childData) 1252 enginetest.TestScript(t, h, script) 1253 } 1254 } 1255 1256 func TestForeignKeyBranchesPrepared(t *testing.T) { 1257 setupPrefix := []string{ 1258 "call dolt_branch('b1')", 1259 "use mydb/b1", 1260 } 1261 assertionsPrefix := []queries.ScriptTestAssertion{ 1262 { 1263 Query: "use mydb/b1", 1264 SkipResultsCheck: true, 1265 }, 1266 } 1267 for _, script := range queries.ForeignKeyTests { 1268 // New harness for every script because we create branches 1269 h := newDoltHarness(t) 1270 h.Setup(setup.MydbData, setup.Parent_childData) 1271 modifiedScript := script 1272 modifiedScript.SetUpScript = append(setupPrefix, modifiedScript.SetUpScript...) 1273 modifiedScript.Assertions = append(assertionsPrefix, modifiedScript.Assertions...) 1274 enginetest.TestScriptPrepared(t, h, modifiedScript) 1275 } 1276 1277 for _, script := range ForeignKeyBranchTests { 1278 // New harness for every script because we create branches 1279 h := newDoltHarness(t) 1280 h.Setup(setup.MydbData, setup.Parent_childData) 1281 enginetest.TestScriptPrepared(t, h, script) 1282 } 1283 } 1284 1285 func TestFulltextIndexes(t *testing.T) { 1286 if !types.IsFormat_DOLT(types.Format_Default) { 1287 t.Skip("FULLTEXT is not supported on the old format") 1288 } 1289 if runtime.GOOS == "windows" && os.Getenv("CI") != "" { 1290 t.Skip("For some reason, this is flaky only on Windows CI.") 1291 } 1292 h := newDoltHarness(t) 1293 defer h.Close() 1294 enginetest.TestFulltextIndexes(t, h) 1295 } 1296 1297 func TestCreateCheckConstraints(t *testing.T) { 1298 h := newDoltHarness(t) 1299 defer h.Close() 1300 enginetest.TestCreateCheckConstraints(t, h) 1301 } 1302 1303 func TestChecksOnInsert(t *testing.T) { 1304 h := newDoltHarness(t) 1305 defer h.Close() 1306 enginetest.TestChecksOnInsert(t, h) 1307 } 1308 1309 func TestChecksOnUpdate(t *testing.T) { 1310 h := newDoltHarness(t) 1311 defer h.Close() 1312 enginetest.TestChecksOnUpdate(t, h) 1313 } 1314 1315 func TestDisallowedCheckConstraints(t *testing.T) { 1316 h := newDoltHarness(t) 1317 defer h.Close() 1318 enginetest.TestDisallowedCheckConstraints(t, h) 1319 } 1320 1321 func TestDropCheckConstraints(t *testing.T) { 1322 h := newDoltHarness(t) 1323 defer h.Close() 1324 enginetest.TestDropCheckConstraints(t, h) 1325 } 1326 1327 func TestReadOnly(t *testing.T) { 1328 h := newDoltHarness(t) 1329 defer h.Close() 1330 enginetest.TestReadOnly(t, h, false /* testStoredProcedures */) 1331 } 1332 1333 func TestViews(t *testing.T) { 1334 h := newDoltHarness(t) 1335 defer h.Close() 1336 enginetest.TestViews(t, h) 1337 } 1338 1339 func TestBranchViews(t *testing.T) { 1340 for _, script := range ViewBranchTests { 1341 func() { 1342 h := newDoltHarness(t) 1343 defer h.Close() 1344 enginetest.TestScript(t, h, script) 1345 }() 1346 } 1347 } 1348 1349 func TestBranchViewsPrepared(t *testing.T) { 1350 for _, script := range ViewBranchTests { 1351 func() { 1352 h := newDoltHarness(t) 1353 defer h.Close() 1354 enginetest.TestScriptPrepared(t, h, script) 1355 }() 1356 } 1357 } 1358 1359 func TestVersionedViews(t *testing.T) { 1360 h := newDoltHarness(t) 1361 defer h.Close() 1362 enginetest.TestVersionedViews(t, h) 1363 } 1364 1365 func TestWindowFunctions(t *testing.T) { 1366 h := newDoltHarness(t) 1367 defer h.Close() 1368 enginetest.TestWindowFunctions(t, h) 1369 } 1370 1371 func TestWindowRowFrames(t *testing.T) { 1372 h := newDoltHarness(t) 1373 defer h.Close() 1374 enginetest.TestWindowRowFrames(t, h) 1375 } 1376 1377 func TestWindowRangeFrames(t *testing.T) { 1378 h := newDoltHarness(t) 1379 defer h.Close() 1380 enginetest.TestWindowRangeFrames(t, h) 1381 } 1382 1383 func TestNamedWindows(t *testing.T) { 1384 h := newDoltHarness(t) 1385 defer h.Close() 1386 enginetest.TestNamedWindows(t, h) 1387 } 1388 1389 func TestNaturalJoin(t *testing.T) { 1390 h := newDoltHarness(t) 1391 defer h.Close() 1392 enginetest.TestNaturalJoin(t, h) 1393 } 1394 1395 func TestNaturalJoinEqual(t *testing.T) { 1396 h := newDoltHarness(t) 1397 defer h.Close() 1398 enginetest.TestNaturalJoinEqual(t, h) 1399 } 1400 1401 func TestNaturalJoinDisjoint(t *testing.T) { 1402 h := newDoltHarness(t) 1403 defer h.Close() 1404 enginetest.TestNaturalJoinEqual(t, h) 1405 } 1406 1407 func TestInnerNestedInNaturalJoins(t *testing.T) { 1408 h := newDoltHarness(t) 1409 defer h.Close() 1410 enginetest.TestInnerNestedInNaturalJoins(t, h) 1411 } 1412 1413 func TestColumnDefaults(t *testing.T) { 1414 h := newDoltHarness(t) 1415 defer h.Close() 1416 enginetest.TestColumnDefaults(t, h) 1417 } 1418 1419 func TestOnUpdateExprScripts(t *testing.T) { 1420 h := newDoltHarness(t) 1421 defer h.Close() 1422 enginetest.TestOnUpdateExprScripts(t, h) 1423 } 1424 1425 func TestAlterTable(t *testing.T) { 1426 // This is a newly added test in GMS that dolt doesn't support yet 1427 h := newDoltHarness(t).WithSkippedQueries([]string{"ALTER TABLE t42 ADD COLUMN s varchar(20), drop check check1"}) 1428 defer h.Close() 1429 enginetest.TestAlterTable(t, h) 1430 } 1431 1432 func TestVariables(t *testing.T) { 1433 h := newDoltHarness(t) 1434 defer h.Close() 1435 enginetest.TestVariables(t, h) 1436 for _, script := range DoltSystemVariables { 1437 enginetest.TestScript(t, h, script) 1438 } 1439 } 1440 1441 func TestVariableErrors(t *testing.T) { 1442 h := newDoltHarness(t) 1443 defer h.Close() 1444 enginetest.TestVariableErrors(t, h) 1445 } 1446 1447 func TestLoadDataPrepared(t *testing.T) { 1448 t.Skip("feature not supported") 1449 skipPreparedTests(t) 1450 h := newDoltHarness(t) 1451 defer h.Close() 1452 enginetest.TestLoadDataPrepared(t, h) 1453 } 1454 1455 func TestLoadData(t *testing.T) { 1456 t.Skip() 1457 h := newDoltHarness(t) 1458 defer h.Close() 1459 enginetest.TestLoadData(t, h) 1460 } 1461 1462 func TestLoadDataErrors(t *testing.T) { 1463 t.Skip() 1464 h := newDoltHarness(t) 1465 defer h.Close() 1466 enginetest.TestLoadDataErrors(t, h) 1467 } 1468 1469 func TestSelectIntoFile(t *testing.T) { 1470 h := newDoltHarness(t) 1471 defer h.Close() 1472 enginetest.TestSelectIntoFile(t, h) 1473 } 1474 1475 func TestJsonScripts(t *testing.T) { 1476 h := newDoltHarness(t) 1477 defer h.Close() 1478 skippedTests := []string{ 1479 "round-trip into table", // The current Dolt JSON format does not preserve decimals and unsigneds in JSON. 1480 } 1481 enginetest.TestJsonScripts(t, h, skippedTests) 1482 } 1483 1484 func TestTriggers(t *testing.T) { 1485 h := newDoltHarness(t) 1486 defer h.Close() 1487 enginetest.TestTriggers(t, h) 1488 } 1489 1490 func TestRollbackTriggers(t *testing.T) { 1491 h := newDoltHarness(t) 1492 defer h.Close() 1493 enginetest.TestRollbackTriggers(t, h) 1494 } 1495 1496 func TestStoredProcedures(t *testing.T) { 1497 tests := make([]queries.ScriptTest, 0, len(queries.ProcedureLogicTests)) 1498 for _, test := range queries.ProcedureLogicTests { 1499 //TODO: this passes locally but SOMETIMES fails tests on GitHub, no clue why 1500 if test.Name != "ITERATE and LEAVE loops" { 1501 tests = append(tests, test) 1502 } 1503 } 1504 queries.ProcedureLogicTests = tests 1505 1506 h := newDoltHarness(t) 1507 defer h.Close() 1508 enginetest.TestStoredProcedures(t, h) 1509 } 1510 1511 func TestDoltStoredProcedures(t *testing.T) { 1512 for _, script := range DoltProcedureTests { 1513 func() { 1514 h := newDoltHarness(t) 1515 defer h.Close() 1516 enginetest.TestScript(t, h, script) 1517 }() 1518 } 1519 } 1520 1521 func TestDoltStoredProceduresPrepared(t *testing.T) { 1522 for _, script := range DoltProcedureTests { 1523 func() { 1524 h := newDoltHarness(t) 1525 defer h.Close() 1526 enginetest.TestScriptPrepared(t, h, script) 1527 }() 1528 } 1529 } 1530 1531 func TestEvents(t *testing.T) { 1532 doltHarness := newDoltHarness(t) 1533 defer doltHarness.Close() 1534 enginetest.TestEvents(t, doltHarness) 1535 } 1536 1537 func TestCallAsOf(t *testing.T) { 1538 for _, script := range DoltCallAsOf { 1539 func() { 1540 h := newDoltHarness(t) 1541 defer h.Close() 1542 enginetest.TestScript(t, h, script) 1543 }() 1544 } 1545 } 1546 1547 func TestLargeJsonObjects(t *testing.T) { 1548 SkipByDefaultInCI(t) 1549 harness := newDoltHarness(t) 1550 defer harness.Close() 1551 for _, script := range LargeJsonObjectScriptTests { 1552 enginetest.TestScript(t, harness, script) 1553 } 1554 } 1555 1556 func SkipByDefaultInCI(t *testing.T) { 1557 if os.Getenv("CI") != "" && os.Getenv("DOLT_TEST_RUN_NON_RACE_TESTS") == "" { 1558 t.Skip() 1559 } 1560 } 1561 1562 func TestTransactions(t *testing.T) { 1563 for _, script := range queries.TransactionTests { 1564 func() { 1565 h := newDoltHarness(t) 1566 defer h.Close() 1567 enginetest.TestTransactionScript(t, h, script) 1568 }() 1569 } 1570 for _, script := range DoltTransactionTests { 1571 func() { 1572 h := newDoltHarness(t) 1573 defer h.Close() 1574 enginetest.TestTransactionScript(t, h, script) 1575 }() 1576 } 1577 for _, script := range DoltStoredProcedureTransactionTests { 1578 func() { 1579 h := newDoltHarness(t) 1580 defer h.Close() 1581 enginetest.TestTransactionScript(t, h, script) 1582 }() 1583 } 1584 for _, script := range DoltConflictHandlingTests { 1585 func() { 1586 h := newDoltHarness(t) 1587 defer h.Close() 1588 enginetest.TestTransactionScript(t, h, script) 1589 }() 1590 } 1591 for _, script := range DoltConstraintViolationTransactionTests { 1592 func() { 1593 h := newDoltHarness(t) 1594 defer h.Close() 1595 enginetest.TestTransactionScript(t, h, script) 1596 }() 1597 } 1598 } 1599 1600 func TestBranchTransactions(t *testing.T) { 1601 for _, script := range BranchIsolationTests { 1602 func() { 1603 h := newDoltHarness(t) 1604 defer h.Close() 1605 enginetest.TestTransactionScript(t, h, script) 1606 }() 1607 } 1608 } 1609 1610 func TestMultiDbTransactions(t *testing.T) { 1611 for _, script := range MultiDbTransactionTests { 1612 func() { 1613 h := newDoltHarness(t) 1614 defer h.Close() 1615 enginetest.TestScript(t, h, script) 1616 }() 1617 } 1618 1619 for _, script := range MultiDbSavepointTests { 1620 func() { 1621 h := newDoltHarness(t) 1622 defer h.Close() 1623 enginetest.TestTransactionScript(t, h, script) 1624 }() 1625 } 1626 } 1627 1628 func TestMultiDbTransactionsPrepared(t *testing.T) { 1629 for _, script := range MultiDbTransactionTests { 1630 func() { 1631 h := newDoltHarness(t) 1632 defer h.Close() 1633 enginetest.TestScriptPrepared(t, h, script) 1634 }() 1635 } 1636 } 1637 1638 func TestConcurrentTransactions(t *testing.T) { 1639 h := newDoltHarness(t) 1640 defer h.Close() 1641 enginetest.TestConcurrentTransactions(t, h) 1642 } 1643 1644 func TestDoltScripts(t *testing.T) { 1645 harness := newDoltHarness(t) 1646 defer harness.Close() 1647 for _, script := range DoltScripts { 1648 enginetest.TestScript(t, harness, script) 1649 } 1650 } 1651 1652 func TestDoltRevisionDbScripts(t *testing.T) { 1653 for _, script := range DoltRevisionDbScripts { 1654 func() { 1655 h := newDoltHarness(t) 1656 defer h.Close() 1657 enginetest.TestScript(t, h, script) 1658 }() 1659 } 1660 1661 // Testing a commit-qualified database revision spec requires 1662 // a little extra work to get the generated commit hash 1663 harness := newDoltHarness(t) 1664 defer harness.Close() 1665 e, err := harness.NewEngine(t) 1666 require.NoError(t, err) 1667 defer e.Close() 1668 ctx := harness.NewContext() 1669 1670 setupScripts := []setup.SetupScript{ 1671 {"create table t01 (pk int primary key, c1 int)"}, 1672 {"call dolt_add('.');"}, 1673 {"call dolt_commit('-am', 'creating table t01 on main');"}, 1674 {"insert into t01 values (1, 1), (2, 2);"}, 1675 {"call dolt_commit('-am', 'adding rows to table t01 on main');"}, 1676 {"insert into t01 values (3, 3);"}, 1677 {"call dolt_commit('-am', 'adding another row to table t01 on main');"}, 1678 } 1679 _, err = enginetest.RunSetupScripts(ctx, harness.engine, setupScripts, true) 1680 require.NoError(t, err) 1681 1682 _, iter, err := harness.engine.Query(ctx, "select hashof('HEAD~2');") 1683 require.NoError(t, err) 1684 rows, err := sql.RowIterToRows(ctx, iter) 1685 require.NoError(t, err) 1686 assert.Equal(t, 1, len(rows)) 1687 commithash := rows[0][0].(string) 1688 1689 scriptTest := queries.ScriptTest{ 1690 Name: "database revision specs: commit-qualified revision spec", 1691 Assertions: []queries.ScriptTestAssertion{ 1692 { 1693 Query: "show databases;", 1694 Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, 1695 }, 1696 { 1697 Query: "use mydb/" + commithash, 1698 Expected: []sql.Row{}, 1699 }, 1700 { 1701 Query: "select active_branch();", 1702 Expected: []sql.Row{ 1703 {nil}, 1704 }, 1705 }, 1706 { 1707 Query: "select database();", 1708 Expected: []sql.Row{{"mydb/" + commithash}}, 1709 }, 1710 { 1711 Query: "show databases;", 1712 Expected: []sql.Row{{"mydb"}, {"mydb/" + commithash}, {"information_schema"}, {"mysql"}}, 1713 }, 1714 { 1715 Query: "select * from t01", 1716 Expected: []sql.Row{}, 1717 }, 1718 { 1719 Query: "call dolt_reset();", 1720 ExpectedErrStr: "unable to reset HEAD in read-only databases", 1721 }, 1722 { 1723 Query: "call dolt_checkout('main');", 1724 Expected: []sql.Row{{0, "Switched to branch 'main'"}}, 1725 }, 1726 { 1727 Query: "select database();", 1728 Expected: []sql.Row{{"mydb"}}, 1729 }, 1730 { 1731 Query: "select active_branch();", 1732 Expected: []sql.Row{{"main"}}, 1733 }, 1734 { 1735 Query: "use mydb;", 1736 Expected: []sql.Row{}, 1737 }, 1738 { 1739 Query: "select database();", 1740 Expected: []sql.Row{{"mydb"}}, 1741 }, 1742 { 1743 Query: "show databases;", 1744 Expected: []sql.Row{{"mydb"}, {"information_schema"}, {"mysql"}}, 1745 }, 1746 }, 1747 } 1748 1749 enginetest.TestScript(t, harness, scriptTest) 1750 } 1751 1752 func TestDoltRevisionDbScriptsPrepared(t *testing.T) { 1753 for _, script := range DoltRevisionDbScripts { 1754 func() { 1755 h := newDoltHarness(t) 1756 defer h.Close() 1757 enginetest.TestScriptPrepared(t, h, script) 1758 }() 1759 } 1760 } 1761 1762 func TestDoltDdlScripts(t *testing.T) { 1763 harness := newDoltHarness(t) 1764 defer harness.Close() 1765 harness.Setup() 1766 1767 for _, script := range ModifyAndChangeColumnScripts { 1768 e, err := harness.NewEngine(t) 1769 require.NoError(t, err) 1770 enginetest.TestScriptWithEngine(t, e, harness, script) 1771 } 1772 1773 for _, script := range ModifyColumnTypeScripts { 1774 e, err := harness.NewEngine(t) 1775 require.NoError(t, err) 1776 enginetest.TestScriptWithEngine(t, e, harness, script) 1777 } 1778 1779 for _, script := range DropColumnScripts { 1780 e, err := harness.NewEngine(t) 1781 require.NoError(t, err) 1782 enginetest.TestScriptWithEngine(t, e, harness, script) 1783 } 1784 if !types.IsFormat_DOLT(types.Format_Default) { 1785 t.Skip("not fixing unique index on keyless tables for old format") 1786 } 1787 for _, script := range AddIndexScripts { 1788 e, err := harness.NewEngine(t) 1789 require.NoError(t, err) 1790 enginetest.TestScriptWithEngine(t, e, harness, script) 1791 } 1792 1793 // TODO: these scripts should be general enough to go in GMS 1794 for _, script := range AddDropPrimaryKeysScripts { 1795 e, err := harness.NewEngine(t) 1796 require.NoError(t, err) 1797 enginetest.TestScriptWithEngine(t, e, harness, script) 1798 } 1799 } 1800 1801 func TestBrokenDdlScripts(t *testing.T) { 1802 for _, script := range BrokenDDLScripts { 1803 t.Skip(script.Name) 1804 } 1805 } 1806 1807 func TestDescribeTableAsOf(t *testing.T) { 1808 h := newDoltHarness(t) 1809 defer h.Close() 1810 enginetest.TestScript(t, h, DescribeTableAsOfScriptTest) 1811 } 1812 1813 func TestShowCreateTable(t *testing.T) { 1814 for _, script := range ShowCreateTableScriptTests { 1815 func() { 1816 h := newDoltHarness(t) 1817 defer h.Close() 1818 enginetest.TestScript(t, h, script) 1819 }() 1820 } 1821 } 1822 1823 func TestShowCreateTablePrepared(t *testing.T) { 1824 for _, script := range ShowCreateTableScriptTests { 1825 func() { 1826 h := newDoltHarness(t) 1827 defer h.Close() 1828 enginetest.TestScriptPrepared(t, h, script) 1829 }() 1830 } 1831 } 1832 1833 func TestViewsWithAsOf(t *testing.T) { 1834 h := newDoltHarness(t) 1835 defer h.Close() 1836 enginetest.TestScript(t, h, ViewsWithAsOfScriptTest) 1837 } 1838 1839 func TestViewsWithAsOfPrepared(t *testing.T) { 1840 skipPreparedTests(t) 1841 h := newDoltHarness(t) 1842 defer h.Close() 1843 enginetest.TestScriptPrepared(t, h, ViewsWithAsOfScriptTest) 1844 } 1845 1846 func TestDoltMerge(t *testing.T) { 1847 for _, script := range MergeScripts { 1848 // harness can't reset effectively when there are new commits / branches created, so use a new harness for 1849 // each script 1850 func() { 1851 h := newDoltHarness(t) 1852 defer h.Close() 1853 h.Setup(setup.MydbData) 1854 enginetest.TestScript(t, h, script) 1855 }() 1856 } 1857 } 1858 1859 func TestDoltRebase(t *testing.T) { 1860 for _, script := range DoltRebaseScriptTests { 1861 func() { 1862 h := newDoltHarness(t) 1863 defer h.Close() 1864 h.skipSetupCommit = true 1865 enginetest.TestScript(t, h, script) 1866 }() 1867 } 1868 1869 testMultiSessionScriptTests(t, DoltRebaseMultiSessionScriptTests) 1870 } 1871 1872 func TestDoltRebasePrepared(t *testing.T) { 1873 for _, script := range DoltRebaseScriptTests { 1874 func() { 1875 h := newDoltHarness(t) 1876 defer h.Close() 1877 h.skipSetupCommit = true 1878 enginetest.TestScriptPrepared(t, h, script) 1879 }() 1880 } 1881 } 1882 1883 func TestDoltMergePrepared(t *testing.T) { 1884 for _, script := range MergeScripts { 1885 // harness can't reset effectively when there are new commits / branches created, so use a new harness for 1886 // each script 1887 func() { 1888 h := newDoltHarness(t) 1889 defer h.Close() 1890 enginetest.TestScriptPrepared(t, h, script) 1891 }() 1892 } 1893 } 1894 1895 func TestDoltRevert(t *testing.T) { 1896 for _, script := range RevertScripts { 1897 // harness can't reset effectively. Use a new harness for each script 1898 func() { 1899 h := newDoltHarness(t) 1900 defer h.Close() 1901 enginetest.TestScript(t, h, script) 1902 }() 1903 } 1904 } 1905 1906 func TestDoltRevertPrepared(t *testing.T) { 1907 for _, script := range RevertScripts { 1908 // harness can't reset effectively. Use a new harness for each script 1909 func() { 1910 h := newDoltHarness(t) 1911 defer h.Close() 1912 enginetest.TestScriptPrepared(t, h, script) 1913 }() 1914 } 1915 } 1916 1917 func TestDoltAutoIncrement(t *testing.T) { 1918 for _, script := range DoltAutoIncrementTests { 1919 // doing commits on different branches is antagonistic to engine reuse, use a new engine on each script 1920 func() { 1921 h := newDoltHarness(t) 1922 defer h.Close() 1923 enginetest.TestScript(t, h, script) 1924 }() 1925 } 1926 } 1927 1928 func TestDoltAutoIncrementPrepared(t *testing.T) { 1929 for _, script := range DoltAutoIncrementTests { 1930 // doing commits on different branches is antagonistic to engine reuse, use a new engine on each script 1931 func() { 1932 h := newDoltHarness(t) 1933 defer h.Close() 1934 enginetest.TestScriptPrepared(t, h, script) 1935 }() 1936 } 1937 } 1938 1939 func TestDoltConflictsTableNameTable(t *testing.T) { 1940 for _, script := range DoltConflictTableNameTableTests { 1941 func() { 1942 h := newDoltHarness(t) 1943 defer h.Close() 1944 enginetest.TestScript(t, h, script) 1945 }() 1946 } 1947 1948 if types.IsFormat_DOLT(types.Format_Default) { 1949 for _, script := range Dolt1ConflictTableNameTableTests { 1950 func() { 1951 h := newDoltHarness(t) 1952 defer h.Close() 1953 enginetest.TestScript(t, h, script) 1954 }() 1955 } 1956 } 1957 } 1958 1959 // tests new format behavior for keyless merges that create CVs and conflicts 1960 func TestKeylessDoltMergeCVsAndConflicts(t *testing.T) { 1961 if !types.IsFormat_DOLT(types.Format_Default) { 1962 t.Skip() 1963 } 1964 for _, script := range KeylessMergeCVsAndConflictsScripts { 1965 func() { 1966 h := newDoltHarness(t) 1967 defer h.Close() 1968 enginetest.TestScript(t, h, script) 1969 }() 1970 } 1971 } 1972 1973 // eventually this will be part of TestDoltMerge 1974 func TestDoltMergeArtifacts(t *testing.T) { 1975 for _, script := range MergeArtifactsScripts { 1976 func() { 1977 h := newDoltHarness(t) 1978 defer h.Close() 1979 enginetest.TestScript(t, h, script) 1980 }() 1981 } 1982 for _, script := range SchemaConflictScripts { 1983 h := newDoltHarness(t) 1984 enginetest.TestScript(t, h, script) 1985 h.Close() 1986 } 1987 } 1988 1989 // these tests are temporary while there is a difference between the old format 1990 // and new format merge behaviors. 1991 func TestOldFormatMergeConflictsAndCVs(t *testing.T) { 1992 if types.IsFormat_DOLT(types.Format_Default) { 1993 t.Skip() 1994 } 1995 for _, script := range OldFormatMergeConflictsAndCVsScripts { 1996 func() { 1997 h := newDoltHarness(t) 1998 defer h.Close() 1999 enginetest.TestScript(t, h, script) 2000 }() 2001 } 2002 } 2003 2004 func TestDoltReset(t *testing.T) { 2005 for _, script := range DoltReset { 2006 // dolt versioning conflicts with reset harness -- use new harness every time 2007 func() { 2008 h := newDoltHarness(t) 2009 defer h.Close() 2010 enginetest.TestScript(t, h, script) 2011 }() 2012 } 2013 } 2014 2015 func TestDoltGC(t *testing.T) { 2016 t.SkipNow() 2017 for _, script := range DoltGC { 2018 func() { 2019 h := newDoltHarness(t) 2020 defer h.Close() 2021 enginetest.TestScript(t, h, script) 2022 }() 2023 } 2024 } 2025 2026 func TestDoltCheckout(t *testing.T) { 2027 for _, script := range DoltCheckoutScripts { 2028 func() { 2029 h := newDoltHarness(t) 2030 defer h.Close() 2031 enginetest.TestScript(t, h, script) 2032 }() 2033 } 2034 2035 h := newDoltHarness(t) 2036 defer h.Close() 2037 engine, err := h.NewEngine(t) 2038 require.NoError(t, err) 2039 readOnlyEngine, err := h.NewReadOnlyEngine(engine.EngineAnalyzer().Catalog.DbProvider) 2040 require.NoError(t, err) 2041 2042 for _, script := range DoltCheckoutReadOnlyScripts { 2043 enginetest.TestScriptWithEngine(t, readOnlyEngine, h, script) 2044 } 2045 } 2046 2047 func TestDoltCheckoutPrepared(t *testing.T) { 2048 for _, script := range DoltCheckoutScripts { 2049 func() { 2050 h := newDoltHarness(t) 2051 defer h.Close() 2052 enginetest.TestScriptPrepared(t, h, script) 2053 }() 2054 } 2055 2056 h := newDoltHarness(t) 2057 defer h.Close() 2058 engine, err := h.NewEngine(t) 2059 require.NoError(t, err) 2060 readOnlyEngine, err := h.NewReadOnlyEngine(engine.EngineAnalyzer().Catalog.DbProvider) 2061 require.NoError(t, err) 2062 2063 for _, script := range DoltCheckoutReadOnlyScripts { 2064 enginetest.TestScriptWithEnginePrepared(t, readOnlyEngine, h, script) 2065 } 2066 } 2067 2068 func TestDoltBranch(t *testing.T) { 2069 for _, script := range DoltBranchScripts { 2070 func() { 2071 h := newDoltHarness(t) 2072 defer h.Close() 2073 enginetest.TestScript(t, h, script) 2074 }() 2075 } 2076 } 2077 2078 func TestDoltTag(t *testing.T) { 2079 for _, script := range DoltTagTestScripts { 2080 func() { 2081 h := newDoltHarness(t) 2082 defer h.Close() 2083 enginetest.TestScript(t, h, script) 2084 }() 2085 } 2086 } 2087 2088 func TestDoltRemote(t *testing.T) { 2089 for _, script := range DoltRemoteTestScripts { 2090 func() { 2091 h := newDoltHarness(t) 2092 defer h.Close() 2093 enginetest.TestScript(t, h, script) 2094 }() 2095 } 2096 } 2097 2098 func TestDoltUndrop(t *testing.T) { 2099 h := newDoltHarnessForLocalFilesystem(t) 2100 defer h.Close() 2101 for _, script := range DoltUndropTestScripts { 2102 enginetest.TestScript(t, h, script) 2103 } 2104 } 2105 2106 type testCommitClock struct { 2107 unixNano int64 2108 } 2109 2110 func (tcc *testCommitClock) Now() time.Time { 2111 now := time.Unix(0, tcc.unixNano) 2112 tcc.unixNano += int64(time.Hour) 2113 return now 2114 } 2115 2116 func installTestCommitClock(tcc *testCommitClock) func() { 2117 oldNowFunc := datas.CommitterDate 2118 oldCommitLoc := datas.CommitLoc 2119 datas.CommitterDate = tcc.Now 2120 datas.CommitLoc = time.UTC 2121 return func() { 2122 datas.CommitterDate = oldNowFunc 2123 datas.CommitLoc = oldCommitLoc 2124 } 2125 } 2126 2127 // TestSingleTransactionScript is a convenience method for debugging a single transaction test. Unskip and set to the 2128 // desired test. 2129 func TestSingleTransactionScript(t *testing.T) { 2130 t.Skip() 2131 2132 tcc := &testCommitClock{} 2133 cleanup := installTestCommitClock(tcc) 2134 defer cleanup() 2135 2136 sql.RunWithNowFunc(tcc.Now, func() error { 2137 script := queries.TransactionTest{ 2138 Name: "Insert error with auto commit off", 2139 SetUpScript: []string{ 2140 "create table t1 (pk int primary key, val int)", 2141 "insert into t1 values (0,0)", 2142 }, 2143 Assertions: []queries.ScriptTestAssertion{ 2144 { 2145 Query: "/* client a */ set autocommit = off", 2146 SkipResultsCheck: true, 2147 }, 2148 { 2149 Query: "/* client b */ set autocommit = off", 2150 SkipResultsCheck: true, 2151 }, 2152 { 2153 Query: "/* client a */ insert into t1 values (1, 1)", 2154 Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, 2155 }, 2156 { 2157 Query: "/* client a */ insert into t1 values (1, 2)", 2158 ExpectedErr: sql.ErrPrimaryKeyViolation, 2159 }, 2160 { 2161 Query: "/* client a */ insert into t1 values (2, 2)", 2162 Expected: []sql.Row{{gmstypes.NewOkResult(1)}}, 2163 }, 2164 { 2165 Query: "/* client a */ select * from t1 order by pk", 2166 Expected: []sql.Row{{0, 0}, {1, 1}, {2, 2}}, 2167 }, 2168 { 2169 Query: "/* client b */ select * from t1 order by pk", 2170 Expected: []sql.Row{{0, 0}}, 2171 }, 2172 { 2173 Query: "/* client a */ commit", 2174 SkipResultsCheck: true, 2175 }, 2176 { 2177 Query: "/* client b */ start transaction", 2178 SkipResultsCheck: true, 2179 }, 2180 { 2181 Query: "/* client b */ select * from t1 order by pk", 2182 Expected: []sql.Row{{0, 0}, {1, 1}, {2, 2}}, 2183 }, 2184 { 2185 Query: "/* client a */ select * from t1 order by pk", 2186 Expected: []sql.Row{{0, 0}, {1, 1}, {2, 2}}, 2187 }, 2188 }, 2189 } 2190 2191 h := newDoltHarness(t) 2192 defer h.Close() 2193 enginetest.TestTransactionScript(t, h, script) 2194 2195 return nil 2196 }) 2197 } 2198 2199 func TestBrokenSystemTableQueries(t *testing.T) { 2200 t.Skip() 2201 2202 h := newDoltHarness(t) 2203 defer h.Close() 2204 enginetest.RunQueryTests(t, h, BrokenSystemTableQueries) 2205 } 2206 2207 func TestHistorySystemTable(t *testing.T) { 2208 harness := newDoltHarness(t).WithParallelism(2) 2209 defer harness.Close() 2210 harness.Setup(setup.MydbData) 2211 for _, test := range HistorySystemTableScriptTests { 2212 harness.engine = nil 2213 t.Run(test.Name, func(t *testing.T) { 2214 enginetest.TestScript(t, harness, test) 2215 }) 2216 } 2217 } 2218 2219 func TestHistorySystemTablePrepared(t *testing.T) { 2220 harness := newDoltHarness(t).WithParallelism(2) 2221 defer harness.Close() 2222 harness.Setup(setup.MydbData) 2223 for _, test := range HistorySystemTableScriptTests { 2224 harness.engine = nil 2225 t.Run(test.Name, func(t *testing.T) { 2226 enginetest.TestScriptPrepared(t, harness, test) 2227 }) 2228 } 2229 } 2230 2231 func TestBrokenHistorySystemTablePrepared(t *testing.T) { 2232 t.Skip() 2233 harness := newDoltHarness(t) 2234 defer harness.Close() 2235 harness.Setup(setup.MydbData) 2236 for _, test := range BrokenHistorySystemTableScriptTests { 2237 harness.engine = nil 2238 t.Run(test.Name, func(t *testing.T) { 2239 enginetest.TestScriptPrepared(t, harness, test) 2240 }) 2241 } 2242 } 2243 2244 func TestUnscopedDiffSystemTable(t *testing.T) { 2245 for _, test := range UnscopedDiffSystemTableScriptTests { 2246 t.Run(test.Name, func(t *testing.T) { 2247 h := newDoltHarness(t) 2248 defer h.Close() 2249 enginetest.TestScript(t, h, test) 2250 }) 2251 } 2252 } 2253 2254 func TestUnscopedDiffSystemTablePrepared(t *testing.T) { 2255 for _, test := range UnscopedDiffSystemTableScriptTests { 2256 t.Run(test.Name, func(t *testing.T) { 2257 h := newDoltHarness(t) 2258 defer h.Close() 2259 enginetest.TestScriptPrepared(t, h, test) 2260 }) 2261 } 2262 } 2263 2264 func TestColumnDiffSystemTable(t *testing.T) { 2265 if !types.IsFormat_DOLT(types.Format_Default) { 2266 t.Skip("correct behavior of dolt_column_diff only guaranteed on new format") 2267 } 2268 for _, test := range ColumnDiffSystemTableScriptTests { 2269 t.Run(test.Name, func(t *testing.T) { 2270 enginetest.TestScript(t, newDoltHarness(t), test) 2271 }) 2272 } 2273 } 2274 2275 func TestColumnDiffSystemTablePrepared(t *testing.T) { 2276 if !types.IsFormat_DOLT(types.Format_Default) { 2277 t.Skip("correct behavior of dolt_column_diff only guaranteed on new format") 2278 } 2279 for _, test := range ColumnDiffSystemTableScriptTests { 2280 t.Run(test.Name, func(t *testing.T) { 2281 enginetest.TestScriptPrepared(t, newDoltHarness(t), test) 2282 }) 2283 } 2284 } 2285 2286 func TestStatBranchTests(t *testing.T) { 2287 harness := newDoltHarness(t) 2288 defer harness.Close() 2289 harness.Setup(setup.MydbData) 2290 harness.configureStats = true 2291 for _, test := range StatBranchTests { 2292 t.Run(test.Name, func(t *testing.T) { 2293 // reset engine so provider statistics are clean 2294 harness.engine = nil 2295 e := mustNewEngine(t, harness) 2296 defer e.Close() 2297 enginetest.TestScriptWithEngine(t, e, harness, test) 2298 }) 2299 } 2300 } 2301 2302 func TestStatsFunctions(t *testing.T) { 2303 harness := newDoltHarness(t) 2304 defer harness.Close() 2305 harness.Setup(setup.MydbData) 2306 harness.configureStats = true 2307 harness.skipSetupCommit = true 2308 for _, test := range StatProcTests { 2309 t.Run(test.Name, func(t *testing.T) { 2310 // reset engine so provider statistics are clean 2311 harness.engine = nil 2312 e := mustNewEngine(t, harness) 2313 defer e.Close() 2314 enginetest.TestScriptWithEngine(t, e, harness, test) 2315 }) 2316 } 2317 } 2318 2319 func TestDiffTableFunction(t *testing.T) { 2320 harness := newDoltHarness(t) 2321 defer harness.Close() 2322 harness.Setup(setup.MydbData) 2323 for _, test := range DiffTableFunctionScriptTests { 2324 harness.engine = nil 2325 t.Run(test.Name, func(t *testing.T) { 2326 enginetest.TestScript(t, harness, test) 2327 }) 2328 } 2329 } 2330 2331 func TestDiffTableFunctionPrepared(t *testing.T) { 2332 harness := newDoltHarness(t) 2333 defer harness.Close() 2334 harness.Setup(setup.MydbData) 2335 for _, test := range DiffTableFunctionScriptTests { 2336 harness.engine = nil 2337 t.Run(test.Name, func(t *testing.T) { 2338 enginetest.TestScriptPrepared(t, harness, test) 2339 }) 2340 } 2341 } 2342 2343 func TestDiffStatTableFunction(t *testing.T) { 2344 harness := newDoltHarness(t) 2345 harness.Setup(setup.MydbData) 2346 for _, test := range DiffStatTableFunctionScriptTests { 2347 harness.engine = nil 2348 t.Run(test.Name, func(t *testing.T) { 2349 enginetest.TestScript(t, harness, test) 2350 }) 2351 } 2352 } 2353 2354 func TestDiffStatTableFunctionPrepared(t *testing.T) { 2355 harness := newDoltHarness(t) 2356 harness.Setup(setup.MydbData) 2357 for _, test := range DiffStatTableFunctionScriptTests { 2358 harness.engine = nil 2359 t.Run(test.Name, func(t *testing.T) { 2360 enginetest.TestScriptPrepared(t, harness, test) 2361 }) 2362 } 2363 } 2364 2365 func TestDiffSummaryTableFunction(t *testing.T) { 2366 harness := newDoltHarness(t) 2367 defer harness.Close() 2368 harness.Setup(setup.MydbData) 2369 for _, test := range DiffSummaryTableFunctionScriptTests { 2370 harness.engine = nil 2371 t.Run(test.Name, func(t *testing.T) { 2372 enginetest.TestScript(t, harness, test) 2373 }) 2374 } 2375 } 2376 2377 func TestDiffSummaryTableFunctionPrepared(t *testing.T) { 2378 harness := newDoltHarness(t) 2379 defer harness.Close() 2380 harness.Setup(setup.MydbData) 2381 for _, test := range DiffSummaryTableFunctionScriptTests { 2382 harness.engine = nil 2383 t.Run(test.Name, func(t *testing.T) { 2384 enginetest.TestScriptPrepared(t, harness, test) 2385 }) 2386 } 2387 } 2388 2389 func TestPatchTableFunction(t *testing.T) { 2390 harness := newDoltHarness(t) 2391 harness.Setup(setup.MydbData) 2392 for _, test := range PatchTableFunctionScriptTests { 2393 harness.engine = nil 2394 t.Run(test.Name, func(t *testing.T) { 2395 enginetest.TestScript(t, harness, test) 2396 }) 2397 } 2398 } 2399 2400 func TestPatchTableFunctionPrepared(t *testing.T) { 2401 harness := newDoltHarness(t) 2402 harness.Setup(setup.MydbData) 2403 for _, test := range PatchTableFunctionScriptTests { 2404 harness.engine = nil 2405 t.Run(test.Name, func(t *testing.T) { 2406 enginetest.TestScriptPrepared(t, harness, test) 2407 }) 2408 } 2409 } 2410 2411 func TestLogTableFunction(t *testing.T) { 2412 harness := newDoltHarness(t) 2413 defer harness.Close() 2414 harness.Setup(setup.MydbData) 2415 for _, test := range LogTableFunctionScriptTests { 2416 harness.engine = nil 2417 harness.skipSetupCommit = true 2418 t.Run(test.Name, func(t *testing.T) { 2419 enginetest.TestScript(t, harness, test) 2420 }) 2421 } 2422 } 2423 2424 func TestLogTableFunctionPrepared(t *testing.T) { 2425 harness := newDoltHarness(t) 2426 defer harness.Close() 2427 harness.Setup(setup.MydbData) 2428 for _, test := range LogTableFunctionScriptTests { 2429 harness.engine = nil 2430 harness.skipSetupCommit = true 2431 t.Run(test.Name, func(t *testing.T) { 2432 enginetest.TestScriptPrepared(t, harness, test) 2433 }) 2434 } 2435 } 2436 2437 func TestDoltReflog(t *testing.T) { 2438 for _, script := range DoltReflogTestScripts { 2439 h := newDoltHarnessForLocalFilesystem(t) 2440 h.SkipSetupCommit() 2441 enginetest.TestScript(t, h, script) 2442 h.Close() 2443 } 2444 } 2445 2446 func TestDoltReflogPrepared(t *testing.T) { 2447 for _, script := range DoltReflogTestScripts { 2448 h := newDoltHarnessForLocalFilesystem(t) 2449 h.SkipSetupCommit() 2450 enginetest.TestScriptPrepared(t, h, script) 2451 h.Close() 2452 } 2453 } 2454 2455 func TestCommitDiffSystemTable(t *testing.T) { 2456 harness := newDoltHarness(t) 2457 defer harness.Close() 2458 harness.Setup(setup.MydbData) 2459 for _, test := range CommitDiffSystemTableScriptTests { 2460 harness.engine = nil 2461 t.Run(test.Name, func(t *testing.T) { 2462 enginetest.TestScript(t, harness, test) 2463 }) 2464 } 2465 } 2466 2467 func TestCommitDiffSystemTablePrepared(t *testing.T) { 2468 harness := newDoltHarness(t) 2469 defer harness.Close() 2470 harness.Setup(setup.MydbData) 2471 for _, test := range CommitDiffSystemTableScriptTests { 2472 harness.engine = nil 2473 t.Run(test.Name, func(t *testing.T) { 2474 enginetest.TestScriptPrepared(t, harness, test) 2475 }) 2476 } 2477 } 2478 2479 func TestDiffSystemTable(t *testing.T) { 2480 if !types.IsFormat_DOLT(types.Format_Default) { 2481 t.Skip("only new format support system table indexing") 2482 } 2483 2484 harness := newDoltHarness(t) 2485 defer harness.Close() 2486 harness.Setup(setup.MydbData) 2487 for _, test := range DiffSystemTableScriptTests { 2488 harness.engine = nil 2489 t.Run(test.Name, func(t *testing.T) { 2490 enginetest.TestScript(t, harness, test) 2491 }) 2492 } 2493 2494 if types.IsFormat_DOLT(types.Format_Default) { 2495 for _, test := range Dolt1DiffSystemTableScripts { 2496 func() { 2497 h := newDoltHarness(t) 2498 defer h.Close() 2499 enginetest.TestScript(t, h, test) 2500 }() 2501 } 2502 } 2503 } 2504 2505 func TestDiffSystemTablePrepared(t *testing.T) { 2506 if !types.IsFormat_DOLT(types.Format_Default) { 2507 t.Skip("only new format support system table indexing") 2508 } 2509 2510 harness := newDoltHarness(t) 2511 defer harness.Close() 2512 harness.Setup(setup.MydbData) 2513 for _, test := range DiffSystemTableScriptTests { 2514 harness.engine = nil 2515 t.Run(test.Name, func(t *testing.T) { 2516 enginetest.TestScriptPrepared(t, harness, test) 2517 }) 2518 } 2519 2520 if types.IsFormat_DOLT(types.Format_Default) { 2521 for _, test := range Dolt1DiffSystemTableScripts { 2522 func() { 2523 h := newDoltHarness(t) 2524 defer h.Close() 2525 enginetest.TestScriptPrepared(t, h, test) 2526 }() 2527 } 2528 } 2529 } 2530 2531 func TestSchemaDiffTableFunction(t *testing.T) { 2532 harness := newDoltHarness(t) 2533 defer harness.Close() 2534 harness.Setup(setup.MydbData) 2535 for _, test := range SchemaDiffTableFunctionScriptTests { 2536 harness.engine = nil 2537 t.Run(test.Name, func(t *testing.T) { 2538 enginetest.TestScript(t, harness, test) 2539 }) 2540 } 2541 } 2542 2543 func TestSchemaDiffTableFunctionPrepared(t *testing.T) { 2544 harness := newDoltHarness(t) 2545 defer harness.Close() 2546 harness.Setup(setup.MydbData) 2547 for _, test := range SchemaDiffTableFunctionScriptTests { 2548 harness.engine = nil 2549 t.Run(test.Name, func(t *testing.T) { 2550 enginetest.TestScriptPrepared(t, harness, test) 2551 }) 2552 } 2553 } 2554 2555 func TestDoltDatabaseCollationDiffs(t *testing.T) { 2556 harness := newDoltHarness(t) 2557 defer harness.Close() 2558 harness.Setup(setup.MydbData) 2559 for _, test := range DoltDatabaseCollationScriptTests { 2560 harness.engine = nil 2561 t.Run(test.Name, func(t *testing.T) { 2562 enginetest.TestScriptPrepared(t, harness, test) 2563 }) 2564 } 2565 } 2566 2567 func TestQueryDiff(t *testing.T) { 2568 harness := newDoltHarness(t) 2569 defer harness.Close() 2570 harness.Setup(setup.MydbData) 2571 for _, test := range QueryDiffTableScriptTests { 2572 harness.engine = nil 2573 t.Run(test.Name, func(t *testing.T) { 2574 enginetest.TestScript(t, harness, test) 2575 }) 2576 } 2577 } 2578 2579 func mustNewEngine(t *testing.T, h enginetest.Harness) enginetest.QueryEngine { 2580 e, err := h.NewEngine(t) 2581 if err != nil { 2582 require.NoError(t, err) 2583 } 2584 return e 2585 } 2586 2587 var biasedCosters = []memo.Coster{ 2588 memo.NewInnerBiasedCoster(), 2589 memo.NewLookupBiasedCoster(), 2590 memo.NewHashBiasedCoster(), 2591 memo.NewMergeBiasedCoster(), 2592 } 2593 2594 func TestSystemTableIndexes(t *testing.T) { 2595 if !types.IsFormat_DOLT(types.Format_Default) { 2596 t.Skip("only new format support system table indexing") 2597 } 2598 2599 for _, stt := range SystemTableIndexTests { 2600 harness := newDoltHarness(t).WithParallelism(2) 2601 defer harness.Close() 2602 harness.SkipSetupCommit() 2603 e := mustNewEngine(t, harness) 2604 defer e.Close() 2605 e.EngineAnalyzer().Coster = memo.NewMergeBiasedCoster() 2606 2607 ctx := enginetest.NewContext(harness) 2608 for _, q := range stt.setup { 2609 enginetest.RunQueryWithContext(t, e, harness, ctx, q) 2610 } 2611 2612 for i, c := range []string{"inner", "lookup", "hash", "merge"} { 2613 e.EngineAnalyzer().Coster = biasedCosters[i] 2614 for _, tt := range stt.queries { 2615 if tt.query == "select count(*) from dolt_blame_xy" && c == "inner" { 2616 // todo we either need join hints to work inside the blame view 2617 // and force the window relation to be primary, or we need the 2618 // blame view's timestamp columns to be specific enough to not 2619 // overlap during testing. 2620 t.Skip("the blame table is unstable as secondary table in join with exchange node") 2621 } 2622 t.Run(fmt.Sprintf("%s(%s): %s", stt.name, c, tt.query), func(t *testing.T) { 2623 if tt.skip { 2624 t.Skip() 2625 } 2626 2627 ctx = ctx.WithQuery(tt.query) 2628 if tt.exp != nil { 2629 enginetest.TestQueryWithContext(t, ctx, e, harness, tt.query, tt.exp, nil, nil) 2630 } 2631 }) 2632 } 2633 } 2634 } 2635 } 2636 2637 func TestSystemTableIndexesPrepared(t *testing.T) { 2638 if !types.IsFormat_DOLT(types.Format_Default) { 2639 t.Skip("only new format support system table indexing") 2640 } 2641 2642 for _, stt := range SystemTableIndexTests { 2643 harness := newDoltHarness(t).WithParallelism(2) 2644 defer harness.Close() 2645 harness.SkipSetupCommit() 2646 e := mustNewEngine(t, harness) 2647 defer e.Close() 2648 2649 ctx := enginetest.NewContext(harness) 2650 for _, q := range stt.setup { 2651 enginetest.RunQueryWithContext(t, e, harness, ctx, q) 2652 } 2653 2654 for _, tt := range stt.queries { 2655 t.Run(fmt.Sprintf("%s: %s", stt.name, tt.query), func(t *testing.T) { 2656 if tt.skip { 2657 t.Skip() 2658 } 2659 2660 ctx = ctx.WithQuery(tt.query) 2661 if tt.exp != nil { 2662 enginetest.TestPreparedQueryWithContext(t, ctx, e, harness, tt.query, tt.exp, nil, nil, false) 2663 } 2664 }) 2665 } 2666 } 2667 } 2668 2669 func TestSystemTableFunctionIndexes(t *testing.T) { 2670 harness := newDoltHarness(t) 2671 harness.Setup(setup.MydbData) 2672 for _, test := range SystemTableFunctionIndexTests { 2673 harness.engine = nil 2674 t.Run(test.Name, func(t *testing.T) { 2675 enginetest.TestScript(t, harness, test) 2676 }) 2677 } 2678 } 2679 2680 func TestSystemTableFunctionIndexesPrepared(t *testing.T) { 2681 harness := newDoltHarness(t) 2682 harness.Setup(setup.MydbData) 2683 for _, test := range SystemTableFunctionIndexTests { 2684 harness.engine = nil 2685 t.Run(test.Name, func(t *testing.T) { 2686 enginetest.TestScriptPrepared(t, harness, test) 2687 }) 2688 } 2689 } 2690 2691 func TestReadOnlyDatabases(t *testing.T) { 2692 h := newDoltHarness(t) 2693 defer h.Close() 2694 enginetest.TestReadOnlyDatabases(t, h) 2695 } 2696 2697 func TestAddDropPks(t *testing.T) { 2698 h := newDoltHarness(t) 2699 defer h.Close() 2700 enginetest.TestAddDropPks(t, h) 2701 } 2702 2703 func TestAddAutoIncrementColumn(t *testing.T) { 2704 h := newDoltHarness(t) 2705 defer h.Close() 2706 2707 for _, script := range queries.AlterTableAddAutoIncrementScripts { 2708 enginetest.TestScript(t, h, script) 2709 } 2710 } 2711 2712 func TestNullRanges(t *testing.T) { 2713 h := newDoltHarness(t) 2714 defer h.Close() 2715 enginetest.TestNullRanges(t, h) 2716 } 2717 2718 func TestPersist(t *testing.T) { 2719 harness := newDoltHarness(t) 2720 defer harness.Close() 2721 dEnv := dtestutils.CreateTestEnv() 2722 defer dEnv.DoltDB.Close() 2723 localConf, ok := dEnv.Config.GetConfig(env.LocalConfig) 2724 require.True(t, ok) 2725 globals := config.NewPrefixConfig(localConf, env.SqlServerGlobalsPrefix) 2726 newPersistableSession := func(ctx *sql.Context) sql.PersistableSession { 2727 session := ctx.Session.(*dsess.DoltSession).WithGlobals(globals) 2728 err := session.RemoveAllPersistedGlobals() 2729 require.NoError(t, err) 2730 return session 2731 } 2732 2733 enginetest.TestPersist(t, harness, newPersistableSession) 2734 } 2735 2736 func TestTypesOverWire(t *testing.T) { 2737 harness := newDoltHarness(t) 2738 defer harness.Close() 2739 enginetest.TestTypesOverWire(t, harness, newSessionBuilder(harness)) 2740 } 2741 2742 func TestDoltCherryPick(t *testing.T) { 2743 for _, script := range DoltCherryPickTests { 2744 harness := newDoltHarness(t) 2745 enginetest.TestScript(t, harness, script) 2746 harness.Close() 2747 } 2748 } 2749 2750 func TestDoltCherryPickPrepared(t *testing.T) { 2751 for _, script := range DoltCherryPickTests { 2752 harness := newDoltHarness(t) 2753 enginetest.TestScriptPrepared(t, harness, script) 2754 harness.Close() 2755 } 2756 } 2757 2758 func TestDoltCommit(t *testing.T) { 2759 harness := newDoltHarness(t) 2760 defer harness.Close() 2761 for _, script := range DoltCommitTests { 2762 enginetest.TestScript(t, harness, script) 2763 } 2764 } 2765 2766 func TestDoltCommitPrepared(t *testing.T) { 2767 harness := newDoltHarness(t) 2768 defer harness.Close() 2769 for _, script := range DoltCommitTests { 2770 enginetest.TestScriptPrepared(t, harness, script) 2771 } 2772 } 2773 2774 func TestQueriesPrepared(t *testing.T) { 2775 h := newDoltHarness(t) 2776 defer h.Close() 2777 enginetest.TestQueriesPrepared(t, h) 2778 } 2779 2780 func TestStatsHistograms(t *testing.T) { 2781 h := newDoltHarness(t) 2782 defer h.Close() 2783 h.configureStats = true 2784 for _, script := range DoltHistogramTests { 2785 h.engine = nil 2786 enginetest.TestScript(t, h, script) 2787 } 2788 } 2789 2790 // TestStatsIO force a provider reload in-between setup and assertions that 2791 // forces a round trip of the statistics table before inspecting values. 2792 func TestStatsIO(t *testing.T) { 2793 h := newDoltHarness(t) 2794 h.configureStats = true 2795 defer h.Close() 2796 for _, script := range append(DoltStatsIOTests, DoltHistogramTests...) { 2797 h.engine = nil 2798 func() { 2799 e := mustNewEngine(t, h) 2800 if enginetest.IsServerEngine(e) { 2801 return 2802 } 2803 defer e.Close() 2804 TestProviderReloadScriptWithEngine(t, e, h, script) 2805 }() 2806 } 2807 } 2808 2809 func TestJoinStats(t *testing.T) { 2810 // these are sensitive to cardinality estimates, 2811 // particularly the join-filter tests that trade-off 2812 // smallest table first vs smallest join first 2813 h := newDoltHarness(t) 2814 defer h.Close() 2815 h.configureStats = true 2816 enginetest.TestJoinStats(t, h) 2817 } 2818 2819 func TestStatisticIndexes(t *testing.T) { 2820 h := newDoltHarness(t) 2821 defer h.Close() 2822 enginetest.TestStatisticIndexFilters(t, h) 2823 } 2824 2825 func TestSpatialQueriesPrepared(t *testing.T) { 2826 skipPreparedTests(t) 2827 2828 h := newDoltHarness(t) 2829 defer h.Close() 2830 enginetest.TestSpatialQueriesPrepared(t, h) 2831 } 2832 2833 func TestPreparedStatistics(t *testing.T) { 2834 h := newDoltHarness(t) 2835 defer h.Close() 2836 h.configureStats = true 2837 for _, script := range DoltHistogramTests { 2838 h.engine = nil 2839 enginetest.TestScriptPrepared(t, h, script) 2840 } 2841 } 2842 2843 func TestVersionedQueriesPrepared(t *testing.T) { 2844 skipPreparedTests(t) 2845 h := newDoltHarness(t) 2846 defer h.Close() 2847 enginetest.TestVersionedQueriesPrepared(t, h) 2848 } 2849 2850 func TestInfoSchemaPrepared(t *testing.T) { 2851 skipPreparedTests(t) 2852 h := newDoltHarness(t) 2853 defer h.Close() 2854 enginetest.TestInfoSchemaPrepared(t, h) 2855 } 2856 2857 func TestUpdateQueriesPrepared(t *testing.T) { 2858 skipPreparedTests(t) 2859 h := newDoltHarness(t) 2860 defer h.Close() 2861 enginetest.TestUpdateQueriesPrepared(t, h) 2862 } 2863 2864 func TestInsertQueriesPrepared(t *testing.T) { 2865 skipPreparedTests(t) 2866 h := newDoltHarness(t) 2867 defer h.Close() 2868 enginetest.TestInsertQueriesPrepared(t, h) 2869 } 2870 2871 func TestReplaceQueriesPrepared(t *testing.T) { 2872 skipPreparedTests(t) 2873 h := newDoltHarness(t) 2874 defer h.Close() 2875 enginetest.TestReplaceQueriesPrepared(t, h) 2876 } 2877 2878 func TestDeleteQueriesPrepared(t *testing.T) { 2879 skipPreparedTests(t) 2880 h := newDoltHarness(t) 2881 defer h.Close() 2882 enginetest.TestDeleteQueriesPrepared(t, h) 2883 } 2884 2885 func TestScriptsPrepared(t *testing.T) { 2886 var skipped []string 2887 if types.IsFormat_DOLT(types.Format_Default) { 2888 skipped = append(skipped, newFormatSkippedScripts...) 2889 } 2890 skipPreparedTests(t) 2891 h := newDoltHarness(t).WithSkippedQueries(skipped) 2892 defer h.Close() 2893 enginetest.TestScriptsPrepared(t, h) 2894 } 2895 2896 func TestInsertScriptsPrepared(t *testing.T) { 2897 skipPreparedTests(t) 2898 h := newDoltHarness(t) 2899 defer h.Close() 2900 enginetest.TestInsertScriptsPrepared(t, h) 2901 } 2902 2903 func TestComplexIndexQueriesPrepared(t *testing.T) { 2904 skipPreparedTests(t) 2905 h := newDoltHarness(t) 2906 defer h.Close() 2907 enginetest.TestComplexIndexQueriesPrepared(t, h) 2908 } 2909 2910 func TestJsonScriptsPrepared(t *testing.T) { 2911 skipPreparedTests(t) 2912 h := newDoltHarness(t) 2913 defer h.Close() 2914 skippedTests := []string{ 2915 "round-trip into table", // The current Dolt JSON format does not preserve decimals and unsigneds in JSON. 2916 } 2917 enginetest.TestJsonScriptsPrepared(t, h, skippedTests) 2918 } 2919 2920 func TestCreateCheckConstraintsScriptsPrepared(t *testing.T) { 2921 skipPreparedTests(t) 2922 h := newDoltHarness(t) 2923 defer h.Close() 2924 enginetest.TestCreateCheckConstraintsScriptsPrepared(t, h) 2925 } 2926 2927 func TestInsertIgnoreScriptsPrepared(t *testing.T) { 2928 skipPreparedTests(t) 2929 h := newDoltHarness(t) 2930 defer h.Close() 2931 enginetest.TestInsertIgnoreScriptsPrepared(t, h) 2932 } 2933 2934 func TestInsertErrorScriptsPrepared(t *testing.T) { 2935 skipPreparedTests(t) 2936 h := newDoltHarness(t) 2937 defer h.Close() 2938 h = h.WithSkippedQueries([]string{ 2939 "create table bad (vb varbinary(65535))", 2940 "insert into bad values (repeat('0', 65536))", 2941 }) 2942 enginetest.TestInsertErrorScriptsPrepared(t, h) 2943 } 2944 2945 func TestViewsPrepared(t *testing.T) { 2946 skipPreparedTests(t) 2947 h := newDoltHarness(t) 2948 defer h.Close() 2949 enginetest.TestViewsPrepared(t, h) 2950 } 2951 2952 func TestVersionedViewsPrepared(t *testing.T) { 2953 t.Skip("not supported for prepareds") 2954 skipPreparedTests(t) 2955 h := newDoltHarness(t) 2956 defer h.Close() 2957 enginetest.TestVersionedViewsPrepared(t, h) 2958 } 2959 2960 func TestShowTableStatusPrepared(t *testing.T) { 2961 skipPreparedTests(t) 2962 h := newDoltHarness(t) 2963 defer h.Close() 2964 enginetest.TestShowTableStatusPrepared(t, h) 2965 } 2966 2967 func TestPrepared(t *testing.T) { 2968 skipPreparedTests(t) 2969 h := newDoltHarness(t) 2970 defer h.Close() 2971 enginetest.TestPrepared(t, h) 2972 } 2973 2974 func TestDoltPreparedScripts(t *testing.T) { 2975 skipPreparedTests(t) 2976 h := newDoltHarness(t) 2977 defer h.Close() 2978 DoltPreparedScripts(t, h) 2979 } 2980 2981 func TestPreparedInsert(t *testing.T) { 2982 skipPreparedTests(t) 2983 h := newDoltHarness(t) 2984 defer h.Close() 2985 enginetest.TestPreparedInsert(t, h) 2986 } 2987 2988 func TestPreparedStatements(t *testing.T) { 2989 skipPreparedTests(t) 2990 h := newDoltHarness(t) 2991 defer h.Close() 2992 enginetest.TestPreparedStatements(t, h) 2993 } 2994 2995 func TestCharsetCollationEngine(t *testing.T) { 2996 skipOldFormat(t) 2997 h := newDoltHarness(t) 2998 defer h.Close() 2999 enginetest.TestCharsetCollationEngine(t, h) 3000 } 3001 3002 func TestCharsetCollationWire(t *testing.T) { 3003 skipOldFormat(t) 3004 harness := newDoltHarness(t) 3005 defer harness.Close() 3006 enginetest.TestCharsetCollationWire(t, harness, newSessionBuilder(harness)) 3007 } 3008 3009 func TestDatabaseCollationWire(t *testing.T) { 3010 skipOldFormat(t) 3011 harness := newDoltHarness(t) 3012 defer harness.Close() 3013 enginetest.TestDatabaseCollationWire(t, harness, newSessionBuilder(harness)) 3014 } 3015 3016 func TestAddDropPrimaryKeys(t *testing.T) { 3017 t.Run("adding and dropping primary keys does not result in duplicate NOT NULL constraints", func(t *testing.T) { 3018 harness := newDoltHarness(t) 3019 defer harness.Close() 3020 addPkScript := queries.ScriptTest{ 3021 Name: "add primary keys", 3022 SetUpScript: []string{ 3023 "create table test (id int not null, c1 int);", 3024 "create index c1_idx on test(c1)", 3025 "insert into test values (1,1),(2,2)", 3026 "ALTER TABLE test ADD PRIMARY KEY(id)", 3027 "ALTER TABLE test DROP PRIMARY KEY", 3028 "ALTER TABLE test ADD PRIMARY KEY(id)", 3029 "ALTER TABLE test DROP PRIMARY KEY", 3030 "ALTER TABLE test ADD PRIMARY KEY(id)", 3031 "ALTER TABLE test DROP PRIMARY KEY", 3032 "ALTER TABLE test ADD PRIMARY KEY(id)", 3033 }, 3034 Assertions: []queries.ScriptTestAssertion{ 3035 { 3036 Query: "show create table test", 3037 Expected: []sql.Row{ 3038 {"test", "CREATE TABLE `test` (\n" + 3039 " `id` int NOT NULL,\n" + 3040 " `c1` int,\n" + 3041 " PRIMARY KEY (`id`),\n" + 3042 " KEY `c1_idx` (`c1`)\n" + 3043 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, 3044 }, 3045 }, 3046 }, 3047 } 3048 3049 enginetest.TestScript(t, harness, addPkScript) 3050 3051 // make sure there is only one NOT NULL constraint after all those mutations 3052 ctx := sql.NewContext(context.Background(), sql.WithSession(harness.session)) 3053 ws, err := harness.session.WorkingSet(ctx, "mydb") 3054 require.NoError(t, err) 3055 3056 table, ok, err := ws.WorkingRoot().GetTable(ctx, doltdb.TableName{Name: "test"}) 3057 require.NoError(t, err) 3058 require.True(t, ok) 3059 3060 sch, err := table.GetSchema(ctx) 3061 for _, col := range sch.GetAllCols().GetColumns() { 3062 count := 0 3063 for _, cc := range col.Constraints { 3064 if cc.GetConstraintType() == schema.NotNullConstraintType { 3065 count++ 3066 } 3067 } 3068 require.Less(t, count, 2) 3069 } 3070 }) 3071 3072 t.Run("Add primary key to table with index", func(t *testing.T) { 3073 harness := newDoltHarness(t) 3074 defer harness.Close() 3075 script := queries.ScriptTest{ 3076 Name: "add primary keys to table with index", 3077 SetUpScript: []string{ 3078 "create table test (id int not null, c1 int);", 3079 "create index c1_idx on test(c1)", 3080 "insert into test values (1,1),(2,2)", 3081 "ALTER TABLE test ADD constraint test_check CHECK (c1 > 0)", 3082 "ALTER TABLE test ADD PRIMARY KEY(id)", 3083 }, 3084 Assertions: []queries.ScriptTestAssertion{ 3085 { 3086 Query: "show create table test", 3087 Expected: []sql.Row{ 3088 {"test", "CREATE TABLE `test` (\n" + 3089 " `id` int NOT NULL,\n" + 3090 " `c1` int,\n" + 3091 " PRIMARY KEY (`id`),\n" + 3092 " KEY `c1_idx` (`c1`),\n" + 3093 " CONSTRAINT `test_check` CHECK ((`c1` > 0))\n" + 3094 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, 3095 }, 3096 }, 3097 { 3098 Query: "select * from test order by id", 3099 Expected: []sql.Row{ 3100 {1, 1}, 3101 {2, 2}, 3102 }, 3103 }, 3104 }, 3105 } 3106 enginetest.TestScript(t, harness, script) 3107 3108 ctx := sql.NewContext(context.Background(), sql.WithSession(harness.session)) 3109 ws, err := harness.session.WorkingSet(ctx, "mydb") 3110 require.NoError(t, err) 3111 3112 table, ok, err := ws.WorkingRoot().GetTable(ctx, doltdb.TableName{Name: "test"}) 3113 require.NoError(t, err) 3114 require.True(t, ok) 3115 3116 // Assert the new index map is not empty 3117 newRows, err := table.GetIndexRowData(ctx, "c1_idx") 3118 require.NoError(t, err) 3119 empty, err := newRows.Empty() 3120 require.NoError(t, err) 3121 assert.False(t, empty) 3122 count, err := newRows.Count() 3123 require.NoError(t, err) 3124 assert.Equal(t, count, uint64(2)) 3125 }) 3126 3127 t.Run("Add primary key when one more cells contain NULL", func(t *testing.T) { 3128 harness := newDoltHarness(t) 3129 defer harness.Close() 3130 script := queries.ScriptTest{ 3131 Name: "Add primary key when one more cells contain NULL", 3132 SetUpScript: []string{ 3133 "create table test (id int not null, c1 int);", 3134 "create index c1_idx on test(c1)", 3135 "insert into test values (1,1),(2,2)", 3136 "ALTER TABLE test ADD PRIMARY KEY (c1)", 3137 "ALTER TABLE test ADD COLUMN (c2 INT NULL)", 3138 "ALTER TABLE test DROP PRIMARY KEY", 3139 }, 3140 Assertions: []queries.ScriptTestAssertion{ 3141 { 3142 Query: "ALTER TABLE test ADD PRIMARY KEY (id, c1, c2)", 3143 ExpectedErr: sql.ErrInsertIntoNonNullableProvidedNull, 3144 }, 3145 }, 3146 } 3147 enginetest.TestScript(t, harness, script) 3148 }) 3149 3150 t.Run("Drop primary key from table with index", func(t *testing.T) { 3151 harness := newDoltHarness(t) 3152 defer harness.Close() 3153 script := queries.ScriptTest{ 3154 Name: "Drop primary key from table with index", 3155 SetUpScript: []string{ 3156 "create table test (id int not null primary key, c1 int);", 3157 "create index c1_idx on test(c1)", 3158 "insert into test values (1,1),(2,2)", 3159 "ALTER TABLE test DROP PRIMARY KEY", 3160 }, 3161 Assertions: []queries.ScriptTestAssertion{ 3162 { 3163 Query: "show create table test", 3164 Expected: []sql.Row{ 3165 {"test", "CREATE TABLE `test` (\n" + 3166 " `id` int NOT NULL,\n" + 3167 " `c1` int,\n" + 3168 " KEY `c1_idx` (`c1`)\n" + 3169 ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"}, 3170 }, 3171 }, 3172 { 3173 Query: "select * from test order by id", 3174 Expected: []sql.Row{ 3175 {1, 1}, 3176 {2, 2}, 3177 }, 3178 }, 3179 }, 3180 } 3181 3182 enginetest.TestScript(t, harness, script) 3183 3184 ctx := sql.NewContext(context.Background(), sql.WithSession(harness.session)) 3185 ws, err := harness.session.WorkingSet(ctx, "mydb") 3186 require.NoError(t, err) 3187 3188 table, ok, err := ws.WorkingRoot().GetTable(ctx, doltdb.TableName{Name: "test"}) 3189 require.NoError(t, err) 3190 require.True(t, ok) 3191 3192 // Assert the index map is not empty 3193 newIdx, err := table.GetIndexRowData(ctx, "c1_idx") 3194 assert.NoError(t, err) 3195 empty, err := newIdx.Empty() 3196 require.NoError(t, err) 3197 assert.False(t, empty) 3198 count, err := newIdx.Count() 3199 require.NoError(t, err) 3200 assert.Equal(t, count, uint64(2)) 3201 }) 3202 } 3203 3204 func TestDoltVerifyConstraints(t *testing.T) { 3205 for _, script := range DoltVerifyConstraintsTestScripts { 3206 func() { 3207 harness := newDoltHarness(t) 3208 defer harness.Close() 3209 enginetest.TestScript(t, harness, script) 3210 }() 3211 } 3212 } 3213 3214 func TestDoltStorageFormat(t *testing.T) { 3215 var expectedFormatString string 3216 if types.IsFormat_DOLT(types.Format_Default) { 3217 expectedFormatString = "NEW ( __DOLT__ )" 3218 } else { 3219 expectedFormatString = fmt.Sprintf("OLD ( %s )", types.Format_Default.VersionString()) 3220 } 3221 script := queries.ScriptTest{ 3222 Name: "dolt storage format function works", 3223 Assertions: []queries.ScriptTestAssertion{ 3224 { 3225 Query: "select dolt_storage_format()", 3226 Expected: []sql.Row{{expectedFormatString}}, 3227 }, 3228 }, 3229 } 3230 h := newDoltHarness(t) 3231 defer h.Close() 3232 enginetest.TestScript(t, h, script) 3233 } 3234 3235 func TestDoltStorageFormatPrepared(t *testing.T) { 3236 var expectedFormatString string 3237 if types.IsFormat_DOLT(types.Format_Default) { 3238 expectedFormatString = "NEW ( __DOLT__ )" 3239 } else { 3240 expectedFormatString = fmt.Sprintf("OLD ( %s )", types.Format_Default.VersionString()) 3241 } 3242 h := newDoltHarness(t) 3243 defer h.Close() 3244 enginetest.TestPreparedQuery(t, h, "SELECT dolt_storage_format()", []sql.Row{{expectedFormatString}}, nil) 3245 } 3246 3247 func TestThreeWayMergeWithSchemaChangeScripts(t *testing.T) { 3248 skipOldFormat(t) 3249 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsBasicCases, "basic cases", false) 3250 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsForDataConflicts, "data conflicts", false) 3251 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsCollations, "collation changes", false) 3252 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsConstraints, "constraint changes", false) 3253 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsSchemaConflicts, "schema conflicts", false) 3254 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsGeneratedColumns, "generated columns", false) 3255 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsForJsonConflicts, "json merge", false) 3256 3257 // Run non-symmetric schema merge tests in just one direction 3258 t.Run("type changes", func(t *testing.T) { 3259 for _, script := range SchemaChangeTestsTypeChanges { 3260 // run in a func() so we can cleanly defer closing the harness 3261 func() { 3262 h := newDoltHarness(t) 3263 defer h.Close() 3264 enginetest.TestScript(t, h, convertMergeScriptTest(script, false)) 3265 }() 3266 } 3267 }) 3268 } 3269 3270 func TestThreeWayMergeWithSchemaChangeScriptsPrepared(t *testing.T) { 3271 skipOldFormat(t) 3272 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsBasicCases, "basic cases", true) 3273 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsForDataConflicts, "data conflicts", true) 3274 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsCollations, "collation changes", true) 3275 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsConstraints, "constraint changes", true) 3276 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsSchemaConflicts, "schema conflicts", true) 3277 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsGeneratedColumns, "generated columns", true) 3278 runMergeScriptTestsInBothDirections(t, SchemaChangeTestsForJsonConflicts, "json merge", true) 3279 3280 // Run non-symmetric schema merge tests in just one direction 3281 t.Run("type changes", func(t *testing.T) { 3282 for _, script := range SchemaChangeTestsTypeChanges { 3283 // run in a func() so we can cleanly defer closing the harness 3284 func() { 3285 h := newDoltHarness(t) 3286 defer h.Close() 3287 enginetest.TestScriptPrepared(t, h, convertMergeScriptTest(script, false)) 3288 }() 3289 } 3290 }) 3291 } 3292 3293 // If CREATE DATABASE has an error within the DatabaseProvider, it should not 3294 // leave behind intermediate filesystem state. 3295 func TestCreateDatabaseErrorCleansUp(t *testing.T) { 3296 dh := newDoltHarness(t) 3297 require.NotNil(t, dh) 3298 e, err := dh.NewEngine(t) 3299 require.NoError(t, err) 3300 require.NotNil(t, e) 3301 3302 doltDatabaseProvider := dh.provider.(*sqle.DoltDatabaseProvider) 3303 doltDatabaseProvider.InitDatabaseHooks = append(doltDatabaseProvider.InitDatabaseHooks, 3304 func(_ *sql.Context, _ *sqle.DoltDatabaseProvider, name string, _ *env.DoltEnv, _ dsess.SqlDatabase) error { 3305 if name == "cannot_create" { 3306 return fmt.Errorf("there was an error initializing this database. abort!") 3307 } 3308 return nil 3309 }) 3310 3311 err = dh.provider.CreateDatabase(enginetest.NewContext(dh), "can_create") 3312 require.NoError(t, err) 3313 3314 err = dh.provider.CreateDatabase(enginetest.NewContext(dh), "cannot_create") 3315 require.Error(t, err) 3316 3317 fs := dh.multiRepoEnv.FileSystem() 3318 exists, _ := fs.Exists("cannot_create") 3319 require.False(t, exists) 3320 exists, isDir := fs.Exists("can_create") 3321 require.True(t, exists) 3322 require.True(t, isDir) 3323 } 3324 3325 // TestStatsAutoRefreshConcurrency tests some common concurrent patterns that stats 3326 // refresh is subject to -- namely reading/writing the stats objects in (1) DML statements 3327 // (2) auto refresh threads, and (3) manual ANALYZE statements. 3328 // todo: the dolt_stat functions should be concurrency tested 3329 func TestStatsAutoRefreshConcurrency(t *testing.T) { 3330 // create engine 3331 harness := newDoltHarness(t) 3332 harness.Setup(setup.MydbData) 3333 engine := mustNewEngine(t, harness) 3334 defer engine.Close() 3335 3336 enginetest.RunQueryWithContext(t, engine, harness, nil, `create table xy (x int primary key, y int, z int, key (z), key (y,z), key (y,z,x))`) 3337 enginetest.RunQueryWithContext(t, engine, harness, nil, `create table uv (u int primary key, v int, w int, key (w), key (w,u), key (u,w,v))`) 3338 3339 sqlDb, _ := harness.provider.BaseDatabase(harness.NewContext(), "mydb") 3340 3341 // Setting an interval of 0 and a threshold of 0 will result 3342 // in the stats being updated after every operation 3343 intervalSec := time.Duration(0) 3344 thresholdf64 := 0. 3345 bThreads := sql.NewBackgroundThreads() 3346 branches := []string{"main"} 3347 statsProv := engine.EngineAnalyzer().Catalog.StatsProvider.(*statspro.Provider) 3348 3349 // it is important to use new sessions for this test, to avoid working root conflicts 3350 readCtx := enginetest.NewSession(harness) 3351 writeCtx := enginetest.NewSession(harness) 3352 newCtx := func(context.Context) (*sql.Context, error) { 3353 return enginetest.NewSession(harness), nil 3354 } 3355 3356 err := statsProv.InitAutoRefreshWithParams(newCtx, sqlDb.Name(), bThreads, intervalSec, thresholdf64, branches) 3357 require.NoError(t, err) 3358 3359 execQ := func(ctx *sql.Context, q string, id int, tag string) { 3360 _, iter, err := engine.Query(ctx, q) 3361 require.NoError(t, err) 3362 _, err = sql.RowIterToRows(ctx, iter) 3363 //fmt.Printf("%s %d\n", tag, id) 3364 require.NoError(t, err) 3365 } 3366 3367 iters := 1_000 3368 { 3369 // 3 threads to test auto-refresh/DML concurrency safety 3370 // - auto refresh (read + write) 3371 // - write (write only) 3372 // - read (read only) 3373 3374 wg := sync.WaitGroup{} 3375 wg.Add(2) 3376 3377 go func() { 3378 for i := 0; i < iters; i++ { 3379 q := "select count(*) from xy a join xy b on a.x = b.x" 3380 execQ(readCtx, q, i, "read") 3381 q = "select count(*) from uv a join uv b on a.u = b.u" 3382 execQ(readCtx, q, i, "read") 3383 } 3384 wg.Done() 3385 }() 3386 3387 go func() { 3388 for i := 0; i < iters; i++ { 3389 q := fmt.Sprintf("insert into xy values (%d,%d,%d)", i, i, i) 3390 execQ(writeCtx, q, i, "write") 3391 q = fmt.Sprintf("insert into uv values (%d,%d,%d)", i, i, i) 3392 execQ(writeCtx, q, i, "write") 3393 } 3394 wg.Done() 3395 }() 3396 3397 wg.Wait() 3398 } 3399 3400 { 3401 // 3 threads to test auto-refresh/manual ANALYZE concurrency 3402 // - auto refresh (read + write) 3403 // - add (read + write) 3404 // - drop (write only) 3405 3406 wg := sync.WaitGroup{} 3407 wg.Add(2) 3408 3409 analyzeAddCtx := enginetest.NewSession(harness) 3410 analyzeDropCtx := enginetest.NewSession(harness) 3411 3412 // hammer the provider with concurrent stat updates 3413 go func() { 3414 for i := 0; i < iters; i++ { 3415 execQ(analyzeAddCtx, "analyze table xy,uv", i, "analyze create") 3416 } 3417 wg.Done() 3418 }() 3419 3420 go func() { 3421 for i := 0; i < iters; i++ { 3422 execQ(analyzeDropCtx, "analyze table xy drop histogram on (y,z)", i, "analyze drop yz") 3423 execQ(analyzeDropCtx, "analyze table uv drop histogram on (w,u)", i, "analyze drop wu") 3424 } 3425 wg.Done() 3426 }() 3427 3428 wg.Wait() 3429 } 3430 } 3431 3432 // runMergeScriptTestsInBothDirections creates a new test run, named |name|, and runs the specified merge |tests| 3433 // in both directions (right to left merge, and left to right merge). If 3434 // |runAsPrepared| is true then the test scripts will be run using the prepared 3435 // statement test code. 3436 func runMergeScriptTestsInBothDirections(t *testing.T, tests []MergeScriptTest, name string, runAsPrepared bool) { 3437 t.Run(name, func(t *testing.T) { 3438 t.Run("right to left merges", func(t *testing.T) { 3439 for _, script := range tests { 3440 // run in a func() so we can cleanly defer closing the harness 3441 func() { 3442 h := newDoltHarness(t) 3443 defer h.Close() 3444 if runAsPrepared { 3445 enginetest.TestScriptPrepared(t, h, convertMergeScriptTest(script, false)) 3446 } else { 3447 enginetest.TestScript(t, h, convertMergeScriptTest(script, false)) 3448 } 3449 }() 3450 } 3451 }) 3452 t.Run("left to right merges", func(t *testing.T) { 3453 for _, script := range tests { 3454 func() { 3455 h := newDoltHarness(t) 3456 defer h.Close() 3457 if runAsPrepared { 3458 enginetest.TestScriptPrepared(t, h, convertMergeScriptTest(script, true)) 3459 } else { 3460 enginetest.TestScript(t, h, convertMergeScriptTest(script, true)) 3461 } 3462 }() 3463 } 3464 }) 3465 }) 3466 } 3467 3468 var newFormatSkippedScripts = []string{ 3469 // Different query plans 3470 "Partial indexes are used and return the expected result", 3471 "Multiple indexes on the same columns in a different order", 3472 } 3473 3474 func skipOldFormat(t *testing.T) { 3475 if !types.IsFormat_DOLT(types.Format_Default) { 3476 t.Skip() 3477 } 3478 } 3479 3480 func skipPreparedTests(t *testing.T) { 3481 if skipPrepared { 3482 t.Skip("skip prepared") 3483 } 3484 } 3485 3486 func newSessionBuilder(harness *DoltHarness) server.SessionBuilder { 3487 return func(ctx context.Context, conn *mysql.Conn, host string) (sql.Session, error) { 3488 newCtx := harness.NewSession() 3489 return newCtx.Session, nil 3490 } 3491 }