func encodeTableKey(b []byte, val parser.Datum) ([]byte, error) { if val == parser.DNull { return encoding.EncodeNull(b), nil } switch t := val.(type) { case parser.DBool: if t { return encoding.EncodeVarint(b, 1), nil } return encoding.EncodeVarint(b, 0), nil case parser.DInt: return encoding.EncodeVarint(b, int64(t)), nil case parser.DFloat: return encoding.EncodeFloat(b, float64(t)), nil case parser.DString: return encoding.EncodeString(b, string(t)), nil case parser.DBytes: return encoding.EncodeString(b, string(t)), nil case parser.DDate: return encoding.EncodeTime(b, t.Time), nil case parser.DTimestamp: return encoding.EncodeTime(b, t.Time), nil case parser.DInterval: return encoding.EncodeVarint(b, int64(t.Duration)), nil } return nil, fmt.Errorf("unable to encode table key: %T", val) }
func TestMVCCScanWithKeyPrefix(t *testing.T) { mvcc := createTestMVCC(t) // Let's say you have: // a // a<T=2> // a<T=1> // aa // aa<T=3> // aa<T=2> // b // b<T=5> // In this case, if we scan from "a"-"b", we wish to skip // a<T=2> and a<T=1> and find "aa'. err := mvcc.Put(Key(encoding.EncodeString([]byte{}, "/a")), makeTS(1, 0), value1, nil) err = mvcc.Put(Key(encoding.EncodeString([]byte{}, "/a")), makeTS(2, 0), value2, nil) err = mvcc.Put(Key(encoding.EncodeString([]byte{}, "/aa")), makeTS(2, 0), value2, nil) err = mvcc.Put(Key(encoding.EncodeString([]byte{}, "/aa")), makeTS(3, 0), value3, nil) err = mvcc.Put(Key(encoding.EncodeString([]byte{}, "/b")), makeTS(1, 0), value3, nil) kvs, err := mvcc.Scan(Key(encoding.EncodeString([]byte{}, "/a")), Key(encoding.EncodeString([]byte{}, "/b")), 0, makeTS(2, 0), nil) if err != nil { t.Fatal(err) } if len(kvs) != 2 || !bytes.Equal(kvs[0].Key, Key(encoding.EncodeString([]byte{}, "/a"))) || !bytes.Equal(kvs[1].Key, Key(encoding.EncodeString([]byte{}, "/aa"))) || !bytes.Equal(kvs[0].Value.Bytes, value2.Bytes) || !bytes.Equal(kvs[1].Value.Bytes, value2.Bytes) { t.Fatal("the value should not be empty") } }
// TestStoreRangeSplitInsideRow verifies an attempt to split a range inside of // a table row will cause a split at a boundary between rows. func TestStoreRangeSplitInsideRow(t *testing.T) { defer leaktest.AfterTest(t) defer config.TestingDisableTableSplits()() store, stopper := createTestStore(t) defer stopper.Stop() // Manually create some the column keys corresponding to the table: // // CREATE TABLE t (id STRING PRIMARY KEY, col1 INT, col2 INT) tableKey := keys.MakeTablePrefix(keys.MaxReservedDescID + 1) rowKey := roachpb.Key(encoding.EncodeVarint(append([]byte(nil), tableKey...), 1)) rowKey = encoding.EncodeString(encoding.EncodeVarint(rowKey, 1), "a") col1Key := keys.MakeColumnKey(append([]byte(nil), rowKey...), 1) col2Key := keys.MakeColumnKey(append([]byte(nil), rowKey...), 2) // We don't care about the value, so just store any old thing. if pErr := store.DB().Put(col1Key, "column 1"); pErr != nil { t.Fatal(pErr) } if pErr := store.DB().Put(col2Key, "column 2"); pErr != nil { t.Fatal(pErr) } // Split between col1Key and col2Key by splitting before col2Key. args := adminSplitArgs(col2Key, col2Key) _, pErr := client.SendWrapped(rg1(store), nil, &args) if pErr != nil { t.Fatalf("%s: split unexpected error: %s", col1Key, pErr) } rng1 := store.LookupReplica(col1Key, nil) rng2 := store.LookupReplica(col2Key, nil) // Verify the two columns are still on the same range. if !reflect.DeepEqual(rng1, rng2) { t.Fatalf("%s: ranges differ: %+v vs %+v", roachpb.Key(col1Key), rng1, rng2) } // Verify we split on a row key. if startKey := rng1.Desc().StartKey; !startKey.Equal(rowKey) { t.Fatalf("%s: expected split on %s, but found %s", roachpb.Key(col1Key), roachpb.Key(rowKey), startKey) } // Verify the previous range was split on a row key. rng3 := store.LookupReplica(tableKey, nil) if endKey := rng3.Desc().EndKey; !endKey.Equal(rowKey) { t.Fatalf("%s: expected split on %s, but found %s", roachpb.Key(col1Key), roachpb.Key(rowKey), endKey) } }
func TestPrettyPrint(t *testing.T) { defer leaktest.AfterTest(t) tm, _ := time.Parse(time.UnixDate, "Sat Mar 7 11:06:39 UTC 2015") testCases := []struct { key roachpb.Key exp string }{ // local {StoreIdentKey(), "/Local/Store/storeIdent"}, {StoreGossipKey(), "/Local/Store/gossipBootstrap"}, {SequenceCacheKeyPrefix(roachpb.RangeID(1000001), []byte("test0")), `/Local/RangeID/1000001/SequenceCache/"test0"`}, {SequenceCacheKey(roachpb.RangeID(1000001), []byte("test0"), uint32(111), uint32(222)), `/Local/RangeID/1000001/SequenceCache/"test0"/epoch:111/seq:222`}, {RaftLeaderLeaseKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftLeaderLease"}, {RaftTombstoneKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftTombstone"}, {RaftHardStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftHardState"}, {RaftAppliedIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftAppliedIndex"}, {RaftLogKey(roachpb.RangeID(1000001), uint64(200001)), "/Local/RangeID/1000001/RaftLog/logIndex:200001"}, {RaftTruncatedStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftTruncatedState"}, {RaftLastIndexKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RaftLastIndex"}, {RangeLastVerificationTimestampKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RangeLastVerificationTimestamp"}, {RangeStatsKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/RangeStats"}, {MakeRangeKeyPrefix(roachpb.RKey("ok")), `/Local/Range/"ok"`}, {RangeDescriptorKey(roachpb.RKey("111")), `/Local/Range/RangeDescriptor/"111"`}, {RangeTreeNodeKey(roachpb.RKey("111")), `/Local/Range/RangeTreeNode/"111"`}, {TransactionKey(roachpb.Key("111"), []byte("22222")), `/Local/Range/Transaction/addrKey:/"111"/id:"22222"`}, {LocalMax, "/Local/Max"}, // system {roachpb.MakeKey(Meta2Prefix, roachpb.Key("foo")), `/Meta2/"foo"`}, {roachpb.MakeKey(Meta1Prefix, roachpb.Key("foo")), `/Meta1/"foo"`}, {StoreStatusKey(2222), "/System/StatusStore/2222"}, {NodeStatusKey(1111), "/System/StatusNode/1111"}, {SystemMax, "/System/Max"}, // table {UserTableDataMin, "/Table/50"}, {MakeTablePrefix(111), "/Table/111"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey("foo")), `/Table/42/"foo"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeFloat(nil, float64(233.221112)))), "/Table/42/233.221112"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeVarint(nil, 1222)), roachpb.RKey(encoding.EncodeString(nil, "handsome man"))), `/Table/42/1222/"handsome man"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytes(nil, []byte{1, 2, 8, 255}))), `/Table/42/"\x01\x02\b\xff"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeBytes(nil, []byte{1, 2, 8, 255})), roachpb.RKey("bar")), `/Table/42/"\x01\x02\b\xff"/"bar"`}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeNull(nil))), "/Table/42/NULL"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeNotNull(nil))), "/Table/42/#"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey(encoding.EncodeTime(nil, tm))), "/Table/42/Sat Mar 7 11:06:39 UTC 2015"}, // others {MakeKey([]byte("")), "/Min"}, {MakeKey(MakeTablePrefix(42), roachpb.RKey([]byte{0x20, 'a', 0x00, 0x02})), "/Table/42/<util/encoding/encoding.go:407: unknown escape>"}, } for i, test := range testCases { keyInfo := PrettyPrint(test.key) if test.exp != keyInfo { t.Fatalf("%d: expected %s, got %s", i, test.exp, keyInfo) } if test.exp != test.key.String() { t.Fatalf("%d: expected %s, got %s", i, test.exp, keyInfo) } } }