// Test that table names are not treated as case sensitive by the name cache. func TestTableNameNotCaseSensitive(t *testing.T) { defer leaktest.AfterTest(t)() s, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t) defer cleanup() leaseManager := s.LeaseManager().(*LeaseManager) if _, err := sqlDB.Exec(` CREATE DATABASE t; CREATE TABLE t.test (k CHAR PRIMARY KEY, v CHAR); `); err != nil { t.Fatal(err) } // Populate the name cache. if _, err := sqlDB.Exec("SELECT * FROM t.test;"); err != nil { t.Fatal(err) } tableDesc := sqlbase.GetTableDescriptor(kvDB, "t", "test") // Check that we can get the table by a different name. lease := leaseManager.tableNames.get(tableDesc.ParentID, "tEsT", s.Clock()) if lease == nil { t.Fatalf("no name cache entry") } if err := leaseManager.Release(lease); err != nil { t.Fatal(err) } }
// Temporary proof-of-concept test that uses the testingshim to set up a test // server from the sql package. func TestPOC(t *testing.T) { defer leaktest.AfterTest(t)() _, _, kvClient, cleanup := sqlutils.SetupServer(t) defer cleanup() err := kvClient.Put("testkey", "testval") if err != nil { t.Fatal(err) } kv, err := kvClient.Get("testkey") if err != nil { t.Fatal(err) } if kv.PrettyValue() != `"testval"` { t.Errorf(`Invalid Get result: %s, expected "testval"`, kv.PrettyValue()) } }
// Check that we properly cleanup all the temporary names when performing a // series of renames in a transaction. func TestSeriesOfRenames(t *testing.T) { defer leaktest.AfterTest(t)() _, db, _, cleanup := sqlutils.SetupServer(t) defer cleanup() sql := ` CREATE DATABASE test; CREATE TABLE test.t (a INT PRIMARY KEY); ` _, err := db.Exec(sql) if err != nil { t.Fatal(err) } txn, err := db.Begin() if err != nil { t.Fatal(err) } if _, err := txn.Exec("ALTER TABLE test.t RENAME TO test.t2"); err != nil { t.Fatal(err) } if _, err := txn.Exec("ALTER TABLE test.t2 RENAME TO test.t3"); err != nil { t.Fatal(err) } if _, err := txn.Exec("ALTER TABLE test.t3 RENAME TO test.t4"); err != nil { t.Fatal(err) } if err := txn.Commit(); err != nil { t.Fatal(err) } // Check that the temp names have been properly cleaned up by creating tables // with those names. if _, err := db.Exec("CREATE TABLE test.t (a INT PRIMARY KEY)"); err != nil { t.Fatal(err) } if _, err := db.Exec("CREATE TABLE test.t2 (a INT PRIMARY KEY)"); err != nil { t.Fatal(err) } if _, err := db.Exec("CREATE TABLE test.t3 (a INT PRIMARY KEY)"); err != nil { t.Fatal(err) } }
// Tests that a name cache entry with by an expired lease is not returned. func TestNameCacheEntryDoesntReturnExpiredLease(t *testing.T) { defer leaktest.AfterTest(t)() s, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t) defer cleanup() leaseManager := s.LeaseManager().(*LeaseManager) if _, err := sqlDB.Exec(` CREATE DATABASE t; CREATE TABLE t.test (k CHAR PRIMARY KEY, v CHAR); `); err != nil { t.Fatal(err) } // Populate the name cache. if _, err := sqlDB.Exec("SELECT * FROM t.test;"); err != nil { t.Fatal(err) } tableDesc := sqlbase.GetTableDescriptor(kvDB, "t", "test") // Check the assumptions this tests makes: that there is a cache entry // (with a valid lease). lease := leaseManager.tableNames.get(tableDesc.ParentID, "test", s.Clock()) if lease == nil { t.Fatalf("no name cache entry") } if err := leaseManager.Release(lease); err != nil { t.Fatal(err) } // Advance the clock to expire the lease. s.Clock().SetMaxOffset(10 * LeaseDuration) s.Clock().Update(s.Clock().Now().Add(int64(2*LeaseDuration), 0)) // Check the the name no longer resolves. if leaseManager.tableNames.get(tableDesc.ParentID, "test", s.Clock()) != nil { t.Fatalf("name resolves when it shouldn't") } }
// Test that a txn doing a rename can use the new name immediately. // It can also use the old name if it took a lease on it before the rename, for // better or worse. func TestTxnCanUseNewNameAfterRename(t *testing.T) { defer leaktest.AfterTest(t)() _, db, _, cleanup := sqlutils.SetupServer(t) defer cleanup() sql := ` CREATE DATABASE test; CREATE TABLE test.t (a INT PRIMARY KEY); ` _, err := db.Exec(sql) if err != nil { t.Fatal(err) } txn, err := db.Begin() if err != nil { t.Fatal(err) } // Make sure we take a lease on the version called "t". if _, err := txn.Exec("SELECT * FROM test.t"); err != nil { t.Fatal(err) } if _, err := txn.Exec("ALTER TABLE test.t RENAME TO test.t2"); err != nil { t.Fatal(err) } // Check that we can use the new name. if _, err := txn.Exec("SELECT * FROM test.t2"); err != nil { t.Fatal(err) } // Check that we can also use the old name, since we have a lease on it. if _, err := txn.Exec("SELECT * FROM test.t"); err != nil { t.Fatal(err) } if err := txn.Commit(); err != nil { t.Fatal(err) } }
// Test that changing a descriptor's name updates the name cache. func TestNameCacheIsUpdated(t *testing.T) { defer leaktest.AfterTest(t)() s, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t) defer cleanup() leaseManager := s.LeaseManager().(*LeaseManager) if _, err := sqlDB.Exec(` CREATE DATABASE t; CREATE DATABASE t1; CREATE TABLE t.test (k CHAR PRIMARY KEY, v CHAR); `); err != nil { t.Fatal(err) } // Populate the name cache. if _, err := sqlDB.Exec("SELECT * FROM t.test;"); err != nil { t.Fatal(err) } tableDesc := sqlbase.GetTableDescriptor(kvDB, "t", "test") // Rename. if _, err := sqlDB.Exec("ALTER TABLE t.test RENAME TO t.test2;"); err != nil { t.Fatal(err) } // Check that the cache has been updated. if leaseManager.tableNames.get(tableDesc.ParentID, "test", s.Clock()) != nil { t.Fatalf("old name still in cache") } lease := leaseManager.tableNames.get(tableDesc.ParentID, "test2", s.Clock()) if lease == nil { t.Fatalf("new name not found in cache") } if lease.ID != tableDesc.ID { t.Fatalf("new name has wrong ID: %d (expected: %d)", lease.ID, tableDesc.ID) } if err := leaseManager.Release(lease); err != nil { t.Fatal(err) } // Rename to a different database. if _, err := sqlDB.Exec("ALTER TABLE t.test2 RENAME TO t1.test2;"); err != nil { t.Fatal(err) } // Re-read the descriptor, to get the new ParentID. newTableDesc := sqlbase.GetTableDescriptor(kvDB, "t1", "test2") if tableDesc.ParentID == newTableDesc.ParentID { t.Fatalf("database didn't change") } // Check that the cache has been updated. if leaseManager.tableNames.get(tableDesc.ParentID, "test2", s.Clock()) != nil { t.Fatalf("old name still in cache") } lease = leaseManager.tableNames.get(newTableDesc.ParentID, "test2", s.Clock()) if lease == nil { t.Fatalf("new name not found in cache") } if lease.ID != tableDesc.ID { t.Fatalf("new name has wrong ID: %d (expected: %d)", lease.ID, tableDesc.ID) } if err := leaseManager.Release(lease); err != nil { t.Fatal(err) } }
func TestTableReader(t *testing.T) { defer leaktest.AfterTest(t)() _, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t) defer cleanup() // Create a table where each row is: // // | a | b | sum | s | // |-----------------------------------------------------------------| // | rowId/10 | rowId%10 | rowId/10 + rowId%10 | IntToEnglish(rowId) | aFn := func(row int) parser.Datum { return parser.NewDInt(parser.DInt(row / 10)) } bFn := func(row int) parser.Datum { return parser.NewDInt(parser.DInt(row % 10)) } sumFn := func(row int) parser.Datum { return parser.NewDInt(parser.DInt(row/10 + row%10)) } sqlutils.CreateTable(t, sqlDB, "t", "a INT, b INT, sum INT, s STRING, PRIMARY KEY (a,b), INDEX bs (b,s)", 99, sqlutils.ToRowFn(aFn, bFn, sumFn, sqlutils.RowEnglishFn)) td := sqlbase.GetTableDescriptor(kvDB, "test", "t") makeIndexSpan := func(start, end int) TableReaderSpan { var span roachpb.Span prefix := roachpb.Key(sqlbase.MakeIndexKeyPrefix(td.ID, td.Indexes[0].ID)) span.Key = append(prefix, encoding.EncodeVarintAscending(nil, int64(start))...) span.EndKey = append(span.EndKey, prefix...) span.EndKey = append(span.EndKey, encoding.EncodeVarintAscending(nil, int64(end))...) return TableReaderSpan{Span: span} } testCases := []struct { spec TableReaderSpec expected string }{ { spec: TableReaderSpec{ Filter: Expression{Expr: "$2 < 5 AND $1 != 3"}, // sum < 5 && b != 3 OutputColumns: []uint32{0, 1}, }, expected: "[[0 1] [0 2] [0 4] [1 0] [1 1] [1 2] [2 0] [2 1] [2 2] [3 0] [3 1] [4 0]]", }, { spec: TableReaderSpec{ Filter: Expression{Expr: "$2 < 5 AND $1 != 3"}, OutputColumns: []uint32{3}, // s HardLimit: 4, }, expected: "[['one'] ['two'] ['four'] ['one-zero']]", }, { spec: TableReaderSpec{ IndexIdx: 1, Reverse: true, Spans: []TableReaderSpan{makeIndexSpan(4, 6)}, Filter: Expression{Expr: "$0 < 3"}, // sum < 8 OutputColumns: []uint32{0, 1}, SoftLimit: 1, }, expected: "[[2 5] [1 5] [0 5] [2 4] [1 4] [0 4]]", }, } for _, c := range testCases { ts := c.spec ts.Table = *td txn := client.NewTxn(context.Background(), *kvDB) out := &RowBuffer{} tr, err := newTableReader(&ts, txn, out, &parser.EvalContext{}) if err != nil { t.Fatal(err) } tr.Run(nil) if out.err != nil { t.Fatal(out.err) } if !out.closed { t.Fatalf("output RowReceiver not closed") } if result := out.rows.String(); result != c.expected { t.Errorf("invalid results: %s, expected %s'", result, c.expected) } } }
func TestTableReader(t *testing.T) { defer leaktest.AfterTest(t)() _, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t) defer cleanup() if _, err := sqlDB.Exec(` CREATE DATABASE test; CREATE TABLE test.t (a INT PRIMARY KEY, b INT, c INT, d INT, INDEX bc (b, c)); INSERT INTO test.t VALUES (1, 10, 11, 12), (2, 20, 21, 22), (3, 30, 31, 32); INSERT INTO test.t VALUES (4, 60, 61, 62), (5, 50, 51, 52), (6, 40, 41, 42); `); err != nil { t.Fatal(err) } td := sqlbase.GetTableDescriptor(kvDB, "test", "t") ts := TableReaderSpec{ Table: *td, IndexIdx: 0, Reverse: false, Spans: nil, Filter: Expression{Expr: "$2 != 21"}, // c != 21 OutputColumns: []uint32{0, 3}, // a, d } txn := client.NewTxn(context.Background(), *kvDB) out := &testingReceiver{} tr, err := newTableReader(&ts, txn, out, parser.EvalContext{}) if err != nil { t.Fatal(err) } tr.run() if out.err != nil { t.Fatal(out.err) } if !out.closed { t.Fatalf("output rowReceiver not closed") } expected := "[[1 12] [3 32] [4 62] [5 52] [6 42]]" if fmt.Sprintf("%s", out.rows) != expected { t.Errorf("invalid results: %s, expected %s'", out.rows, expected) } // Read using the bc index var span roachpb.Span span.Key = roachpb.Key(sqlbase.MakeIndexKeyPrefix(td.ID, td.Indexes[0].ID)) span.EndKey = append(span.Key, encoding.EncodeVarintAscending(nil, 50)...) ts = TableReaderSpec{ Table: *td, IndexIdx: 1, Reverse: true, Spans: []TableReaderSpan{{Span: span}}, Filter: Expression{Expr: "$1 != 30"}, // b != 30 OutputColumns: []uint32{0, 2}, // a, c } out = &testingReceiver{} tr, err = newTableReader(&ts, txn, out, parser.EvalContext{}) if err != nil { t.Fatal(err) } tr.run() if out.err != nil { t.Fatal(out.err) } if !out.closed { t.Fatalf("output rowReceiver not closed") } expected = "[[6 41] [2 21] [1 11]]" if fmt.Sprintf("%s", out.rows) != expected { t.Errorf("invalid results: %s, expected %s'", out.rows, expected) } }
func TestServer(t *testing.T) { defer leaktest.AfterTest(t)() s, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t) defer cleanup() conn, err := s.RPCContext().GRPCDial(s.ServingAddr()) if err != nil { t.Fatal(err) } if _, err := sqlDB.Exec(` CREATE DATABASE test; CREATE TABLE test.t (a INT PRIMARY KEY, b INT); INSERT INTO test.t VALUES (1, 10), (2, 20), (3, 30); `); err != nil { t.Fatal(err) } td := sqlbase.GetTableDescriptor(kvDB, "test", "t") ts := TableReaderSpec{ Table: *td, IndexIdx: 0, Reverse: false, Spans: nil, Filter: Expression{Expr: "$0 != 2"}, // a != 2 OutputColumns: []uint32{0, 1}, // a } txn := client.NewTxn(context.Background(), *kvDB) req := &SetupFlowsRequest{Txn: txn.Proto} req.Flows = []FlowSpec{{ Processors: []ProcessorSpec{{ Core: ProcessorCoreUnion{TableReader: &ts}, Output: []OutputRouterSpec{{ Type: OutputRouterSpec_MIRROR, Streams: []StreamEndpointSpec{{Mailbox: &MailboxSpec{SimpleResponse: true}}}, }}, }}, }} distSQLClient := NewDistSQLClient(conn) stream, err := distSQLClient.RunSimpleFlow(context.Background(), req) if err != nil { t.Fatal(err) } var decoder StreamDecoder var rows sqlbase.EncDatumRows for { msg, err := stream.Recv() if err != nil { if err == io.EOF { break } t.Fatal(err) } err = decoder.AddMessage(msg) if err != nil { t.Fatal(err) } rows = testGetDecodedRows(t, &decoder, rows) } if done, trailerErr := decoder.IsDone(); !done { t.Fatal("stream not done") } else if trailerErr != nil { t.Fatal("error in the stream trailer:", trailerErr) } str := rows.String() expected := "[[1 10] [3 30]]" if str != expected { t.Errorf("invalid results: %s, expected %s'", str, expected) } }
func TestJoinReader(t *testing.T) { defer leaktest.AfterTest(t)() _, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t) defer cleanup() // Create a table where each row is: // // | a | b | sum | s | // |-----------------------------------------------------------------| // | rowId/10 | rowId%10 | rowId/10 + rowId%10 | IntToEnglish(rowId) | aFn := func(row int) parser.Datum { return parser.NewDInt(parser.DInt(row / 10)) } bFn := func(row int) parser.Datum { return parser.NewDInt(parser.DInt(row % 10)) } sumFn := func(row int) parser.Datum { return parser.NewDInt(parser.DInt(row/10 + row%10)) } sqlutils.CreateTable(t, sqlDB, "t", "a INT, b INT, sum INT, s STRING, PRIMARY KEY (a,b), INDEX bs (b,s)", 99, sqlutils.ToRowFn(aFn, bFn, sumFn, sqlutils.RowEnglishFn)) td := sqlbase.GetTableDescriptor(kvDB, "test", "t") testCases := []struct { spec JoinReaderSpec input [][]parser.Datum expected string }{ { spec: JoinReaderSpec{ OutputColumns: []uint32{0, 1, 2}, }, input: [][]parser.Datum{ {aFn(2), bFn(2)}, {aFn(5), bFn(5)}, {aFn(10), bFn(10)}, {aFn(15), bFn(15)}, }, expected: "[[0 2 2] [0 5 5] [1 0 1] [1 5 6]]", }, { spec: JoinReaderSpec{ Filter: Expression{Expr: "$2 <= 5"}, // sum <= 5 OutputColumns: []uint32{3}, }, input: [][]parser.Datum{ {aFn(1), bFn(1)}, {aFn(25), bFn(25)}, {aFn(5), bFn(5)}, {aFn(21), bFn(21)}, {aFn(34), bFn(34)}, {aFn(13), bFn(13)}, {aFn(51), bFn(51)}, {aFn(50), bFn(50)}, }, expected: "[['one'] ['five'] ['two-one'] ['one-three'] ['five-zero']]", }, } for _, c := range testCases { js := c.spec js.Table = *td txn := client.NewTxn(context.Background(), *kvDB) out := &testingReceiver{} jr, err := newJoinReader(&js, txn, out, &parser.EvalContext{}) if err != nil { t.Fatal(err) } var wg sync.WaitGroup wg.Add(1) go jr.Run(&wg) for _, row := range c.input { encRow := make(sqlbase.EncDatumRow, len(row)) for i, d := range row { encRow[i].SetDatum(sqlbase.ColumnType_INT, d) } ok := jr.PushRow(encRow) if !ok { t.Fatal("joinReader stopped accepting rows") } } jr.Close(nil) wg.Wait() if out.err != nil { t.Fatal(out.err) } if !out.closed { t.Fatalf("output rowReceiver not closed") } if result := out.rows.String(); result != c.expected { t.Errorf("invalid results: %s, expected %s'", result, c.expected) } } }
// TestRenameTable tests the table descriptor changes during // a rename operation. func TestRenameTable(t *testing.T) { defer leaktest.AfterTest(t)() defer config.TestingDisableTableSplits()() _, sqlDB, kvDB, cleanup := sqlutils.SetupServer(t) defer cleanup() counter := int64(keys.MaxReservedDescID + 1) // Table creation should fail, and nothing should have been written. oldDBID := sqlbase.ID(counter) if _, err := sqlDB.Exec(`CREATE DATABASE test`); err != nil { t.Fatal(err) } counter++ // Create table in 'test'. tableCounter := counter oldName := "foo" if _, err := sqlDB.Exec(`CREATE TABLE test.foo (k INT PRIMARY KEY, v int)`); err != nil { t.Fatal(err) } counter++ // Check the table descriptor. desc := &sqlbase.Descriptor{} tableDescKey := sqlbase.MakeDescMetadataKey(sqlbase.ID(tableCounter)) if err := kvDB.GetProto(tableDescKey, desc); err != nil { t.Fatal(err) } tableDesc := desc.GetTable() if tableDesc.Name != oldName { t.Fatalf("Wrong table name, expected %s, got: %+v", oldName, tableDesc) } if tableDesc.ParentID != oldDBID { t.Fatalf("Wrong parent ID on table, expected %d, got: %+v", oldDBID, tableDesc) } // Create database test2. newDBID := sqlbase.ID(counter) if _, err := sqlDB.Exec(`CREATE DATABASE test2`); err != nil { t.Fatal(err) } counter++ // Move table to test2 and change its name as well. newName := "bar" if _, err := sqlDB.Exec(`ALTER TABLE test.foo RENAME TO test2.bar`); err != nil { t.Fatal(err) } // Check the table descriptor again. if err := kvDB.GetProto(tableDescKey, desc); err != nil { t.Fatal(err) } tableDesc = desc.GetTable() if tableDesc.Name != newName { t.Fatalf("Wrong table name, expected %s, got: %+v", newName, tableDesc) } if tableDesc.ParentID != newDBID { t.Fatalf("Wrong parent ID on table, expected %d, got: %+v", newDBID, tableDesc) } }