vitess.io/vitess@v0.16.2/go/vt/vttablet/tabletserver/schema/engine_test.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package schema 18 19 import ( 20 "context" 21 "expvar" 22 "fmt" 23 "net/http" 24 "net/http/httptest" 25 "sort" 26 "strings" 27 "testing" 28 "time" 29 30 "vitess.io/vitess/go/test/utils" 31 32 "github.com/stretchr/testify/assert" 33 "github.com/stretchr/testify/require" 34 35 "vitess.io/vitess/go/mysql" 36 "vitess.io/vitess/go/mysql/fakesqldb" 37 "vitess.io/vitess/go/sqltypes" 38 "vitess.io/vitess/go/vt/dbconfigs" 39 "vitess.io/vitess/go/vt/sqlparser" 40 "vitess.io/vitess/go/vt/vttablet/tabletserver/schema/schematest" 41 "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" 42 43 querypb "vitess.io/vitess/go/vt/proto/query" 44 ) 45 46 const baseShowTablesPattern = `SELECT t\.table_name.*` 47 48 var mustMatch = utils.MustMatchFn(".Mutex") 49 50 func TestOpenAndReload(t *testing.T) { 51 db := fakesqldb.New(t) 52 defer db.Close() 53 schematest.AddDefaultQueries(db) 54 db.AddQueryPattern(baseShowTablesPattern, 55 &sqltypes.Result{ 56 Fields: mysql.BaseShowTablesFields, 57 RowsAffected: 0, 58 InsertID: 0, 59 Rows: [][]sqltypes.Value{ 60 mysql.BaseShowTablesRow("test_table_01", false, ""), 61 mysql.BaseShowTablesRow("test_table_02", false, ""), 62 mysql.BaseShowTablesRow("test_table_03", false, ""), 63 mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), 64 mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), 65 }, 66 SessionStateChanges: "", 67 StatusFlags: 0, 68 }) 69 70 // advance to one second after the default 1427325875. 71 db.AddQuery("select unix_timestamp()", sqltypes.MakeTestResult(sqltypes.MakeTestFields( 72 "t", 73 "int64"), 74 "1427325876", 75 )) 76 firstReadRowsValue := 12 77 AddFakeInnoDBReadRowsResult(db, firstReadRowsValue) 78 se := newEngine(10, 10*time.Second, 10*time.Second, db) 79 se.Open() 80 defer se.Close() 81 82 want := initialSchema() 83 mustMatch(t, want, se.GetSchema()) 84 assert.Equal(t, int64(100), se.tableFileSizeGauge.Counts()["msg"]) 85 assert.Equal(t, int64(150), se.tableAllocatedSizeGauge.Counts()["msg"]) 86 87 // Advance time some more. 88 db.AddQuery("select unix_timestamp()", sqltypes.MakeTestResult(sqltypes.MakeTestFields( 89 "t", 90 "int64"), 91 "1427325877", 92 )) 93 assert.EqualValues(t, firstReadRowsValue, se.innoDbReadRowsCounter.Get()) 94 95 // Modify test_table_03 96 // Add test_table_04 97 // Drop msg 98 db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ 99 Fields: mysql.BaseShowTablesFields, 100 Rows: [][]sqltypes.Value{ 101 mysql.BaseShowTablesRow("test_table_01", false, ""), 102 mysql.BaseShowTablesRow("test_table_02", false, ""), 103 { 104 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("test_table_03")), // table_name 105 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("BASE TABLE")), // table_type 106 sqltypes.MakeTrusted(sqltypes.Int64, []byte("1427325877")), // unix_timestamp(t.create_time) 107 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("")), // table_comment 108 sqltypes.MakeTrusted(sqltypes.Int64, []byte("128")), // file_size 109 sqltypes.MakeTrusted(sqltypes.Int64, []byte("256")), // allocated_size 110 }, 111 // test_table_04 will in spite of older timestamp because it doesn't exist yet. 112 mysql.BaseShowTablesRow("test_table_04", false, ""), 113 mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), 114 }, 115 }) 116 db.MockQueriesForTable("test_table_03", &sqltypes.Result{ 117 Fields: []*querypb.Field{{ 118 Name: "pk1", 119 Type: sqltypes.Int32, 120 }, { 121 Name: "pk2", 122 Type: sqltypes.Int32, 123 }, { 124 Name: "val", 125 Type: sqltypes.Int32, 126 }}, 127 }) 128 129 db.MockQueriesForTable("test_table_04", &sqltypes.Result{ 130 Fields: []*querypb.Field{{ 131 Name: "pk", 132 Type: sqltypes.Int32, 133 }}, 134 }) 135 136 db.AddQuery(mysql.BaseShowPrimary, &sqltypes.Result{ 137 Fields: mysql.ShowPrimaryFields, 138 Rows: [][]sqltypes.Value{ 139 mysql.ShowPrimaryRow("test_table_01", "pk"), 140 mysql.ShowPrimaryRow("test_table_02", "pk"), 141 mysql.ShowPrimaryRow("test_table_03", "pk1"), 142 mysql.ShowPrimaryRow("test_table_03", "pk2"), 143 mysql.ShowPrimaryRow("test_table_04", "pk"), 144 mysql.ShowPrimaryRow("seq", "id"), 145 }, 146 }) 147 secondReadRowsValue := 123 148 AddFakeInnoDBReadRowsResult(db, secondReadRowsValue) 149 150 firstTime := true 151 notifier := func(full map[string]*Table, created, altered, dropped []string) { 152 if firstTime { 153 firstTime = false 154 sort.Strings(created) 155 assert.Equal(t, []string{"dual", "msg", "seq", "test_table_01", "test_table_02", "test_table_03"}, created) 156 assert.Equal(t, []string(nil), altered) 157 assert.Equal(t, []string(nil), dropped) 158 } else { 159 assert.Equal(t, []string{"test_table_04"}, created) 160 assert.Equal(t, []string{"test_table_03"}, altered) 161 sort.Strings(dropped) 162 assert.Equal(t, []string{"msg"}, dropped) 163 } 164 } 165 se.RegisterNotifier("test", notifier) 166 err := se.Reload(context.Background()) 167 require.NoError(t, err) 168 169 assert.EqualValues(t, secondReadRowsValue, se.innoDbReadRowsCounter.Get()) 170 171 want["test_table_03"] = &Table{ 172 Name: sqlparser.NewIdentifierCS("test_table_03"), 173 Fields: []*querypb.Field{{ 174 Name: "pk1", 175 Type: sqltypes.Int32, 176 }, { 177 Name: "pk2", 178 Type: sqltypes.Int32, 179 }, { 180 Name: "val", 181 Type: sqltypes.Int32, 182 }}, 183 PKColumns: []int{0, 1}, 184 CreateTime: 1427325877, 185 FileSize: 128, 186 AllocatedSize: 256, 187 } 188 want["test_table_04"] = &Table{ 189 Name: sqlparser.NewIdentifierCS("test_table_04"), 190 Fields: []*querypb.Field{{ 191 Name: "pk", 192 Type: sqltypes.Int32, 193 }}, 194 PKColumns: []int{0}, 195 CreateTime: 1427325875, 196 FileSize: 100, 197 AllocatedSize: 150, 198 } 199 delete(want, "msg") 200 assert.Equal(t, want, se.GetSchema()) 201 assert.Equal(t, int64(0), se.tableAllocatedSizeGauge.Counts()["msg"]) 202 assert.Equal(t, int64(0), se.tableFileSizeGauge.Counts()["msg"]) 203 204 //ReloadAt tests 205 pos1, err := mysql.DecodePosition("MariaDB/0-41983-20") 206 require.NoError(t, err) 207 pos2, err := mysql.DecodePosition("MariaDB/0-41983-40") 208 require.NoError(t, err) 209 se.UnregisterNotifier("test") 210 211 err = se.ReloadAt(context.Background(), mysql.Position{}) 212 require.NoError(t, err) 213 assert.Equal(t, want, se.GetSchema()) 214 215 err = se.ReloadAt(context.Background(), pos1) 216 require.NoError(t, err) 217 assert.Equal(t, want, se.GetSchema()) 218 219 db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ 220 Fields: mysql.BaseShowTablesFields, 221 Rows: [][]sqltypes.Value{ 222 mysql.BaseShowTablesRow("test_table_01", false, ""), 223 mysql.BaseShowTablesRow("test_table_02", false, ""), 224 mysql.BaseShowTablesRow("test_table_04", false, ""), 225 mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), 226 }, 227 }) 228 db.AddQuery(mysql.BaseShowPrimary, &sqltypes.Result{ 229 Fields: mysql.ShowPrimaryFields, 230 Rows: [][]sqltypes.Value{ 231 mysql.ShowPrimaryRow("test_table_01", "pk"), 232 mysql.ShowPrimaryRow("test_table_02", "pk"), 233 mysql.ShowPrimaryRow("test_table_04", "pk"), 234 mysql.ShowPrimaryRow("seq", "id"), 235 }, 236 }) 237 err = se.ReloadAt(context.Background(), pos1) 238 require.NoError(t, err) 239 assert.Equal(t, want, se.GetSchema()) 240 241 delete(want, "test_table_03") 242 err = se.ReloadAt(context.Background(), pos2) 243 require.NoError(t, err) 244 assert.Equal(t, want, se.GetSchema()) 245 } 246 247 func TestReloadWithSwappedTables(t *testing.T) { 248 db := fakesqldb.New(t) 249 defer db.Close() 250 schematest.AddDefaultQueries(db) 251 db.AddQueryPattern(baseShowTablesPattern, 252 &sqltypes.Result{ 253 Fields: mysql.BaseShowTablesFields, 254 RowsAffected: 0, 255 InsertID: 0, 256 Rows: [][]sqltypes.Value{ 257 mysql.BaseShowTablesRow("test_table_01", false, ""), 258 mysql.BaseShowTablesRow("test_table_02", false, ""), 259 mysql.BaseShowTablesRow("test_table_03", false, ""), 260 mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), 261 mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), 262 }, 263 SessionStateChanges: "", 264 StatusFlags: 0, 265 }) 266 firstReadRowsValue := 12 267 AddFakeInnoDBReadRowsResult(db, firstReadRowsValue) 268 269 se := newEngine(10, 10*time.Second, 10*time.Second, db) 270 se.Open() 271 defer se.Close() 272 want := initialSchema() 273 mustMatch(t, want, se.GetSchema()) 274 275 // Add test_table_04 with a newer timestamp 276 // Advance time some more. 277 db.AddQuery("select unix_timestamp()", sqltypes.MakeTestResult(sqltypes.MakeTestFields( 278 "t", 279 "int64"), 280 "1427325876", 281 )) 282 db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ 283 Fields: mysql.BaseShowTablesFields, 284 Rows: [][]sqltypes.Value{ 285 mysql.BaseShowTablesRow("test_table_01", false, ""), 286 mysql.BaseShowTablesRow("test_table_02", false, ""), 287 mysql.BaseShowTablesRow("test_table_03", false, ""), 288 { 289 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("test_table_04")), 290 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("BASE TABLE")), 291 sqltypes.MakeTrusted(sqltypes.Int64, []byte("1427325877")), // unix_timestamp(create_time) 292 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("")), 293 sqltypes.MakeTrusted(sqltypes.Int64, []byte("128")), // file_size 294 sqltypes.MakeTrusted(sqltypes.Int64, []byte("256")), // allocated_size 295 }, 296 mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), 297 mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), 298 }, 299 }) 300 db.MockQueriesForTable("test_table_04", &sqltypes.Result{ 301 Fields: []*querypb.Field{{ 302 Name: "mypk", 303 Type: sqltypes.Int32, 304 }}, 305 }) 306 db.AddQuery(mysql.BaseShowPrimary, &sqltypes.Result{ 307 Fields: mysql.ShowPrimaryFields, 308 Rows: [][]sqltypes.Value{ 309 mysql.ShowPrimaryRow("test_table_01", "pk"), 310 mysql.ShowPrimaryRow("test_table_02", "pk"), 311 mysql.ShowPrimaryRow("test_table_03", "pk"), 312 mysql.ShowPrimaryRow("test_table_04", "mypk"), 313 mysql.ShowPrimaryRow("seq", "id"), 314 mysql.ShowPrimaryRow("msg", "id"), 315 }, 316 }) 317 err := se.Reload(context.Background()) 318 require.NoError(t, err) 319 want["test_table_04"] = &Table{ 320 Name: sqlparser.NewIdentifierCS("test_table_04"), 321 Fields: []*querypb.Field{{ 322 Name: "mypk", 323 Type: sqltypes.Int32, 324 }}, 325 PKColumns: []int{0}, 326 CreateTime: 1427325877, 327 FileSize: 128, 328 AllocatedSize: 256, 329 } 330 331 mustMatch(t, want, se.GetSchema()) 332 333 // swap test_table_03 and test_table_04 334 // Advance time some more. 335 db.AddQuery("select unix_timestamp()", sqltypes.MakeTestResult(sqltypes.MakeTestFields( 336 "t", 337 "int64"), 338 "1427325877", 339 )) 340 db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ 341 Fields: mysql.BaseShowTablesFields, 342 Rows: [][]sqltypes.Value{ 343 mysql.BaseShowTablesRow("test_table_01", false, ""), 344 mysql.BaseShowTablesRow("test_table_02", false, ""), 345 { 346 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("test_table_03")), 347 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("BASE TABLE")), 348 sqltypes.MakeTrusted(sqltypes.Int64, []byte("1427325877")), // unix_timestamp(create_time) 349 sqltypes.MakeTrusted(sqltypes.VarChar, []byte("")), 350 sqltypes.MakeTrusted(sqltypes.Int64, []byte("128")), // file_size 351 sqltypes.MakeTrusted(sqltypes.Int64, []byte("256")), // allocated_size 352 }, 353 mysql.BaseShowTablesRow("test_table_04", false, ""), 354 mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), 355 mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), 356 }, 357 }) 358 db.MockQueriesForTable("test_table_03", &sqltypes.Result{ 359 Fields: []*querypb.Field{{ 360 Name: "mypk", 361 Type: sqltypes.Int32, 362 }}, 363 }) 364 365 db.MockQueriesForTable("test_table_04", &sqltypes.Result{ 366 Fields: []*querypb.Field{{ 367 Name: "pk", 368 Type: sqltypes.Int32, 369 }}, 370 }) 371 372 db.AddQuery(mysql.BaseShowPrimary, &sqltypes.Result{ 373 Fields: mysql.ShowPrimaryFields, 374 Rows: [][]sqltypes.Value{ 375 mysql.ShowPrimaryRow("test_table_01", "pk"), 376 mysql.ShowPrimaryRow("test_table_02", "pk"), 377 mysql.ShowPrimaryRow("test_table_03", "mypk"), 378 mysql.ShowPrimaryRow("test_table_04", "pk"), 379 mysql.ShowPrimaryRow("seq", "id"), 380 mysql.ShowPrimaryRow("msg", "id"), 381 }, 382 }) 383 err = se.Reload(context.Background()) 384 require.NoError(t, err) 385 386 delete(want, "test_table_03") 387 delete(want, "test_table_04") 388 want["test_table_03"] = &Table{ 389 Name: sqlparser.NewIdentifierCS("test_table_03"), 390 Fields: []*querypb.Field{{ 391 Name: "mypk", 392 Type: sqltypes.Int32, 393 }}, 394 PKColumns: []int{0}, 395 CreateTime: 1427325877, 396 FileSize: 128, 397 AllocatedSize: 256, 398 } 399 want["test_table_04"] = &Table{ 400 Name: sqlparser.NewIdentifierCS("test_table_04"), 401 Fields: []*querypb.Field{{ 402 Name: "pk", 403 Type: sqltypes.Int32, 404 }}, 405 PKColumns: []int{0}, 406 CreateTime: 1427325875, 407 FileSize: 100, 408 AllocatedSize: 150, 409 } 410 mustMatch(t, want, se.GetSchema()) 411 } 412 413 func TestOpenFailedDueToExecErr(t *testing.T) { 414 db := fakesqldb.New(t) 415 defer db.Close() 416 schematest.AddDefaultQueries(db) 417 want := "injected error" 418 db.RejectQueryPattern(baseShowTablesPattern, want) 419 se := newEngine(10, 1*time.Second, 1*time.Second, db) 420 err := se.Open() 421 if err == nil || !strings.Contains(err.Error(), want) { 422 t.Errorf("se.Open: %v, want %s", err, want) 423 } 424 } 425 426 func TestOpenFailedDueToTableErr(t *testing.T) { 427 db := fakesqldb.New(t) 428 defer db.Close() 429 schematest.AddDefaultQueries(db) 430 db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ 431 Fields: mysql.BaseShowTablesFields, 432 Rows: [][]sqltypes.Value{ 433 mysql.BaseShowTablesRow("test_table", false, ""), 434 }, 435 }) 436 db.MockQueriesForTable("test_table", &sqltypes.Result{ 437 // this will cause NewTable error, as it expects zero rows. 438 Fields: []*querypb.Field{ 439 { 440 Type: querypb.Type_VARCHAR, 441 }, 442 }, 443 Rows: [][]sqltypes.Value{ 444 {sqltypes.NewVarBinary("")}, 445 }, 446 }) 447 448 AddFakeInnoDBReadRowsResult(db, 0) 449 se := newEngine(10, 1*time.Second, 1*time.Second, db) 450 err := se.Open() 451 want := "Row count exceeded" 452 if err == nil || !strings.Contains(err.Error(), want) { 453 t.Errorf("se.Open: %v, want %s", err, want) 454 } 455 } 456 457 func TestExportVars(t *testing.T) { 458 db := fakesqldb.New(t) 459 defer db.Close() 460 schematest.AddDefaultQueries(db) 461 se := newEngine(10, 1*time.Second, 1*time.Second, db) 462 se.Open() 463 defer se.Close() 464 expvar.Do(func(kv expvar.KeyValue) { 465 _ = kv.Value.String() 466 }) 467 } 468 469 func TestStatsURL(t *testing.T) { 470 db := fakesqldb.New(t) 471 defer db.Close() 472 schematest.AddDefaultQueries(db) 473 se := newEngine(10, 1*time.Second, 1*time.Second, db) 474 se.Open() 475 defer se.Close() 476 477 request, _ := http.NewRequest("GET", "/debug/schema", nil) 478 response := httptest.NewRecorder() 479 se.handleDebugSchema(response, request) 480 } 481 482 func TestSchemaEngineCloseTickRace(t *testing.T) { 483 db := fakesqldb.New(t) 484 defer db.Close() 485 schematest.AddDefaultQueries(db) 486 db.AddQueryPattern(baseShowTablesPattern, 487 &sqltypes.Result{ 488 Fields: mysql.BaseShowTablesFields, 489 RowsAffected: 0, 490 InsertID: 0, 491 Rows: [][]sqltypes.Value{ 492 mysql.BaseShowTablesRow("test_table_01", false, ""), 493 mysql.BaseShowTablesRow("test_table_02", false, ""), 494 mysql.BaseShowTablesRow("test_table_03", false, ""), 495 mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), 496 mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), 497 }, 498 SessionStateChanges: "", 499 StatusFlags: 0, 500 }) 501 AddFakeInnoDBReadRowsResult(db, 12) 502 // Start the engine with a small reload tick 503 se := newEngine(10, 100*time.Millisecond, 1*time.Second, db) 504 err := se.Open() 505 require.NoError(t, err) 506 507 finished := make(chan bool) 508 go func() { 509 { 510 // Emulate the command of se.Close(), but with a wait in between 511 // to ensure that a reload-tick happens after locking the mutex but before 512 // stopping the ticks 513 se.mu.Lock() 514 // We wait for 200 milliseconds to be sure that the timer tick happens after acquiring the lock 515 // before we call closeLocked function 516 time.Sleep(200 * time.Millisecond) 517 se.closeLocked() 518 } 519 finished <- true 520 }() 521 // Wait until the ticks are stopped or 2 seonds have expired. 522 select { 523 case <-finished: 524 return 525 case <-time.After(2 * time.Second): 526 t.Fatal("Could not stop the ticks after 2 seconds") 527 } 528 } 529 530 func newEngine(queryCacheSize int, reloadTime time.Duration, idleTimeout time.Duration, db *fakesqldb.DB) *Engine { 531 config := tabletenv.NewDefaultConfig() 532 config.QueryCacheSize = queryCacheSize 533 config.SchemaReloadIntervalSeconds.Set(reloadTime) 534 config.OltpReadPool.IdleTimeoutSeconds.Set(idleTimeout) 535 config.OlapReadPool.IdleTimeoutSeconds.Set(idleTimeout) 536 config.TxPool.IdleTimeoutSeconds.Set(idleTimeout) 537 se := NewEngine(tabletenv.NewEnv(config, "SchemaTest")) 538 se.InitDBConfig(newDBConfigs(db).DbaWithDB()) 539 return se 540 } 541 542 func newDBConfigs(db *fakesqldb.DB) *dbconfigs.DBConfigs { 543 params, _ := db.ConnParams().MysqlParams() 544 cp := *params 545 return dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") 546 } 547 548 func initialSchema() map[string]*Table { 549 return map[string]*Table{ 550 "dual": { 551 Name: sqlparser.NewIdentifierCS("dual"), 552 }, 553 "test_table_01": { 554 Name: sqlparser.NewIdentifierCS("test_table_01"), 555 Fields: []*querypb.Field{{ 556 Name: "pk", 557 Type: sqltypes.Int32, 558 }}, 559 PKColumns: []int{0}, 560 CreateTime: 1427325875, 561 FileSize: 0x64, 562 AllocatedSize: 0x96, 563 }, 564 "test_table_02": { 565 Name: sqlparser.NewIdentifierCS("test_table_02"), 566 Fields: []*querypb.Field{{ 567 Name: "pk", 568 Type: sqltypes.Int32, 569 }}, 570 PKColumns: []int{0}, 571 CreateTime: 1427325875, 572 FileSize: 0x64, 573 AllocatedSize: 0x96, 574 }, 575 "test_table_03": { 576 Name: sqlparser.NewIdentifierCS("test_table_03"), 577 Fields: []*querypb.Field{{ 578 Name: "pk", 579 Type: sqltypes.Int32, 580 }}, 581 PKColumns: []int{0}, 582 CreateTime: 1427325875, 583 FileSize: 0x64, 584 AllocatedSize: 0x96, 585 }, 586 "seq": { 587 Name: sqlparser.NewIdentifierCS("seq"), 588 Type: Sequence, 589 Fields: []*querypb.Field{{ 590 Name: "id", 591 Type: sqltypes.Int32, 592 }, { 593 Name: "next_id", 594 Type: sqltypes.Int64, 595 }, { 596 Name: "cache", 597 Type: sqltypes.Int64, 598 }, { 599 Name: "increment", 600 Type: sqltypes.Int64, 601 }}, 602 PKColumns: []int{0}, 603 CreateTime: 1427325875, 604 FileSize: 0x64, 605 AllocatedSize: 0x96, 606 SequenceInfo: &SequenceInfo{}, 607 }, 608 "msg": { 609 Name: sqlparser.NewIdentifierCS("msg"), 610 Type: Message, 611 Fields: []*querypb.Field{{ 612 Name: "id", 613 Type: sqltypes.Int64, 614 }, { 615 Name: "priority", 616 Type: sqltypes.Int64, 617 }, { 618 Name: "time_next", 619 Type: sqltypes.Int64, 620 }, { 621 Name: "epoch", 622 Type: sqltypes.Int64, 623 }, { 624 Name: "time_acked", 625 Type: sqltypes.Int64, 626 }, { 627 Name: "message", 628 Type: sqltypes.Int64, 629 }}, 630 PKColumns: []int{0}, 631 CreateTime: 1427325875, 632 FileSize: 0x64, 633 AllocatedSize: 0x96, 634 MessageInfo: &MessageInfo{ 635 Fields: []*querypb.Field{{ 636 Name: "id", 637 Type: sqltypes.Int64, 638 }, { 639 Name: "message", 640 Type: sqltypes.Int64, 641 }}, 642 AckWaitDuration: 30 * time.Second, 643 PurgeAfterDuration: 120 * time.Second, 644 MinBackoff: 30 * time.Second, 645 BatchSize: 1, 646 CacheSize: 10, 647 PollInterval: 30 * time.Second, 648 }, 649 }, 650 } 651 } 652 653 func AddFakeInnoDBReadRowsResult(db *fakesqldb.DB, value int) *fakesqldb.ExpectedResult { 654 return db.AddQuery("show status like 'Innodb_rows_read'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( 655 "Variable_name|Value", 656 "varchar|int64"), 657 fmt.Sprintf("Innodb_rows_read|%d", value), 658 )) 659 }