github.com/dolthub/go-mysql-server@v0.18.0/enginetest/enginetests.go (about) 1 // Copyright 2020-2021 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 dsql "database/sql" 20 "fmt" 21 "io" 22 "net" 23 "os" 24 "reflect" 25 "strings" 26 "sync" 27 "testing" 28 "time" 29 30 "github.com/dolthub/vitess/go/sqltypes" 31 "github.com/dolthub/vitess/go/vt/proto/query" 32 _ "github.com/go-sql-driver/mysql" 33 "github.com/gocraft/dbr/v2" 34 "github.com/stretchr/testify/assert" 35 "github.com/stretchr/testify/require" 36 "gopkg.in/src-d/go-errors.v1" 37 38 sqle "github.com/dolthub/go-mysql-server" 39 "github.com/dolthub/go-mysql-server/enginetest/queries" 40 "github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup" 41 "github.com/dolthub/go-mysql-server/server" 42 "github.com/dolthub/go-mysql-server/sql" 43 "github.com/dolthub/go-mysql-server/sql/analyzer/analyzererrors" 44 "github.com/dolthub/go-mysql-server/sql/expression" 45 "github.com/dolthub/go-mysql-server/sql/expression/function/aggregation" 46 "github.com/dolthub/go-mysql-server/sql/mysql_db" 47 "github.com/dolthub/go-mysql-server/sql/mysql_db/serial" 48 "github.com/dolthub/go-mysql-server/sql/plan" 49 "github.com/dolthub/go-mysql-server/sql/planbuilder" 50 "github.com/dolthub/go-mysql-server/sql/transform" 51 "github.com/dolthub/go-mysql-server/sql/types" 52 "github.com/dolthub/go-mysql-server/sql/variables" 53 "github.com/dolthub/go-mysql-server/test" 54 ) 55 56 // TestQueries tests a variety of queries against databases and tables provided by the given harness. 57 func TestQueries(t *testing.T, harness Harness) { 58 harness.Setup(setup.SimpleSetup...) 59 e := mustNewEngine(t, harness) 60 defer e.Close() 61 ctx := NewContext(harness) 62 for _, tt := range queries.QueryTests { 63 t.Run(tt.Query, func(t *testing.T) { 64 if sh, ok := harness.(SkippingHarness); ok { 65 if sh.SkipQueryTest(tt.Query) { 66 t.Skipf("Skipping query plan for %s", tt.Query) 67 } 68 } 69 if IsServerEngine(e) && tt.SkipServerEngine { 70 t.Skip("skipping for server engine") 71 } 72 TestQueryWithContext(t, ctx, e, harness, tt.Query, tt.Expected, tt.ExpectedColumns, nil) 73 }) 74 } 75 76 // TODO: move this into its own test method 77 if keyless, ok := harness.(KeylessTableHarness); ok && keyless.SupportsKeylessTables() { 78 for _, tt := range queries.KeylessQueries { 79 TestQuery2(t, harness, e, tt.Query, tt.Expected, tt.ExpectedColumns, nil) 80 } 81 } 82 } 83 84 // TestStatistics tests the statistics from ANALYZE TABLE 85 func TestStatistics(t *testing.T, harness Harness) { 86 for _, script := range queries.StatisticsQueries { 87 TestScript(t, harness, script) 88 } 89 } 90 91 // TestStatisticIndexFilters tests index histogram costing 92 func TestStatisticIndexFilters(t *testing.T, harness Harness) { 93 for _, script := range queries.StatsIndexTests { 94 TestScript(t, harness, script) 95 } 96 } 97 98 // TestStatisticsPrepared tests the statistics from ANALYZE TABLE 99 func TestStatisticsPrepared(t *testing.T, harness Harness) { 100 for _, script := range queries.StatisticsQueries { 101 TestScriptPrepared(t, harness, script) 102 } 103 } 104 105 // TestSpatialQueries tests a variety of geometry queries against databases and tables provided by the given harness. 106 func TestSpatialQueries(t *testing.T, harness Harness) { 107 harness.Setup(setup.SpatialSetup...) 108 e := mustNewEngine(t, harness) 109 defer e.Close() 110 for _, tt := range queries.SpatialQueryTests { 111 TestQueryWithEngine(t, harness, e, tt) 112 } 113 } 114 115 // TestSpatialQueriesPrepared tests a variety of geometry queries against databases and tables provided by the given harness. 116 func TestSpatialQueriesPrepared(t *testing.T, harness Harness) { 117 harness.Setup(setup.SpatialSetup...) 118 e := mustNewEngine(t, harness) 119 defer e.Close() 120 for _, tt := range queries.SpatialQueryTests { 121 TestPreparedQueryWithEngine(t, harness, e, tt) 122 } 123 124 for _, tt := range queries.SpatialDeleteTests { 125 runWriteQueryTestPrepared(t, harness, tt) 126 } 127 for _, tt := range queries.SpatialInsertQueries { 128 runWriteQueryTestPrepared(t, harness, tt) 129 } 130 for _, tt := range queries.SpatialUpdateTests { 131 runWriteQueryTestPrepared(t, harness, tt) 132 } 133 } 134 135 // TestJoinQueries tests join queries against a provided harness. 136 func TestJoinQueries(t *testing.T, harness Harness) { 137 harness.Setup(setup.MydbData, setup.MytableData, setup.Pk_tablesData, setup.OthertableData, setup.NiltableData, setup.XyData, setup.FooData) 138 e, err := harness.NewEngine(t) 139 require.NoError(t, err) 140 141 for _, tt := range queries.JoinQueryTests { 142 TestQuery2(t, harness, e, tt.Query, tt.Expected, tt.ExpectedColumns, nil) 143 } 144 for _, ts := range queries.JoinScriptTests { 145 TestScript(t, harness, ts) 146 } 147 } 148 149 func TestLateralJoinQueries(t *testing.T, harness Harness) { 150 for _, ts := range queries.LateralJoinScriptTests { 151 TestScript(t, harness, ts) 152 } 153 } 154 155 func TestJSONTableQueries(t *testing.T, harness Harness) { 156 harness.Setup(setup.MydbData, setup.Pk_tablesData) 157 e, err := harness.NewEngine(t) 158 require.NoError(t, err) 159 160 for _, tt := range queries.JSONTableQueryTests { 161 TestQuery2(t, harness, e, tt.Query, tt.Expected, tt.ExpectedColumns, nil) 162 } 163 } 164 165 func TestJSONTableQueriesPrepared(t *testing.T, harness Harness) { 166 harness.Setup(setup.MydbData, setup.Pk_tablesData) 167 e, err := harness.NewEngine(t) 168 require.NoError(t, err) 169 170 for _, tt := range queries.JSONTableQueryTests { 171 TestPreparedQueryWithEngine(t, harness, e, tt) 172 } 173 } 174 175 func TestJSONTableScripts(t *testing.T, harness Harness) { 176 for _, tt := range queries.JSONTableScriptTests { 177 TestScript(t, harness, tt) 178 } 179 } 180 181 func TestJSONTableScriptsPrepared(t *testing.T, harness Harness) { 182 for _, tt := range queries.JSONTableScriptTests { 183 TestScriptPrepared(t, harness, tt) 184 } 185 } 186 187 func TestBrokenJSONTableScripts(t *testing.T, harness Harness) { 188 for _, tt := range queries.BrokenJSONTableScriptTests { 189 TestScript(t, harness, tt) 190 } 191 } 192 193 // TestInfoSchemaPrepared runs tests of the information_schema database 194 func TestInfoSchemaPrepared(t *testing.T, harness Harness) { 195 harness.Setup(setup.MydbData, setup.MytableData, setup.Fk_tblData, setup.FooData) 196 for _, tt := range queries.InfoSchemaQueries { 197 TestPreparedQuery(t, harness, tt.Query, tt.Expected, tt.ExpectedColumns) 198 } 199 200 for _, script := range queries.InfoSchemaScripts { 201 TestScriptPrepared(t, harness, script) 202 } 203 } 204 205 func TestQueriesPrepared(t *testing.T, harness Harness) { 206 harness.Setup(setup.SimpleSetup...) 207 e := mustNewEngine(t, harness) 208 defer e.Close() 209 t.Run("query prepared tests", func(t *testing.T) { 210 for _, tt := range queries.QueryTests { 211 if tt.SkipPrepared { 212 continue 213 } 214 t.Run(tt.Query, func(t *testing.T) { 215 TestPreparedQueryWithEngine(t, harness, e, tt) 216 }) 217 } 218 }) 219 220 t.Run("keyless prepared tests", func(t *testing.T) { 221 harness.Setup(setup.MydbData, setup.KeylessData, setup.Keyless_idxData, setup.MytableData) 222 for _, tt := range queries.KeylessQueries { 223 t.Run(tt.Query, func(t *testing.T) { 224 TestPreparedQueryWithEngine(t, harness, e, tt) 225 }) 226 } 227 }) 228 229 t.Run("date parse prepared tests", func(t *testing.T) { 230 harness.Setup(setup.MydbData) 231 for _, tt := range queries.DateParseQueries { 232 t.Run(tt.Query, func(t *testing.T) { 233 TestPreparedQueryWithEngine(t, harness, e, tt) 234 }) 235 } 236 }) 237 } 238 239 // TestJoinQueriesPrepared tests join queries as prepared statements against a provided harness. 240 func TestJoinQueriesPrepared(t *testing.T, harness Harness) { 241 harness.Setup(setup.MydbData, setup.MytableData, setup.Pk_tablesData, setup.OthertableData, setup.NiltableData, setup.XyData, setup.FooData) 242 for _, tt := range queries.JoinQueryTests { 243 if tt.SkipPrepared { 244 continue 245 } 246 TestPreparedQuery(t, harness, tt.Query, tt.Expected, tt.ExpectedColumns) 247 } 248 for _, ts := range queries.JoinScriptTests { 249 if ts.SkipPrepared { 250 continue 251 } 252 TestScriptPrepared(t, harness, ts) 253 } 254 } 255 256 func TestBrokenQueries(t *testing.T, harness Harness) { 257 harness.Setup(setup.MydbData, setup.MytableData, setup.Pk_tablesData, setup.Fk_tblData, setup.OthertableData) 258 RunQueryTests(t, harness, queries.BrokenQueries) 259 } 260 261 // RunQueryTests runs the query tests given after setting up the engine. Useful for testing out a smaller subset of 262 // queries during debugging. 263 func RunQueryTests(t *testing.T, harness Harness, queries []queries.QueryTest) { 264 for _, tt := range queries { 265 TestQuery(t, harness, tt.Query, tt.Expected, tt.ExpectedColumns, nil) 266 } 267 } 268 269 // TestInfoSchema runs tests of the information_schema database 270 func TestInfoSchema(t *testing.T, h Harness) { 271 h.Setup(setup.MydbData, setup.MytableData, setup.Fk_tblData, setup.FooData) 272 for _, tt := range queries.InfoSchemaQueries { 273 TestQuery(t, h, tt.Query, tt.Expected, tt.ExpectedColumns, nil) 274 } 275 276 for _, script := range queries.InfoSchemaScripts { 277 TestScript(t, h, script) 278 } 279 280 t.Run("information_schema.processlist", func(t *testing.T) { 281 e := mustNewEngine(t, h) 282 defer e.Close() 283 284 if IsServerEngine(e) { 285 t.Skip("skipping for server engine as the processlist returned from server differs") 286 } 287 p := sqle.NewProcessList() 288 p.AddConnection(1, "localhost") 289 290 ctx := NewContext(h) 291 ctx.Session.SetClient(sql.Client{Address: "localhost", User: "root"}) 292 ctx.Session.SetConnectionId(1) 293 ctx.ProcessList = p 294 ctx.SetCurrentDatabase("") 295 296 p.ConnectionReady(ctx.Session) 297 298 ctx, err := p.BeginQuery(ctx, "SELECT foo") 299 require.NoError(t, err) 300 301 p.AddConnection(2, "otherhost") 302 sess2 := sql.NewBaseSessionWithClientServer("localhost", sql.Client{Address: "otherhost", User: "root"}, 2) 303 sess2.SetCurrentDatabase("otherdb") 304 p.ConnectionReady(sess2) 305 ctx2 := sql.NewContext(context.Background(), sql.WithPid(2), sql.WithSession(sess2)) 306 ctx2, err = p.BeginQuery(ctx2, "SELECT bar") 307 require.NoError(t, err) 308 p.EndQuery(ctx2) 309 310 TestQueryWithContext(t, ctx, e, h, "SELECT * FROM information_schema.processlist ORDER BY id", []sql.Row{ 311 {uint64(1), "root", "localhost", nil, "Query", 0, "processlist(processlist (0/? partitions))", "SELECT foo"}, 312 {uint64(2), "root", "otherhost", "otherdb", "Sleep", 0, "", ""}, 313 }, nil, nil) 314 }) 315 316 for _, tt := range queries.SkippedInfoSchemaQueries { 317 t.Run(tt.Query, func(t *testing.T) { 318 t.Skip() 319 TestQuery(t, h, tt.Query, tt.Expected, tt.ExpectedColumns, nil) 320 }) 321 } 322 323 for _, script := range queries.SkippedInfoSchemaScripts { 324 t.Run(script.Name, func(t *testing.T) { 325 t.Skip() 326 TestScript(t, h, script) 327 }) 328 } 329 } 330 331 func TestMySqlDb(t *testing.T, harness Harness) { 332 harness.Setup(setup.MydbData) 333 for _, tt := range queries.MySqlDbTests { 334 TestScript(t, harness, tt) 335 } 336 } 337 338 func TestMySqlDbPrepared(t *testing.T, harness Harness) { 339 harness.Setup(setup.MydbData) 340 for _, tt := range queries.MySqlDbTests { 341 TestScriptPrepared(t, harness, tt) 342 } 343 } 344 345 func TestReadOnlyDatabases(t *testing.T, harness ReadOnlyDatabaseHarness) { 346 // Data setup for a read only database looks like normal setup, then creating a new read-only version of the engine 347 // and provider with the data inserted 348 harness.Setup(setup.SimpleSetup...) 349 engine := mustNewEngine(t, harness) 350 engine, err := harness.NewReadOnlyEngine(engine.EngineAnalyzer().Catalog.DbProvider) 351 require.NoError(t, err) 352 353 for _, querySet := range [][]queries.QueryTest{ 354 queries.QueryTests, 355 queries.KeylessQueries, 356 } { 357 for _, tt := range querySet { 358 TestQueryWithEngine(t, harness, engine, tt) 359 } 360 } 361 362 for _, querySet := range [][]queries.WriteQueryTest{ 363 queries.InsertQueries, 364 queries.UpdateTests, 365 queries.DeleteTests, 366 queries.ReplaceQueries, 367 } { 368 for _, tt := range querySet { 369 t.Run(tt.WriteQuery, func(t *testing.T) { 370 AssertErrWithBindings(t, engine, harness, tt.WriteQuery, tt.Bindings, analyzererrors.ErrReadOnlyDatabase) 371 }) 372 } 373 } 374 } 375 376 func TestReadOnlyVersionedQueries(t *testing.T, harness Harness) { 377 _, ok := harness.(ReadOnlyDatabaseHarness) 378 if !ok { 379 t.Fatal("harness is not ReadOnlyDatabaseHarness") 380 } 381 382 vh, ok := harness.(VersionedDBHarness) 383 if !ok { 384 t.Fatal("harness is not ReadOnlyDatabaseHarness") 385 } 386 387 CreateVersionedTestData(t, vh) 388 engine, err := vh.NewEngine(t) 389 require.NoError(t, err) 390 defer engine.Close() 391 392 for _, tt := range queries.VersionedQueries { 393 TestQueryWithEngine(t, harness, engine, tt) 394 } 395 396 for _, tt := range queries.VersionedScripts { 397 TestScriptWithEngine(t, engine, harness, tt) 398 } 399 } 400 401 func TestAnsiQuotesSqlMode(t *testing.T, harness Harness) { 402 for _, tt := range queries.AnsiQuotesTests { 403 TestScript(t, harness, tt) 404 } 405 } 406 407 func TestAnsiQuotesSqlModePrepared(t *testing.T, harness Harness) { 408 for _, tt := range queries.AnsiQuotesTests { 409 TestScriptPrepared(t, harness, tt) 410 } 411 } 412 413 var DebugQueryPlan = sql.DescribeOptions{ 414 Analyze: false, 415 Estimates: false, 416 Debug: true, 417 } 418 419 // TestQueryPlans tests generating the correct query plans for various queries using databases and tables provided by 420 // the given harness. 421 func TestQueryPlans(t *testing.T, harness Harness, planTests []queries.QueryPlanTest) { 422 harness.Setup(setup.PlanSetup...) 423 e := mustNewEngine(t, harness) 424 defer e.Close() 425 runTestWithDescribeOptions := func(t *testing.T, query, expectedPlan string, options sql.DescribeOptions) { 426 TestQueryPlanWithName(t, options.String(), harness, e, query, expectedPlan, options) 427 } 428 for _, tt := range planTests { 429 t.Run(tt.Query, func(t *testing.T) { 430 runTestWithDescribeOptions(t, tt.Query, tt.ExpectedPlan, sql.DescribeOptions{ 431 Debug: true, 432 }) 433 if tt.ExpectedEstimates != "" { 434 runTestWithDescribeOptions(t, tt.Query, tt.ExpectedEstimates, sql.DescribeOptions{ 435 Estimates: true, 436 }) 437 } 438 if tt.ExpectedAnalysis != "" { 439 runTestWithDescribeOptions(t, tt.Query, tt.ExpectedAnalysis, sql.DescribeOptions{ 440 Estimates: true, 441 Analyze: true, 442 }) 443 } 444 }) 445 446 } 447 } 448 449 func TestIntegrationPlans(t *testing.T, harness Harness) { 450 harness.Setup(setup.MydbData, setup.Integration_testData) 451 e := mustNewEngine(t, harness) 452 defer e.Close() 453 for _, tt := range queries.IntegrationPlanTests { 454 TestQueryPlan(t, harness, e, tt.Query, tt.ExpectedPlan, DebugQueryPlan) 455 } 456 } 457 458 func TestImdbPlans(t *testing.T, harness Harness) { 459 harness.Setup(setup.ImdbPlanSetup...) 460 e := mustNewEngine(t, harness) 461 defer e.Close() 462 for _, tt := range queries.ImdbPlanTests { 463 TestQueryPlan(t, harness, e, tt.Query, tt.ExpectedPlan, DebugQueryPlan) 464 } 465 } 466 467 func TestTpchPlans(t *testing.T, harness Harness) { 468 harness.Setup(setup.TpchPlanSetup...) 469 e := mustNewEngine(t, harness) 470 defer e.Close() 471 for _, tt := range queries.TpchPlanTests { 472 TestQueryPlan(t, harness, e, tt.Query, tt.ExpectedPlan, DebugQueryPlan) 473 } 474 } 475 476 func TestTpccPlans(t *testing.T, harness Harness) { 477 harness.Setup(setup.TpccPlanSetup...) 478 e := mustNewEngine(t, harness) 479 defer e.Close() 480 for _, tt := range queries.TpccPlanTests { 481 TestQueryPlan(t, harness, e, tt.Query, tt.ExpectedPlan, DebugQueryPlan) 482 } 483 } 484 485 func TestTpcdsPlans(t *testing.T, harness Harness) { 486 harness.Setup(setup.TpcdsPlanSetup...) 487 e := mustNewEngine(t, harness) 488 defer e.Close() 489 for _, tt := range queries.TpcdsPlanTests { 490 TestQueryPlan(t, harness, e, tt.Query, tt.ExpectedPlan, DebugQueryPlan) 491 } 492 } 493 494 func TestIndexQueryPlans(t *testing.T, harness Harness) { 495 harness.Setup(setup.ComplexIndexSetup...) 496 e := mustNewEngine(t, harness) 497 defer e.Close() 498 for _, tt := range queries.IndexPlanTests { 499 TestQueryPlanWithEngine(t, harness, e, tt, true) 500 } 501 502 t.Run("no database selected", func(t *testing.T) { 503 ctx := NewContext(harness) 504 ctx.SetCurrentDatabase("") 505 506 RunQueryWithContext(t, e, harness, ctx, "CREATE DATABASE otherdb") 507 RunQueryWithContext(t, e, harness, ctx, `CREATE TABLE otherdb.a (x int, y int)`) 508 RunQueryWithContext(t, e, harness, ctx, `CREATE INDEX idx1 ON otherdb.a (y);`) 509 510 TestQueryWithContext(t, ctx, e, harness, "SHOW INDEXES FROM otherdb.a", []sql.Row{ 511 {"a", 1, "idx1", 1, "y", nil, 0, nil, nil, "YES", "BTREE", "", "", "YES", nil}, 512 }, nil, nil) 513 514 }) 515 } 516 517 // TestVersionedQueries tests a variety of versioned queries 518 func TestVersionedQueries(t *testing.T, harness VersionedDBHarness) { 519 CreateVersionedTestData(t, harness) 520 engine, err := harness.NewEngine(t) 521 require.NoError(t, err) 522 defer engine.Close() 523 524 for _, tt := range queries.VersionedQueries { 525 TestQueryWithEngine(t, harness, engine, tt) 526 } 527 528 for _, tt := range queries.VersionedScripts { 529 TestScriptWithEngine(t, engine, harness, tt) 530 } 531 532 // These queries return different errors in the Memory engine and in the Dolt engine. 533 // Memory engine returns ErrTableNotFound, while Dolt engine returns ErrBranchNotFound. 534 // Until that is fixed, this test will not pass in both GMS and Dolt. 535 skippedTests := []queries.ScriptTest{ 536 { 537 Query: "DESCRIBE myhistorytable AS OF '2018-12-01'", 538 ExpectedErr: sql.ErrTableNotFound, 539 }, 540 { 541 Query: "SHOW CREATE TABLE myhistorytable AS OF '2018-12-01'", 542 ExpectedErr: sql.ErrTableNotFound, 543 }, 544 } 545 for _, skippedTest := range skippedTests { 546 t.Run(skippedTest.Query, func(t *testing.T) { 547 t.Skip() 548 TestScript(t, harness, skippedTest) 549 }) 550 } 551 } 552 553 // TestVersionedQueriesPrepared tests a variety of queries against databases and tables provided by the given harness. 554 func TestVersionedQueriesPrepared(t *testing.T, harness VersionedDBHarness) { 555 CreateVersionedTestData(t, harness) 556 e, err := harness.NewEngine(t) 557 require.NoError(t, err) 558 defer e.Close() 559 560 for _, tt := range queries.VersionedQueries { 561 TestPreparedQueryWithEngine(t, harness, e, tt) 562 } 563 564 t.Skip("skipping tests that version using UserVars instead of BindVars") 565 for _, tt := range queries.VersionedScripts { 566 TestScriptPrepared(t, harness, tt) 567 } 568 } 569 570 // TestQueryPlan analyzes the query given and asserts that its printed plan matches the expected one. 571 func TestQueryPlan(t *testing.T, harness Harness, e QueryEngine, query, expectedPlan string, options sql.DescribeOptions) { 572 TestQueryPlanWithName(t, query, harness, e, query, expectedPlan, options) 573 } 574 575 func TestQueryPlanWithName(t *testing.T, name string, harness Harness, e QueryEngine, query, expectedPlan string, options sql.DescribeOptions) { 576 t.Run(name, func(t *testing.T) { 577 ctx := NewContext(harness) 578 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, query) 579 require.NoError(t, err) 580 581 node, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 582 require.NoError(t, err) 583 584 if sh, ok := harness.(SkippingHarness); ok { 585 if sh.SkipQueryTest(query) { 586 t.Skipf("Skipping query plan for %s", query) 587 } 588 } 589 590 // If iterating over the node won't have side effects, 591 // do it in order to populate actual stats data. 592 if node.IsReadOnly() { 593 err = ExecuteNode(ctx, e, node) 594 require.NoError(t, err) 595 } 596 597 cmp := sql.Describe(ExtractQueryNode(node), options) 598 assert.Equal(t, expectedPlan, cmp, "Unexpected result for query: "+query) 599 }) 600 } 601 602 func TestQueryPlanWithEngine(t *testing.T, harness Harness, e QueryEngine, tt queries.QueryPlanTest, verbose bool) { 603 t.Run(tt.Query, func(t *testing.T) { 604 ctx := NewContext(harness) 605 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, tt.Query) 606 require.NoError(t, err) 607 608 node, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 609 require.NoError(t, err) 610 611 if sh, ok := harness.(SkippingHarness); ok { 612 if sh.SkipQueryTest(tt.Query) { 613 t.Skipf("Skipping query plan for %s", tt.Query) 614 } 615 } 616 617 var cmp string 618 if verbose { 619 cmp = sql.DebugString(ExtractQueryNode(node)) 620 } else { 621 cmp = ExtractQueryNode(node).String() 622 } 623 assert.Equal(t, tt.ExpectedPlan, cmp, "Unexpected result for query: "+tt.Query) 624 }) 625 } 626 627 func TestOrderByGroupBy(t *testing.T, harness Harness) { 628 for _, tt := range queries.OrderByGroupByScriptTests { 629 TestScript(t, harness, tt) 630 } 631 632 t.Run("non-deterministic group by", func(t *testing.T) { 633 e := mustNewEngine(t, harness) 634 defer e.Close() 635 ctx := NewContext(harness) 636 637 RunQueryWithContext(t, e, harness, ctx, "create table members (id int primary key, team text);") 638 RunQueryWithContext(t, e, harness, ctx, "insert into members values (3,'red'), (4,'red'),(5,'orange'),(6,'orange'),(7,'orange'),(8,'purple');") 639 640 var rowIter sql.RowIter 641 var row sql.Row 642 var err error 643 var rowCount int 644 645 // group by with any_value or non-strict are non-deterministic (unless there's only one value), so we must accept multiple 646 // group by with any_value() 647 648 _, rowIter, err = e.Query(ctx, "select any_value(id), team from members group by team order by id") 649 require.NoError(t, err) 650 rowCount = 0 651 isServerTest := IsServerEngine(e) 652 for { 653 row, err = rowIter.Next(ctx) 654 if err == io.EOF { 655 break 656 } 657 rowCount++ 658 require.NoError(t, err) 659 660 // TODO: needs fix to match MySQL, which its type is `LONG` = Int32 661 // currently, we convert any int result to SQL int64 type before sending it over the wire 662 var val int64 663 if isServerTest { 664 val = row[0].(int64) 665 } else { 666 val = int64(row[0].(int32)) 667 } 668 669 team := row[1].(string) 670 switch team { 671 case "red": 672 require.True(t, val == 3 || val == 4) 673 case "orange": 674 require.True(t, val == 5 || val == 6 || val == 7) 675 case "purple": 676 require.True(t, val == 8) 677 default: 678 panic("received non-existent team") 679 } 680 } 681 require.Equal(t, rowCount, 3) 682 683 // TODO: this should error; the order by doesn't count towards ONLY_FULL_GROUP_BY 684 _, rowIter, err = e.Query(ctx, "select id, team from members group by team order by id") 685 require.NoError(t, err) 686 rowCount = 0 687 for { 688 row, err = rowIter.Next(ctx) 689 if err == io.EOF { 690 break 691 } 692 rowCount++ 693 require.NoError(t, err) 694 695 // TODO: needs fix to match MySQL, which its type is `LONG` = Int32 696 // currently, we convert any int result to SQL int64 type before sending it over the wire 697 var val int64 698 if isServerTest { 699 val = row[0].(int64) 700 } else { 701 val = int64(row[0].(int32)) 702 } 703 704 team := row[1].(string) 705 switch team { 706 case "red": 707 require.True(t, val == 3 || val == 4) 708 case "orange": 709 require.True(t, val == 5 || val == 6 || val == 7) 710 case "purple": 711 require.True(t, val == 8) 712 default: 713 panic("received non-existent team") 714 } 715 } 716 require.Equal(t, rowCount, 3) 717 }) 718 } 719 720 func TestReadOnly(t *testing.T, harness Harness, testStoredProcedures bool) { 721 harness.Setup(setup.Mytable...) 722 engine := mustNewEngine(t, harness) 723 724 e, ok := engine.(*sqle.Engine) 725 if !ok { 726 t.Skip("Need a *sqle.Engine for TestReadOnly") 727 } 728 729 e.ReadOnly.Store(true) 730 defer e.Close() 731 732 var workingQueries = []string{ 733 `SELECT i FROM mytable`, 734 `EXPLAIN INSERT INTO mytable (i, s) VALUES (42, 'yolo')`, 735 } 736 737 if testStoredProcedures { 738 workingQueries = append(workingQueries, `CALL memory_inout_add_readonly(1, 1)`) 739 } 740 741 for _, q := range workingQueries { 742 t.Run(q, func(t *testing.T) { 743 RunQueryWithContext(t, e, harness, nil, q) 744 }) 745 } 746 747 writingQueries := []string{ 748 `CREATE INDEX foo USING BTREE ON mytable (i, s)`, 749 `DROP INDEX idx_si ON mytable`, 750 `INSERT INTO mytable (i, s) VALUES(42, 'yolo')`, 751 `CREATE VIEW myview3 AS SELECT i FROM mytable`, 752 `DROP VIEW myview`, 753 `DROP DATABASE mydb`, 754 `CREATE DATABASE newdb`, 755 `CREATE USER tester@localhost`, 756 `CREATE ROLE test_role`, 757 `GRANT SUPER ON * TO 'root'@'localhost'`, 758 } 759 760 if testStoredProcedures { 761 writingQueries = append(writingQueries, `CALL memory_inout_add_readwrite(1, 1)`) 762 } 763 764 for _, query := range writingQueries { 765 t.Run(query, func(t *testing.T) { 766 AssertErr(t, e, harness, query, sql.ErrReadOnly) 767 }) 768 } 769 } 770 771 // TestColumnAliases exercises the logic for naming and referring to column aliases, and unlike other tests in this 772 // file checks that the name of the columns in the result schema is correct. 773 func TestColumnAliases(t *testing.T, harness Harness) { 774 harness.Setup(setup.Mytable...) 775 for _, tt := range queries.ColumnAliasQueries { 776 TestScript(t, harness, tt) 777 } 778 } 779 780 func TestDerivedTableOuterScopeVisibility(t *testing.T, harness Harness) { 781 for _, tt := range queries.DerivedTableOuterScopeVisibilityQueries { 782 TestScript(t, harness, tt) 783 } 784 } 785 786 func TestAmbiguousColumnResolution(t *testing.T, harness Harness) { 787 harness.Setup([]setup.SetupScript{{ 788 "create database mydb", 789 "use mydb", 790 "create table foo (a bigint primary key, b text)", 791 "create table bar (b varchar(20) primary key, c bigint)", 792 "insert into foo values (1, 'foo'), (2,'bar'), (3,'baz')", 793 "insert into bar values ('qux',3), ('mux',2), ('pux',1)", 794 }}) 795 e := mustNewEngine(t, harness) 796 defer e.Close() 797 798 ctx := NewContext(harness) 799 expected := []sql.Row{ 800 {int64(1), "pux", "foo"}, 801 {int64(2), "mux", "bar"}, 802 {int64(3), "qux", "baz"}, 803 } 804 TestQueryWithContext(t, ctx, e, harness, `SELECT f.a, bar.b, f.b FROM foo f INNER JOIN bar ON f.a = bar.c order by 1`, expected, nil, nil) 805 } 806 807 func TestQueryErrors(t *testing.T, harness Harness) { 808 harness.Setup(setup.MydbData, setup.MytableData, setup.Pk_tablesData, setup.MyhistorytableData, setup.OthertableData, setup.SpecialtableData, setup.DatetimetableData, setup.NiltableData, setup.FooData) 809 for _, tt := range queries.ErrorQueries { 810 runQueryErrorTest(t, harness, tt) 811 } 812 } 813 814 func TestInsertInto(t *testing.T, harness Harness) { 815 harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.KeylessData, setup.Keyless_idxData, setup.NiltableData, setup.TypestableData, setup.EmptytableData, setup.AutoincrementData, setup.OthertableData, setup.Othertable_del_idxData) 816 t.Run("insert queries", func(t *testing.T) { 817 for _, insertion := range queries.InsertQueries { 818 RunWriteQueryTest(t, harness, insertion) 819 } 820 }) 821 822 harness.Setup(setup.MydbData) 823 t.Run("insert scripts", func(t *testing.T) { 824 for _, script := range queries.InsertScripts { 825 TestScript(t, harness, script) 826 } 827 }) 828 } 829 830 func TestInsertDuplicateKeyKeyless(t *testing.T, harness Harness) { 831 harness.Setup(setup.MydbData) 832 for _, script := range queries.InsertDuplicateKeyKeyless { 833 TestScript(t, harness, script) 834 } 835 } 836 837 func TestInsertIgnoreInto(t *testing.T, harness Harness) { 838 harness.Setup(setup.MydbData) 839 for _, script := range queries.InsertIgnoreScripts { 840 TestScript(t, harness, script) 841 } 842 } 843 844 func TestIgnoreIntoWithDuplicateUniqueKeyKeyless(t *testing.T, harness Harness) { 845 harness.Setup(setup.MydbData) 846 for _, script := range queries.IgnoreWithDuplicateUniqueKeyKeylessScripts { 847 TestScript(t, harness, script) 848 } 849 } 850 851 func TestInsertDuplicateKeyKeylessPrepared(t *testing.T, harness Harness) { 852 harness.Setup(setup.MydbData) 853 for _, script := range queries.InsertDuplicateKeyKeyless { 854 TestScriptPrepared(t, harness, script) 855 } 856 } 857 858 func TestIgnoreIntoWithDuplicateUniqueKeyKeylessPrepared(t *testing.T, harness Harness) { 859 harness.Setup(setup.MydbData) 860 for _, script := range queries.IgnoreWithDuplicateUniqueKeyKeylessScripts { 861 TestScriptPrepared(t, harness, script) 862 } 863 } 864 865 func TestInsertIntoErrors(t *testing.T, harness Harness) { 866 harness.Setup(setup.Mytable...) 867 for _, expectedFailure := range queries.InsertErrorTests { 868 runGenericErrorTest(t, harness, expectedFailure) 869 } 870 871 harness.Setup(setup.MydbData) 872 for _, script := range queries.InsertErrorScripts { 873 TestScript(t, harness, script) 874 } 875 } 876 877 func TestBrokenInsertScripts(t *testing.T, harness Harness) { 878 for _, script := range queries.InsertBrokenScripts { 879 t.Skip() 880 TestScript(t, harness, script) 881 } 882 } 883 884 func TestSpatialInsertInto(t *testing.T, harness Harness) { 885 harness.Setup(setup.SpatialSetup...) 886 for _, tt := range queries.SpatialInsertQueries { 887 RunWriteQueryTest(t, harness, tt) 888 } 889 } 890 891 // setSecureFilePriv sets the secure_file_priv system variable to the current working directory. 892 func setSecureFilePriv() error { 893 wd, err := os.Getwd() 894 if err != nil { 895 wd = "./" 896 } 897 return sql.SystemVariables.AssignValues(map[string]interface{}{ 898 "secure_file_priv": wd, 899 }) 900 } 901 902 func TestLoadData(t *testing.T, harness Harness) { 903 harness.Setup(setup.MydbData) 904 905 require.NoError(t, setSecureFilePriv()) 906 TestQuery(t, harness, "select @@secure_file_priv != '';", []sql.Row{{true}}, nil, nil) 907 908 for _, script := range queries.LoadDataScripts { 909 TestScript(t, harness, script) 910 } 911 } 912 913 func TestLoadDataErrors(t *testing.T, harness Harness) { 914 require.NoError(t, setSecureFilePriv()) 915 TestQuery(t, harness, "select @@secure_file_priv != '';", []sql.Row{{true}}, nil, nil) 916 917 for _, script := range queries.LoadDataErrorScripts { 918 TestScript(t, harness, script) 919 } 920 } 921 922 func TestLoadDataFailing(t *testing.T, harness Harness) { 923 t.Skip() 924 925 require.NoError(t, setSecureFilePriv()) 926 TestQuery(t, harness, "select @@secure_file_priv != '';", []sql.Row{{true}}, nil, nil) 927 928 for _, script := range queries.LoadDataFailingScripts { 929 TestScript(t, harness, script) 930 } 931 } 932 933 func TestSelectIntoFile(t *testing.T, harness Harness) { 934 harness.Setup(setup.MydbData, setup.MytableData, setup.EmptytableData, setup.NiltableData) 935 e := mustNewEngine(t, harness) 936 defer e.Close() 937 938 ctx := NewContext(harness) 939 err := CreateNewConnectionForServerEngine(ctx, e) 940 require.NoError(t, err, nil) 941 942 require.NoError(t, setSecureFilePriv()) 943 TestQuery(t, harness, "select @@secure_file_priv != '';", []sql.Row{{true}}, nil, nil) 944 945 tests := []struct { 946 file string 947 query string 948 exp string 949 err *errors.Kind 950 skip bool 951 }{ 952 { 953 file: "outfile.txt", 954 query: "select * from mytable into outfile 'outfile.txt';", 955 exp: "" + 956 "1\tfirst row\n" + 957 "2\tsecond row\n" + 958 "3\tthird row\n", 959 }, 960 { 961 file: "dumpfile.txt", 962 query: "select * from mytable limit 1 into dumpfile 'dumpfile.txt';", 963 exp: "1first row", 964 }, 965 { 966 file: "outfile.txt", 967 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',';", 968 exp: "" + 969 "1,first row\n" + 970 "2,second row\n" + 971 "3,third row\n", 972 }, 973 { 974 file: "outfile.txt", 975 query: "select * from mytable into outfile 'outfile.txt' fields terminated by '$$';", 976 exp: "" + 977 "1$$first row\n" + 978 "2$$second row\n" + 979 "3$$third row\n", 980 }, 981 { 982 file: "outfile.txt", 983 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' optionally enclosed by '\"';", 984 exp: "" + 985 "1,\"first row\"\n" + 986 "2,\"second row\"\n" + 987 "3,\"third row\"\n", 988 }, 989 { 990 file: "outfile.txt", 991 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' optionally enclosed by '$$';", 992 err: sql.ErrUnexpectedSeparator, 993 }, 994 { 995 file: "outfile.txt", 996 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' escaped by '$$';", 997 err: sql.ErrUnexpectedSeparator, 998 }, 999 { 1000 file: "outfile.txt", 1001 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' enclosed by '\"';", 1002 exp: "" + 1003 "\"1\",\"first row\"\n" + 1004 "\"2\",\"second row\"\n" + 1005 "\"3\",\"third row\"\n", 1006 }, 1007 { 1008 file: "outfile.txt", 1009 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by ';';", 1010 exp: "" + 1011 "1,first row;" + 1012 "2,second row;" + 1013 "3,third row;", 1014 }, 1015 { 1016 file: "outfile.txt", 1017 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by 'r';", 1018 exp: "" + 1019 "1,fi\\rst \\rowr" + 1020 "2,second \\rowr" + 1021 "3,thi\\rd \\rowr", 1022 }, 1023 { 1024 file: "outfile.txt", 1025 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines starting by 'r';", 1026 exp: "" + 1027 "r1,first row\n" + 1028 "r2,second row\n" + 1029 "r3,third row\n", 1030 }, 1031 { 1032 file: "outfile.txt", 1033 query: "select * from mytable into outfile 'outfile.txt' fields terminated by '';", 1034 exp: "" + 1035 "1\tfirst row\n" + 1036 "2\tsecond row\n" + 1037 "3\tthird row\n", 1038 }, 1039 { 1040 file: "outfile.txt", 1041 query: "select * from mytable into outfile 'outfile.txt' fields terminated by ',' lines terminated by '';", 1042 exp: "" + 1043 "1,first row" + 1044 "2,second row" + 1045 "3,third row", 1046 }, 1047 { 1048 file: "outfile.txt", 1049 query: "select * from niltable into outfile 'outfile.txt';", 1050 exp: "1\t\\N\t\\N\t\\N\n" + 1051 "2\t2\t1\t\\N\n" + 1052 "3\t\\N\t0\t\\N\n" + 1053 "4\t4\t\\N\t4\n" + 1054 "5\t\\N\t1\t5\n" + 1055 "6\t6\t0\t6\n", 1056 }, 1057 { 1058 file: "outfile.txt", 1059 query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' enclosed by '\"';", 1060 exp: "\"1\",\\N,\\N,\\N\n" + 1061 "\"2\",\"2\",\"1\",\\N\n" + 1062 "\"3\",\\N,\"0\",\\N\n" + 1063 "\"4\",\"4\",\\N,\"4\"\n" + 1064 "\"5\",\\N,\"1\",\"5\"\n" + 1065 "\"6\",\"6\",\"0\",\"6\"\n", 1066 }, 1067 { 1068 file: "outfile.txt", 1069 query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' escaped by '$';", 1070 exp: "1,$N,$N,$N\n" + 1071 "2,2,1,$N\n" + 1072 "3,$N,0,$N\n" + 1073 "4,4,$N,4\n" + 1074 "5,$N,1,5\n" + 1075 "6,6,0,6\n", 1076 }, 1077 { 1078 file: "outfile.txt", 1079 query: "select * from niltable into outfile 'outfile.txt' fields terminated by ',' escaped by '';", 1080 exp: "1,NULL,NULL,NULL\n" + 1081 "2,2,1,NULL\n" + 1082 "3,NULL,0,NULL\n" + 1083 "4,4,NULL,4\n" + 1084 "5,NULL,1,5\n" + 1085 "6,6,0,6\n", 1086 }, 1087 { 1088 file: "./subdir/outfile.txt", 1089 query: "select * from mytable into outfile './subdir/outfile.txt';", 1090 exp: "" + 1091 "1\tfirst row\n" + 1092 "2\tsecond row\n" + 1093 "3\tthird row\n", 1094 }, 1095 { 1096 file: "../outfile.txt", 1097 query: "select * from mytable into outfile '../outfile.txt';", 1098 err: sql.ErrSecureFilePriv, 1099 }, 1100 { 1101 file: "outfile.txt", 1102 query: "select * from mytable into outfile 'outfile.txt' charset binary;", 1103 err: sql.ErrUnsupportedFeature, 1104 }, 1105 } 1106 1107 subdir := "subdir" 1108 if _, subErr := os.Stat(subdir); subErr == nil { 1109 subErr = os.RemoveAll(subdir) 1110 require.NoError(t, subErr) 1111 } 1112 err = os.Mkdir(subdir, 0777) 1113 require.NoError(t, err) 1114 defer os.RemoveAll(subdir) 1115 1116 for _, tt := range tests { 1117 t.Run(tt.query, func(t *testing.T) { 1118 if tt.skip { 1119 t.Skip() 1120 } 1121 if tt.err != nil { 1122 AssertErrWithCtx(t, e, harness, ctx, tt.query, tt.err) 1123 return 1124 } 1125 // in case there are any residual files from previous runs 1126 os.Remove(tt.file) 1127 TestQueryWithContext(t, ctx, e, harness, tt.query, nil, nil, nil) 1128 res, err := os.ReadFile(tt.file) 1129 require.NoError(t, err) 1130 require.Equal(t, tt.exp, string(res)) 1131 os.Remove(tt.file) 1132 }) 1133 } 1134 1135 // remove tmp directory from previously failed runs 1136 exists := "exists.txt" 1137 if _, existsErr := os.Stat(exists); existsErr == nil { 1138 err = os.Remove(exists) 1139 require.NoError(t, err) 1140 } 1141 file, err := os.Create(exists) 1142 require.NoError(t, err) 1143 file.Close() 1144 defer os.Remove(exists) 1145 1146 AssertErrWithCtx(t, e, harness, ctx, "SELECT * FROM mytable INTO OUTFILE './exists.txt'", sql.ErrFileExists) 1147 AssertErrWithCtx(t, e, harness, ctx, "SELECT * FROM mytable LIMIT 1 INTO DUMPFILE './exists.txt'", sql.ErrFileExists) 1148 } 1149 1150 func TestReplaceInto(t *testing.T, harness Harness) { 1151 harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.TypestableData) 1152 for _, tt := range queries.ReplaceQueries { 1153 RunWriteQueryTest(t, harness, tt) 1154 } 1155 } 1156 1157 func TestReplaceIntoErrors(t *testing.T, harness Harness) { 1158 harness.Setup(setup.MydbData, setup.MytableData) 1159 for _, tt := range queries.ReplaceErrorTests { 1160 runGenericErrorTest(t, harness, tt) 1161 } 1162 } 1163 1164 func TestUpdate(t *testing.T, harness Harness) { 1165 harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.FloattableData, setup.NiltableData, setup.TypestableData, setup.Pk_tablesData, setup.OthertableData, setup.TabletestData) 1166 for _, tt := range queries.UpdateTests { 1167 RunWriteQueryTest(t, harness, tt) 1168 } 1169 } 1170 1171 func TestUpdateIgnore(t *testing.T, harness Harness) { 1172 harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.FloattableData, setup.NiltableData, setup.TypestableData, setup.Pk_tablesData, setup.OthertableData, setup.TabletestData) 1173 for _, tt := range queries.UpdateIgnoreTests { 1174 RunWriteQueryTest(t, harness, tt) 1175 } 1176 1177 for _, script := range queries.UpdateIgnoreScripts { 1178 TestScript(t, harness, script) 1179 } 1180 } 1181 1182 func TestUpdateErrors(t *testing.T, harness Harness) { 1183 harness.Setup(setup.MydbData, setup.MytableData, setup.FloattableData, setup.TypestableData) 1184 for _, expectedFailure := range queries.GenericUpdateErrorTests { 1185 runGenericErrorTest(t, harness, expectedFailure) 1186 } 1187 1188 harness.Setup(setup.MydbData, setup.KeylessData, setup.Keyless_idxData, setup.PeopleData, setup.Pk_tablesData) 1189 for _, expectedFailure := range queries.UpdateErrorTests { 1190 runQueryErrorTest(t, harness, expectedFailure) 1191 } 1192 1193 for _, script := range queries.UpdateErrorScripts { 1194 TestScript(t, harness, script) 1195 } 1196 } 1197 1198 func TestSpatialUpdate(t *testing.T, harness Harness) { 1199 harness.Setup(setup.SpatialSetup...) 1200 for _, update := range queries.SpatialUpdateTests { 1201 RunWriteQueryTest(t, harness, update) 1202 } 1203 } 1204 1205 func TestDelete(t *testing.T, harness Harness) { 1206 harness.Setup(setup.MydbData, setup.MytableData, setup.TabletestData) 1207 t.Run("Delete from single table", func(t *testing.T) { 1208 for _, tt := range queries.DeleteTests { 1209 RunWriteQueryTest(t, harness, tt) 1210 } 1211 }) 1212 t.Run("Delete from join", func(t *testing.T) { 1213 // Run tests with each biased coster to get coverage over join types 1214 for name, coster := range biasedCosters { 1215 t.Run(name+" join", func(t *testing.T) { 1216 for _, tt := range queries.DeleteJoinTests { 1217 e := mustNewEngine(t, harness) 1218 e.EngineAnalyzer().Coster = coster 1219 defer e.Close() 1220 RunWriteQueryTestWithEngine(t, harness, e, tt) 1221 } 1222 }) 1223 } 1224 }) 1225 } 1226 1227 func TestUpdateQueriesPrepared(t *testing.T, harness Harness) { 1228 harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.OthertableData, setup.TypestableData, setup.Pk_tablesData, setup.FloattableData, setup.NiltableData, setup.TabletestData) 1229 for _, tt := range queries.UpdateTests { 1230 runWriteQueryTestPrepared(t, harness, tt) 1231 } 1232 } 1233 1234 func TestDeleteQueriesPrepared(t *testing.T, harness Harness) { 1235 harness.Setup(setup.MydbData, setup.MytableData, setup.TabletestData) 1236 t.Run("Delete from single table", func(t *testing.T) { 1237 for _, tt := range queries.DeleteTests { 1238 runWriteQueryTestPrepared(t, harness, tt) 1239 } 1240 }) 1241 t.Run("Delete from join", func(t *testing.T) { 1242 for _, tt := range queries.DeleteJoinTests { 1243 runWriteQueryTestPrepared(t, harness, tt) 1244 } 1245 }) 1246 } 1247 1248 func TestInsertQueriesPrepared(t *testing.T, harness Harness) { 1249 harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.KeylessData, setup.Keyless_idxData, setup.TypestableData, setup.NiltableData, setup.EmptytableData, setup.AutoincrementData, setup.OthertableData) 1250 for _, tt := range queries.InsertQueries { 1251 runWriteQueryTestPrepared(t, harness, tt) 1252 } 1253 } 1254 1255 func TestReplaceQueriesPrepared(t *testing.T, harness Harness) { 1256 harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.TypestableData) 1257 for _, tt := range queries.ReplaceQueries { 1258 runWriteQueryTestPrepared(t, harness, tt) 1259 } 1260 } 1261 1262 func TestDeleteErrors(t *testing.T, harness Harness) { 1263 harness.Setup(setup.MydbData, setup.MytableData, setup.TabletestData, setup.TestdbData, []setup.SetupScript{{"create table test.other (pk int primary key);"}}) 1264 for _, tt := range queries.DeleteErrorTests { 1265 TestScript(t, harness, tt) 1266 } 1267 } 1268 1269 func TestSpatialDelete(t *testing.T, harness Harness) { 1270 harness.Setup(setup.SpatialSetup...) 1271 for _, delete := range queries.SpatialDeleteTests { 1272 RunWriteQueryTest(t, harness, delete) 1273 } 1274 } 1275 1276 func TestTruncate(t *testing.T, harness Harness) { 1277 harness.Setup(setup.MydbData, setup.MytableData) 1278 e := mustNewEngine(t, harness) 1279 defer e.Close() 1280 ctx := NewContext(harness) 1281 1282 t.Run("Standard TRUNCATE", func(t *testing.T) { 1283 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t1 (pk BIGINT PRIMARY KEY, v1 BIGINT, INDEX(v1))") 1284 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t1 VALUES (1,1), (2,2), (3,3)") 1285 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t1 ORDER BY 1", []sql.Row{{int64(1), int64(1)}, {int64(2), int64(2)}, {int64(3), int64(3)}}, nil, nil) 1286 TestQueryWithContext(t, ctx, e, harness, "TRUNCATE t1", []sql.Row{{types.NewOkResult(3)}}, nil, nil) 1287 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t1 ORDER BY 1", []sql.Row{}, nil, nil) 1288 1289 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t1 VALUES (4,4), (5,5)") 1290 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t1 WHERE v1 > 0 ORDER BY 1", []sql.Row{{int64(4), int64(4)}, {int64(5), int64(5)}}, nil, nil) 1291 TestQueryWithContext(t, ctx, e, harness, "TRUNCATE TABLE t1", []sql.Row{{types.NewOkResult(2)}}, nil, nil) 1292 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t1 ORDER BY 1", []sql.Row{}, nil, nil) 1293 }) 1294 1295 t.Run("Foreign Key References", func(t *testing.T) { 1296 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t2parent (pk BIGINT PRIMARY KEY, v1 BIGINT, INDEX (v1))") 1297 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t2child (pk BIGINT PRIMARY KEY, v1 BIGINT, "+ 1298 "FOREIGN KEY (v1) REFERENCES t2parent (v1))") 1299 AssertErrWithCtx(t, e, harness, ctx, "TRUNCATE t2parent", sql.ErrTruncateReferencedFromForeignKey) 1300 }) 1301 1302 t.Run("ON DELETE Triggers", func(t *testing.T) { 1303 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t3 (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1304 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t3i (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1305 RunQueryWithContext(t, e, harness, ctx, "CREATE TRIGGER trig_t3 BEFORE DELETE ON t3 FOR EACH ROW INSERT INTO t3i VALUES (old.pk, old.v1)") 1306 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t3 VALUES (1,1), (3,3)") 1307 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t3 ORDER BY 1", []sql.Row{{int64(1), int64(1)}, {int64(3), int64(3)}}, nil, nil) 1308 TestQueryWithContext(t, ctx, e, harness, "TRUNCATE t3", []sql.Row{{types.NewOkResult(2)}}, nil, nil) 1309 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t3 ORDER BY 1", []sql.Row{}, nil, nil) 1310 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t3i ORDER BY 1", []sql.Row{}, nil, nil) 1311 }) 1312 1313 t.Run("auto_increment column", func(t *testing.T) { 1314 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t4 (pk BIGINT AUTO_INCREMENT PRIMARY KEY, v1 BIGINT)") 1315 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t4(v1) VALUES (5), (6)") 1316 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t4 ORDER BY 1", []sql.Row{{int64(1), int64(5)}, {int64(2), int64(6)}}, nil, nil) 1317 TestQueryWithContext(t, ctx, e, harness, "TRUNCATE t4", []sql.Row{{types.NewOkResult(2)}}, nil, nil) 1318 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t4 ORDER BY 1", []sql.Row{}, nil, nil) 1319 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t4(v1) VALUES (7)") 1320 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t4 ORDER BY 1", []sql.Row{{int64(1), int64(7)}}, nil, nil) 1321 }) 1322 1323 t.Run("Naked DELETE", func(t *testing.T) { 1324 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t5 (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1325 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t5 VALUES (1,1), (2,2)") 1326 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t5 ORDER BY 1", []sql.Row{{int64(1), int64(1)}, {int64(2), int64(2)}}, nil, nil) 1327 1328 deleteStr := "DELETE FROM t5" 1329 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, deleteStr) 1330 require.NoError(t, err) 1331 analyzed, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 1332 require.NoError(t, err) 1333 truncateFound := false 1334 transform.Inspect(analyzed, func(n sql.Node) bool { 1335 switch n.(type) { 1336 case *plan.Truncate: 1337 truncateFound = true 1338 return false 1339 } 1340 return true 1341 }) 1342 if !truncateFound { 1343 require.FailNow(t, "DELETE did not convert to TRUNCATE", 1344 "Expected Truncate Node, got:\n%s", analyzed.String()) 1345 } 1346 1347 TestQueryWithContext(t, ctx, e, harness, deleteStr, []sql.Row{{types.NewOkResult(2)}}, nil, nil) 1348 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t5 ORDER BY 1", []sql.Row{}, nil, nil) 1349 }) 1350 1351 t.Run("Naked DELETE with Foreign Key References", func(t *testing.T) { 1352 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t6parent (pk BIGINT PRIMARY KEY, v1 BIGINT, INDEX (v1))") 1353 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t6child (pk BIGINT PRIMARY KEY, v1 BIGINT, "+ 1354 "CONSTRAINT fk_a123 FOREIGN KEY (v1) REFERENCES t6parent (v1))") 1355 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t6parent VALUES (1,1), (2,2)") 1356 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t6child VALUES (1,1), (2,2)") 1357 1358 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, "DELETE FROM t6parent") 1359 require.NoError(t, err) 1360 analyzed, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 1361 require.NoError(t, err) 1362 truncateFound := false 1363 transform.Inspect(analyzed, func(n sql.Node) bool { 1364 switch n.(type) { 1365 case *plan.Truncate: 1366 truncateFound = true 1367 return false 1368 } 1369 return true 1370 }) 1371 if truncateFound { 1372 require.FailNow(t, "Incorrectly converted DELETE with fks to TRUNCATE") 1373 } 1374 }) 1375 1376 t.Run("Naked DELETE with ON DELETE Triggers", func(t *testing.T) { 1377 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t7 (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1378 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t7i (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1379 RunQueryWithContext(t, e, harness, ctx, "CREATE TRIGGER trig_t7 BEFORE DELETE ON t7 FOR EACH ROW INSERT INTO t7i VALUES (old.pk, old.v1)") 1380 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t7 VALUES (1,1), (3,3)") 1381 RunQueryWithContext(t, e, harness, ctx, "DELETE FROM t7 WHERE pk = 3") 1382 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t7 ORDER BY 1", []sql.Row{{int64(1), int64(1)}}, nil, nil) 1383 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t7i ORDER BY 1", []sql.Row{{int64(3), int64(3)}}, nil, nil) 1384 1385 deleteStr := "DELETE FROM t7" 1386 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, deleteStr) 1387 require.NoError(t, err) 1388 analyzed, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 1389 require.NoError(t, err) 1390 truncateFound := false 1391 transform.Inspect(analyzed, func(n sql.Node) bool { 1392 switch n.(type) { 1393 case *plan.Truncate: 1394 truncateFound = true 1395 return false 1396 } 1397 return true 1398 }) 1399 if truncateFound { 1400 require.FailNow(t, "Incorrectly converted DELETE with triggers to TRUNCATE") 1401 } 1402 1403 TestQueryWithContext(t, ctx, e, harness, deleteStr, []sql.Row{{types.NewOkResult(1)}}, nil, nil) 1404 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t7 ORDER BY 1", []sql.Row{}, nil, nil) 1405 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t7i ORDER BY 1", []sql.Row{{int64(1), int64(1)}, {int64(3), int64(3)}}, nil, nil) 1406 }) 1407 1408 t.Run("Naked DELETE with auto_increment column", func(t *testing.T) { 1409 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t8 (pk BIGINT AUTO_INCREMENT PRIMARY KEY, v1 BIGINT)") 1410 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t8(v1) VALUES (4), (5)") 1411 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t8 ORDER BY 1", []sql.Row{{int64(1), int64(4)}, {int64(2), int64(5)}}, nil, nil) 1412 1413 deleteStr := "DELETE FROM t8" 1414 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, deleteStr) 1415 require.NoError(t, err) 1416 analyzed, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 1417 require.NoError(t, err) 1418 truncateFound := false 1419 transform.Inspect(analyzed, func(n sql.Node) bool { 1420 switch n.(type) { 1421 case *plan.Truncate: 1422 truncateFound = true 1423 return false 1424 } 1425 return true 1426 }) 1427 if truncateFound { 1428 require.FailNow(t, "Incorrectly converted DELETE with auto_increment cols to TRUNCATE") 1429 } 1430 1431 TestQueryWithContext(t, ctx, e, harness, deleteStr, []sql.Row{{types.NewOkResult(2)}}, nil, nil) 1432 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t8 ORDER BY 1", []sql.Row{}, nil, nil) 1433 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t8(v1) VALUES (6)") 1434 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t8 ORDER BY 1", []sql.Row{{int64(3), int64(6)}}, nil, nil) 1435 }) 1436 1437 t.Run("DELETE with WHERE clause", func(t *testing.T) { 1438 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t9 (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1439 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t9 VALUES (7,7), (8,8)") 1440 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t9 ORDER BY 1", []sql.Row{{int64(7), int64(7)}, {int64(8), int64(8)}}, nil, nil) 1441 1442 deleteStr := "DELETE FROM t9 WHERE pk > 0" 1443 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, deleteStr) 1444 require.NoError(t, err) 1445 analyzed, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 1446 require.NoError(t, err) 1447 truncateFound := false 1448 transform.Inspect(analyzed, func(n sql.Node) bool { 1449 switch n.(type) { 1450 case *plan.Truncate: 1451 truncateFound = true 1452 return false 1453 } 1454 return true 1455 }) 1456 if truncateFound { 1457 require.FailNow(t, "Incorrectly converted DELETE with WHERE clause to TRUNCATE") 1458 } 1459 1460 TestQueryWithContext(t, ctx, e, harness, deleteStr, []sql.Row{{types.NewOkResult(2)}}, nil, nil) 1461 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t9 ORDER BY 1", []sql.Row{}, nil, nil) 1462 }) 1463 1464 t.Run("DELETE with LIMIT clause", func(t *testing.T) { 1465 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t10 (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1466 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t10 VALUES (8,8), (9,9)") 1467 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t10 ORDER BY 1", []sql.Row{{int64(8), int64(8)}, {int64(9), int64(9)}}, nil, nil) 1468 1469 deleteStr := "DELETE FROM t10 LIMIT 1000" 1470 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, deleteStr) 1471 require.NoError(t, err) 1472 analyzed, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 1473 require.NoError(t, err) 1474 truncateFound := false 1475 transform.Inspect(analyzed, func(n sql.Node) bool { 1476 switch n.(type) { 1477 case *plan.Truncate: 1478 truncateFound = true 1479 return false 1480 } 1481 return true 1482 }) 1483 if truncateFound { 1484 require.FailNow(t, "Incorrectly converted DELETE with LIMIT clause to TRUNCATE") 1485 } 1486 1487 TestQueryWithContext(t, ctx, e, harness, deleteStr, []sql.Row{{types.NewOkResult(2)}}, nil, nil) 1488 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t10 ORDER BY 1", []sql.Row{}, nil, nil) 1489 }) 1490 1491 t.Run("DELETE with ORDER BY clause", func(t *testing.T) { 1492 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t11 (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1493 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t11 VALUES (1,1), (9,9)") 1494 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t11 ORDER BY 1", []sql.Row{{int64(1), int64(1)}, {int64(9), int64(9)}}, nil, nil) 1495 1496 deleteStr := "DELETE FROM t11 ORDER BY 1" 1497 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, deleteStr) 1498 require.NoError(t, err) 1499 analyzed, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 1500 require.NoError(t, err) 1501 truncateFound := false 1502 transform.Inspect(analyzed, func(n sql.Node) bool { 1503 switch n.(type) { 1504 case *plan.Truncate: 1505 truncateFound = true 1506 return false 1507 } 1508 return true 1509 }) 1510 if truncateFound { 1511 require.FailNow(t, "Incorrectly converted DELETE with ORDER BY clause to TRUNCATE") 1512 } 1513 1514 TestQueryWithContext(t, ctx, e, harness, deleteStr, []sql.Row{{types.NewOkResult(2)}}, nil, nil) 1515 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t11 ORDER BY 1", []sql.Row{}, nil, nil) 1516 }) 1517 1518 t.Run("Multi-table DELETE", func(t *testing.T) { 1519 t.Skip("Multi-table DELETE currently broken") 1520 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t12a (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1521 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t12b (pk BIGINT PRIMARY KEY, v1 BIGINT)") 1522 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t12a VALUES (1,1), (2,2)") 1523 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t12b VALUES (1,1), (2,2)") 1524 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t12a ORDER BY 1", []sql.Row{{int64(1), int64(1)}, {int64(2), int64(2)}}, nil, nil) 1525 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t12b ORDER BY 1", []sql.Row{{int64(1), int64(1)}, {int64(2), int64(2)}}, nil, nil) 1526 1527 deleteStr := "DELETE t12a, t12b FROM t12a INNER JOIN t12b WHERE t12a.pk=t12b.pk" 1528 parsed, err := planbuilder.Parse(ctx, e.EngineAnalyzer().Catalog, deleteStr) 1529 require.NoError(t, err) 1530 analyzed, err := e.EngineAnalyzer().Analyze(ctx, parsed, nil) 1531 require.NoError(t, err) 1532 truncateFound := false 1533 transform.Inspect(analyzed, func(n sql.Node) bool { 1534 switch n.(type) { 1535 case *plan.Truncate: 1536 truncateFound = true 1537 return false 1538 } 1539 return true 1540 }) 1541 if truncateFound { 1542 require.FailNow(t, "Incorrectly converted DELETE with WHERE clause to TRUNCATE") 1543 } 1544 1545 TestQueryWithContext(t, ctx, e, harness, deleteStr, []sql.Row{{types.NewOkResult(4)}}, nil, nil) 1546 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t12a ORDER BY 1", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 1547 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t12b ORDER BY 1", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 1548 }) 1549 } 1550 1551 func TestConvert(t *testing.T, harness Harness) { 1552 harness.Setup(setup.MydbData, setup.TypestableData) 1553 for _, tt := range queries.ConvertTests { 1554 query := fmt.Sprintf("select count(*) from typestable where %s %s %s", tt.Field, tt.Op, tt.Operand) 1555 t.Run(query, func(t *testing.T) { 1556 TestQuery(t, harness, query, []sql.Row{{tt.ExpCnt}}, nil, nil) 1557 }) 1558 } 1559 1560 } 1561 1562 func TestConvertPrepared(t *testing.T, harness Harness) { 1563 harness.Setup(setup.MydbData, setup.TypestableData) 1564 for _, tt := range queries.ConvertTests { 1565 query := fmt.Sprintf("select count(*) from typestable where %s %s %s", tt.Field, tt.Op, tt.Operand) 1566 t.Run(query, func(t *testing.T) { 1567 TestPreparedQuery(t, harness, query, []sql.Row{{tt.ExpCnt}}, nil) 1568 }) 1569 } 1570 } 1571 1572 func TestRowLimit(t *testing.T, harness Harness) { 1573 harness.Setup(setup.MydbData) 1574 for _, script := range queries.RowLimitTests { 1575 if sh, ok := harness.(SkippingHarness); ok { 1576 if sh.SkipQueryTest(script.Name) { 1577 t.Run(script.Name, func(t *testing.T) { 1578 t.Skip(script.Name) 1579 }) 1580 continue 1581 } 1582 } 1583 TestScript(t, harness, script) 1584 } 1585 } 1586 1587 func TestScripts(t *testing.T, harness Harness) { 1588 harness.Setup(setup.MydbData) 1589 for _, script := range queries.ScriptTests { 1590 if sh, ok := harness.(SkippingHarness); ok { 1591 if sh.SkipQueryTest(script.Name) { 1592 t.Run(script.Name, func(t *testing.T) { 1593 t.Skip(script.Name) 1594 }) 1595 continue 1596 } 1597 } 1598 TestScript(t, harness, script) 1599 } 1600 } 1601 1602 func TestSpatialScripts(t *testing.T, harness Harness) { 1603 harness.Setup(setup.MydbData) 1604 for _, script := range queries.SpatialScriptTests { 1605 TestScript(t, harness, script) 1606 } 1607 } 1608 1609 func TestSpatialScriptsPrepared(t *testing.T, harness Harness) { 1610 harness.Setup(setup.MydbData) 1611 for _, script := range queries.SpatialScriptTests { 1612 TestScriptPrepared(t, harness, script) 1613 } 1614 } 1615 1616 func TestSpatialIndexScripts(t *testing.T, harness Harness) { 1617 harness.Setup(setup.MydbData) 1618 for _, script := range queries.SpatialIndexScriptTests { 1619 TestScript(t, harness, script) 1620 } 1621 } 1622 1623 func TestSpatialIndexScriptsPrepared(t *testing.T, harness Harness) { 1624 harness.Setup(setup.MydbData) 1625 for _, script := range queries.SpatialIndexScriptTests { 1626 TestScriptPrepared(t, harness, script) 1627 } 1628 } 1629 1630 func TestLoadDataPrepared(t *testing.T, harness Harness) { 1631 harness.Setup(setup.MydbData) 1632 for _, script := range queries.LoadDataScripts { 1633 TestScriptPrepared(t, harness, script) 1634 } 1635 } 1636 1637 func TestScriptsPrepared(t *testing.T, harness Harness) { 1638 harness.Setup(setup.MydbData) 1639 for _, script := range queries.ScriptTests { 1640 if sh, ok := harness.(SkippingHarness); ok { 1641 if sh.SkipQueryTest(script.Name) { 1642 t.Run(script.Name, func(t *testing.T) { 1643 t.Skip(script.Name) 1644 }) 1645 continue 1646 } 1647 } 1648 TestScriptPrepared(t, harness, script) 1649 } 1650 } 1651 1652 func TestInsertScriptsPrepared(t *testing.T, harness Harness) { 1653 harness.Setup(setup.MydbData) 1654 for _, script := range queries.InsertScripts { 1655 TestScriptPrepared(t, harness, script) 1656 } 1657 } 1658 1659 func TestGeneratedColumns(t *testing.T, harness Harness) { 1660 harness.Setup(setup.MydbData) 1661 for _, script := range queries.GeneratedColumnTests { 1662 TestScriptPrepared(t, harness, script) 1663 } 1664 for _, script := range queries.BrokenGeneratedColumnTests { 1665 t.Run(script.Name, func(t *testing.T) { 1666 t.Skip(script.Name) 1667 TestScriptPrepared(t, harness, script) 1668 }) 1669 } 1670 } 1671 1672 func TestGeneratedColumnPlans(t *testing.T, harness Harness) { 1673 harness.Setup(setup.GeneratedColumnSetup...) 1674 e := mustNewEngine(t, harness) 1675 defer e.Close() 1676 for _, tt := range queries.GeneratedColumnPlanTests { 1677 TestQueryPlan(t, harness, e, tt.Query, tt.ExpectedPlan, DebugQueryPlan) 1678 } 1679 } 1680 1681 func TestSysbenchPlans(t *testing.T, harness Harness) { 1682 harness.Setup(setup.SysbenchSetup...) 1683 e := mustNewEngine(t, harness) 1684 defer e.Close() 1685 for _, tt := range queries.SysbenchPlanTests { 1686 TestQueryPlan(t, harness, e, tt.Query, tt.ExpectedPlan, DebugQueryPlan) 1687 } 1688 } 1689 1690 func TestComplexIndexQueriesPrepared(t *testing.T, harness Harness) { 1691 harness.Setup(setup.ComplexIndexSetup...) 1692 e := mustNewEngine(t, harness) 1693 defer e.Close() 1694 for _, tt := range queries.ComplexIndexQueries { 1695 TestPreparedQueryWithEngine(t, harness, e, tt) 1696 } 1697 } 1698 1699 func TestJsonScriptsPrepared(t *testing.T, harness Harness) { 1700 harness.Setup(setup.MydbData) 1701 for _, script := range queries.JsonScripts { 1702 TestScriptPrepared(t, harness, script) 1703 } 1704 } 1705 1706 func TestCreateCheckConstraintsScriptsPrepared(t *testing.T, harness Harness) { 1707 harness.Setup(setup.MydbData, setup.Check_constraintData) 1708 for _, script := range queries.CreateCheckConstraintsScripts { 1709 TestScriptPrepared(t, harness, script) 1710 } 1711 } 1712 1713 func TestInsertIgnoreScriptsPrepared(t *testing.T, harness Harness) { 1714 harness.Setup(setup.MydbData) 1715 for _, script := range queries.InsertIgnoreScripts { 1716 TestScriptPrepared(t, harness, script) 1717 } 1718 } 1719 1720 func TestInsertErrorScriptsPrepared(t *testing.T, harness Harness) { 1721 harness.Setup(setup.MydbData) 1722 for _, script := range queries.InsertErrorScripts { 1723 TestScriptPrepared(t, harness, script) 1724 } 1725 } 1726 1727 func TestUserPrivileges(t *testing.T, harness ClientHarness) { 1728 harness.Setup(setup.MydbData, setup.MytableData) 1729 for _, script := range queries.UserPrivTests { 1730 t.Run(script.Name, func(t *testing.T) { 1731 engine := mustNewEngine(t, harness) 1732 defer engine.Close() 1733 1734 ctx := NewContext(harness) 1735 ctx.NewCtxWithClient(sql.Client{ 1736 User: "root", 1737 Address: "localhost", 1738 }) 1739 engine.EngineAnalyzer().Catalog.MySQLDb.AddRootAccount() 1740 engine.EngineAnalyzer().Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) 1741 1742 for _, statement := range script.SetUpScript { 1743 if sh, ok := harness.(SkippingHarness); ok { 1744 if sh.SkipQueryTest(statement) { 1745 t.Skip() 1746 } 1747 } 1748 RunQueryWithContext(t, engine, harness, ctx, statement) 1749 } 1750 for _, assertion := range script.Assertions { 1751 if sh, ok := harness.(SkippingHarness); ok { 1752 if sh.SkipQueryTest(assertion.Query) { 1753 t.Skipf("Skipping query %s", assertion.Query) 1754 } 1755 } 1756 1757 user := assertion.User 1758 host := assertion.Host 1759 if user == "" { 1760 user = "root" 1761 } 1762 if host == "" { 1763 host = "localhost" 1764 } 1765 ctx := NewContextWithClient(harness, sql.Client{ 1766 User: user, 1767 Address: host, 1768 }) 1769 1770 if assertion.ExpectedErr != nil { 1771 t.Run(assertion.Query, func(t *testing.T) { 1772 AssertErrWithCtx(t, engine, harness, ctx, assertion.Query, assertion.ExpectedErr) 1773 }) 1774 } else if assertion.ExpectedErrStr != "" { 1775 t.Run(assertion.Query, func(t *testing.T) { 1776 AssertErrWithCtx(t, engine, harness, ctx, assertion.Query, nil, assertion.ExpectedErrStr) 1777 }) 1778 } else { 1779 t.Run(assertion.Query, func(t *testing.T) { 1780 TestQueryWithContext(t, ctx, engine, harness, assertion.Query, assertion.Expected, nil, nil) 1781 }) 1782 } 1783 } 1784 }) 1785 } 1786 1787 // These tests are functionally identical to UserPrivTests, hence their inclusion in the same testing function. 1788 // They're just written a little differently to ease the developer's ability to produce as many as possible. 1789 1790 harness.Setup([]setup.SetupScript{{ 1791 "create database mydb", 1792 "create database otherdb", 1793 }}) 1794 for _, script := range queries.QuickPrivTests { 1795 t.Run(strings.Join(script.Queries, "\n > "), func(t *testing.T) { 1796 engine := mustNewEngine(t, harness) 1797 defer engine.Close() 1798 1799 engine.EngineAnalyzer().Catalog.MySQLDb.AddRootAccount() 1800 engine.EngineAnalyzer().Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) 1801 rootCtx := harness.NewContextWithClient(sql.Client{ 1802 User: "root", 1803 Address: "localhost", 1804 }) 1805 rootCtx.SetCurrentDatabase("mydb") 1806 for _, setupQuery := range []string{ 1807 "CREATE USER tester@localhost;", 1808 "CREATE TABLE mydb.test (pk BIGINT PRIMARY KEY, v1 BIGINT);", 1809 "CREATE TABLE mydb.test2 (pk BIGINT PRIMARY KEY, v1 BIGINT);", 1810 "CREATE TABLE otherdb.test (pk BIGINT PRIMARY KEY, v1 BIGINT);", 1811 "CREATE TABLE otherdb.test2 (pk BIGINT PRIMARY KEY, v1 BIGINT);", 1812 "INSERT INTO mydb.test VALUES (0, 0), (1, 1);", 1813 "INSERT INTO mydb.test2 VALUES (0, 1), (1, 2);", 1814 "INSERT INTO otherdb.test VALUES (1, 1), (2, 2);", 1815 "INSERT INTO otherdb.test2 VALUES (1, 1), (2, 2);", 1816 } { 1817 RunQueryWithContext(t, engine, harness, rootCtx, setupQuery) 1818 } 1819 1820 for i := 0; i < len(script.Queries)-1; i++ { 1821 if sh, ok := harness.(SkippingHarness); ok { 1822 if sh.SkipQueryTest(script.Queries[i]) { 1823 t.Skipf("Skipping query %s", script.Queries[i]) 1824 } 1825 } 1826 RunQueryWithContext(t, engine, harness, rootCtx, script.Queries[i]) 1827 } 1828 lastQuery := script.Queries[len(script.Queries)-1] 1829 if sh, ok := harness.(SkippingHarness); ok { 1830 if sh.SkipQueryTest(lastQuery) { 1831 t.Skipf("Skipping query %s", lastQuery) 1832 } 1833 } 1834 ctx := rootCtx.NewCtxWithClient(sql.Client{ 1835 User: "tester", 1836 Address: "localhost", 1837 }) 1838 ctx.SetCurrentDatabase(rootCtx.GetCurrentDatabase()) 1839 if script.ExpectedErr != nil { 1840 t.Run(lastQuery, func(t *testing.T) { 1841 AssertErrWithCtx(t, engine, harness, ctx, lastQuery, script.ExpectedErr) 1842 }) 1843 } else if script.ExpectingErr { 1844 t.Run(lastQuery, func(t *testing.T) { 1845 _, iter, err := engine.Query(ctx, lastQuery) 1846 if err == nil { 1847 _, err = sql.RowIterToRows(ctx, iter) 1848 } 1849 require.Error(t, err) 1850 for _, errKind := range []*errors.Kind{ 1851 sql.ErrPrivilegeCheckFailed, 1852 sql.ErrDatabaseAccessDeniedForUser, 1853 sql.ErrTableAccessDeniedForUser, 1854 } { 1855 if errKind.Is(err) { 1856 return 1857 } 1858 } 1859 t.Fatalf("Not a standard privilege-check error: %s", err.Error()) 1860 }) 1861 } else { 1862 t.Run(lastQuery, func(t *testing.T) { 1863 sch, iter, err := engine.Query(ctx, lastQuery) 1864 require.NoError(t, err) 1865 rows, err := sql.RowIterToRows(ctx, iter) 1866 require.NoError(t, err) 1867 // See the comment on QuickPrivilegeTest for a more in-depth explanation, but essentially we treat 1868 // nil in script.Expected as matching "any" non-error result. 1869 if script.Expected != nil && (rows != nil || len(script.Expected) != 0) { 1870 checkResults(t, script.Expected, nil, sch, rows, lastQuery, engine) 1871 } 1872 }) 1873 } 1874 }) 1875 } 1876 } 1877 1878 func TestUserAuthentication(t *testing.T, h Harness) { 1879 clientHarness, ok := h.(ClientHarness) 1880 if !ok { 1881 t.Skip("Cannot run TestUserAuthentication as the harness must implement ClientHarness") 1882 } 1883 clientHarness.Setup(setup.MydbData, setup.MytableData) 1884 1885 port := getEmptyPort(t) 1886 for _, script := range queries.ServerAuthTests { 1887 t.Run(script.Name, func(t *testing.T) { 1888 ctx := NewContextWithClient(clientHarness, sql.Client{ 1889 User: "root", 1890 Address: "localhost", 1891 }) 1892 serverConfig := server.Config{ 1893 Protocol: "tcp", 1894 Address: fmt.Sprintf("localhost:%d", port), 1895 MaxConnections: 1000, 1896 AllowClearTextWithoutTLS: true, 1897 } 1898 1899 e := mustNewEngine(t, clientHarness) 1900 engine, ok := e.(*sqle.Engine) 1901 if !ok { 1902 t.Skip("Need a *sqle.Engine for TestUserAuthentication") 1903 } 1904 1905 defer engine.Close() 1906 engine.EngineAnalyzer().Catalog.MySQLDb.AddRootAccount() 1907 engine.EngineAnalyzer().Catalog.MySQLDb.SetPersister(&mysql_db.NoopPersister{}) 1908 1909 if script.SetUpFunc != nil { 1910 script.SetUpFunc(ctx, t, engine) 1911 } 1912 for _, statement := range script.SetUpScript { 1913 if sh, ok := clientHarness.(SkippingHarness); ok { 1914 if sh.SkipQueryTest(statement) { 1915 t.Skip() 1916 } 1917 } 1918 RunQueryWithContext(t, engine, clientHarness, ctx, statement) 1919 } 1920 1921 serverHarness, ok := h.(ServerHarness) 1922 if !ok { 1923 require.FailNow(t, "harness must implement ServerHarness") 1924 } 1925 1926 s, err := server.NewServer(serverConfig, engine, serverHarness.SessionBuilder(), nil) 1927 require.NoError(t, err) 1928 go func() { 1929 err := s.Start() 1930 require.NoError(t, err) 1931 }() 1932 defer func() { 1933 require.NoError(t, s.Close()) 1934 }() 1935 1936 for _, assertion := range script.Assertions { 1937 conn, err := dbr.Open("mysql", fmt.Sprintf("%s:%s@tcp(localhost:%d)/?allowCleartextPasswords=true", 1938 assertion.Username, assertion.Password, port), nil) 1939 require.NoError(t, err) 1940 r, err := conn.Query(assertion.Query) 1941 if assertion.ExpectedErr || len(assertion.ExpectedErrStr) > 0 || assertion.ExpectedErrKind != nil { 1942 if !assert.Error(t, err) { 1943 require.NoError(t, r.Close()) 1944 } else if len(assertion.ExpectedErrStr) > 0 { 1945 assert.Equal(t, assertion.ExpectedErrStr, err.Error()) 1946 } else if assertion.ExpectedErrKind != nil { 1947 assert.True(t, assertion.ExpectedErrKind.Is(err)) 1948 } 1949 } else { 1950 if assert.NoError(t, err) { 1951 require.NoError(t, r.Close()) 1952 } 1953 } 1954 require.NoError(t, conn.Close()) 1955 } 1956 }) 1957 } 1958 } 1959 1960 func getEmptyPort(t *testing.T) int { 1961 listener, err := net.Listen("tcp", ":0") 1962 require.NoError(t, err) 1963 port := listener.Addr().(*net.TCPAddr).Port 1964 require.NoError(t, listener.Close()) 1965 return port 1966 } 1967 1968 func TestComplexIndexQueries(t *testing.T, harness Harness) { 1969 harness.Setup(setup.ComplexIndexSetup...) 1970 e := mustNewEngine(t, harness) 1971 defer e.Close() 1972 for _, tt := range queries.ComplexIndexQueries { 1973 TestQueryWithEngine(t, harness, e, tt) 1974 } 1975 } 1976 1977 func TestTriggers(t *testing.T, harness Harness) { 1978 harness.Setup(setup.MydbData, setup.FooData) 1979 for _, script := range queries.TriggerTests { 1980 TestScript(t, harness, script) 1981 } 1982 1983 harness.Setup(setup.MydbData) 1984 e := mustNewEngine(t, harness) 1985 defer e.Close() 1986 t.Run("no database selected", func(t *testing.T) { 1987 ctx := NewContext(harness) 1988 ctx.SetCurrentDatabase("") 1989 1990 RunQueryWithContext(t, e, harness, ctx, "create table mydb.a (i int primary key, j int)") 1991 RunQueryWithContext(t, e, harness, ctx, "create table mydb.b (x int primary key)") 1992 1993 TestQueryWithContext(t, ctx, e, harness, "CREATE TRIGGER mydb.trig BEFORE INSERT ON mydb.a FOR EACH ROW BEGIN SET NEW.j = (SELECT COALESCE(MAX(x),1) FROM mydb.b); UPDATE mydb.b SET x = x + 1; END", []sql.Row{{types.OkResult{}}}, nil, nil) 1994 1995 RunQueryWithContext(t, e, harness, ctx, "insert into mydb.b values (1)") 1996 RunQueryWithContext(t, e, harness, ctx, "insert into mydb.a values (1,0), (2,0), (3,0)") 1997 1998 TestQueryWithContext(t, ctx, e, harness, "select * from mydb.a order by i", []sql.Row{{1, 1}, {2, 2}, {3, 3}}, nil, nil) 1999 2000 TestQueryWithContext(t, ctx, e, harness, "DROP TRIGGER mydb.trig", []sql.Row{{types.OkResult{}}}, nil, nil) 2001 TestQueryWithContext(t, ctx, e, harness, "SHOW TRIGGERS FROM mydb", []sql.Row{}, nil, nil) 2002 }) 2003 } 2004 2005 func TestRollbackTriggers(t *testing.T, harness Harness) { 2006 harness.Setup() 2007 for _, script := range queries.RollbackTriggerTests { 2008 TestScript(t, harness, script) 2009 } 2010 } 2011 2012 func TestShowTriggers(t *testing.T, harness Harness) { 2013 harness.Setup(setup.MydbData) 2014 e := mustNewEngine(t, harness) 2015 2016 // Pick a valid date 2017 date := time.Unix(1257894000, 0).UTC() 2018 2019 // Set up Harness to contain triggers; created at a specific time 2020 var ctx *sql.Context 2021 setupTriggers := []struct { 2022 Query string 2023 Expected []sql.Row 2024 }{ 2025 {"create table a (x int primary key)", []sql.Row{{types.NewOkResult(0)}}}, 2026 {"create table b (y int primary key)", []sql.Row{{types.NewOkResult(0)}}}, 2027 {"create trigger a1 before insert on a for each row set new.x = New.x + 1", []sql.Row{{types.NewOkResult(0)}}}, 2028 {"create trigger a2 before insert on a for each row precedes a1 set new.x = New.x * 2", []sql.Row{{types.NewOkResult(0)}}}, 2029 {"create trigger a3 before insert on a for each row precedes a2 set new.x = New.x - 5", []sql.Row{{types.NewOkResult(0)}}}, 2030 {"create trigger a4 before insert on a for each row follows a2 set new.x = New.x * 3", []sql.Row{{types.NewOkResult(0)}}}, 2031 // order of execution should be: a3, a2, a4, a1 2032 {"create trigger a5 after insert on a for each row update b set y = y + 1 order by y asc", []sql.Row{{types.NewOkResult(0)}}}, 2033 {"create trigger a6 after insert on a for each row precedes a5 update b set y = y * 2 order by y asc", []sql.Row{{types.NewOkResult(0)}}}, 2034 {"create trigger a7 after insert on a for each row precedes a6 update b set y = y - 5 order by y asc", []sql.Row{{types.NewOkResult(0)}}}, 2035 {"create trigger a8 after insert on a for each row follows a6 update b set y = y * 3 order by y asc", []sql.Row{{types.NewOkResult(0)}}}, 2036 // order of execution should be: a7, a6, a8, a5 2037 } 2038 for _, tt := range setupTriggers { 2039 t.Run("setting up triggers", func(t *testing.T) { 2040 sql.RunWithNowFunc(func() time.Time { return date }, func() error { 2041 ctx = NewContext(harness) 2042 TestQueryWithContext(t, ctx, e, harness, tt.Query, tt.Expected, nil, nil) 2043 return nil 2044 }) 2045 }) 2046 } 2047 2048 // Test selecting these queries 2049 expectedResults := []struct { 2050 Query string 2051 Expected []sql.Row 2052 }{ 2053 { 2054 Query: "select * from information_schema.triggers", 2055 Expected: []sql.Row{ 2056 { 2057 "def", // trigger_catalog 2058 "mydb", // trigger_schema 2059 "a1", // trigger_name 2060 "INSERT", // event_manipulation 2061 "def", // event_object_catalog 2062 "mydb", // event_object_schema 2063 "a", // event_object_table 2064 int64(4), // action_order 2065 nil, // action_condition 2066 "set new.x = New.x + 1", // action_statement 2067 "ROW", // action_orientation 2068 "BEFORE", // action_timing 2069 nil, // action_reference_old_table 2070 nil, // action_reference_new_table 2071 "OLD", // action_reference_old_row 2072 "NEW", // action_reference_new_row 2073 date, // created 2074 "NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES", // sql_mode 2075 "root@localhost", // definer 2076 sql.Collation_Default.CharacterSet().String(), // character_set_client 2077 sql.Collation_Default.String(), // collation_connection 2078 sql.Collation_Default.String(), // database_collation 2079 }, 2080 { 2081 "def", // trigger_catalog 2082 "mydb", // trigger_schema 2083 "a2", // trigger_name 2084 "INSERT", // event_manipulation 2085 "def", // event_object_catalog 2086 "mydb", // event_object_schema 2087 "a", // event_object_table 2088 int64(2), // action_order 2089 nil, // action_condition 2090 "set new.x = New.x * 2", // action_statement 2091 "ROW", // action_orientation 2092 "BEFORE", // action_timing 2093 nil, // action_reference_old_table 2094 nil, // action_reference_new_table 2095 "OLD", // action_reference_old_row 2096 "NEW", // action_reference_new_row 2097 date, // created 2098 "NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES", // sql_mode 2099 "root@localhost", // definer 2100 sql.Collation_Default.CharacterSet().String(), // character_set_client 2101 sql.Collation_Default.String(), // collation_connection 2102 sql.Collation_Default.String(), // database_collation 2103 }, 2104 { 2105 "def", // trigger_catalog 2106 "mydb", // trigger_schema 2107 "a3", // trigger_name 2108 "INSERT", // event_manipulation 2109 "def", // event_object_catalog 2110 "mydb", // event_object_schema 2111 "a", // event_object_table 2112 int64(1), // action_order 2113 nil, // action_condition 2114 "set new.x = New.x - 5", // action_statement 2115 "ROW", // action_orientation 2116 "BEFORE", // action_timing 2117 nil, // action_reference_old_table 2118 nil, // action_reference_new_table 2119 "OLD", // action_reference_old_row 2120 "NEW", // action_reference_new_row 2121 date, // created 2122 "NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES", // sql_mode 2123 "root@localhost", // definer 2124 sql.Collation_Default.CharacterSet().String(), // character_set_client 2125 sql.Collation_Default.String(), // collation_connection 2126 sql.Collation_Default.String(), // database_collation 2127 }, 2128 { 2129 "def", // trigger_catalog 2130 "mydb", // trigger_schema 2131 "a4", // trigger_name 2132 "INSERT", // event_manipulation 2133 "def", // event_object_catalog 2134 "mydb", // event_object_schema 2135 "a", // event_object_table 2136 int64(3), // action_order 2137 nil, // action_condition 2138 "set new.x = New.x * 3", // action_statement 2139 "ROW", // action_orientation 2140 "BEFORE", // action_timing 2141 nil, // action_reference_old_table 2142 nil, // action_reference_new_table 2143 "OLD", // action_reference_old_row 2144 "NEW", // action_reference_new_row 2145 date, // created 2146 "NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES", // sql_mode 2147 "root@localhost", // definer 2148 sql.Collation_Default.CharacterSet().String(), // character_set_client 2149 sql.Collation_Default.String(), // collation_connection 2150 sql.Collation_Default.String(), // database_collation 2151 }, 2152 { 2153 "def", // trigger_catalog 2154 "mydb", // trigger_schema 2155 "a5", // trigger_name 2156 "INSERT", // event_manipulation 2157 "def", // event_object_catalog 2158 "mydb", // event_object_schema 2159 "a", // event_object_table 2160 int64(4), // action_order 2161 nil, // action_condition 2162 "update b set y = y + 1 order by y asc", // action_statement 2163 "ROW", // action_orientation 2164 "AFTER", // action_timing 2165 nil, // action_reference_old_table 2166 nil, // action_reference_new_table 2167 "OLD", // action_reference_old_row 2168 "NEW", // action_reference_new_row 2169 date, // created 2170 "NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES", // sql_mode 2171 "root@localhost", // definer 2172 sql.Collation_Default.CharacterSet().String(), // character_set_client 2173 sql.Collation_Default.String(), // collation_connection 2174 sql.Collation_Default.String(), // database_collation 2175 }, 2176 { 2177 "def", // trigger_catalog 2178 "mydb", // trigger_schema 2179 "a6", // trigger_name 2180 "INSERT", // event_manipulation 2181 "def", // event_object_catalog 2182 "mydb", // event_object_schema 2183 "a", // event_object_table 2184 int64(2), // action_order 2185 nil, // action_condition 2186 "update b set y = y * 2 order by y asc", // action_statement 2187 "ROW", // action_orientation 2188 "AFTER", // action_timing 2189 nil, // action_reference_old_table 2190 nil, // action_reference_new_table 2191 "OLD", // action_reference_old_row 2192 "NEW", // action_reference_new_row 2193 date, // created 2194 "NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES", // sql_mode 2195 "root@localhost", // definer 2196 sql.Collation_Default.CharacterSet().String(), // character_set_client 2197 sql.Collation_Default.String(), // collation_connection 2198 sql.Collation_Default.String(), // database_collation 2199 }, 2200 { 2201 "def", // trigger_catalog 2202 "mydb", // trigger_schema 2203 "a7", // trigger_name 2204 "INSERT", // event_manipulation 2205 "def", // event_object_catalog 2206 "mydb", // event_object_schema 2207 "a", // event_object_table 2208 int64(1), // action_order 2209 nil, // action_condition 2210 "update b set y = y - 5 order by y asc", // action_statement 2211 "ROW", // action_orientation 2212 "AFTER", // action_timing 2213 nil, // action_reference_old_table 2214 nil, // action_reference_new_table 2215 "OLD", // action_reference_old_row 2216 "NEW", // action_reference_new_row 2217 date, // created 2218 "NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES", // sql_mode 2219 "root@localhost", // definer 2220 sql.Collation_Default.CharacterSet().String(), // character_set_client 2221 sql.Collation_Default.String(), // collation_connection 2222 sql.Collation_Default.String(), // database_collation 2223 }, 2224 { 2225 "def", // trigger_catalog 2226 "mydb", // trigger_schema 2227 "a8", // trigger_name 2228 "INSERT", // event_manipulation 2229 "def", // event_object_catalog 2230 "mydb", // event_object_schema 2231 "a", // event_object_table 2232 int64(3), // action_order 2233 nil, // action_condition 2234 "update b set y = y * 3 order by y asc", // action_statement 2235 "ROW", // action_orientation 2236 "AFTER", // action_timing 2237 nil, // action_reference_old_table 2238 nil, // action_reference_new_table 2239 "OLD", // action_reference_old_row 2240 "NEW", // action_reference_new_row 2241 date, // created 2242 "NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES", // sql_mode 2243 "root@localhost", // definer 2244 sql.Collation_Default.CharacterSet().String(), // character_set_client 2245 sql.Collation_Default.String(), // collation_connection 2246 sql.Collation_Default.String(), // database_collation 2247 }, 2248 }, 2249 }, 2250 } 2251 2252 for _, tt := range expectedResults { 2253 t.Run(tt.Query, func(t *testing.T) { 2254 TestQueryWithContext(t, ctx, e, harness, tt.Query, tt.Expected, nil, nil) 2255 }) 2256 } 2257 } 2258 2259 func TestStoredProcedures(t *testing.T, harness Harness) { 2260 t.Run("logic tests", func(t *testing.T) { 2261 for _, script := range queries.ProcedureLogicTests { 2262 TestScript(t, harness, script) 2263 } 2264 }) 2265 t.Run("call tests", func(t *testing.T) { 2266 for _, script := range queries.ProcedureCallTests { 2267 TestScript(t, harness, script) 2268 } 2269 }) 2270 t.Run("drop tests", func(t *testing.T) { 2271 for _, script := range queries.ProcedureDropTests { 2272 TestScript(t, harness, script) 2273 } 2274 }) 2275 t.Run("show status tests", func(t *testing.T) { 2276 for _, script := range queries.ProcedureShowStatus { 2277 TestScript(t, harness, script) 2278 } 2279 }) 2280 t.Run("show create tests", func(t *testing.T) { 2281 for _, script := range queries.ProcedureShowCreate { 2282 TestScript(t, harness, script) 2283 } 2284 }) 2285 harness.Setup(setup.MydbData) 2286 e := mustNewEngine(t, harness) 2287 defer e.Close() 2288 t.Run("no database selected", func(t *testing.T) { 2289 ctx := NewContext(harness) 2290 ctx.SetCurrentDatabase("") 2291 2292 for _, script := range queries.NoDbProcedureTests { 2293 t.Run(script.Query, func(t *testing.T) { 2294 if script.Expected != nil || script.SkipResultsCheck { 2295 expectedResult := script.Expected 2296 if script.SkipResultsCheck { 2297 expectedResult = nil 2298 } 2299 TestQueryWithContext(t, ctx, e, harness, script.Query, expectedResult, nil, nil) 2300 } else if script.ExpectedErr != nil { 2301 AssertErrWithCtx(t, e, harness, ctx, script.Query, script.ExpectedErr) 2302 } 2303 }) 2304 } 2305 2306 TestQueryWithContext(t, ctx, e, harness, "CREATE PROCEDURE mydb.p1() SELECT 5", []sql.Row{{types.OkResult{}}}, nil, nil) 2307 TestQueryWithContext(t, ctx, e, harness, "CREATE PROCEDURE mydb.p2() SELECT 6", []sql.Row{{types.OkResult{}}}, nil, nil) 2308 2309 TestQueryWithContext(t, ctx, e, harness, "SHOW PROCEDURE STATUS", []sql.Row{ 2310 {"mydb", "p1", "PROCEDURE", "", time.Unix(0, 0).UTC(), time.Unix(0, 0).UTC(), 2311 "DEFINER", "", "utf8mb4", "utf8mb4_0900_bin", "utf8mb4_0900_bin"}, 2312 {"mydb", "p2", "PROCEDURE", "", time.Unix(0, 0).UTC(), time.Unix(0, 0).UTC(), 2313 "DEFINER", "", "utf8mb4", "utf8mb4_0900_bin", "utf8mb4_0900_bin"}, 2314 {"mydb", "p5", "PROCEDURE", "", time.Unix(0, 0).UTC(), time.Unix(0, 0).UTC(), 2315 "DEFINER", "", "utf8mb4", "utf8mb4_0900_bin", "utf8mb4_0900_bin"}, 2316 }, nil, nil) 2317 2318 TestQueryWithContext(t, ctx, e, harness, "DROP PROCEDURE mydb.p1", []sql.Row{{types.OkResult{}}}, nil, nil) 2319 2320 TestQueryWithContext(t, ctx, e, harness, "SHOW PROCEDURE STATUS", []sql.Row{ 2321 {"mydb", "p2", "PROCEDURE", "", time.Unix(0, 0).UTC(), time.Unix(0, 0).UTC(), 2322 "DEFINER", "", "utf8mb4", "utf8mb4_0900_bin", "utf8mb4_0900_bin"}, 2323 {"mydb", "p5", "PROCEDURE", "", time.Unix(0, 0).UTC(), time.Unix(0, 0).UTC(), 2324 "DEFINER", "", "utf8mb4", "utf8mb4_0900_bin", "utf8mb4_0900_bin"}, 2325 }, nil, nil) 2326 }) 2327 } 2328 2329 func TestEvents(t *testing.T, h Harness) { 2330 for _, script := range queries.EventTests { 2331 TestScript(t, h, script) 2332 } 2333 } 2334 2335 func TestTriggerErrors(t *testing.T, harness Harness) { 2336 for _, script := range queries.TriggerErrorTests { 2337 TestScript(t, harness, script) 2338 } 2339 } 2340 2341 func getClient(query string) string { 2342 startCommentIdx := strings.Index(query, "/*") 2343 endCommentIdx := strings.Index(query, "*/") 2344 if startCommentIdx < 0 || endCommentIdx < 0 { 2345 panic("no client comment found in query " + query) 2346 } 2347 2348 query = query[startCommentIdx+2 : endCommentIdx] 2349 if strings.Index(query, "client ") < 0 { 2350 panic("no client comment found in query " + query) 2351 } 2352 2353 return strings.TrimSpace(strings.TrimPrefix(query, "client")) 2354 } 2355 2356 func TestViews(t *testing.T, harness Harness) { 2357 harness.Setup(setup.MydbData, setup.MytableData) 2358 e := mustNewEngine(t, harness) 2359 defer e.Close() 2360 ctx := NewContext(harness) 2361 2362 // nested views 2363 RunQueryWithContext(t, e, harness, ctx, "CREATE VIEW myview2 AS SELECT * FROM myview WHERE i = 1") 2364 for _, testCase := range queries.ViewTests { 2365 t.Run(testCase.Query, func(t *testing.T) { 2366 TestQueryWithContext(t, ctx, e, harness, testCase.Query, testCase.Expected, nil, nil) 2367 }) 2368 } 2369 2370 // Views with non-standard select statements 2371 RunQueryWithContext(t, e, harness, ctx, "create view unionView as (select * from myTable order by i limit 1) union all (select * from mytable order by i limit 1)") 2372 t.Run("select * from unionview order by i", func(t *testing.T) { 2373 TestQueryWithContext(t, ctx, e, harness, "select * from unionview order by i", []sql.Row{ 2374 {1, "first row"}, 2375 {1, "first row"}, 2376 }, nil, nil) 2377 }) 2378 2379 t.Run("create view with algorithm, definer, security defined", func(t *testing.T) { 2380 TestQueryWithContext(t, ctx, e, harness, "CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW newview AS SELECT * FROM myview WHERE i = 1", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2381 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM newview ORDER BY i", []sql.Row{ 2382 sql.NewRow(int64(1), "first row"), 2383 }, nil, nil) 2384 2385 TestQueryWithContext(t, ctx, e, harness, "CREATE OR REPLACE ALGORITHM=MERGE DEFINER=doltUser SQL SECURITY INVOKER VIEW newview AS SELECT * FROM myview WHERE i = 2", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2386 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM newview ORDER BY i", []sql.Row{ 2387 sql.NewRow(int64(2), "second row"), 2388 }, nil, nil) 2389 }) 2390 2391 // Newer Tests should be put in view_queries.go 2392 harness.Setup(setup.MydbData) 2393 for _, script := range queries.ViewScripts { 2394 TestScript(t, harness, script) 2395 } 2396 } 2397 2398 func TestRecursiveViewDefinition(t *testing.T, harness Harness) { 2399 harness.Setup(setup.MydbData, setup.MytableData) 2400 e := mustNewEngine(t, harness) 2401 defer e.Close() 2402 ctx := NewContext(harness) 2403 2404 db, err := e.EngineAnalyzer().Catalog.Database(ctx, "mydb") 2405 require.NoError(t, err) 2406 2407 _, ok := db.(sql.ViewDatabase) 2408 require.True(t, ok, "expected sql.ViewDatabase") 2409 2410 AssertErr(t, e, harness, "create view recursiveView AS select * from recursiveView", sql.ErrTableNotFound) 2411 } 2412 2413 func TestViewsPrepared(t *testing.T, harness Harness) { 2414 harness.Setup(setup.MydbData, setup.MytableData) 2415 e := mustNewEngine(t, harness) 2416 defer e.Close() 2417 ctx := NewContext(harness) 2418 2419 RunQueryWithContext(t, e, harness, ctx, "CREATE VIEW myview2 AS SELECT * FROM myview WHERE i = 1") 2420 for _, testCase := range queries.ViewTests { 2421 TestPreparedQueryWithEngine(t, harness, e, testCase) 2422 } 2423 } 2424 2425 // initializeViewsForVersionedViewsTests creates the test views used by the TestVersionedViews and 2426 // TestVersionedViewsPrepared functions. 2427 func initializeViewsForVersionedViewsTests(t *testing.T, harness VersionedDBHarness, e QueryEngine) { 2428 require := require.New(t) 2429 2430 ctx := NewContext(harness) 2431 _, iter, err := e.Query(ctx, "CREATE VIEW myview1 AS SELECT * FROM myhistorytable") 2432 require.NoError(err) 2433 _, err = sql.RowIterToRows(ctx, iter) 2434 require.NoError(err) 2435 2436 // nested views 2437 _, iter, err = e.Query(ctx, "CREATE VIEW myview2 AS SELECT * FROM myview1 WHERE i = 1") 2438 require.NoError(err) 2439 _, err = sql.RowIterToRows(ctx, iter) 2440 require.NoError(err) 2441 2442 // views with unions 2443 _, iter, err = e.Query(ctx, "CREATE VIEW myview3 AS SELECT i from myview1 union select s from myhistorytable") 2444 require.NoError(err) 2445 _, err = sql.RowIterToRows(ctx, iter) 2446 require.NoError(err) 2447 2448 // views with subqueries 2449 _, iter, err = e.Query(ctx, "CREATE VIEW myview4 AS SELECT * FROM myhistorytable where i in (select distinct cast(RIGHT(s, 1) as signed) from myhistorytable)") 2450 require.NoError(err) 2451 _, err = sql.RowIterToRows(ctx, iter) 2452 require.NoError(err) 2453 2454 // views with a subquery alias 2455 _, iter, err = e.Query(ctx, "CREATE VIEW myview5 AS SELECT * FROM (select * from myhistorytable where i in (select distinct cast(RIGHT(s, 1) as signed))) as sq") 2456 require.NoError(err) 2457 _, err = sql.RowIterToRows(ctx, iter) 2458 require.NoError(err) 2459 } 2460 2461 func TestVersionedViews(t *testing.T, harness VersionedDBHarness) { 2462 CreateVersionedTestData(t, harness) 2463 e, err := harness.NewEngine(t) 2464 require.NoError(t, err) 2465 defer e.Close() 2466 2467 initializeViewsForVersionedViewsTests(t, harness, e) 2468 for _, testCase := range queries.VersionedViewTests { 2469 t.Run(testCase.Query, func(t *testing.T) { 2470 ctx := NewContext(harness) 2471 TestQueryWithContext(t, ctx, e, harness, testCase.Query, testCase.Expected, testCase.ExpectedColumns, nil) 2472 }) 2473 } 2474 } 2475 2476 func TestVersionedViewsPrepared(t *testing.T, harness VersionedDBHarness) { 2477 CreateVersionedTestData(t, harness) 2478 e, err := harness.NewEngine(t) 2479 require.NoError(t, err) 2480 defer e.Close() 2481 2482 initializeViewsForVersionedViewsTests(t, harness, e) 2483 for _, testCase := range queries.VersionedViewTests { 2484 TestPreparedQueryWithEngine(t, harness, e, testCase) 2485 } 2486 } 2487 2488 func TestCreateTable(t *testing.T, harness Harness) { 2489 harness.Setup(setup.MydbData, setup.MytableData, setup.FooData) 2490 for _, tt := range queries.CreateTableQueries { 2491 t.Run(tt.WriteQuery, func(t *testing.T) { 2492 RunWriteQueryTest(t, harness, tt) 2493 }) 2494 } 2495 2496 for _, script := range queries.CreateTableScriptTests { 2497 TestScript(t, harness, script) 2498 } 2499 2500 for _, script := range queries.CreateTableAutoIncrementTests { 2501 TestScript(t, harness, script) 2502 } 2503 2504 harness.Setup(setup.MydbData, setup.MytableData) 2505 e := mustNewEngine(t, harness) 2506 defer e.Close() 2507 2508 t.Run("no database selected", func(t *testing.T) { 2509 ctx := NewContext(harness) 2510 ctx.SetCurrentDatabase("") 2511 2512 TestQueryWithContext(t, ctx, e, harness, "CREATE TABLE mydb.t11 (a INTEGER NOT NULL PRIMARY KEY, "+ 2513 "b VARCHAR(10) NOT NULL)", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2514 2515 db, err := e.EngineAnalyzer().Catalog.Database(ctx, "mydb") 2516 require.NoError(t, err) 2517 2518 testTable, ok, err := db.GetTableInsensitive(ctx, "t11") 2519 require.NoError(t, err) 2520 require.True(t, ok) 2521 2522 s := sql.Schema{ 2523 {Name: "a", Type: types.Int32, Nullable: false, PrimaryKey: true, DatabaseSource: "mydb", Source: "t11"}, 2524 {Name: "b", Type: types.MustCreateStringWithDefaults(sqltypes.VarChar, 10), Nullable: false, DatabaseSource: "mydb", Source: "t11"}, 2525 } 2526 2527 require.Equal(t, s, testTable.Schema()) 2528 }) 2529 2530 t.Run("CREATE TABLE with multiple unnamed indexes", func(t *testing.T) { 2531 ctx := NewContext(harness) 2532 ctx.SetCurrentDatabase("") 2533 2534 TestQueryWithContext(t, ctx, e, harness, "CREATE TABLE mydb.t12 (a INTEGER NOT NULL PRIMARY KEY, "+ 2535 "b VARCHAR(10) UNIQUE, c varchar(10) UNIQUE)", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2536 2537 db, err := e.EngineAnalyzer().Catalog.Database(ctx, "mydb") 2538 require.NoError(t, err) 2539 2540 t12Table, ok, err := db.GetTableInsensitive(ctx, "t12") 2541 require.NoError(t, err) 2542 require.True(t, ok) 2543 2544 t9TableIndexable, ok := t12Table.(sql.IndexAddressableTable) 2545 require.True(t, ok) 2546 t9Indexes, err := t9TableIndexable.GetIndexes(ctx) 2547 require.NoError(t, err) 2548 uniqueCount := 0 2549 for _, index := range t9Indexes { 2550 if index.IsUnique() { 2551 uniqueCount += 1 2552 } 2553 } 2554 2555 // We want two unique indexes to be created with unique names being generated. It is up to the integrator 2556 // to decide how empty string indexes are created. Adding in the primary key gives us a result of 3. 2557 require.Equal(t, 3, uniqueCount) 2558 2559 // Validate No Unique Index has an empty Name 2560 for _, index := range t9Indexes { 2561 require.True(t, index.ID() != "") 2562 } 2563 }) 2564 2565 t.Run("create table with blob column with null default", func(t *testing.T) { 2566 ctx := NewContext(harness) 2567 RunQueryWithContext(t, e, harness, ctx, "USE mydb") 2568 TestQueryWithContext(t, ctx, e, harness, "CREATE TABLE t_blob_default_null(c BLOB DEFAULT NULL)", 2569 []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2570 2571 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t_blob_default_null VALUES ()") 2572 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t_blob_default_null", 2573 []sql.Row{{nil}}, nil, nil) 2574 }) 2575 2576 t.Run("create table like works and can have keys removed", func(t *testing.T) { 2577 ctx := NewContext(harness) 2578 RunQueryWithContext(t, e, harness, ctx, "USE mydb") 2579 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE test(pk int AUTO_INCREMENT PRIMARY KEY, val int)") 2580 2581 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE test2 like test") 2582 2583 RunQueryWithContext(t, e, harness, ctx, "ALTER TABLE test2 modify pk int") 2584 TestQueryWithContext(t, ctx, e, harness, "DESCRIBE test2", []sql.Row{{"pk", "int", "NO", "PRI", "NULL", ""}, 2585 {"val", "int", "YES", "", "NULL", ""}}, nil, nil) 2586 2587 RunQueryWithContext(t, e, harness, ctx, "ALTER TABLE test2 drop primary key") 2588 2589 TestQueryWithContext(t, ctx, e, harness, "DESCRIBE test2", []sql.Row{{"pk", "int", "NO", "", "NULL", ""}, 2590 {"val", "int", "YES", "", "NULL", ""}}, nil, nil) 2591 }) 2592 2593 for _, tt := range queries.BrokenCreateTableQueries { 2594 t.Skip("primary key lengths are not stored properly") 2595 RunWriteQueryTest(t, harness, tt) 2596 } 2597 } 2598 2599 func TestDropTable(t *testing.T, harness Harness) { 2600 require := require.New(t) 2601 2602 harness.Setup(setup.MydbData, setup.MytableData, setup.OthertableData, setup.TabletestData, setup.Pk_tablesData) 2603 2604 func() { 2605 e := mustNewEngine(t, harness) 2606 defer e.Close() 2607 ctx := NewContext(harness) 2608 db, err := e.EngineAnalyzer().Catalog.Database(ctx, "mydb") 2609 require.NoError(err) 2610 2611 _, ok, err := db.GetTableInsensitive(ctx, "mytable") 2612 require.True(ok) 2613 2614 TestQueryWithContext(t, ctx, e, harness, "DROP TABLE IF EXISTS mytable, not_exist", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2615 2616 _, ok, err = db.GetTableInsensitive(ctx, "mytable") 2617 require.NoError(err) 2618 require.False(ok) 2619 2620 _, ok, err = db.GetTableInsensitive(ctx, "othertable") 2621 require.NoError(err) 2622 require.True(ok) 2623 2624 _, ok, err = db.GetTableInsensitive(ctx, "tabletest") 2625 require.NoError(err) 2626 require.True(ok) 2627 2628 TestQueryWithContext(t, ctx, e, harness, "DROP TABLE IF EXISTS othertable, tabletest", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2629 2630 _, ok, err = db.GetTableInsensitive(ctx, "othertable") 2631 require.NoError(err) 2632 require.False(ok) 2633 2634 _, ok, err = db.GetTableInsensitive(ctx, "tabletest") 2635 require.NoError(err) 2636 require.False(ok) 2637 2638 _, _, err = e.Query(NewContext(harness), "DROP TABLE not_exist") 2639 require.Error(err) 2640 2641 _, _, err = e.Query(NewContext(harness), "DROP TABLE IF EXISTS not_exist") 2642 require.NoError(err) 2643 }() 2644 2645 t.Run("no database selected", func(t *testing.T) { 2646 e := mustNewEngine(t, harness) 2647 defer e.Close() 2648 2649 ctx := NewContext(harness) 2650 ctx.SetCurrentDatabase("") 2651 2652 db, err := e.EngineAnalyzer().Catalog.Database(ctx, "mydb") 2653 require.NoError(err) 2654 2655 RunQueryWithContext(t, e, harness, ctx, "CREATE DATABASE otherdb") 2656 otherdb, err := e.EngineAnalyzer().Catalog.Database(ctx, "otherdb") 2657 2658 TestQueryWithContext(t, ctx, e, harness, "DROP TABLE mydb.one_pk", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2659 2660 _, ok, err := db.GetTableInsensitive(ctx, "mydb.one_pk") 2661 require.NoError(err) 2662 require.False(ok) 2663 2664 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE otherdb.table1 (pk1 integer primary key)") 2665 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE otherdb.table2 (pk2 integer primary key)") 2666 2667 _, _, err = e.Query(ctx, "DROP TABLE otherdb.table1, mydb.one_pk_two_idx") 2668 require.Error(err) 2669 2670 _, ok, err = otherdb.GetTableInsensitive(ctx, "table1") 2671 require.NoError(err) 2672 require.True(ok) 2673 2674 _, ok, err = db.GetTableInsensitive(ctx, "one_pk_two_idx") 2675 require.NoError(err) 2676 require.True(ok) 2677 2678 _, _, err = e.Query(ctx, "DROP TABLE IF EXISTS otherdb.table1, mydb.one_pk") 2679 require.Error(err) 2680 2681 _, ok, err = otherdb.GetTableInsensitive(ctx, "table1") 2682 require.NoError(err) 2683 require.True(ok) 2684 2685 _, ok, err = db.GetTableInsensitive(ctx, "one_pk_two_idx") 2686 require.NoError(err) 2687 require.True(ok) 2688 2689 _, _, err = e.Query(ctx, "DROP TABLE otherdb.table1, otherdb.table3") 2690 require.Error(err) 2691 2692 _, ok, err = otherdb.GetTableInsensitive(ctx, "table1") 2693 require.NoError(err) 2694 require.True(ok) 2695 2696 _, _, err = e.Query(ctx, "DROP TABLE IF EXISTS otherdb.table1, otherdb.table3") 2697 require.NoError(err) 2698 2699 _, ok, err = otherdb.GetTableInsensitive(ctx, "table1") 2700 require.NoError(err) 2701 require.False(ok) 2702 }) 2703 2704 t.Run("cur database selected, drop tables in other db", func(t *testing.T) { 2705 e := mustNewEngine(t, harness) 2706 defer e.Close() 2707 2708 ctx := NewContext(harness) 2709 ctx.SetCurrentDatabase("mydb") 2710 2711 db, err := e.EngineAnalyzer().Catalog.Database(ctx, "mydb") 2712 require.NoError(err) 2713 2714 RunQueryWithContext(t, e, harness, ctx, "DROP DATABASE IF EXISTS otherdb") 2715 RunQueryWithContext(t, e, harness, ctx, "CREATE DATABASE otherdb") 2716 otherdb, err := e.EngineAnalyzer().Catalog.Database(ctx, "otherdb") 2717 2718 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE tab1 (pk1 integer primary key, c1 text)") 2719 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE otherdb.tab1 (other_pk1 integer primary key)") 2720 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE otherdb.tab2 (other_pk2 integer primary key)") 2721 2722 _, _, err = e.Query(ctx, "DROP TABLE otherdb.tab1") 2723 require.NoError(err) 2724 2725 _, ok, err := db.GetTableInsensitive(ctx, "tab1") 2726 require.NoError(err) 2727 require.True(ok) 2728 2729 _, ok, err = otherdb.GetTableInsensitive(ctx, "tab1") 2730 require.NoError(err) 2731 require.False(ok) 2732 2733 _, _, err = e.Query(ctx, "DROP TABLE nonExistentTable, otherdb.tab2") 2734 require.Error(err) 2735 2736 _, _, err = e.Query(ctx, "DROP TABLE IF EXISTS nonExistentTable, otherdb.tab2") 2737 require.Error(err) 2738 2739 _, ok, err = otherdb.GetTableInsensitive(ctx, "tab2") 2740 require.NoError(err) 2741 require.True(ok) 2742 2743 _, _, err = e.Query(ctx, "DROP TABLE IF EXISTS otherdb.tab3, otherdb.tab2") 2744 require.NoError(err) 2745 2746 _, ok, err = otherdb.GetTableInsensitive(ctx, "tab2") 2747 require.NoError(err) 2748 require.False(ok) 2749 }) 2750 } 2751 2752 func TestRenameTable(t *testing.T, harness Harness) { 2753 harness.Setup(setup.MydbData, setup.MytableData, setup.OthertableData, setup.NiltableData, setup.EmptytableData) 2754 e := mustNewEngine(t, harness) 2755 defer e.Close() 2756 2757 for _, tt := range queries.RenameTableScripts { 2758 TestScriptWithEngine(t, e, harness, tt) 2759 } 2760 2761 t.Run("no database selected", func(t *testing.T) { 2762 ctx := NewContext(harness) 2763 ctx.SetCurrentDatabase("") 2764 if se, ok := e.(*ServerQueryEngine); ok { 2765 se.NewConnection(ctx) 2766 } 2767 TestQueryWithContext(t, ctx, e, harness, "select database()", []sql.Row{{nil}}, nil, nil) 2768 2769 t.Skip("broken") 2770 TestQueryWithContext(t, ctx, e, harness, "RENAME TABLE mydb.emptytable TO mydb.emptytable2", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2771 AssertErrWithCtx(t, e, harness, ctx, "SELECT COUNT(*) FROM mydb.emptytable", sql.ErrTableNotFound) 2772 TestQueryWithContext(t, ctx, e, harness, "SELECT COUNT(*) FROM mydb.emptytable2", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2773 AssertErrWithCtx(t, e, harness, ctx, "RENAME TABLE mydb.emptytable2 TO emptytable3", sql.ErrNoDatabaseSelected) 2774 }) 2775 } 2776 2777 func TestRenameColumn(t *testing.T, harness Harness) { 2778 harness.Setup(setup.MydbData, setup.MytableData, setup.TabletestData) 2779 e := mustNewEngine(t, harness) 2780 defer e.Close() 2781 2782 for _, tt := range queries.RenameColumnScripts { 2783 TestScriptWithEngine(t, e, harness, tt) 2784 } 2785 2786 t.Run("no database selected", func(t *testing.T) { 2787 ctx := NewContext(harness) 2788 ctx.SetCurrentDatabase("") 2789 if se, ok := e.(*ServerQueryEngine); ok { 2790 se.NewConnection(ctx) 2791 } 2792 TestQueryWithContext(t, ctx, e, harness, "select database()", []sql.Row{{nil}}, nil, nil) 2793 TestQueryWithContext(t, ctx, e, harness, "ALTER TABLE mydb.tabletest RENAME COLUMN s TO i1", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2794 TestQueryWithContext(t, ctx, e, harness, "SHOW FULL COLUMNS FROM mydb.tabletest", []sql.Row{ 2795 {"i", "int", nil, "NO", "PRI", "NULL", "", "", ""}, 2796 {"i1", "varchar(20)", "utf8mb4_0900_bin", "NO", "", "NULL", "", "", ""}, 2797 }, nil, nil) 2798 }) 2799 } 2800 2801 func TestAddColumn(t *testing.T, harness Harness) { 2802 harness.Setup(setup.MydbData, setup.MytableData) 2803 e := mustNewEngine(t, harness) 2804 defer e.Close() 2805 2806 for _, tt := range queries.AddColumnScripts { 2807 TestScriptWithEngine(t, e, harness, tt) 2808 } 2809 2810 t.Run("no database selected", func(t *testing.T) { 2811 ctx := NewContext(harness) 2812 ctx.SetCurrentDatabase("") 2813 if se, ok := e.(*ServerQueryEngine); ok { 2814 se.NewConnection(ctx) 2815 } 2816 TestQueryWithContext(t, ctx, e, harness, "select database()", []sql.Row{{nil}}, nil, nil) 2817 TestQueryWithContext(t, ctx, e, harness, "ALTER TABLE mydb.mytable ADD COLUMN s10 VARCHAR(26)", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2818 TestQueryWithContext(t, ctx, e, harness, "SHOW FULL COLUMNS FROM mydb.mytable", []sql.Row{ 2819 {"s3", "varchar(25)", "utf8mb4_0900_bin", "YES", "", "'yay'", "", "", "hello"}, 2820 {"s4", "varchar(1)", "utf8mb4_0900_bin", "NO", "", "NULL", "", "", ""}, 2821 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", ""}, 2822 {"s2", "text", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "hello"}, 2823 {"s", "varchar(20)", "utf8mb4_0900_bin", "NO", "UNI", "NULL", "", "", "column s"}, 2824 {"i2", "int", nil, "YES", "", "42", "", "", "hello"}, 2825 {"s5", "varchar(26)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", ""}, 2826 {"s6", "varchar(27)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", ""}, 2827 {"s10", "varchar(26)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", ""}, 2828 }, nil, nil) 2829 }) 2830 } 2831 2832 func TestModifyColumn(t *testing.T, harness Harness) { 2833 harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData) 2834 e := mustNewEngine(t, harness) 2835 defer e.Close() 2836 2837 for _, tt := range queries.ModifyColumnScripts { 2838 TestScriptWithEngine(t, e, harness, tt) 2839 } 2840 2841 t.Run("no database selected", func(t *testing.T) { 2842 ctx := NewContext(harness) 2843 ctx.SetCurrentDatabase("") 2844 if se, ok := e.(*ServerQueryEngine); ok { 2845 se.NewConnection(ctx) 2846 } 2847 TestQueryWithContext(t, ctx, e, harness, "select database()", []sql.Row{{nil}}, nil, nil) 2848 TestQueryWithContext(t, ctx, e, harness, "ALTER TABLE mydb.mytable MODIFY COLUMN s VARCHAR(21) NULL COMMENT 'changed again'", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2849 TestQueryWithContext(t, ctx, e, harness, "SHOW FULL COLUMNS FROM mydb.mytable", []sql.Row{ 2850 {"i", "bigint", nil, "NO", "PRI", "NULL", "", "", "ok"}, 2851 {"s", "varchar(21)", "utf8mb4_0900_bin", "YES", "", "NULL", "", "", "changed again"}, 2852 {"i2", "bigint", nil, "YES", "", "NULL", "", "", ""}, 2853 }, nil, nil) 2854 }) 2855 } 2856 2857 func TestDropColumn(t *testing.T, harness Harness) { 2858 harness.Setup(setup.MydbData, setup.MytableData, setup.TabletestData) 2859 e := mustNewEngine(t, harness) 2860 defer e.Close() 2861 2862 for _, tt := range queries.DropColumnScripts { 2863 TestScriptWithEngine(t, e, harness, tt) 2864 } 2865 2866 t.Run("no database selected", func(t *testing.T) { 2867 ctx := NewContext(harness) 2868 ctx.SetCurrentDatabase("") 2869 if se, ok := e.(*ServerQueryEngine); ok { 2870 se.NewConnection(ctx) 2871 } 2872 2873 TestQueryWithContext(t, ctx, e, harness, "select database()", []sql.Row{{nil}}, nil, nil) 2874 TestQueryWithContext(t, ctx, e, harness, "ALTER TABLE mydb.tabletest DROP COLUMN s", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2875 TestQueryWithContext(t, ctx, e, harness, "SHOW FULL COLUMNS FROM mydb.tabletest", []sql.Row{{"i", "int", nil, "NO", "PRI", "NULL", "", "", ""}}, nil, nil) 2876 }) 2877 } 2878 2879 func TestDropColumnKeylessTables(t *testing.T, harness Harness) { 2880 harness.Setup(setup.MydbData, setup.TabletestData) 2881 e := mustNewEngine(t, harness) 2882 defer e.Close() 2883 2884 for _, tt := range queries.DropColumnKeylessTablesScripts { 2885 TestScriptWithEngine(t, e, harness, tt) 2886 } 2887 2888 t.Run("no database selected", func(t *testing.T) { 2889 ctx := NewContext(harness) 2890 ctx.SetCurrentDatabase("") 2891 if se, ok := e.(*ServerQueryEngine); ok { 2892 se.NewConnection(ctx) 2893 } 2894 2895 TestQueryWithContext(t, ctx, e, harness, "select database()", []sql.Row{{nil}}, nil, nil) 2896 TestQueryWithContext(t, ctx, e, harness, "ALTER TABLE mydb.tabletest DROP COLUMN s", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 2897 TestQueryWithContext(t, ctx, e, harness, "SHOW FULL COLUMNS FROM mydb.tabletest", []sql.Row{{"i", "int", nil, "NO", "PRI", "NULL", "", "", ""}}, nil, nil) 2898 }) 2899 } 2900 2901 func TestCreateDatabase(t *testing.T, harness Harness) { 2902 harness.Setup() 2903 e := mustNewEngine(t, harness) 2904 defer e.Close() 2905 2906 for _, tt := range queries.CreateDatabaseScripts { 2907 TestScriptWithEngine(t, e, harness, tt) 2908 } 2909 } 2910 2911 func TestPkOrdinalsDDL(t *testing.T, harness Harness) { 2912 harness.Setup(setup.OrdinalSetup...) 2913 for _, tt := range queries.OrdinalDDLQueries { 2914 TestQuery(t, harness, tt.Query, tt.Expected, tt.ExpectedColumns, nil) 2915 } 2916 2917 for _, tt := range queries.OrdinalDDLWriteQueries { 2918 RunWriteQueryTest(t, harness, tt) 2919 } 2920 } 2921 2922 func TestPkOrdinalsDML(t *testing.T, harness Harness) { 2923 dml := []struct { 2924 create string 2925 insert string 2926 mutate string 2927 sel string 2928 exp []sql.Row 2929 }{ 2930 { 2931 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2932 insert: "INSERT INTO a values (0,0,0,0), (1,1,1,1), (2,2,2,2)", 2933 mutate: "DELETE FROM a WHERE x = 0", 2934 sel: "select * from a", 2935 exp: []sql.Row{{1, 1, 1, 1}, {2, 2, 2, 2}}, 2936 }, 2937 { 2938 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x,w))", 2939 insert: "INSERT INTO a values (0,0,0,0), (1,1,1,1), (2,2,2,2)", 2940 mutate: "DELETE FROM a WHERE x = 0 and z = 0", 2941 sel: "select * from a", 2942 exp: []sql.Row{{1, 1, 1, 1}, {2, 2, 2, 2}}, 2943 }, 2944 { 2945 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2946 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 2947 mutate: "DELETE FROM a WHERE y = 2", 2948 sel: "select * from a", 2949 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}}, 2950 }, 2951 { 2952 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2953 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 2954 mutate: "DELETE FROM a WHERE y in (2)", 2955 sel: "select * from a", 2956 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}}, 2957 }, 2958 { 2959 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2960 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 2961 mutate: "DELETE FROM a WHERE y not in (NULL)", 2962 sel: "select * from a", 2963 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}, {2, 2, 2, 2}}, 2964 }, 2965 { 2966 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2967 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 2968 mutate: "DELETE FROM a WHERE y IS NOT NULL", 2969 sel: "select * from a", 2970 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}}, 2971 }, 2972 { 2973 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2974 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 2975 mutate: "DELETE FROM a WHERE y IS NULL", 2976 sel: "select * from a", 2977 exp: []sql.Row{{2, 2, 2, 2}}, 2978 }, 2979 { 2980 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2981 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 2982 mutate: "DELETE FROM a WHERE y = NULL", 2983 sel: "select * from a", 2984 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}, {2, 2, 2, 2}}, 2985 }, 2986 { 2987 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2988 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 2989 mutate: "DELETE FROM a WHERE y = NULL or y in (2,4)", 2990 sel: "select * from a", 2991 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}}, 2992 }, 2993 { 2994 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 2995 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 2996 mutate: "DELETE FROM a WHERE y IS NULL or y in (2,4)", 2997 sel: "select * from a", 2998 exp: []sql.Row{}, 2999 }, 3000 { 3001 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 3002 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 3003 mutate: "DELETE FROM a WHERE y IS NULL AND z != 0", 3004 sel: "select * from a", 3005 exp: []sql.Row{{0, nil, 0, 0}, {2, 2, 2, 2}}, 3006 }, 3007 { 3008 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 3009 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 3010 mutate: "DELETE FROM a WHERE y != NULL", 3011 sel: "select * from a", 3012 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}, {2, 2, 2, 2}}, 3013 }, 3014 { 3015 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x,w))", 3016 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 3017 mutate: "DELETE FROM a WHERE x in (0,2) and z in (0,4)", 3018 sel: "select * from a", 3019 exp: []sql.Row{{1, nil, 1, 1}, {2, 2, 2, 2}}, 3020 }, 3021 { 3022 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 3023 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 3024 mutate: "DELETE FROM a WHERE y in (2,-1)", 3025 sel: "select * from a", 3026 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}}, 3027 }, 3028 { 3029 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 3030 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 3031 mutate: "DELETE FROM a WHERE y < 3", 3032 sel: "select * from a", 3033 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}}, 3034 }, 3035 { 3036 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 3037 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 3038 mutate: "DELETE FROM a WHERE y > 0 and z = 2", 3039 sel: "select * from a", 3040 exp: []sql.Row{{0, nil, 0, 0}, {1, nil, 1, 1}}, 3041 }, 3042 { 3043 create: "CREATE TABLE a (x int, y int, z int, w int, primary key (z,x))", 3044 insert: "INSERT INTO a values (0,NULL,0,0), (1,NULL,1,1), (2,2,2,2)", 3045 mutate: "DELETE FROM a WHERE y = 2", 3046 sel: "select y from a", 3047 exp: []sql.Row{{nil}, {nil}}, 3048 }, 3049 { 3050 create: "CREATE TABLE a (x int, y int, z int, w int, index idx1 (y))", 3051 insert: "INSERT INTO a values (0,0,0,0), (1,1,1,1), (2,2,2,2)", 3052 mutate: "", 3053 sel: "select * from a where y = 3", 3054 exp: []sql.Row{}, 3055 }, 3056 } 3057 3058 harness.Setup(setup.MydbData, setup.MytableData) 3059 e := mustNewEngine(t, harness) 3060 defer e.Close() 3061 ctx := NewContext(harness) 3062 RunQueryWithContext(t, e, harness, ctx, "create table b (y char(6) primary key)") 3063 RunQueryWithContext(t, e, harness, ctx, "insert into b values ('aaaaaa'),('bbbbbb'),('cccccc')") 3064 for _, tt := range dml { 3065 t.Run(fmt.Sprintf("%s", tt.mutate), func(t *testing.T) { 3066 defer RunQueryWithContext(t, e, harness, ctx, "DROP TABLE IF EXISTS a") 3067 if tt.create != "" { 3068 RunQueryWithContext(t, e, harness, ctx, tt.create) 3069 } 3070 if tt.insert != "" { 3071 RunQueryWithContext(t, e, harness, ctx, tt.insert) 3072 } 3073 if tt.mutate != "" { 3074 RunQueryWithContext(t, e, harness, ctx, tt.mutate) 3075 } 3076 TestQueryWithContext(t, ctx, e, harness, tt.sel, tt.exp, nil, nil) 3077 }) 3078 } 3079 } 3080 3081 func TestDropDatabase(t *testing.T, harness Harness) { 3082 harness.Setup(setup.MydbData) 3083 for _, tt := range queries.DropDatabaseScripts { 3084 TestScript(t, harness, tt) 3085 } 3086 } 3087 3088 func TestCreateForeignKeys(t *testing.T, harness Harness) { 3089 harness.Setup(setup.MydbData, setup.MytableData) 3090 e := mustNewEngine(t, harness) 3091 defer e.Close() 3092 for _, tt := range queries.CreateForeignKeyTests { 3093 TestScriptWithEngine(t, e, harness, tt) 3094 } 3095 } 3096 3097 func TestDropForeignKeys(t *testing.T, harness Harness) { 3098 harness.Setup(setup.MydbData, setup.MytableData) 3099 e := mustNewEngine(t, harness) 3100 defer e.Close() 3101 for _, tt := range queries.DropForeignKeyTests { 3102 TestScriptWithEngine(t, e, harness, tt) 3103 } 3104 } 3105 3106 func TestForeignKeys(t *testing.T, harness Harness) { 3107 harness.Setup(setup.MydbData, setup.Parent_childData) 3108 for _, script := range queries.ForeignKeyTests { 3109 TestScript(t, harness, script) 3110 } 3111 } 3112 3113 func TestFulltextIndexes(t *testing.T, harness Harness) { 3114 harness.Setup(setup.MydbData) 3115 for _, script := range queries.FulltextTests { 3116 TestScript(t, harness, script) 3117 } 3118 t.Run("Type Hashing", func(t *testing.T) { 3119 for _, script := range queries.TypeWireTests { 3120 t.Run(script.Name, func(t *testing.T) { 3121 e := mustNewEngine(t, harness) 3122 defer e.Close() 3123 3124 for _, statement := range script.SetUpScript { 3125 if sh, ok := harness.(SkippingHarness); ok { 3126 if sh.SkipQueryTest(statement) { 3127 t.Skip() 3128 } 3129 } 3130 ctx := NewContext(harness).WithQuery(statement) 3131 RunQueryWithContext(t, e, harness, ctx, statement) 3132 } 3133 3134 ctx := NewContext(harness) 3135 RunQueryWithContext(t, e, harness, ctx, "ALTER TABLE test ADD COLUMN extracol VARCHAR(200) DEFAULT '';") 3136 RunQueryWithContext(t, e, harness, ctx, "CREATE FULLTEXT INDEX idx ON test (extracol);") 3137 }) 3138 } 3139 }) 3140 } 3141 3142 func TestCreateCheckConstraints(t *testing.T, harness Harness) { 3143 harness.Setup(setup.ChecksSetup...) 3144 e := mustNewEngine(t, harness) 3145 defer e.Close() 3146 3147 // Test any scripts relevant to CheckConstraints. We do this separately from the rest of the scripts 3148 // as certain integrators might not implement check constraints. 3149 for _, script := range queries.CreateCheckConstraintsScripts { 3150 TestScript(t, harness, script) 3151 } 3152 } 3153 3154 func TestChecksOnInsert(t *testing.T, harness Harness) { 3155 harness.Setup(setup.MydbData) 3156 e := mustNewEngine(t, harness) 3157 defer e.Close() 3158 for _, tt := range queries.ChecksOnInsertScripts { 3159 TestScriptWithEngine(t, e, harness, tt) 3160 } 3161 } 3162 3163 func TestChecksOnUpdate(t *testing.T, harness Harness) { 3164 harness.Setup(setup.MydbData) 3165 for _, script := range queries.ChecksOnUpdateScriptTests { 3166 TestScript(t, harness, script) 3167 } 3168 } 3169 3170 func TestDisallowedCheckConstraints(t *testing.T, harness Harness) { 3171 harness.Setup(setup.MydbData) 3172 e := mustNewEngine(t, harness) 3173 defer e.Close() 3174 3175 // TODO: need checks for stored procedures, also not allowed 3176 for _, tt := range queries.DisallowedCheckConstraintsScripts { 3177 TestScriptWithEngine(t, e, harness, tt) 3178 } 3179 } 3180 3181 func TestDropCheckConstraints(t *testing.T, harness Harness) { 3182 harness.Setup(setup.MydbData) 3183 e := mustNewEngine(t, harness) 3184 defer e.Close() 3185 3186 for _, tt := range queries.DropCheckConstraintsScripts { 3187 TestScriptWithEngine(t, e, harness, tt) 3188 } 3189 } 3190 3191 func TestWindowFunctions(t *testing.T, harness Harness) { 3192 harness.Setup(setup.MydbData) 3193 e := mustNewEngine(t, harness) 3194 defer e.Close() 3195 ctx := NewContext(harness) 3196 3197 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE empty_tbl (a int, b int)") 3198 TestQueryWithContext(t, ctx, e, harness, `SELECT a, rank() over (order by b) FROM empty_tbl order by a`, []sql.Row{}, nil, nil) 3199 TestQueryWithContext(t, ctx, e, harness, `SELECT a, dense_rank() over (order by b) FROM empty_tbl order by a`, []sql.Row{}, nil, nil) 3200 TestQueryWithContext(t, ctx, e, harness, `SELECT a, percent_rank() over (order by b) FROM empty_tbl order by a`, []sql.Row{}, nil, nil) 3201 3202 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE results (name varchar(20), subject varchar(20), mark int)") 3203 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO results VALUES ('Pratibha', 'Maths', 100),('Ankita','Science',80),('Swarna','English',100),('Ankita','Maths',65),('Pratibha','Science',80),('Swarna','Science',50),('Pratibha','English',70),('Swarna','Maths',85),('Ankita','English',90)") 3204 3205 TestQueryWithContext(t, ctx, e, harness, `SELECT subject, name, mark, rank() OVER (partition by subject order by mark desc ) FROM results order by subject, mark desc, name`, []sql.Row{ 3206 {"English", "Swarna", 100, uint64(1)}, 3207 {"English", "Ankita", 90, uint64(2)}, 3208 {"English", "Pratibha", 70, uint64(3)}, 3209 {"Maths", "Pratibha", 100, uint64(1)}, 3210 {"Maths", "Swarna", 85, uint64(2)}, 3211 {"Maths", "Ankita", 65, uint64(3)}, 3212 {"Science", "Ankita", 80, uint64(1)}, 3213 {"Science", "Pratibha", 80, uint64(1)}, 3214 {"Science", "Swarna", 50, uint64(3)}, 3215 }, nil, nil) 3216 3217 TestQueryWithContext(t, ctx, e, harness, `SELECT subject, name, mark, dense_rank() OVER (partition by subject order by mark desc ) FROM results order by subject, mark desc, name`, []sql.Row{ 3218 {"English", "Swarna", 100, uint64(1)}, 3219 {"English", "Ankita", 90, uint64(2)}, 3220 {"English", "Pratibha", 70, uint64(3)}, 3221 {"Maths", "Pratibha", 100, uint64(1)}, 3222 {"Maths", "Swarna", 85, uint64(2)}, 3223 {"Maths", "Ankita", 65, uint64(3)}, 3224 {"Science", "Ankita", 80, uint64(1)}, 3225 {"Science", "Pratibha", 80, uint64(1)}, 3226 {"Science", "Swarna", 50, uint64(2)}, 3227 }, nil, nil) 3228 3229 TestQueryWithContext(t, ctx, e, harness, `SELECT subject, name, mark, percent_rank() OVER (partition by subject order by mark desc ) FROM results order by subject, mark desc, name`, []sql.Row{ 3230 {"English", "Swarna", 100, float64(0)}, 3231 {"English", "Ankita", 90, float64(0.5)}, 3232 {"English", "Pratibha", 70, float64(1)}, 3233 {"Maths", "Pratibha", 100, float64(0)}, 3234 {"Maths", "Swarna", 85, float64(0.5)}, 3235 {"Maths", "Ankita", 65, float64(1)}, 3236 {"Science", "Ankita", 80, float64(0)}, 3237 {"Science", "Pratibha", 80, float64(0)}, 3238 {"Science", "Swarna", 50, float64(1)}, 3239 }, nil, nil) 3240 3241 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t1 (a INTEGER PRIMARY KEY, b INTEGER, c integer)") 3242 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t1 VALUES (0,0,0), (1,1,1), (2,2,0), (3,0,0), (4,1,0), (5,3,0)") 3243 3244 TestQueryWithContext(t, ctx, e, harness, `SELECT a, percent_rank() over (order by b) FROM t1 order by a`, []sql.Row{ 3245 {0, 0.0}, 3246 {1, 0.4}, 3247 {2, 0.8}, 3248 {3, 0.0}, 3249 {4, 0.4}, 3250 {5, 1.0}, 3251 }, nil, nil) 3252 3253 TestQueryWithContext(t, ctx, e, harness, `SELECT a, rank() over (order by b) FROM t1 order by a`, []sql.Row{ 3254 {0, uint64(1)}, 3255 {1, uint64(3)}, 3256 {2, uint64(5)}, 3257 {3, uint64(1)}, 3258 {4, uint64(3)}, 3259 {5, uint64(6)}, 3260 }, nil, nil) 3261 3262 TestQueryWithContext(t, ctx, e, harness, `SELECT a, dense_rank() over (order by b) FROM t1 order by a`, []sql.Row{ 3263 {0, uint64(1)}, 3264 {1, uint64(2)}, 3265 {2, uint64(3)}, 3266 {3, uint64(1)}, 3267 {4, uint64(2)}, 3268 {5, uint64(4)}, 3269 }, nil, nil) 3270 3271 TestQueryWithContext(t, ctx, e, harness, `SELECT a, percent_rank() over (order by b desc) FROM t1 order by a`, []sql.Row{ 3272 {0, 0.8}, 3273 {1, 0.4}, 3274 {2, 0.2}, 3275 {3, 0.8}, 3276 {4, 0.4}, 3277 {5, 0.0}, 3278 }, nil, nil) 3279 3280 TestQueryWithContext(t, ctx, e, harness, `SELECT a, rank() over (order by b desc) FROM t1 order by a`, []sql.Row{ 3281 {0, uint64(5)}, 3282 {1, uint64(3)}, 3283 {2, uint64(2)}, 3284 {3, uint64(5)}, 3285 {4, uint64(3)}, 3286 {5, uint64(1)}, 3287 }, nil, nil) 3288 3289 TestQueryWithContext(t, ctx, e, harness, `SELECT a, dense_rank() over (order by b desc) FROM t1 order by a`, []sql.Row{ 3290 {0, uint64(4)}, 3291 {1, uint64(3)}, 3292 {2, uint64(2)}, 3293 {3, uint64(4)}, 3294 {4, uint64(3)}, 3295 {5, uint64(1)}, 3296 }, nil, nil) 3297 3298 TestQueryWithContext(t, ctx, e, harness, `SELECT a, percent_rank() over (partition by c order by b) FROM t1 order by a`, []sql.Row{ 3299 {0, 0.0}, 3300 {1, 0.0}, 3301 {2, 0.75}, 3302 {3, 0.0}, 3303 {4, 0.5}, 3304 {5, 1.0}, 3305 }, nil, nil) 3306 3307 TestQueryWithContext(t, ctx, e, harness, `SELECT a, rank() over (partition by c order by b) FROM t1 order by a`, []sql.Row{ 3308 {0, uint64(1)}, 3309 {1, uint64(1)}, 3310 {2, uint64(4)}, 3311 {3, uint64(1)}, 3312 {4, uint64(3)}, 3313 {5, uint64(5)}, 3314 }, nil, nil) 3315 3316 TestQueryWithContext(t, ctx, e, harness, `SELECT a, dense_rank() over (partition by c order by b) FROM t1 order by a`, []sql.Row{ 3317 {0, uint64(1)}, 3318 {1, uint64(1)}, 3319 {2, uint64(3)}, 3320 {3, uint64(1)}, 3321 {4, uint64(2)}, 3322 {5, uint64(4)}, 3323 }, nil, nil) 3324 3325 TestQueryWithContext(t, ctx, e, harness, `SELECT a, percent_rank() over (partition by b order by c) FROM t1 order by a`, []sql.Row{ 3326 {0, 0.0}, 3327 {1, 1.0}, 3328 {2, 0.0}, 3329 {3, 0.0}, 3330 {4, 0.0}, 3331 {5, 0.0}, 3332 }, nil, nil) 3333 3334 TestQueryWithContext(t, ctx, e, harness, `SELECT a, rank() over (partition by b order by c) FROM t1 order by a`, []sql.Row{ 3335 {0, uint64(1)}, 3336 {1, uint64(2)}, 3337 {2, uint64(1)}, 3338 {3, uint64(1)}, 3339 {4, uint64(1)}, 3340 {5, uint64(1)}, 3341 }, nil, nil) 3342 3343 TestQueryWithContext(t, ctx, e, harness, `SELECT a, dense_rank() over (partition by b order by c) FROM t1 order by a`, []sql.Row{ 3344 {0, uint64(1)}, 3345 {1, uint64(2)}, 3346 {2, uint64(1)}, 3347 {3, uint64(1)}, 3348 {4, uint64(1)}, 3349 {5, uint64(1)}, 3350 }, nil, nil) 3351 3352 // no order by clause -> all rows are peers 3353 TestQueryWithContext(t, ctx, e, harness, `SELECT a, percent_rank() over (partition by b) FROM t1 order by a`, []sql.Row{ 3354 {0, 0.0}, 3355 {1, 0.0}, 3356 {2, 0.0}, 3357 {3, 0.0}, 3358 {4, 0.0}, 3359 {5, 0.0}, 3360 }, nil, nil) 3361 3362 // no order by clause -> all rows are peers 3363 TestQueryWithContext(t, ctx, e, harness, `SELECT a, rank() over (partition by b) FROM t1 order by a`, []sql.Row{ 3364 {0, uint64(1)}, 3365 {1, uint64(1)}, 3366 {2, uint64(1)}, 3367 {3, uint64(1)}, 3368 {4, uint64(1)}, 3369 {5, uint64(1)}, 3370 }, nil, nil) 3371 3372 // no order by clause -> all rows are peers 3373 TestQueryWithContext(t, ctx, e, harness, `SELECT a, dense_rank() over (partition by b) FROM t1 order by a`, []sql.Row{ 3374 {0, uint64(1)}, 3375 {1, uint64(1)}, 3376 {2, uint64(1)}, 3377 {3, uint64(1)}, 3378 {4, uint64(1)}, 3379 {5, uint64(1)}, 3380 }, nil, nil) 3381 3382 TestQueryWithContext(t, ctx, e, harness, `SELECT a, first_value(b) over (partition by c order by b) FROM t1 order by a`, []sql.Row{ 3383 {0, 0}, 3384 {1, 1}, 3385 {2, 0}, 3386 {3, 0}, 3387 {4, 0}, 3388 {5, 0}, 3389 }, nil, nil) 3390 3391 TestQueryWithContext(t, ctx, e, harness, `SELECT a, first_value(a) over (partition by b order by a ASC, c ASC) FROM t1 order by a`, []sql.Row{ 3392 {0, 0}, 3393 {1, 1}, 3394 {2, 2}, 3395 {3, 0}, 3396 {4, 1}, 3397 {5, 5}, 3398 }, nil, nil) 3399 3400 TestQueryWithContext(t, ctx, e, harness, `SELECT a, first_value(a-1) over (partition by b order by a ASC, c ASC) FROM t1 order by a`, []sql.Row{ 3401 {0, -1}, 3402 {1, 0}, 3403 {2, 1}, 3404 {3, -1}, 3405 {4, 0}, 3406 {5, 4}, 3407 }, nil, nil) 3408 3409 TestQueryWithContext(t, ctx, e, harness, `SELECT a, first_value(c) over (partition by b order by a) FROM t1 order by a*b,a`, []sql.Row{ 3410 {0, 0}, 3411 {3, 0}, 3412 {1, 1}, 3413 {2, 0}, 3414 {4, 1}, 3415 {5, 0}, 3416 }, nil, nil) 3417 3418 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lead(a) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3419 {0, 2}, 3420 {1, nil}, 3421 {2, 3}, 3422 {3, 4}, 3423 {4, 5}, 3424 {5, nil}, 3425 }, nil, nil) 3426 3427 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lead(a, 1) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3428 {0, 2}, 3429 {1, nil}, 3430 {2, 3}, 3431 {3, 4}, 3432 {4, 5}, 3433 {5, nil}, 3434 }, nil, nil) 3435 3436 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lead(a+2) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3437 {0, 4}, 3438 {1, nil}, 3439 {2, 5}, 3440 {3, 6}, 3441 {4, 7}, 3442 {5, nil}, 3443 }, nil, nil) 3444 3445 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lead(a, 1, a-1) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3446 {0, 2}, 3447 {1, 0}, 3448 {2, 3}, 3449 {3, 4}, 3450 {4, 5}, 3451 {5, 4}, 3452 }, nil, nil) 3453 3454 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lead(a, 0) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3455 {0, 0}, 3456 {1, 1}, 3457 {2, 2}, 3458 {3, 3}, 3459 {4, 4}, 3460 {5, 5}, 3461 }, nil, nil) 3462 3463 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lead(a, 1, -1) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3464 {0, 2}, 3465 {1, -1}, 3466 {2, 3}, 3467 {3, 4}, 3468 {4, 5}, 3469 {5, -1}, 3470 }, nil, nil) 3471 3472 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lead(a, 3, -1) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3473 {0, 4}, 3474 {1, -1}, 3475 {2, 5}, 3476 {3, -1}, 3477 {4, -1}, 3478 {5, -1}, 3479 }, nil, nil) 3480 3481 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lead('s') over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3482 {0, "s"}, 3483 {1, nil}, 3484 {2, "s"}, 3485 {3, "s"}, 3486 {4, "s"}, 3487 {5, nil}, 3488 }, nil, nil) 3489 3490 TestQueryWithContext(t, ctx, e, harness, `SELECT a, last_value(b) over (partition by c order by b) FROM t1 order by a`, []sql.Row{ 3491 {0, 0}, 3492 {1, 1}, 3493 {2, 2}, 3494 {3, 0}, 3495 {4, 1}, 3496 {5, 3}, 3497 }, nil, nil) 3498 3499 TestQueryWithContext(t, ctx, e, harness, `SELECT a, last_value(a) over (partition by b order by a ASC, c ASC) FROM t1 order by a`, []sql.Row{ 3500 {0, 0}, 3501 {1, 1}, 3502 {2, 2}, 3503 {3, 3}, 3504 {4, 4}, 3505 {5, 5}, 3506 }, nil, nil) 3507 3508 TestQueryWithContext(t, ctx, e, harness, `SELECT a, last_value(a-1) over (partition by b order by a ASC, c ASC) FROM t1 order by a`, []sql.Row{ 3509 {0, -1}, 3510 {1, 0}, 3511 {2, 1}, 3512 {3, 2}, 3513 {4, 3}, 3514 {5, 4}, 3515 }, nil, nil) 3516 3517 TestQueryWithContext(t, ctx, e, harness, `SELECT a, last_value(c) over (partition by b order by c) FROM t1 order by a*b,a`, []sql.Row{ 3518 {0, 0}, 3519 {3, 0}, 3520 {1, 1}, 3521 {2, 0}, 3522 {4, 0}, 3523 {5, 0}, 3524 }, nil, nil) 3525 3526 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lag(a) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3527 {0, nil}, 3528 {1, nil}, 3529 {2, 0}, 3530 {3, 2}, 3531 {4, 3}, 3532 {5, 4}, 3533 }, nil, nil) 3534 3535 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lag(a, 1) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3536 {0, nil}, 3537 {1, nil}, 3538 {2, 0}, 3539 {3, 2}, 3540 {4, 3}, 3541 {5, 4}, 3542 }, nil, nil) 3543 3544 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lag(a+2) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3545 {0, nil}, 3546 {1, nil}, 3547 {2, 2}, 3548 {3, 4}, 3549 {4, 5}, 3550 {5, 6}, 3551 }, nil, nil) 3552 3553 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lag(a, 1, a-1) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3554 {0, -1}, 3555 {1, 0}, 3556 {2, 0}, 3557 {3, 2}, 3558 {4, 3}, 3559 {5, 4}, 3560 }, nil, nil) 3561 3562 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lag(a, 0) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3563 {0, 0}, 3564 {1, 1}, 3565 {2, 2}, 3566 {3, 3}, 3567 {4, 4}, 3568 {5, 5}, 3569 }, nil, nil) 3570 3571 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lag(a, 1, -1) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3572 {0, -1}, 3573 {1, -1}, 3574 {2, 0}, 3575 {3, 2}, 3576 {4, 3}, 3577 {5, 4}, 3578 }, nil, nil) 3579 3580 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lag(a, 3, -1) over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3581 {0, -1}, 3582 {1, -1}, 3583 {2, -1}, 3584 {3, -1}, 3585 {4, 0}, 3586 {5, 2}, 3587 }, nil, nil) 3588 3589 TestQueryWithContext(t, ctx, e, harness, `SELECT a, lag('s') over (partition by c order by a) FROM t1 order by a`, []sql.Row{ 3590 {0, nil}, 3591 {1, nil}, 3592 {2, "s"}, 3593 {3, "s"}, 3594 {4, "s"}, 3595 {5, "s"}, 3596 }, nil, nil) 3597 3598 AssertErr(t, e, harness, "SELECT a, lag(a, -1) over (partition by c) FROM t1", expression.ErrInvalidOffset) 3599 AssertErr(t, e, harness, "SELECT a, lag(a, 's') over (partition by c) FROM t1", expression.ErrInvalidOffset) 3600 3601 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t2 (a int, b int, c int)") 3602 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t2 VALUES (1,1,1), (3,2,2), (7,4,5)") 3603 TestQueryWithContext(t, ctx, e, harness, `SELECT bit_and(a), bit_or(b), bit_xor(c) FROM t2`, []sql.Row{ 3604 {uint64(1), uint64(7), uint64(6)}, 3605 }, nil, nil) 3606 3607 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t3 (x varchar(100))") 3608 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t3 VALUES ('these'), ('are'), ('strings')") 3609 TestQueryWithContext(t, ctx, e, harness, `SELECT bit_and(x) from t3`, []sql.Row{ 3610 {uint64(0)}, 3611 }, nil, nil) 3612 TestQueryWithContext(t, ctx, e, harness, `SELECT bit_or(x) from t3`, []sql.Row{ 3613 {uint64(0)}, 3614 }, nil, nil) 3615 TestQueryWithContext(t, ctx, e, harness, `SELECT bit_xor(x) from t3`, []sql.Row{ 3616 {uint64(0)}, 3617 }, nil, nil) 3618 3619 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t4 (x int)") 3620 TestQueryWithContext(t, ctx, e, harness, `SELECT bit_and(x) from t4`, []sql.Row{ 3621 {^uint64(0)}, 3622 }, nil, nil) 3623 TestQueryWithContext(t, ctx, e, harness, `SELECT bit_or(x) from t4`, []sql.Row{ 3624 {uint64(0)}, 3625 }, nil, nil) 3626 TestQueryWithContext(t, ctx, e, harness, `SELECT bit_xor(x) from t4`, []sql.Row{ 3627 {uint64(0)}, 3628 }, nil, nil) 3629 3630 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE t5 (a INTEGER, b INTEGER)") 3631 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t5 VALUES (0,0), (0,1), (1,0), (1,1)") 3632 3633 TestQueryWithContext(t, ctx, e, harness, `SELECT a, b, row_number() over (partition by a, b) FROM t5 order by a, b`, []sql.Row{ 3634 {0, 0, 1}, 3635 {0, 1, 1}, 3636 {1, 0, 1}, 3637 {1, 1, 1}, 3638 }, nil, nil) 3639 } 3640 3641 func TestWindowRowFrames(t *testing.T, harness Harness) { 3642 harness.Setup(setup.MydbData) 3643 e := mustNewEngine(t, harness) 3644 defer e.Close() 3645 ctx := NewContext(harness) 3646 3647 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE a (x INTEGER PRIMARY KEY, y INTEGER, z INTEGER)") 3648 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO a VALUES (0,0,0), (1,1,0), (2,2,0), (3,0,0), (4,1,0), (5,3,0)") 3649 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows unbounded preceding) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(3)}, {float64(3)}, {float64(4)}, {float64(7)}}, nil, nil) 3650 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows current row) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(2)}, {float64(0)}, {float64(1)}, {float64(3)}}, nil, nil) 3651 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows 2 preceding) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(3)}, {float64(3)}, {float64(3)}, {float64(4)}}, nil, nil) 3652 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between current row and 1 following) FROM a order by x`, []sql.Row{{float64(1)}, {float64(3)}, {float64(2)}, {float64(1)}, {float64(4)}, {float64(3)}}, nil, nil) 3653 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between 1 preceding and current row) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(3)}, {float64(2)}, {float64(1)}, {float64(4)}}, nil, nil) 3654 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between current row and 2 following) FROM a order by x`, []sql.Row{{float64(3)}, {float64(3)}, {float64(3)}, {float64(4)}, {float64(4)}, {float64(3)}}, nil, nil) 3655 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between current row and current row) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(2)}, {float64(0)}, {float64(1)}, {float64(3)}}, nil, nil) 3656 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between current row and unbounded following) FROM a order by x`, []sql.Row{{float64(7)}, {float64(7)}, {float64(6)}, {float64(4)}, {float64(4)}, {float64(3)}}, nil, nil) 3657 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between 1 preceding and 1 following) FROM a order by x`, []sql.Row{{float64(1)}, {float64(3)}, {float64(3)}, {float64(3)}, {float64(4)}, {float64(4)}}, nil, nil) 3658 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between 1 preceding and unbounded following) FROM a order by x`, []sql.Row{{float64(7)}, {float64(7)}, {float64(7)}, {float64(6)}, {float64(4)}, {float64(4)}}, nil, nil) 3659 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between unbounded preceding and unbounded following) FROM a order by x`, []sql.Row{{float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}}, nil, nil) 3660 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x rows between 2 preceding and 1 preceding) FROM a order by x`, []sql.Row{{nil}, {float64(0)}, {float64(1)}, {float64(3)}, {float64(2)}, {float64(1)}}, nil, nil) 3661 } 3662 3663 func TestWindowRangeFrames(t *testing.T, harness Harness) { 3664 harness.Setup(setup.MydbData, setup.MytableData) 3665 e := mustNewEngine(t, harness) 3666 defer e.Close() 3667 ctx := NewContext(harness) 3668 3669 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE a (x INTEGER PRIMARY KEY, y INTEGER, z INTEGER)") 3670 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO a VALUES (0,0,0), (1,1,0), (2,2,0), (3,0,0), (4,1,0), (5,3,0)") 3671 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range unbounded preceding) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(3)}, {float64(3)}, {float64(4)}, {float64(7)}}, nil, nil) 3672 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range current row) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(2)}, {float64(0)}, {float64(1)}, {float64(3)}}, nil, nil) 3673 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range 2 preceding) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(3)}, {float64(3)}, {float64(3)}, {float64(4)}}, nil, nil) 3674 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between current row and 1 following) FROM a order by x`, []sql.Row{{float64(1)}, {float64(3)}, {float64(2)}, {float64(1)}, {float64(4)}, {float64(3)}}, nil, nil) 3675 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between 1 preceding and current row) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(3)}, {float64(2)}, {float64(1)}, {float64(4)}}, nil, nil) 3676 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between current row and 2 following) FROM a order by x`, []sql.Row{{float64(3)}, {float64(3)}, {float64(3)}, {float64(4)}, {float64(4)}, {float64(3)}}, nil, nil) 3677 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between current row and current row) FROM a order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(2)}, {float64(0)}, {float64(1)}, {float64(3)}}, nil, nil) 3678 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between current row and unbounded following) FROM a order by x`, []sql.Row{{float64(7)}, {float64(7)}, {float64(6)}, {float64(4)}, {float64(4)}, {float64(3)}}, nil, nil) 3679 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between 1 preceding and 1 following) FROM a order by x`, []sql.Row{{float64(1)}, {float64(3)}, {float64(3)}, {float64(3)}, {float64(4)}, {float64(4)}}, nil, nil) 3680 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between 1 preceding and unbounded following) FROM a order by x`, []sql.Row{{float64(7)}, {float64(7)}, {float64(7)}, {float64(6)}, {float64(4)}, {float64(4)}}, nil, nil) 3681 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between unbounded preceding and unbounded following) FROM a order by x`, []sql.Row{{float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}}, nil, nil) 3682 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by x range between 2 preceding and 1 preceding) FROM a order by x`, []sql.Row{{nil}, {float64(0)}, {float64(1)}, {float64(3)}, {float64(2)}, {float64(1)}}, nil, nil) 3683 3684 // range framing without an order by clause 3685 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by y range between unbounded preceding and unbounded following) FROM a order by x`, 3686 []sql.Row{{float64(0)}, {float64(2)}, {float64(2)}, {float64(0)}, {float64(2)}, {float64(3)}}, nil, nil) 3687 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by y range between unbounded preceding and current row) FROM a order by x`, 3688 []sql.Row{{float64(0)}, {float64(2)}, {float64(2)}, {float64(0)}, {float64(2)}, {float64(3)}}, nil, nil) 3689 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by y range between current row and unbounded following) FROM a order by x`, 3690 []sql.Row{{float64(0)}, {float64(2)}, {float64(2)}, {float64(0)}, {float64(2)}, {float64(3)}}, nil, nil) 3691 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by y range between current row and current row) FROM a order by x`, 3692 []sql.Row{{float64(0)}, {float64(2)}, {float64(2)}, {float64(0)}, {float64(2)}, {float64(3)}}, nil, nil) 3693 3694 // fixed frame size, 3 days 3695 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE b (x INTEGER PRIMARY KEY, y INTEGER, z INTEGER, date DATE)") 3696 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO b VALUES (0,0,0,'2022-01-26'), (1,0,0,'2022-01-27'), (2,0,0, '2022-01-28'), (3,1,0,'2022-01-29'), (4,1,0,'2022-01-30'), (5,3,0,'2022-01-31')") 3697 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between interval 2 DAY preceding and interval 1 DAY preceding) FROM b order by x`, []sql.Row{{nil}, {float64(0)}, {float64(0)}, {float64(0)}, {float64(1)}, {float64(2)}}, nil, nil) 3698 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between interval 1 DAY preceding and interval 1 DAY following) FROM b order by x`, []sql.Row{{float64(0)}, {float64(0)}, {float64(1)}, {float64(2)}, {float64(5)}, {float64(4)}}, nil, nil) 3699 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between interval 1 DAY following and interval 2 DAY following) FROM b order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(2)}, {float64(4)}, {float64(3)}, {nil}}, nil, nil) 3700 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range interval 1 DAY preceding) FROM b order by x`, []sql.Row{{float64(0)}, {float64(0)}, {float64(0)}, {float64(1)}, {float64(2)}, {float64(4)}}, nil, nil) 3701 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between interval 1 DAY preceding and current row) FROM b order by x`, []sql.Row{{float64(0)}, {float64(0)}, {float64(0)}, {float64(1)}, {float64(2)}, {float64(4)}}, nil, nil) 3702 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between interval 1 DAY preceding and unbounded following) FROM b order by x`, []sql.Row{{float64(5)}, {float64(5)}, {float64(5)}, {float64(5)}, {float64(5)}, {float64(4)}}, nil, nil) 3703 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between unbounded preceding and interval 1 DAY following) FROM b order by x`, []sql.Row{{float64(0)}, {float64(0)}, {float64(1)}, {float64(2)}, {float64(5)}, {float64(5)}}, nil, nil) 3704 3705 // variable range size, 1 or many days 3706 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE c (x INTEGER PRIMARY KEY, y INTEGER, z INTEGER, date DATE)") 3707 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO c VALUES (0,0,0,'2022-01-26'), (1,0,0,'2022-01-26'), (2,0,0, '2022-01-26'), (3,1,0,'2022-01-27'), (4,1,0,'2022-01-29'), (5,3,0,'2022-01-30'), (6,0,0, '2022-02-03'), (7,1,0,'2022-02-03'), (8,1,0,'2022-02-04'), (9,3,0,'2022-02-04')") 3708 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between interval '2' DAY preceding and interval '1' DAY preceding) FROM c order by x`, []sql.Row{{nil}, {nil}, {nil}, {float64(0)}, {float64(1)}, {float64(1)}, {nil}, {nil}, {float64(1)}, {float64(1)}}, nil, nil) 3709 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between interval '1' DAY preceding and interval '1' DAY following) FROM c order by x`, []sql.Row{{float64(1)}, {float64(1)}, {float64(1)}, {float64(1)}, {float64(4)}, {float64(4)}, {float64(5)}, {float64(5)}, {float64(5)}, {float64(5)}}, nil, nil) 3710 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between interval '1' DAY preceding and current row) FROM c order by x`, []sql.Row{{float64(0)}, {float64(0)}, {float64(0)}, {float64(1)}, {float64(1)}, {float64(4)}, {float64(1)}, {float64(1)}, {float64(5)}, {float64(5)}}, nil, nil) 3711 TestQueryWithContext(t, ctx, e, harness, `SELECT avg(y) over (partition by z order by date range between interval '1' DAY preceding and unbounded following) FROM c order by x`, []sql.Row{{float64(1)}, {float64(1)}, {float64(1)}, {float64(1)}, {float64(3) / float64(2)}, {float64(3) / float64(2)}, {float64(5) / float64(4)}, {float64(5) / float64(4)}, {float64(5) / float64(4)}, {float64(5) / float64(4)}}, nil, nil) 3712 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between unbounded preceding and interval '1' DAY following) FROM c order by x`, []sql.Row{{float64(1)}, {float64(1)}, {float64(1)}, {float64(1)}, {float64(5)}, {float64(5)}, {float64(10)}, {float64(10)}, {float64(10)}, {float64(10)}}, nil, nil) 3713 TestQueryWithContext(t, ctx, e, harness, `SELECT count(y) over (partition by z order by date range between interval '1' DAY following and interval '2' DAY following) FROM c order by x`, []sql.Row{{1}, {1}, {1}, {1}, {1}, {0}, {2}, {2}, {0}, {0}}, nil, nil) 3714 TestQueryWithContext(t, ctx, e, harness, `SELECT count(y) over (partition by z order by date range between interval '1' DAY preceding and interval '2' DAY following) FROM c order by x`, []sql.Row{{4}, {4}, {4}, {5}, {2}, {2}, {4}, {4}, {4}, {4}}, nil, nil) 3715 3716 AssertErr(t, e, harness, "SELECT sum(y) over (partition by z range between unbounded preceding and interval '1' DAY following) FROM c order by x", aggregation.ErrRangeInvalidOrderBy) 3717 AssertErr(t, e, harness, "SELECT sum(y) over (partition by z order by date range interval 'e' DAY preceding) FROM c order by x", sql.ErrInvalidValue) 3718 } 3719 3720 func TestNamedWindows(t *testing.T, harness Harness) { 3721 harness.Setup(setup.MydbData) 3722 e := mustNewEngine(t, harness) 3723 defer e.Close() 3724 ctx := NewContext(harness) 3725 3726 RunQueryWithContext(t, e, harness, ctx, "CREATE TABLE a (x INTEGER PRIMARY KEY, y INTEGER, z INTEGER)") 3727 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO a VALUES (0,0,0), (1,1,0), (2,2,0), (3,0,0), (4,1,0), (5,3,0)") 3728 3729 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (w1) FROM a WINDOW w1 as (order by z) order by x`, []sql.Row{{float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}}, nil, nil) 3730 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (w1) FROM a WINDOW w1 as (partition by z) order by x`, []sql.Row{{float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}, {float64(7)}}, nil, nil) 3731 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over w FROM a WINDOW w as (partition by z order by x rows unbounded preceding) order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(3)}, {float64(3)}, {float64(4)}, {float64(7)}}, nil, nil) 3732 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over w FROM a WINDOW w as (partition by z order by x rows current row) order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(2)}, {float64(0)}, {float64(1)}, {float64(3)}}, nil, nil) 3733 TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (w) FROM a WINDOW w as (partition by z order by x rows 2 preceding) order by x`, []sql.Row{{float64(0)}, {float64(1)}, {float64(3)}, {float64(3)}, {float64(3)}, {float64(4)}}, nil, nil) 3734 TestQueryWithContext(t, ctx, e, harness, `SELECT row_number() over (w3) FROM a WINDOW w3 as (w2), w2 as (w1), w1 as (partition by z order by x) order by x`, []sql.Row{{int64(1)}, {int64(2)}, {int64(3)}, {int64(4)}, {int64(5)}, {int64(6)}}, nil, nil) 3735 3736 // errors 3737 AssertErr(t, e, harness, "SELECT sum(y) over (w1 partition by x) FROM a WINDOW w1 as (partition by z) order by x", sql.ErrInvalidWindowInheritance) 3738 AssertErr(t, e, harness, "SELECT sum(y) over (w1 order by x) FROM a WINDOW w1 as (order by z) order by x", sql.ErrInvalidWindowInheritance) 3739 AssertErr(t, e, harness, "SELECT sum(y) over (w1 rows unbounded preceding) FROM a WINDOW w1 as (range unbounded preceding) order by x", sql.ErrInvalidWindowInheritance) 3740 AssertErr(t, e, harness, "SELECT sum(y) over (w3) FROM a WINDOW w1 as (w2), w2 as (w3), w3 as (w1) order by x", sql.ErrCircularWindowInheritance) 3741 3742 // TODO parser needs to differentiate between window replacement and copying -- window frames can't be copied 3743 //AssertErr(t, e, harness, "SELECT sum(y) over w FROM a WINDOW (w) as (partition by z order by x rows unbounded preceding) order by x", sql.ErrInvalidWindowInheritance) 3744 } 3745 3746 func TestNaturalJoin(t *testing.T, harness Harness) { 3747 harness.Setup([]setup.SetupScript{{ 3748 "create database mydb", 3749 "use mydb", 3750 "create table t1 (a varchar(20) primary key, b text, c text)", 3751 "create table t2 (a varchar(20) primary key, b text, d text)", 3752 "insert into t1 values ('a_1', 'b_1', 'c_1'), ('a_2', 'b_2', 'c_2'), ('a_3', 'b_3', 'c_3')", 3753 "insert into t2 values ('a_1', 'b_1', 'd_1'), ('a_2', 'b_2', 'd_2'), ('a_3', 'b_3', 'd_3')", 3754 }}) 3755 e := mustNewEngine(t, harness) 3756 defer e.Close() 3757 3758 TestQuery(t, harness, `SELECT * FROM t1 NATURAL JOIN t2`, []sql.Row{ 3759 {"a_1", "b_1", "c_1", "d_1"}, 3760 {"a_2", "b_2", "c_2", "d_2"}, 3761 {"a_3", "b_3", "c_3", "d_3"}, 3762 }, nil, nil) 3763 } 3764 3765 func TestNaturalJoinEqual(t *testing.T, harness Harness) { 3766 harness.Setup([]setup.SetupScript{{ 3767 "create database mydb", 3768 "use mydb", 3769 "create table t1 (a varchar(20) primary key, b text, c text)", 3770 "create table t2 (a varchar(20) primary key, b text, c text)", 3771 "insert into t1 values ('a_1', 'b_1', 'c_1'), ('a_2', 'b_2', 'c_2'), ('a_3', 'b_3', 'c_3')", 3772 "insert into t2 values ('a_1', 'b_1', 'c_1'), ('a_2', 'b_2', 'c_2'), ('a_3', 'b_3', 'c_3')", 3773 }}) 3774 e := mustNewEngine(t, harness) 3775 defer e.Close() 3776 TestQuery(t, harness, `SELECT * FROM t1 NATURAL JOIN t2`, []sql.Row{ 3777 {"a_1", "b_1", "c_1"}, 3778 {"a_2", "b_2", "c_2"}, 3779 {"a_3", "b_3", "c_3"}, 3780 }, nil, nil) 3781 } 3782 3783 func TestNaturalJoinDisjoint(t *testing.T, harness Harness) { 3784 harness.Setup([]setup.SetupScript{{ 3785 "create database mydb", 3786 "use mydb", 3787 "create table t1 (a varchar(20) primary key)", 3788 "create table t2 (b varchar(20) primary key)", 3789 "insert into t1 values ('a1'), ('a2'), ('a3')", 3790 "insert into t2 values ('b1'), ('b2'), ('b3')", 3791 }}) 3792 e := mustNewEngine(t, harness) 3793 defer e.Close() 3794 TestQuery(t, harness, `SELECT * FROM t1 NATURAL JOIN t2`, []sql.Row{ 3795 {"a1", "b1"}, 3796 {"a1", "b2"}, 3797 {"a1", "b3"}, 3798 {"a2", "b1"}, 3799 {"a2", "b2"}, 3800 {"a2", "b3"}, 3801 {"a3", "b1"}, 3802 {"a3", "b2"}, 3803 {"a3", "b3"}, 3804 }, nil, nil) 3805 } 3806 3807 func TestInnerNestedInNaturalJoins(t *testing.T, harness Harness) { 3808 harness.Setup([]setup.SetupScript{{ 3809 "create database mydb", 3810 "use mydb", 3811 "create table table1 (i int, f float, t text)", 3812 "create table table2 (i2 int, f2 float, t2 text)", 3813 "create table table3 (i int, f2 float, t3 text)", 3814 "insert into table1 values (1, 2.1000, 'table1'), (1, 2.1000, 'table1'), (10, 2.1000, 'table1')", 3815 "insert into table2 values (1, 2.1000, 'table2'), (1, 2.2000, 'table2'), (20, 2.2000, 'table2')", 3816 "insert into table3 values (1, 2.2000, 'table3'), (2, 2.2000, 'table3'), (30, 2.2000, 'table3')", 3817 }}) 3818 e := mustNewEngine(t, harness) 3819 defer e.Close() 3820 3821 TestQuery(t, harness, `SELECT table1.i, t, i2, t2, t3 FROM table1 INNER JOIN table2 ON table1.i = table2.i2 NATURAL JOIN table3`, []sql.Row{ 3822 {int32(1), "table1", int32(1), "table2", "table3"}, 3823 {int32(1), "table1", int32(1), "table2", "table3"}, 3824 }, nil, nil) 3825 } 3826 3827 func TestVariables(t *testing.T, harness Harness) { 3828 for _, query := range queries.VariableQueries { 3829 TestScript(t, harness, query) 3830 } 3831 3832 // Test session pulling from global 3833 engine, err := harness.NewEngine(t) 3834 require.NoError(t, err) 3835 3836 // Since we are using empty contexts below, rather than ones provided by the harness, make sure that the engine has 3837 // no permissions established. 3838 engine.EngineAnalyzer().Catalog.MySQLDb = mysql_db.CreateEmptyMySQLDb() 3839 3840 ctx1 := sql.NewEmptyContext() 3841 err = CreateNewConnectionForServerEngine(ctx1, engine) 3842 require.NoError(t, err) 3843 for _, assertion := range []queries.ScriptTestAssertion{ 3844 { 3845 Query: "SELECT @@select_into_buffer_size", 3846 Expected: []sql.Row{{131072}}, 3847 }, 3848 { 3849 Query: "SELECT @@GLOBAL.select_into_buffer_size", 3850 Expected: []sql.Row{{131072}}, 3851 }, 3852 { 3853 Query: "SET GLOBAL select_into_buffer_size = 9001", 3854 Expected: []sql.Row{{}}, 3855 }, 3856 { 3857 Query: "SELECT @@SESSION.select_into_buffer_size", 3858 Expected: []sql.Row{{131072}}, 3859 }, 3860 { 3861 Query: "SELECT @@GLOBAL.select_into_buffer_size", 3862 Expected: []sql.Row{{9001}}, 3863 }, 3864 { 3865 Query: "SET @@GLOBAL.select_into_buffer_size = 9002", 3866 Expected: []sql.Row{{}}, 3867 }, 3868 { 3869 Query: "SELECT @@GLOBAL.select_into_buffer_size", 3870 Expected: []sql.Row{{9002}}, 3871 }, 3872 } { 3873 t.Run(assertion.Query, func(t *testing.T) { 3874 TestQueryWithContext(t, ctx1, engine, harness, assertion.Query, assertion.Expected, nil, nil) 3875 }) 3876 } 3877 3878 ctx2 := sql.NewEmptyContext() 3879 err = CreateNewConnectionForServerEngine(ctx2, engine) 3880 require.NoError(t, err) 3881 for _, assertion := range []queries.ScriptTestAssertion{ 3882 { 3883 Query: "SELECT @@select_into_buffer_size", 3884 Expected: []sql.Row{{9002}}, 3885 }, 3886 { 3887 Query: "SELECT @@GLOBAL.select_into_buffer_size", 3888 Expected: []sql.Row{{9002}}, 3889 }, 3890 { 3891 Query: "SET GLOBAL select_into_buffer_size = 131072", 3892 Expected: []sql.Row{{}}, 3893 }, 3894 } { 3895 t.Run(assertion.Query, func(t *testing.T) { 3896 TestQueryWithContext(t, ctx2, engine, harness, assertion.Query, assertion.Expected, nil, nil) 3897 }) 3898 } 3899 } 3900 3901 func TestPreparedInsert(t *testing.T, harness Harness) { 3902 harness.Setup(setup.MydbData, setup.MytableData) 3903 e := mustNewEngine(t, harness) 3904 defer e.Close() 3905 3906 tests := []queries.ScriptTest{ 3907 { 3908 Name: "simple insert", 3909 SetUpScript: []string{ 3910 "create table test (pk int primary key, value int)", 3911 "insert into test values (0,0)", 3912 }, 3913 Assertions: []queries.ScriptTestAssertion{ 3914 { 3915 Query: "insert into test values (?, ?)", 3916 Bindings: map[string]*query.BindVariable{ 3917 "v1": sqltypes.Int64BindVariable(1), 3918 "v2": sqltypes.Int64BindVariable(1), 3919 }, 3920 Expected: []sql.Row{ 3921 {types.OkResult{RowsAffected: 1}}, 3922 }, 3923 }, 3924 }, 3925 }, 3926 { 3927 Name: "simple decimal type insert", 3928 SetUpScript: []string{ 3929 "CREATE TABLE test(id int primary key auto_increment, decimal_test DECIMAL(9,2), decimal_test_2 DECIMAL(9,2), decimal_test_3 DECIMAL(9,2))", 3930 }, 3931 Assertions: []queries.ScriptTestAssertion{ 3932 { 3933 Query: "INSERT INTO test(decimal_test, decimal_test_2, decimal_test_3) VALUES (?, ?, ?)", 3934 Bindings: map[string]*query.BindVariable{ 3935 "v1": mustBuildBindVariable(10), 3936 "v2": mustBuildBindVariable([]byte("10.5")), 3937 "v3": mustBuildBindVariable(20.40), 3938 }, 3939 Expected: []sql.Row{ 3940 {types.OkResult{RowsAffected: 1, InsertID: 1}}, 3941 }, 3942 }, 3943 }, 3944 }, 3945 { 3946 Name: "Insert on duplicate key", 3947 SetUpScript: []string{ 3948 `CREATE TABLE users ( 3949 id varchar(42) PRIMARY KEY 3950 )`, 3951 `CREATE TABLE nodes ( 3952 id varchar(42) PRIMARY KEY, 3953 owner varchar(42), 3954 status varchar(12), 3955 timestamp bigint NOT NULL, 3956 FOREIGN KEY(owner) REFERENCES users(id) 3957 )`, 3958 "INSERT INTO users values ('milo'), ('dabe')", 3959 "INSERT INTO nodes values ('id1', 'milo', 'off', 1)", 3960 }, 3961 Assertions: []queries.ScriptTestAssertion{ 3962 { 3963 Query: "insert into nodes(id,owner,status,timestamp) values(?, ?, ?, ?) on duplicate key update owner=?,status=?", 3964 Bindings: map[string]*query.BindVariable{ 3965 "v1": mustBuildBindVariable("id1"), 3966 "v2": mustBuildBindVariable("dabe"), 3967 "v3": mustBuildBindVariable("off"), 3968 "v4": mustBuildBindVariable(2), 3969 "v5": mustBuildBindVariable("milo"), 3970 "v6": mustBuildBindVariable("on"), 3971 }, 3972 Expected: []sql.Row{ 3973 {types.OkResult{RowsAffected: 2}}, 3974 }, 3975 }, 3976 { 3977 Query: "insert into nodes(id,owner,status,timestamp) values(?, ?, ?, ?) on duplicate key update owner=?,status=?", 3978 Bindings: map[string]*query.BindVariable{ 3979 "v1": mustBuildBindVariable("id2"), 3980 "v2": mustBuildBindVariable("dabe"), 3981 "v3": mustBuildBindVariable("off"), 3982 "v4": mustBuildBindVariable(3), 3983 "v5": mustBuildBindVariable("milo"), 3984 "v6": mustBuildBindVariable("on"), 3985 }, 3986 Expected: []sql.Row{ 3987 {types.OkResult{RowsAffected: 1}}, 3988 }, 3989 }, 3990 { 3991 Query: "select * from nodes", 3992 Expected: []sql.Row{ 3993 {"id1", "milo", "on", 1}, 3994 {"id2", "dabe", "off", 3}, 3995 }, 3996 }, 3997 }, 3998 }, 3999 } 4000 for _, tt := range tests { 4001 TestScript(t, harness, tt) 4002 } 4003 } 4004 4005 func mustBuildBindVariable(v interface{}) *query.BindVariable { 4006 ret, err := sqltypes.BuildBindVariable(v) 4007 if err != nil { 4008 panic(err) 4009 } 4010 return ret 4011 } 4012 4013 func TestPreparedStatements(t *testing.T, harness Harness) { 4014 e := mustNewEngine(t, harness) 4015 defer e.Close() 4016 4017 for _, query := range queries.PreparedScriptTests { 4018 TestScript(t, harness, query) 4019 } 4020 } 4021 4022 // Runs tests on SHOW TABLE STATUS queries. 4023 func TestShowTableStatus(t *testing.T, harness Harness) { 4024 harness.Setup(setup.MydbData, setup.MytableData, setup.OthertableData) 4025 for _, tt := range queries.ShowTableStatusQueries { 4026 TestQuery(t, harness, tt.Query, tt.Expected, nil, nil) 4027 } 4028 } 4029 4030 func TestDateParse(t *testing.T, harness Harness) { 4031 harness.Setup() 4032 for _, tt := range queries.DateParseQueries { 4033 TestQuery(t, harness, tt.Query, tt.Expected, nil, nil) 4034 } 4035 } 4036 4037 func TestShowTableStatusPrepared(t *testing.T, harness Harness) { 4038 harness.Setup(setup.MydbData, setup.MytableData, setup.OthertableData) 4039 for _, tt := range queries.ShowTableStatusQueries { 4040 TestPreparedQuery(t, harness, tt.Query, tt.Expected, nil) 4041 } 4042 } 4043 4044 func TestVariableErrors(t *testing.T, harness Harness) { 4045 harness.Setup() 4046 e := mustNewEngine(t, harness) 4047 defer e.Close() 4048 for _, test := range queries.VariableErrorTests { 4049 t.Run(test.Query, func(t *testing.T) { 4050 AssertErr(t, e, harness, test.Query, test.ExpectedErr) 4051 }) 4052 } 4053 } 4054 4055 func TestWarnings(t *testing.T, harness Harness) { 4056 var queries = []queries.QueryTest{ 4057 { 4058 Query: ` 4059 SHOW WARNINGS 4060 `, 4061 Expected: []sql.Row{ 4062 {"Note", 1051, "Unknown table 'table3'"}, 4063 {"Note", 1051, "Unknown table 'table2'"}, 4064 {"Note", 1051, "Unknown table 'table1'"}, 4065 }, 4066 }, 4067 { 4068 Query: ` 4069 SHOW WARNINGS LIMIT 1 4070 `, 4071 Expected: []sql.Row{ 4072 {"Note", 1051, "Unknown table 'table3'"}, 4073 }, 4074 }, 4075 { 4076 Query: ` 4077 SHOW WARNINGS LIMIT 1,2 4078 `, 4079 Expected: []sql.Row{ 4080 {"Note", 1051, "Unknown table 'table2'"}, 4081 {"Note", 1051, "Unknown table 'table1'"}, 4082 }, 4083 }, 4084 { 4085 Query: ` 4086 SHOW WARNINGS LIMIT 0 4087 `, 4088 Expected: nil, 4089 }, 4090 { 4091 Query: ` 4092 SHOW WARNINGS LIMIT 2,1 4093 `, 4094 Expected: []sql.Row{ 4095 {"Note", 1051, "Unknown table 'table1'"}, 4096 }, 4097 }, 4098 { 4099 Query: ` 4100 SHOW WARNINGS LIMIT 10 4101 `, 4102 Expected: []sql.Row{ 4103 {"Note", 1051, "Unknown table 'table3'"}, 4104 {"Note", 1051, "Unknown table 'table2'"}, 4105 {"Note", 1051, "Unknown table 'table1'"}, 4106 }, 4107 }, 4108 { 4109 Query: ` 4110 SHOW WARNINGS LIMIT 10,1 4111 `, 4112 Expected: nil, 4113 }, 4114 } 4115 4116 harness.Setup() 4117 e := mustNewEngine(t, harness) 4118 defer e.Close() 4119 ctx := NewContext(harness) 4120 4121 // This will cause 3 warnings; 4122 RunQueryWithContext(t, e, harness, ctx, "drop table if exists table1, table2, table3;") 4123 4124 for _, tt := range queries { 4125 TestQueryWithContext(t, ctx, e, harness, tt.Query, tt.Expected, nil, nil) 4126 } 4127 } 4128 4129 func TestClearWarnings(t *testing.T, harness Harness) { 4130 require := require.New(t) 4131 harness.Setup(setup.Mytable...) 4132 e := mustNewEngine(t, harness) 4133 defer e.Close() 4134 4135 ctx := NewContext(harness) 4136 err := CreateNewConnectionForServerEngine(ctx, e) 4137 require.NoError(err) 4138 4139 // this query will cause 3 warnings. 4140 _, iter, err := e.Query(ctx, "drop table if exists table1, table2, table3;") 4141 require.NoError(err) 4142 err = iter.Close(ctx) 4143 require.NoError(err) 4144 4145 _, iter, err = e.Query(ctx, "SHOW WARNINGS") 4146 require.NoError(err) 4147 rows, err := sql.RowIterToRows(ctx, iter) 4148 require.NoError(err) 4149 err = iter.Close(ctx) 4150 require.NoError(err) 4151 require.Equal(3, len(rows)) 4152 4153 _, iter, err = e.Query(ctx, "SHOW WARNINGS LIMIT 1") 4154 require.NoError(err) 4155 rows, err = sql.RowIterToRows(ctx, iter) 4156 require.NoError(err) 4157 err = iter.Close(ctx) 4158 require.NoError(err) 4159 require.Equal(1, len(rows)) 4160 4161 _, iter, err = e.Query(ctx, "SELECT * FROM mytable LIMIT 1") 4162 require.NoError(err) 4163 _, err = sql.RowIterToRows(ctx, iter) 4164 require.NoError(err) 4165 err = iter.Close(ctx) 4166 require.NoError(err) 4167 4168 require.Equal(0, len(ctx.Session.Warnings())) 4169 } 4170 4171 func TestUse(t *testing.T, harness Harness) { 4172 require := require.New(t) 4173 harness.Setup(setup.MydbData, setup.MytableData, setup.FooData) 4174 e := mustNewEngine(t, harness) 4175 defer e.Close() 4176 ctx := NewContext(harness) 4177 err := CreateNewConnectionForServerEngine(ctx, e) 4178 require.NoError(err) 4179 4180 var script = queries.ScriptTest{ 4181 Name: "ALTER TABLE, ALTER COLUMN SET , DROP DEFAULT", 4182 SetUpScript: []string{ 4183 "CREATE TABLE test (pk BIGINT PRIMARY KEY, v1 BIGINT NOT NULL default 88);", 4184 }, 4185 Assertions: []queries.ScriptTestAssertion{ 4186 { 4187 Query: "SELECT DATABASE();", 4188 Expected: []sql.Row{{"mydb"}}, 4189 }, 4190 { 4191 Query: "USE bar;", 4192 ExpectedErrStr: "database not found: bar", 4193 }, 4194 { 4195 Query: "SELECT DATABASE();", 4196 Expected: []sql.Row{{"mydb"}}, 4197 }, 4198 { 4199 Query: "USE foo;", 4200 Expected: []sql.Row{}, 4201 }, 4202 { 4203 Query: "SELECT DATABASE();", 4204 Expected: []sql.Row{{"foo"}}, 4205 }, 4206 { 4207 Query: "USE MYDB;", 4208 Expected: []sql.Row{}, 4209 }, 4210 { 4211 Query: "SELECT DATABASE();", 4212 Expected: []sql.Row{{"mydb"}}, 4213 }, 4214 }, 4215 } 4216 4217 TestScriptWithEngine(t, e, harness, script) 4218 } 4219 4220 // TestConcurrentTransactions tests that two concurrent processes/transactions can successfully execute without early 4221 // cancellation. 4222 func TestConcurrentTransactions(t *testing.T, harness Harness) { 4223 require := require.New(t) 4224 harness.Setup(setup.MydbData) 4225 engine := mustNewEngine(t, harness) 4226 4227 e, ok := engine.(*sqle.Engine) 4228 if !ok { 4229 t.Skip("Need a *sqle.Engine for TestConcurrentTransactions") 4230 } 4231 defer e.Close() 4232 4233 pl := e.ProcessList 4234 4235 RunQueryWithContext(t, e, harness, nil, `CREATE TABLE a (x int primary key, y int)`) 4236 4237 clientSessionA := NewSession(harness) 4238 clientSessionA.ProcessList = pl 4239 pl.AddConnection(clientSessionA.ID(), clientSessionA.Address()) 4240 pl.ConnectionReady(clientSessionA.Session) 4241 4242 clientSessionB := NewSession(harness) 4243 clientSessionB.ProcessList = pl 4244 pl.AddConnection(clientSessionB.ID(), clientSessionB.Address()) 4245 pl.ConnectionReady(clientSessionB.Session) 4246 4247 var err error 4248 // We want to add the query to the process list to represent the full workflow. 4249 clientSessionA, err = pl.BeginQuery(clientSessionA, "INSERT INTO a VALUES (1,1)") 4250 require.NoError(err) 4251 _, iter, err := e.Query(clientSessionA, "INSERT INTO a VALUES (1,1)") 4252 require.NoError(err) 4253 4254 clientSessionB, err = pl.BeginQuery(clientSessionB, "INSERT INTO a VALUES (2,2)") 4255 require.NoError(err) 4256 _, iter2, err := e.Query(clientSessionB, "INSERT INTO a VALUES (2,2)") 4257 require.NoError(err) 4258 4259 rows, err := sql.RowIterToRows(clientSessionA, iter) 4260 require.NoError(err) 4261 require.Len(rows, 1) 4262 4263 rows, err = sql.RowIterToRows(clientSessionB, iter2) 4264 require.NoError(err) 4265 require.Len(rows, 1) 4266 } 4267 4268 func TestTransactionScripts(t *testing.T, harness Harness) { 4269 for _, script := range queries.TransactionTests { 4270 TestTransactionScript(t, harness, script) 4271 } 4272 } 4273 4274 func TestConcurrentProcessList(t *testing.T, harness Harness) { 4275 require := require.New(t) 4276 pl := sqle.NewProcessList() 4277 numSessions := 2 4278 4279 for i := 0; i < numSessions; i++ { 4280 pl.AddConnection(uint32(i), "foo") 4281 sess := sql.NewBaseSessionWithClientServer("0.0.0.0:3306", sql.Client{Address: "", User: ""}, uint32(i)) 4282 pl.ConnectionReady(sess) 4283 4284 var err error 4285 ctx := sql.NewContext(context.Background(), sql.WithPid(uint64(i)), sql.WithSession(sess), sql.WithProcessList(pl)) 4286 _, err = pl.BeginQuery(ctx, "foo") 4287 require.NoError(err) 4288 } 4289 4290 var wg sync.WaitGroup 4291 4292 // Read concurrently 4293 for i := 0; i < numSessions; i++ { 4294 wg.Add(1) 4295 go func(x int) { 4296 defer wg.Done() 4297 procs := pl.Processes() 4298 for _, proc := range procs { 4299 for prog, part := range proc.Progress { 4300 if prog == "" { 4301 } 4302 for p, pp := range part.PartitionsProgress { 4303 if p == "" { 4304 } 4305 if pp.Name == "" { 4306 } 4307 } 4308 } 4309 } 4310 }(i) 4311 } 4312 4313 // Writes concurrently 4314 for i := 0; i < numSessions; i++ { 4315 wg.Add(4) 4316 go func(x int) { 4317 defer wg.Done() 4318 pl.AddTableProgress(uint64(x), "foo", 100) 4319 }(i) 4320 go func(x int) { 4321 defer wg.Done() 4322 pl.AddPartitionProgress(uint64(x), "foo", "bar", 100) 4323 }(i) 4324 go func(x int) { 4325 defer wg.Done() 4326 pl.UpdateTableProgress(uint64(x), "foo", 100) 4327 }(i) 4328 go func(x int) { 4329 defer wg.Done() 4330 pl.UpdatePartitionProgress(uint64(x), "foo", "bar", 100) 4331 }(i) 4332 } 4333 4334 wg.Wait() 4335 } 4336 4337 func TestNoDatabaseSelected(t *testing.T, harness Harness) { 4338 harness.Setup(setup.MydbData) 4339 e := mustNewEngine(t, harness) 4340 defer e.Close() 4341 ctx := NewContext(harness) 4342 ctx.SetCurrentDatabase("") 4343 4344 AssertErrWithCtx(t, e, harness, ctx, "create table a (b int primary key)", sql.ErrNoDatabaseSelected) 4345 AssertErrWithCtx(t, e, harness, ctx, "show tables", sql.ErrNoDatabaseSelected) 4346 AssertErrWithCtx(t, e, harness, ctx, "show triggers", sql.ErrNoDatabaseSelected) 4347 4348 _, _, err := e.Query(ctx, "ROLLBACK") 4349 require.NoError(t, err) 4350 } 4351 4352 func TestSessionSelectLimit(t *testing.T, harness Harness) { 4353 q := []queries.QueryTest{ 4354 { 4355 Query: "SELECT i FROM mytable ORDER BY i", 4356 Expected: []sql.Row{{1}, {2}}, 4357 }, 4358 { 4359 Query: "SELECT i FROM (SELECT i FROM mytable ORDER BY i LIMIT 3) t", 4360 Expected: []sql.Row{{1}, {2}}, 4361 }, 4362 { 4363 Query: "SELECT i FROM (SELECT i FROM mytable ORDER BY i DESC) t ORDER BY i LIMIT 3", 4364 Expected: []sql.Row{{1}, {2}, {3}}, 4365 }, 4366 { 4367 Query: "SELECT i FROM (SELECT i FROM mytable ORDER BY i DESC) t ORDER BY i LIMIT 3", 4368 Expected: []sql.Row{{1}, {2}, {3}}, 4369 }, 4370 { 4371 Query: "select count(*), y from a group by y;", 4372 Expected: []sql.Row{{2, 1}, {3, 2}}, 4373 }, 4374 { 4375 Query: "select count(*), y from (select y from a) b group by y;", 4376 Expected: []sql.Row{{2, 1}, {3, 2}}, 4377 }, 4378 { 4379 Query: "select count(*), y from (select y from a) b group by y;", 4380 Expected: []sql.Row{{2, 1}, {3, 2}}, 4381 }, 4382 { 4383 Query: "with b as (select y from a order by x) select * from b", 4384 Expected: []sql.Row{{1}, {1}}, 4385 }, 4386 { 4387 Query: "select x, row_number() over (partition by y) from a order by x;", 4388 Expected: []sql.Row{{0, 1}, {1, 2}}, 4389 }, 4390 { 4391 Query: "select y from a where x < 1 union select y from a where x > 1", 4392 Expected: []sql.Row{{1}, {2}}, 4393 }, 4394 } 4395 4396 customSetup := []setup.SetupScript{{ 4397 "Create table a (x int primary key, y int);", 4398 "Insert into a values (0,1), (1,1), (2,2), (3,2), (4,2), (5,3),(6,3);", 4399 }} 4400 harness.Setup(setup.MydbData, setup.MytableData, customSetup) 4401 e := mustNewEngine(t, harness) 4402 defer e.Close() 4403 ctx := NewContext(harness) 4404 if IsServerEngine(e) { 4405 RunQueryWithContext(t, e, harness, ctx, "SET @@sql_select_limit = 2") 4406 } else { 4407 err := ctx.Session.SetSessionVariable(ctx, "sql_select_limit", int64(2)) 4408 require.NoError(t, err) 4409 } 4410 4411 for _, tt := range q { 4412 t.Run(tt.Query, func(t *testing.T) { 4413 TestQueryWithContext(t, ctx, e, harness, tt.Query, tt.Expected, nil, nil) 4414 }) 4415 } 4416 } 4417 4418 func TestTracing(t *testing.T, harness Harness) { 4419 harness.Setup(setup.MydbData, setup.MytableData) 4420 e := mustNewEngine(t, harness) 4421 defer e.Close() 4422 4423 ctx := NewContext(harness) 4424 tracer := new(test.MemTracer) 4425 4426 sql.WithTracer(tracer)(ctx) 4427 4428 _, iter, err := e.Query(ctx, `SELECT DISTINCT i 4429 FROM mytable 4430 WHERE s = 'first row' 4431 ORDER BY i DESC 4432 LIMIT 1`) 4433 require.NoError(t, err) 4434 4435 rows, err := sql.RowIterToRows(ctx, iter) 4436 require.Len(t, rows, 1) 4437 require.NoError(t, err) 4438 4439 spans := tracer.Spans 4440 // TODO restore TopN 4441 var expectedSpans = []string{ 4442 "plan.Limit", 4443 "plan.Distinct", 4444 "plan.Project", 4445 "plan.Sort", 4446 "plan.Filter", 4447 "plan.IndexedTableAccess", 4448 } 4449 4450 var spanOperations []string 4451 for _, s := range spans { 4452 // only check the ones inside the execution tree 4453 if strings.HasPrefix(s, "plan.") || 4454 strings.HasPrefix(s, "expression.") || 4455 strings.HasPrefix(s, "function.") || 4456 strings.HasPrefix(s, "aggregation.") { 4457 spanOperations = append(spanOperations, s) 4458 } 4459 } 4460 4461 require.Equal(t, expectedSpans, spanOperations) 4462 } 4463 4464 func TestCurrentTimestamp(t *testing.T, harness Harness) { 4465 harness.Setup(setup.MydbData) 4466 e := mustNewEngine(t, harness) 4467 defer e.Close() 4468 4469 date := time.Date( 4470 2000, // year 4471 12, // month 4472 12, // day 4473 10, // hour 4474 15, // min 4475 45, // sec 4476 987654321, // nsec 4477 time.UTC, // location (UTC) 4478 ) 4479 4480 testCases := []queries.QueryTest{ 4481 { 4482 Query: `SELECT CURRENT_TIMESTAMP(0)`, 4483 Expected: []sql.Row{{time.Date(2000, time.December, 12, 10, 15, 45, 0, time.UTC)}}, 4484 }, 4485 { 4486 Query: `SELECT CURRENT_TIMESTAMP(1)`, 4487 Expected: []sql.Row{{time.Date(2000, time.December, 12, 10, 15, 45, 900000000, time.UTC)}}, 4488 }, 4489 { 4490 Query: `SELECT CURRENT_TIMESTAMP(2)`, 4491 Expected: []sql.Row{{time.Date(2000, time.December, 12, 10, 15, 45, 980000000, time.UTC)}}, 4492 }, 4493 { 4494 Query: `SELECT CURRENT_TIMESTAMP(3)`, 4495 Expected: []sql.Row{{time.Date(2000, time.December, 12, 10, 15, 45, 987000000, time.UTC)}}, 4496 }, 4497 { 4498 Query: `SELECT CURRENT_TIMESTAMP(4)`, 4499 Expected: []sql.Row{{time.Date(2000, time.December, 12, 10, 15, 45, 987600000, time.UTC)}}, 4500 }, 4501 { 4502 Query: `SELECT CURRENT_TIMESTAMP(5)`, 4503 Expected: []sql.Row{{time.Date(2000, time.December, 12, 10, 15, 45, 987650000, time.UTC)}}, 4504 }, 4505 { 4506 Query: `SELECT CURRENT_TIMESTAMP(6)`, 4507 Expected: []sql.Row{{time.Date(2000, time.December, 12, 10, 15, 45, 987654000, time.UTC)}}, 4508 }, 4509 } 4510 4511 errorTests := []queries.GenericErrorQueryTest{ 4512 { 4513 Query: "SELECT CURRENT_TIMESTAMP(-1)", 4514 }, 4515 { 4516 Query: `SELECT CURRENT_TIMESTAMP(NULL)`, 4517 }, 4518 { 4519 Query: "SELECT CURRENT_TIMESTAMP('notanint')", 4520 }, 4521 } 4522 4523 for _, tt := range testCases { 4524 sql.RunWithNowFunc(func() time.Time { 4525 return date 4526 }, func() error { 4527 TestQuery(t, harness, tt.Query, tt.Expected, tt.ExpectedColumns, tt.Bindings) 4528 return nil 4529 }) 4530 } 4531 for _, tt := range errorTests { 4532 sql.RunWithNowFunc(func() time.Time { 4533 return date 4534 }, func() error { 4535 runGenericErrorTest(t, harness, tt) 4536 return nil 4537 }) 4538 } 4539 } 4540 4541 func TestOnUpdateExprScripts(t *testing.T, harness Harness) { 4542 harness.Setup(setup.MydbData) 4543 for _, script := range queries.OnUpdateExprScripts { 4544 if sh, ok := harness.(SkippingHarness); ok { 4545 if sh.SkipQueryTest(script.Name) { 4546 t.Run(script.Name, func(t *testing.T) { 4547 t.Skip(script.Name) 4548 }) 4549 continue 4550 } 4551 } 4552 e := mustNewEngine(t, harness) 4553 ctx := NewContext(harness) 4554 err := CreateNewConnectionForServerEngine(ctx, e) 4555 require.NoError(t, err, nil) 4556 4557 t.Run(script.Name, func(t *testing.T) { 4558 for _, statement := range script.SetUpScript { 4559 sql.RunWithNowFunc(func() time.Time { return queries.Jan1Noon }, func() error { 4560 ctx = ctx.WithQuery(statement) 4561 ctx.SetQueryTime(queries.Jan1Noon) 4562 RunQueryWithContext(t, e, harness, ctx, statement) 4563 return nil 4564 }) 4565 } 4566 4567 assertions := script.Assertions 4568 if len(assertions) == 0 { 4569 assertions = []queries.ScriptTestAssertion{ 4570 { 4571 Query: script.Query, 4572 Expected: script.Expected, 4573 ExpectedErr: script.ExpectedErr, 4574 ExpectedIndexes: script.ExpectedIndexes, 4575 }, 4576 } 4577 } 4578 4579 for _, assertion := range script.Assertions { 4580 t.Run(assertion.Query, func(t *testing.T) { 4581 if assertion.Skip { 4582 t.Skip() 4583 } 4584 sql.RunWithNowFunc(func() time.Time { return queries.Dec15_1_30 }, func() error { 4585 ctx.SetQueryTime(queries.Dec15_1_30) 4586 if assertion.ExpectedErr != nil { 4587 AssertErr(t, e, harness, assertion.Query, assertion.ExpectedErr) 4588 } else if assertion.ExpectedErrStr != "" { 4589 AssertErr(t, e, harness, assertion.Query, nil, assertion.ExpectedErrStr) 4590 } else { 4591 var expected = assertion.Expected 4592 if IsServerEngine(e) && assertion.SkipResultCheckOnServerEngine { 4593 // TODO: remove this check in the future 4594 expected = nil 4595 } 4596 TestQueryWithContext(t, ctx, e, harness, assertion.Query, expected, assertion.ExpectedColumns, assertion.Bindings) 4597 } 4598 return nil 4599 }) 4600 }) 4601 } 4602 }) 4603 4604 e.Close() 4605 } 4606 } 4607 4608 func TestAddDropPks(t *testing.T, harness Harness) { 4609 for _, tt := range queries.AddDropPrimaryKeyScripts { 4610 TestScript(t, harness, tt) 4611 } 4612 } 4613 4614 func TestNullRanges(t *testing.T, harness Harness) { 4615 harness.Setup(setup.NullsSetup...) 4616 for _, tt := range queries.NullRangeTests { 4617 TestQuery(t, harness, tt.Query, tt.Expected, nil, nil) 4618 } 4619 } 4620 4621 func TestJsonScripts(t *testing.T, harness Harness) { 4622 for _, script := range queries.JsonScripts { 4623 TestScript(t, harness, script) 4624 } 4625 } 4626 4627 func TestAlterTable(t *testing.T, harness Harness) { 4628 harness.Setup(setup.MydbData, setup.Pk_tablesData) 4629 e := mustNewEngine(t, harness) 4630 defer e.Close() 4631 4632 for _, script := range queries.AlterTableScripts { 4633 TestScript(t, harness, script) 4634 } 4635 } 4636 4637 func NewColumnDefaultValue(expr sql.Expression, outType sql.Type, representsLiteral, isParenthesized, mayReturnNil bool) *sql.ColumnDefaultValue { 4638 cdv, err := sql.NewColumnDefaultValue(expr, outType, representsLiteral, isParenthesized, mayReturnNil) 4639 if err != nil { 4640 panic(err) 4641 } 4642 return cdv 4643 } 4644 4645 func TestColumnDefaults(t *testing.T, harness Harness) { 4646 harness.Setup(setup.MydbData) 4647 4648 for _, tt := range queries.ColumnDefaultTests { 4649 TestScript(t, harness, tt) 4650 } 4651 4652 e := mustNewEngine(t, harness) 4653 defer e.Close() 4654 ctx := NewContext(harness) 4655 4656 // Some tests can't currently be run with as a script because they do additional checks 4657 t.Run("DATETIME/TIMESTAMP NOW/CURRENT_TIMESTAMP current_timestamp", func(t *testing.T) { 4658 if IsServerEngine(e) { 4659 t.Skip("TODO: fix result formatting for server engine tests") 4660 } 4661 // ctx = NewContext(harness) 4662 // e.Query(ctx, "set @@session.time_zone='SYSTEM';") 4663 // TODO: NOW() and CURRENT_TIMESTAMP() are supposed to be the same function in MySQL, but we have two different 4664 // implementations with slightly different behavior. 4665 TestQueryWithContext(t, ctx, e, harness, "CREATE TABLE t10(pk BIGINT PRIMARY KEY, v1 DATETIME(6) DEFAULT NOW(), v2 DATETIME(6) DEFAULT CURRENT_TIMESTAMP(),"+ 4666 "v3 TIMESTAMP(6) DEFAULT NOW(), v4 TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP())", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 4667 4668 // truncating time to microseconds for compatibility with integrators who may store more precision (go gives nanos) 4669 now := time.Now().Truncate(time.Microsecond).UTC() 4670 sql.RunWithNowFunc(func() time.Time { 4671 return now 4672 }, func() error { 4673 RunQueryWithContext(t, e, harness, nil, "insert into t10(pk) values (1)") 4674 return nil 4675 }) 4676 TestQueryWithContext(t, ctx, e, harness, "select * from t10 order by 1", []sql.Row{ 4677 {1, now.Truncate(time.Second), now.Truncate(time.Second), now.Truncate(time.Second), now.Truncate(time.Second)}, 4678 }, nil, nil) 4679 }) 4680 4681 // TODO: zero timestamps work slightly differently than they do in MySQL, where the zero time is "0000-00-00 00:00:00" 4682 // We use "0000-01-01 00:00:00" 4683 t.Run("DATETIME/TIMESTAMP NOW/CURRENT_TIMESTAMP literals", func(t *testing.T) { 4684 if IsServerEngine(e) { 4685 t.Skip("TODO: fix result formatting for server engine tests") 4686 } 4687 TestQueryWithContext(t, ctx, e, harness, "CREATE TABLE t10zero(pk BIGINT PRIMARY KEY, v1 DATETIME DEFAULT '2020-01-01 01:02:03', v2 DATETIME DEFAULT 0,"+ 4688 "v3 TIMESTAMP DEFAULT '2020-01-01 01:02:03', v4 TIMESTAMP DEFAULT 0)", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 4689 4690 RunQueryWithContext(t, e, harness, ctx, "insert into t10zero(pk) values (1)") 4691 4692 // TODO: the string conversion does not transform to UTC like other NOW() calls, fix this 4693 TestQueryWithContext(t, ctx, e, harness, "select * from t10zero order by 1", []sql.Row{{1, time.Date(2020, 1, 1, 1, 2, 3, 0, time.UTC), types.Datetime.Zero(), time.Date(2020, 1, 1, 1, 2, 3, 0, time.UTC), types.Timestamp.Zero()}}, nil, nil) 4694 }) 4695 4696 t.Run("Non-DATETIME/TIMESTAMP NOW/CURRENT_TIMESTAMP expression", func(t *testing.T) { 4697 TestQueryWithContext(t, ctx, e, harness, "CREATE TABLE t11(pk BIGINT PRIMARY KEY, v1 DATE DEFAULT (NOW()), v2 VARCHAR(20) DEFAULT (CURRENT_TIMESTAMP()))", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 4698 4699 now := time.Now() 4700 expectedDate := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC) 4701 expectedDatetimeString := now.Truncate(time.Second).Format(sql.TimestampDatetimeLayout) 4702 4703 sql.RunWithNowFunc(func() time.Time { 4704 return now 4705 }, func() error { 4706 RunQueryWithContext(t, e, harness, ctx, "insert into t11(pk) values (1)") 4707 return nil 4708 }) 4709 4710 // TODO: the string conversion does not transform to UTC like other NOW() calls, fix this 4711 TestQueryWithContext(t, ctx, e, harness, "select * from t11 order by 1", 4712 []sql.Row{{1, expectedDate, expectedDatetimeString}}, nil, nil) 4713 }) 4714 4715 t.Run("Table referenced with column", func(t *testing.T) { 4716 TestQueryWithContext(t, ctx, e, harness, "CREATE TABLE t28(pk BIGINT PRIMARY KEY, v1 BIGINT DEFAULT (t28.pk))", []sql.Row{{types.NewOkResult(0)}}, nil, nil) 4717 4718 RunQueryWithContext(t, e, harness, ctx, "INSERT INTO t28 (pk) VALUES (1), (2)") 4719 TestQueryWithContext(t, ctx, e, harness, "SELECT * FROM t28 order by 1", []sql.Row{{1, 1}, {2, 2}}, nil, nil) 4720 4721 ctx := NewContext(harness) 4722 t28, _, err := e.EngineAnalyzer().Catalog.Table(ctx, ctx.GetCurrentDatabase(), "t28") 4723 require.NoError(t, err) 4724 sch := t28.Schema() 4725 require.Len(t, sch, 2) 4726 require.Equal(t, "v1", sch[1].Name) 4727 require.NotContains(t, sch[1].Default.String(), "t28") 4728 }) 4729 } 4730 4731 func TestPersist(t *testing.T, harness Harness, newPersistableSess func(ctx *sql.Context) sql.PersistableSession) { 4732 q := []struct { 4733 Name string 4734 Query string 4735 Expected []sql.Row 4736 ExpectedGlobal interface{} 4737 ExpectedPersist interface{} 4738 }{ 4739 { 4740 Query: "SET PERSIST max_connections = 1000;", 4741 Expected: []sql.Row{{}}, 4742 ExpectedGlobal: int64(1000), 4743 ExpectedPersist: int64(1000), 4744 }, { 4745 Query: "SET @@PERSIST.max_connections = 1000;", 4746 Expected: []sql.Row{{}}, 4747 ExpectedGlobal: int64(1000), 4748 ExpectedPersist: int64(1000), 4749 }, { 4750 Query: "SET PERSIST_ONLY max_connections = 1000;", 4751 Expected: []sql.Row{{}}, 4752 ExpectedGlobal: int64(151), 4753 ExpectedPersist: int64(1000), 4754 }, 4755 } 4756 4757 harness.Setup(setup.MydbData, setup.MytableData) 4758 e := mustNewEngine(t, harness) 4759 defer e.Close() 4760 4761 for _, tt := range q { 4762 t.Run(tt.Name, func(t *testing.T) { 4763 variables.InitSystemVariables() 4764 ctx := NewContext(harness) 4765 ctx.Session = newPersistableSess(ctx) 4766 4767 TestQueryWithContext(t, ctx, e, harness, tt.Query, tt.Expected, nil, nil) 4768 4769 if tt.ExpectedGlobal != nil { 4770 _, res, _ := sql.SystemVariables.GetGlobal("max_connections") 4771 require.Equal(t, tt.ExpectedGlobal, res) 4772 4773 showGlobalVarsQuery := "SHOW GLOBAL VARIABLES LIKE 'max_connections'" 4774 TestQueryWithContext(t, ctx, e, harness, showGlobalVarsQuery, []sql.Row{{"max_connections", tt.ExpectedGlobal}}, nil, nil) 4775 } 4776 4777 if tt.ExpectedPersist != nil { 4778 res, err := ctx.Session.(sql.PersistableSession).GetPersistedValue("max_connections") 4779 require.NoError(t, err) 4780 assert.Equal(t, 4781 tt.ExpectedPersist, res) 4782 } 4783 }) 4784 } 4785 } 4786 4787 func TestValidateSession(t *testing.T, harness Harness, newSessFunc func(ctx *sql.Context) sql.PersistableSession, count *int) { 4788 queries := []string{"SHOW TABLES;", "SELECT i from mytable;"} 4789 harness.Setup(setup.MydbData, setup.MytableData) 4790 e := mustNewEngine(t, harness) 4791 defer e.Close() 4792 4793 ctx := NewContext(harness) 4794 ctx.Session = newSessFunc(ctx) 4795 4796 for _, q := range queries { 4797 t.Run("test running queries to check callbacks on ValidateSession()", func(t *testing.T) { 4798 RunQueryWithContext(t, e, harness, ctx, q) 4799 }) 4800 } 4801 // This asserts that ValidateSession() method was called once for every statement. 4802 require.Equal(t, len(queries), *count) 4803 } 4804 4805 func TestPrepared(t *testing.T, harness Harness) { 4806 qtests := []queries.QueryTest{ 4807 { 4808 Query: "select 1,2 limit ?,?", 4809 Expected: []sql.Row{{1, 2}}, 4810 Bindings: map[string]*query.BindVariable{ 4811 "v1": sqltypes.Float64BindVariable(0.0), 4812 "v2": sqltypes.Float64BindVariable(1.0), 4813 }, 4814 }, 4815 { 4816 Query: "SELECT i, 1 AS foo, 2 AS bar FROM (SELECT i FROM mYtABLE WHERE i = ?) AS a ORDER BY foo, i", 4817 Expected: []sql.Row{ 4818 {2, 1, 2}}, 4819 Bindings: map[string]*query.BindVariable{ 4820 "v1": sqltypes.Int64BindVariable(int64(2)), 4821 }, 4822 }, 4823 { 4824 Query: "SELECT i, 1 AS foo, 2 AS bar FROM (SELECT i FROM mYtABLE WHERE i = ?) AS a HAVING bar = ? ORDER BY foo, i", 4825 Expected: []sql.Row{ 4826 {2, 1, 2}}, 4827 Bindings: map[string]*query.BindVariable{ 4828 "v1": sqltypes.Int64BindVariable(int64(2)), 4829 "v2": sqltypes.Int64BindVariable(int64(2)), 4830 }, 4831 }, 4832 { 4833 Query: "SELECT i, 1 AS foo, 2 AS bar FROM MyTable HAVING bar = ? ORDER BY foo, i;", 4834 Expected: []sql.Row{}, 4835 Bindings: map[string]*query.BindVariable{ 4836 "v1": sqltypes.Int64BindVariable(int64(1)), 4837 }, 4838 }, 4839 { 4840 Query: "SELECT i, 1 AS foo, 2 AS bar FROM MyTable HAVING bar = ? AND foo = ? ORDER BY foo, i;", 4841 Expected: []sql.Row{}, 4842 Bindings: map[string]*query.BindVariable{ 4843 "v1": sqltypes.Int64BindVariable(int64(1)), 4844 "v2": sqltypes.Int64BindVariable(int64(1)), 4845 }, 4846 }, 4847 { 4848 Query: "SELECT ? * 2", 4849 Expected: []sql.Row{ 4850 {2}, 4851 }, 4852 Bindings: map[string]*query.BindVariable{ 4853 "v1": sqltypes.Int64BindVariable(int64(1)), 4854 }, 4855 }, 4856 { 4857 Query: "SELECT i from mytable where i in (?, ?) order by 1", 4858 Expected: []sql.Row{ 4859 {1}, 4860 {2}, 4861 }, 4862 Bindings: map[string]*query.BindVariable{ 4863 "v1": sqltypes.Int64BindVariable(int64(1)), 4864 "v2": sqltypes.Int64BindVariable(int64(2)), 4865 }, 4866 }, 4867 { 4868 Query: "SELECT i from mytable where i = ? * 2", 4869 Expected: []sql.Row{ 4870 {2}, 4871 }, 4872 Bindings: map[string]*query.BindVariable{ 4873 "v1": sqltypes.Int64BindVariable(int64(1)), 4874 }, 4875 }, 4876 { 4877 Query: "SELECT i from mytable where 4 = ? * 2 order by 1", 4878 Expected: []sql.Row{ 4879 {1}, 4880 {2}, 4881 {3}, 4882 }, 4883 Bindings: map[string]*query.BindVariable{ 4884 "v1": sqltypes.Int64BindVariable(int64(2)), 4885 }, 4886 }, 4887 { 4888 Query: "SELECT i FROM mytable WHERE s = 'first row' ORDER BY i DESC LIMIT ?;", 4889 Bindings: map[string]*query.BindVariable{ 4890 "v1": sqltypes.Int64BindVariable(1), 4891 }, 4892 Expected: []sql.Row{{int64(1)}}, 4893 }, 4894 { 4895 Query: "SELECT i FROM mytable ORDER BY i LIMIT ? OFFSET 2;", 4896 Bindings: map[string]*query.BindVariable{ 4897 "v1": sqltypes.Int64BindVariable(1), 4898 }, 4899 Expected: []sql.Row{{int64(3)}}, 4900 }, 4901 // todo(max): sort function expressions w/ bindvars are aliased incorrectly 4902 //{ 4903 // Query: "SELECT sum(?) as x FROM mytable ORDER BY sum(?)", 4904 // Bindings: map[string]*query.BindVariable{ 4905 // "v1": querypb.&query{Val: 1, Type: sql.Int8}, 4906 // "v2": {Value: mustConvertToValue().Val1, Type: sql.Int8}, 4907 // }, 4908 // Expected: []sql.Row{{float64(3)}}, 4909 //}, 4910 { 4911 Query: "SELECT (select sum(?) from mytable) as x FROM mytable ORDER BY (select sum(?) from mytable)", 4912 Bindings: map[string]*query.BindVariable{ 4913 "v1": sqltypes.Int64BindVariable(1), 4914 "v2": sqltypes.Int64BindVariable(1), 4915 }, 4916 Expected: []sql.Row{{float64(3)}, {float64(3)}, {float64(3)}}, 4917 }, 4918 { 4919 Query: "With x as (select sum(?) from mytable) select sum(?) from x ORDER BY (select sum(?) from mytable)", 4920 Bindings: map[string]*query.BindVariable{ 4921 "v1": sqltypes.Int64BindVariable(1), 4922 "v2": sqltypes.Int64BindVariable(1), 4923 "v3": sqltypes.Int64BindVariable(1), 4924 }, 4925 Expected: []sql.Row{{float64(1)}}, 4926 }, 4927 { 4928 Query: "SELECT CAST(? as CHAR) UNION SELECT CAST(? as CHAR)", 4929 Bindings: map[string]*query.BindVariable{ 4930 "v1": sqltypes.Int64BindVariable(1), 4931 "v2": mustBuildBindVariable("1"), 4932 }, 4933 Expected: []sql.Row{{"1"}}, 4934 }, 4935 { 4936 Query: "SELECT GET_LOCK(?, 10)", 4937 Bindings: map[string]*query.BindVariable{ 4938 "v1": sqltypes.StringBindVariable("10"), 4939 }, 4940 Expected: []sql.Row{{1}}, 4941 }, 4942 { 4943 Query: "Select IS_FREE_LOCK(?)", 4944 Bindings: map[string]*query.BindVariable{ 4945 "v1": sqltypes.StringBindVariable("10"), 4946 }, 4947 Expected: []sql.Row{{0}}, 4948 }, 4949 { 4950 Query: "Select IS_USED_LOCK(?)", 4951 Bindings: map[string]*query.BindVariable{ 4952 "v1": sqltypes.StringBindVariable("10"), 4953 }, 4954 Expected: []sql.Row{{uint64(1)}}, 4955 }, 4956 { 4957 Query: "Select RELEASE_LOCK(?)", 4958 Bindings: map[string]*query.BindVariable{ 4959 "v1": sqltypes.StringBindVariable("10"), 4960 }, 4961 Expected: []sql.Row{{1}}, 4962 }, 4963 { 4964 Query: "Select RELEASE_ALL_LOCKS()", 4965 Expected: []sql.Row{{0}}, 4966 }, 4967 { 4968 Query: "SELECT DATE_ADD(TIMESTAMP(?), INTERVAL 1 DAY);", 4969 Expected: []sql.Row{{time.Date(2022, time.October, 27, 13, 14, 15, 0, time.UTC)}}, 4970 Bindings: map[string]*query.BindVariable{ 4971 "v1": mustBuildBindVariable("2022-10-26 13:14:15"), 4972 }, 4973 }, 4974 { 4975 Query: "SELECT DATE_ADD(?, INTERVAL 1 DAY);", 4976 Expected: []sql.Row{{time.Date(2022, time.October, 27, 13, 14, 15, 0, time.UTC)}}, 4977 Bindings: map[string]*query.BindVariable{ 4978 "v1": mustBuildBindVariable("2022-10-26 13:14:15"), 4979 }, 4980 }, 4981 } 4982 qErrTests := []queries.QueryErrorTest{ 4983 { 4984 Query: "SELECT i, 1 AS foo, 2 AS bar FROM (SELECT i FROM mYtABLE WHERE i = ?) AS a ORDER BY foo, i", 4985 ExpectedErrStr: "invalid bind variable count: expected: 1, found: 2", 4986 Bindings: map[string]*query.BindVariable{ 4987 "v1": sqltypes.Int64BindVariable(int64(2)), 4988 "v2": sqltypes.Int64BindVariable(int64(2)), 4989 }, 4990 }, 4991 } 4992 4993 harness.Setup(setup.MydbData, setup.MytableData) 4994 e := mustNewEngine(t, harness) 4995 defer e.Close() 4996 4997 RunQueryWithContext(t, e, harness, nil, "CREATE TABLE a (x int, y int, z int)") 4998 RunQueryWithContext(t, e, harness, nil, "INSERT INTO a VALUES (0,1,1), (1,1,1), (2,1,1), (3,2,2), (4,2,2)") 4999 for _, tt := range qtests { 5000 t.Run(fmt.Sprintf("%s", tt.Query), func(t *testing.T) { 5001 ctx := NewContext(harness) 5002 _, err := e.PrepareQuery(ctx, tt.Query) 5003 require.NoError(t, err) 5004 TestQueryWithContext(t, ctx, e, harness, tt.Query, tt.Expected, tt.ExpectedColumns, tt.Bindings) 5005 }) 5006 } 5007 5008 for _, tt := range qErrTests { 5009 t.Run(fmt.Sprintf("%s", tt.Query), func(t *testing.T) { 5010 ctx := NewContext(harness) 5011 _, err := e.PrepareQuery(ctx, tt.Query) 5012 require.NoError(t, err) 5013 ctx = ctx.WithQuery(tt.Query) 5014 _, _, err = e.QueryWithBindings(ctx, tt.Query, nil, tt.Bindings) 5015 require.Error(t, err) 5016 }) 5017 } 5018 5019 repeatTests := []queries.QueryTest{ 5020 { 5021 Bindings: map[string]*query.BindVariable{ 5022 "v1": sqltypes.Int64BindVariable(int64(2)), 5023 }, 5024 Expected: []sql.Row{ 5025 {2, float64(4)}, 5026 }, 5027 }, 5028 { 5029 Bindings: map[string]*query.BindVariable{ 5030 "v1": sqltypes.Int64BindVariable(int64(2)), 5031 }, 5032 Expected: []sql.Row{ 5033 {2, float64(4)}, 5034 }, 5035 }, 5036 { 5037 Bindings: map[string]*query.BindVariable{ 5038 "v1": sqltypes.Int64BindVariable(int64(0)), 5039 }, 5040 Expected: []sql.Row{ 5041 {1, float64(2)}, 5042 {2, float64(4)}, 5043 }, 5044 }, 5045 { 5046 Bindings: map[string]*query.BindVariable{ 5047 "v1": sqltypes.Int64BindVariable(int64(3)), 5048 }, 5049 Expected: []sql.Row{ 5050 {2, float64(2)}, 5051 }, 5052 }, 5053 { 5054 Bindings: map[string]*query.BindVariable{ 5055 "v1": sqltypes.Int64BindVariable(int64(1)), 5056 }, 5057 Expected: []sql.Row{ 5058 {1, float64(1)}, 5059 {2, float64(4)}, 5060 }, 5061 }, 5062 } 5063 repeatQ := "select y, sum(y) from a where x > ? group by y order by y" 5064 ctx := NewContext(harness) 5065 _, err := e.PrepareQuery(ctx, repeatQ) 5066 require.NoError(t, err) 5067 for _, tt := range repeatTests { 5068 t.Run(fmt.Sprintf("%s", tt.Query), func(t *testing.T) { 5069 TestQueryWithContext(t, ctx, e, harness, repeatQ, tt.Expected, tt.ExpectedColumns, tt.Bindings) 5070 }) 5071 } 5072 } 5073 5074 func TestDatabaseCollationWire(t *testing.T, h Harness, sessionBuilder server.SessionBuilder) { 5075 testCharsetCollationWire(t, h, sessionBuilder, false, queries.DatabaseCollationWireTests) 5076 } 5077 5078 func TestCharsetCollationEngine(t *testing.T, harness Harness) { 5079 harness.Setup(setup.MydbData) 5080 for _, script := range queries.CharsetCollationEngineTests { 5081 t.Run(script.Name, func(t *testing.T) { 5082 engine := mustNewEngine(t, harness) 5083 defer engine.Close() 5084 5085 ctx := harness.NewContext() 5086 ctx.SetCurrentDatabase("mydb") 5087 5088 for _, statement := range script.SetUpScript { 5089 if sh, ok := harness.(SkippingHarness); ok { 5090 if sh.SkipQueryTest(statement) { 5091 t.Skip() 5092 } 5093 } 5094 RunQueryWithContext(t, engine, harness, ctx, statement) 5095 } 5096 5097 for _, query := range script.Queries { 5098 t.Run(query.Query, func(t *testing.T) { 5099 _, iter, err := engine.Query(ctx, query.Query) 5100 if query.Error || query.ErrKind != nil { 5101 if err == nil { 5102 _, err := sql.RowIterToRows(ctx, iter) 5103 require.Error(t, err) 5104 if query.ErrKind != nil { 5105 require.True(t, query.ErrKind.Is(err)) 5106 } 5107 } else { 5108 require.Error(t, err) 5109 if query.ErrKind != nil { 5110 require.True(t, query.ErrKind.Is(err)) 5111 } 5112 } 5113 } else { 5114 require.NoError(t, err) 5115 rows, err := sql.RowIterToRows(ctx, iter) 5116 require.NoError(t, err) 5117 require.Equal(t, query.Expected, rows) 5118 } 5119 }) 5120 } 5121 }) 5122 } 5123 } 5124 5125 func TestCharsetCollationWire(t *testing.T, h Harness, sessionBuilder server.SessionBuilder) { 5126 testCharsetCollationWire(t, h, sessionBuilder, true, queries.CharsetCollationWireTests) 5127 } 5128 5129 func testCharsetCollationWire(t *testing.T, h Harness, sessionBuilder server.SessionBuilder, useDefaultData bool, tests []queries.CharsetCollationWireTest) { 5130 harness, ok := h.(ClientHarness) 5131 if !ok { 5132 t.Skip(fmt.Sprintf("Cannot run %s as the harness must implement ClientHarness", t.Name())) 5133 } 5134 if useDefaultData { 5135 harness.Setup(setup.MydbData) 5136 } 5137 5138 port := getEmptyPort(t) 5139 for _, script := range tests { 5140 t.Run(script.Name, func(t *testing.T) { 5141 serverConfig := server.Config{ 5142 Protocol: "tcp", 5143 Address: fmt.Sprintf("localhost:%d", port), 5144 MaxConnections: 1000, 5145 } 5146 5147 e := mustNewEngine(t, harness) 5148 5149 engine, ok := e.(*sqle.Engine) 5150 // TODO: do we? 5151 if !ok { 5152 t.Skip("Need a *sqle.Engine for testCharsetCollationWire") 5153 } 5154 5155 defer engine.Close() 5156 engine.EngineAnalyzer().Catalog.MySQLDb.AddRootAccount() 5157 5158 s, err := server.NewServer(serverConfig, engine, sessionBuilder, nil) 5159 require.NoError(t, err) 5160 go func() { 5161 err := s.Start() 5162 require.NoError(t, err) 5163 }() 5164 defer func() { 5165 require.NoError(t, s.Close()) 5166 }() 5167 5168 conn, err := dbr.Open("mysql", fmt.Sprintf("root:@tcp(localhost:%d)/", port), nil) 5169 require.NoError(t, err) 5170 if useDefaultData { 5171 _, err = conn.Exec("USE mydb;") 5172 require.NoError(t, err) 5173 } 5174 5175 for _, statement := range script.SetUpScript { 5176 if sh, ok := harness.(SkippingHarness); ok { 5177 if sh.SkipQueryTest(statement) { 5178 t.Skip() 5179 } 5180 } 5181 _, err = conn.Exec(statement) 5182 require.NoError(t, err) 5183 } 5184 5185 for _, query := range script.Queries { 5186 t.Run(query.Query, func(t *testing.T) { 5187 r, err := conn.Query(query.Query) 5188 if query.Error { 5189 require.Error(t, err) 5190 } else if assert.NoError(t, err) { 5191 rowIdx := -1 5192 for r.Next() { 5193 rowIdx++ 5194 connRow := make([]*string, len(query.Expected[rowIdx])) 5195 interfaceRow := make([]any, len(connRow)) 5196 for i := range connRow { 5197 interfaceRow[i] = &connRow[i] 5198 } 5199 err = r.Scan(interfaceRow...) 5200 require.NoError(t, err) 5201 outRow := make(sql.Row, len(connRow)) 5202 for i, str := range connRow { 5203 if str == nil { 5204 outRow[i] = nil 5205 } else { 5206 outRow[i] = *str 5207 } 5208 } 5209 assert.Equal(t, query.Expected[rowIdx], outRow) 5210 5211 if query.ExpectedCollations != nil { 5212 for i, expectedCollation := range query.ExpectedCollations { 5213 assert.Equal(t, uint64(expectedCollation), extractCollationIdForField(r, i)) 5214 } 5215 } 5216 } 5217 } 5218 }) 5219 } 5220 require.NoError(t, conn.Close()) 5221 }) 5222 } 5223 } 5224 5225 // extractCollationIdForField uses reflection to access the MySQL field metadata for field |i| in result set |r| and 5226 // returns the field's character set ID metadata. This character set ID is not exposed through the standard golang 5227 // sql database interfaces, so we have to use reflection to access this so we can validate that we are sending the 5228 // correct character set metadata for fields. 5229 func extractCollationIdForField(r *dsql.Rows, i int) uint64 { 5230 rowsi := reflect.ValueOf(r).Elem().FieldByName("rowsi") 5231 mysqlRows := rowsi.Elem().Elem().FieldByName("mysqlRows") 5232 rs := mysqlRows.FieldByName("rs") 5233 columns := rs.FieldByName("columns") 5234 column := columns.Index(i) 5235 charSet := column.FieldByName("charSet") 5236 return charSet.Uint() 5237 } 5238 5239 func TestTypesOverWire(t *testing.T, harness ClientHarness, sessionBuilder server.SessionBuilder) { 5240 harness.Setup(setup.MydbData) 5241 5242 port := getEmptyPort(t) 5243 for _, script := range queries.TypeWireTests { 5244 t.Run(script.Name, func(t *testing.T) { 5245 e := mustNewEngine(t, harness) 5246 5247 engine, ok := e.(*sqle.Engine) 5248 // TODO: do we? 5249 if !ok { 5250 t.Skip("Need a *sqle.Engine for TestTypesOverWire") 5251 } 5252 defer engine.Close() 5253 5254 ctx := NewContextWithClient(harness, sql.Client{ 5255 User: "root", 5256 Address: "localhost", 5257 }) 5258 5259 engine.EngineAnalyzer().Catalog.MySQLDb.AddRootAccount() 5260 for _, statement := range script.SetUpScript { 5261 if sh, ok := harness.(SkippingHarness); ok { 5262 if sh.SkipQueryTest(statement) { 5263 t.Skip() 5264 } 5265 } 5266 RunQueryWithContext(t, engine, harness, ctx, statement) 5267 } 5268 5269 serverConfig := server.Config{ 5270 Protocol: "tcp", 5271 Address: fmt.Sprintf("localhost:%d", port), 5272 MaxConnections: 1000, 5273 } 5274 s, err := server.NewServer(serverConfig, engine, sessionBuilder, nil) 5275 require.NoError(t, err) 5276 go func() { 5277 err := s.Start() 5278 require.NoError(t, err) 5279 }() 5280 defer func() { 5281 require.NoError(t, s.Close()) 5282 }() 5283 5284 conn, err := dbr.Open("mysql", fmt.Sprintf("root:@tcp(localhost:%d)/", port), nil) 5285 require.NoError(t, err) 5286 _, err = conn.Exec("USE mydb;") 5287 require.NoError(t, err) 5288 for queryIdx, query := range script.Queries { 5289 r, err := conn.Query(query) 5290 if assert.NoError(t, err) { 5291 sch, engineIter, err := engine.Query(ctx, query) 5292 require.NoError(t, err) 5293 expectedRowSet := script.Results[queryIdx] 5294 expectedRowIdx := 0 5295 var engineRow sql.Row 5296 for engineRow, err = engineIter.Next(ctx); err == nil; engineRow, err = engineIter.Next(ctx) { 5297 if !assert.True(t, r.Next()) { 5298 break 5299 } 5300 expectedRow := expectedRowSet[expectedRowIdx] 5301 expectedRowIdx++ 5302 connRow := make([]*string, len(engineRow)) 5303 interfaceRow := make([]any, len(connRow)) 5304 for i := range connRow { 5305 interfaceRow[i] = &connRow[i] 5306 } 5307 err = r.Scan(interfaceRow...) 5308 if !assert.NoError(t, err) { 5309 break 5310 } 5311 expectedEngineRow := make([]*string, len(engineRow)) 5312 for i := range engineRow { 5313 sqlVal, err := sch[i].Type.SQL(ctx, nil, engineRow[i]) 5314 if !assert.NoError(t, err) { 5315 break 5316 } 5317 if !sqlVal.IsNull() { 5318 str := sqlVal.ToString() 5319 expectedEngineRow[i] = &str 5320 } 5321 } 5322 5323 for i := range expectedEngineRow { 5324 expectedVal := expectedEngineRow[i] 5325 connVal := connRow[i] 5326 if !assert.Equal(t, expectedVal == nil, connVal == nil) { 5327 continue 5328 } 5329 if expectedVal != nil { 5330 assert.Equal(t, *expectedVal, *connVal) 5331 if script.Name == "JSON" { 5332 // Different integrators may return their JSON strings with different spacing, so we 5333 // special case the test since the spacing is not significant 5334 *connVal = strings.Replace(*connVal, `, `, `,`, -1) 5335 *connVal = strings.Replace(*connVal, `: "`, `:"`, -1) 5336 } 5337 assert.Equal(t, expectedRow[i], *connVal) 5338 } 5339 } 5340 } 5341 assert.True(t, err == io.EOF) 5342 assert.False(t, r.Next()) 5343 require.NoError(t, r.Close()) 5344 } 5345 } 5346 require.NoError(t, conn.Close()) 5347 }) 5348 } 5349 } 5350 5351 type memoryPersister struct { 5352 users []*mysql_db.User 5353 roles []*mysql_db.RoleEdge 5354 } 5355 5356 var _ mysql_db.MySQLDbPersistence = &memoryPersister{} 5357 5358 func (p *memoryPersister) Persist(ctx *sql.Context, data []byte) error { 5359 //erase everything from users and roles 5360 p.users = make([]*mysql_db.User, 0) 5361 p.roles = make([]*mysql_db.RoleEdge, 0) 5362 5363 // Deserialize the flatbuffer 5364 serialMySQLDb := serial.GetRootAsMySQLDb(data, 0) 5365 5366 // Fill in users 5367 for i := 0; i < serialMySQLDb.UserLength(); i++ { 5368 serialUser := new(serial.User) 5369 if !serialMySQLDb.User(serialUser, i) { 5370 continue 5371 } 5372 user := mysql_db.LoadUser(serialUser) 5373 p.users = append(p.users, user) 5374 } 5375 5376 // Fill in roles 5377 for i := 0; i < serialMySQLDb.RoleEdgesLength(); i++ { 5378 serialRoleEdge := new(serial.RoleEdge) 5379 if !serialMySQLDb.RoleEdges(serialRoleEdge, i) { 5380 continue 5381 } 5382 role := mysql_db.LoadRoleEdge(serialRoleEdge) 5383 p.roles = append(p.roles, role) 5384 } 5385 5386 return nil 5387 } 5388 5389 func TestPrivilegePersistence(t *testing.T, h Harness) { 5390 harness, ok := h.(ClientHarness) 5391 if !ok { 5392 t.Skip("Cannot run TestPrivilegePersistence as the harness must implement ClientHarness") 5393 } 5394 5395 engine := mustNewEngine(t, harness) 5396 defer engine.Close() 5397 5398 persister := &memoryPersister{} 5399 engine.EngineAnalyzer().Catalog.MySQLDb.AddRootAccount() 5400 engine.EngineAnalyzer().Catalog.MySQLDb.SetPersister(persister) 5401 ctx := NewContextWithClient(harness, sql.Client{ 5402 User: "root", 5403 Address: "localhost", 5404 }) 5405 5406 RunQueryWithContext(t, engine, harness, ctx, "CREATE USER tester@localhost") 5407 // If the user exists in []*mysql_db.User, then it must be NOT nil. 5408 require.NotNil(t, findUser("tester", "localhost", persister.users)) 5409 5410 RunQueryWithContext(t, engine, harness, ctx, "INSERT INTO mysql.user (Host, User) VALUES ('localhost', 'tester1')") 5411 require.Nil(t, findUser("tester1", "localhost", persister.users)) 5412 5413 RunQueryWithContext(t, engine, harness, ctx, "UPDATE mysql.user SET User = 'test_user' WHERE User = 'tester'") 5414 require.NotNil(t, findUser("tester", "localhost", persister.users)) 5415 5416 RunQueryWithContext(t, engine, harness, ctx, "FLUSH PRIVILEGES") 5417 require.NotNil(t, findUser("tester1", "localhost", persister.users)) 5418 require.Nil(t, findUser("tester", "localhost", persister.users)) 5419 require.NotNil(t, findUser("test_user", "localhost", persister.users)) 5420 5421 RunQueryWithContext(t, engine, harness, ctx, "DELETE FROM mysql.user WHERE User = 'tester1'") 5422 require.NotNil(t, findUser("tester1", "localhost", persister.users)) 5423 5424 RunQueryWithContext(t, engine, harness, ctx, "GRANT SELECT ON mydb.* TO test_user@localhost") 5425 user := findUser("test_user", "localhost", persister.users) 5426 require.True(t, user.PrivilegeSet.Database("mydb").Has(sql.PrivilegeType_Select)) 5427 5428 RunQueryWithContext(t, engine, harness, ctx, "UPDATE mysql.db SET Insert_priv = 'Y' WHERE User = 'test_user'") 5429 require.False(t, user.PrivilegeSet.Database("mydb").Has(sql.PrivilegeType_Insert)) 5430 5431 RunQueryWithContext(t, engine, harness, ctx, "CREATE USER dolt@localhost") 5432 RunQueryWithContext(t, engine, harness, ctx, "INSERT INTO mysql.db (Host, Db, User, Select_priv) VALUES ('localhost', 'mydb', 'dolt', 'Y')") 5433 user1 := findUser("dolt", "localhost", persister.users) 5434 require.NotNil(t, user1) 5435 require.False(t, user1.PrivilegeSet.Database("mydb").Has(sql.PrivilegeType_Select)) 5436 5437 RunQueryWithContext(t, engine, harness, ctx, "FLUSH PRIVILEGES") 5438 require.Nil(t, findUser("tester1", "localhost", persister.users)) 5439 user = findUser("test_user", "localhost", persister.users) 5440 require.True(t, user.PrivilegeSet.Database("mydb").Has(sql.PrivilegeType_Insert)) 5441 user1 = findUser("dolt", "localhost", persister.users) 5442 require.True(t, user1.PrivilegeSet.Database("mydb").Has(sql.PrivilegeType_Select)) 5443 5444 RunQueryWithContext(t, engine, harness, ctx, "CREATE ROLE test_role") 5445 RunQueryWithContext(t, engine, harness, ctx, "GRANT SELECT ON *.* TO test_role") 5446 require.Zero(t, len(persister.roles)) 5447 RunQueryWithContext(t, engine, harness, ctx, "GRANT test_role TO test_user@localhost") 5448 require.NotZero(t, len(persister.roles)) 5449 5450 RunQueryWithContext(t, engine, harness, ctx, "UPDATE mysql.role_edges SET to_user = 'tester2' WHERE to_user = 'test_user'") 5451 require.NotNil(t, findRole("test_user", persister.roles)) 5452 require.Nil(t, findRole("tester2", persister.roles)) 5453 5454 RunQueryWithContext(t, engine, harness, ctx, "FLUSH PRIVILEGES") 5455 require.Nil(t, findRole("test_user", persister.roles)) 5456 require.NotNil(t, findRole("tester2", persister.roles)) 5457 5458 RunQueryWithContext(t, engine, harness, ctx, "INSERT INTO mysql.role_edges VALUES ('%', 'test_role', 'localhost', 'test_user', 'N')") 5459 require.Nil(t, findRole("test_user", persister.roles)) 5460 5461 RunQueryWithContext(t, engine, harness, ctx, "FLUSH PRIVILEGES") 5462 require.NotNil(t, findRole("test_user", persister.roles)) 5463 5464 RunQueryWithContext(t, engine, harness, ctx, "CREATE USER testuser@localhost;") 5465 RunQueryWithContext(t, engine, harness, ctx, "GRANT REPLICATION_SLAVE_ADMIN ON *.* TO testuser@localhost;") 5466 RunQueryWithContext(t, engine, harness, ctx, "FLUSH PRIVILEGES") 5467 testuser := findUser("testuser", "localhost", persister.users) 5468 require.ElementsMatch(t, []string{"REPLICATION_SLAVE_ADMIN"}, testuser.PrivilegeSet.ToSliceDynamic(false)) 5469 require.ElementsMatch(t, []string{}, testuser.PrivilegeSet.ToSliceDynamic(true)) 5470 5471 _, _, err := engine.Query(ctx, "FLUSH NO_WRITE_TO_BINLOG PRIVILEGES") 5472 require.Error(t, err) 5473 5474 _, _, err = engine.Query(ctx, "FLUSH LOCAL PRIVILEGES") 5475 require.Error(t, err) 5476 } 5477 5478 // findUser returns *mysql_db.User corresponding to specific user and host names. 5479 // If not found, returns nil *mysql_db.User. 5480 func findUser(user string, host string, users []*mysql_db.User) *mysql_db.User { 5481 for _, u := range users { 5482 if u.User == user && u.Host == host { 5483 return u 5484 } 5485 } 5486 return nil 5487 } 5488 5489 // findRole returns *mysql_db.RoleEdge corresponding to specific to_user. 5490 // If not found, returns nil *mysql_db.RoleEdge. 5491 func findRole(toUser string, roles []*mysql_db.RoleEdge) *mysql_db.RoleEdge { 5492 for _, r := range roles { 5493 if r.ToUser == toUser { 5494 return r 5495 } 5496 } 5497 return nil 5498 } 5499 5500 func TestBlobs(t *testing.T, h Harness) { 5501 h.Setup(setup.MydbData, setup.BlobData, setup.MytableData) 5502 5503 for _, tt := range queries.BlobErrors { 5504 runQueryErrorTest(t, h, tt) 5505 } 5506 5507 e := mustNewEngine(t, h) 5508 defer e.Close() 5509 for _, tt := range queries.BlobQueries { 5510 TestQueryWithEngine(t, h, e, tt) 5511 } 5512 5513 for _, tt := range queries.BlobWriteQueries { 5514 RunWriteQueryTest(t, h, tt) 5515 } 5516 } 5517 5518 func TestIndexes(t *testing.T, h Harness) { 5519 for _, tt := range queries.IndexQueries { 5520 TestScript(t, h, tt) 5521 } 5522 } 5523 5524 func TestIndexPrefix(t *testing.T, h Harness) { 5525 for _, tt := range queries.IndexPrefixQueries { 5526 TestScript(t, h, tt) 5527 } 5528 } 5529 5530 func TestSQLLogicTests(t *testing.T, harness Harness) { 5531 harness.Setup(setup.MydbData) 5532 for _, script := range queries.SQLLogicJoinTests { 5533 if sh, ok := harness.(SkippingHarness); ok { 5534 if sh.SkipQueryTest(script.Name) { 5535 t.Run(script.Name, func(t *testing.T) { 5536 t.Skip(script.Name) 5537 }) 5538 continue 5539 } 5540 } 5541 TestScript(t, harness, script) 5542 } 5543 for _, script := range queries.SQLLogicSubqueryTests { 5544 if sh, ok := harness.(SkippingHarness); ok { 5545 if sh.SkipQueryTest(script.Name) { 5546 t.Run(script.Name, func(t *testing.T) { 5547 t.Skip(script.Name) 5548 }) 5549 continue 5550 } 5551 } 5552 TestScript(t, harness, script) 5553 } 5554 } 5555 5556 // ExecuteNode builds an iterator and then drains it. 5557 // This is useful for populating actual row counts for `DESCRIBE ANALYZE`. 5558 func ExecuteNode(ctx *sql.Context, engine QueryEngine, node sql.Node) error { 5559 iter, err := engine.EngineAnalyzer().ExecBuilder.Build(ctx, node, nil) 5560 if err != nil { 5561 return err 5562 } 5563 return DrainIterator(ctx, iter) 5564 } 5565 5566 func DrainIterator(ctx *sql.Context, iter sql.RowIter) error { 5567 if iter == nil { 5568 return nil 5569 } 5570 5571 for { 5572 _, err := iter.Next(ctx) 5573 if err == io.EOF { 5574 break 5575 } else if err != nil { 5576 return err 5577 } 5578 } 5579 5580 return iter.Close(ctx) 5581 } 5582 5583 // This shouldn't be necessary -- the fact that an iterator can return an error but not clean up after itself in all 5584 // cases is a bug. 5585 func DrainIteratorIgnoreErrors(ctx *sql.Context, iter sql.RowIter) { 5586 if iter == nil { 5587 return 5588 } 5589 5590 for { 5591 _, err := iter.Next(ctx) 5592 if err == io.EOF { 5593 return 5594 } 5595 } 5596 }