func decodeTableKey(valType parser.Datum, key []byte) (parser.Datum, []byte, error) { var isNull bool if key, isNull = encoding.DecodeIfNull(key); isNull { return parser.DNull, key, nil } switch valType.(type) { case parser.DBool: rkey, i, err := encoding.DecodeVarint(key) return parser.DBool(i != 0), rkey, err case parser.DInt: rkey, i, err := encoding.DecodeVarint(key) return parser.DInt(i), rkey, err case parser.DFloat: rkey, f, err := encoding.DecodeFloat(key, nil) return parser.DFloat(f), rkey, err case parser.DString: rkey, r, err := encoding.DecodeString(key, nil) return parser.DString(r), rkey, err case parser.DBytes: rkey, r, err := encoding.DecodeString(key, nil) return parser.DBytes(r), rkey, err case parser.DDate: rkey, t, err := encoding.DecodeTime(key) return parser.DDate{Time: t}, rkey, err case parser.DTimestamp: rkey, t, err := encoding.DecodeTime(key) return parser.DTimestamp{Time: t}, rkey, err case parser.DInterval: rkey, d, err := encoding.DecodeVarint(key) return parser.DInterval{Duration: time.Duration(d)}, rkey, err default: return nil, nil, util.Errorf("TODO(pmattis): decoded index key: %s", valType.Type()) } }
// DecodeDataKey decodes a time series key into its components. func DecodeDataKey(key roachpb.Key) (string, string, Resolution, int64, error) { // Detect and remove prefix. remainder := key if !bytes.HasPrefix(remainder, keyDataPrefix) { return "", "", 0, 0, util.Errorf("malformed time series data key %v: improper prefix", key) } remainder = remainder[len(keyDataPrefix):] // Decode series name. remainder, name, err := encoding.DecodeBytes(remainder, nil) if err != nil { return "", "", 0, 0, err } // Decode resolution. remainder, resolutionInt, err := encoding.DecodeVarint(remainder) if err != nil { return "", "", 0, 0, err } resolution := Resolution(resolutionInt) // Decode timestamp. remainder, timeslot, err := encoding.DecodeVarint(remainder) if err != nil { return "", "", 0, 0, err } timestamp := timeslot * resolution.KeyDuration() // The remaining bytes are the source. source := remainder return string(name), string(source), resolution, timestamp, nil }
func decodeTableKey(valType parser.Datum, key []byte) (parser.Datum, []byte, error) { var isNull bool if key, isNull = encoding.DecodeIfNull(key); isNull { return parser.DNull, key, nil } switch valType.(type) { case parser.DBool: var i int64 key, i = encoding.DecodeVarint(key) return parser.DBool(i != 0), key, nil case parser.DInt: var i int64 key, i = encoding.DecodeVarint(key) return parser.DInt(i), key, nil case parser.DFloat: var f float64 key, f = encoding.DecodeFloat(key, nil) return parser.DFloat(f), key, nil case parser.DString: var r string key, r = encoding.DecodeString(key, nil) return parser.DString(r), key, nil default: return nil, nil, util.Errorf("TODO(pmattis): decoded index key: %s", valType.Type()) } }
// DecodeDataKey decodes a time series key into its components. func DecodeDataKey(key proto.Key) (string, string, Resolution, int64) { var ( name []byte source []byte resolutionInt int64 timeslot int64 remainder = key ) // Detect and remove prefix. if !bytes.HasPrefix(remainder, keyDataPrefix) { panic(fmt.Sprintf("malformed time series data key %v: improper prefix", key)) } remainder = remainder[len(keyDataPrefix):] // Decode series name. remainder, name = encoding.DecodeBytes(remainder, nil) // Decode resolution. remainder, resolutionInt = encoding.DecodeVarint(remainder) resolution := Resolution(resolutionInt) // Decode timestamp. remainder, timeslot = encoding.DecodeVarint(remainder) timestamp := timeslot * resolution.KeyDuration() // The remaining bytes are the source. source = remainder return string(name), string(source), resolution, timestamp }
// decodeKeyVals decodes the values that are part of the key. ValTypes is a // slice returned from makeKeyVals. The decoded values are stored in the vals // parameter while the valTypes parameter is unmodified. Note that len(vals) >= // len(valTypes). The types of the decoded values will match the corresponding // entry in the valTypes parameter with the exception that a value might also // be parser.DNull. The remaining bytes in the key after decoding the values // are returned. func decodeKeyVals(valTypes, vals []parser.Datum, key []byte) ([]byte, error) { for j := range valTypes { var isNull bool if key, isNull = encoding.DecodeIfNull(key); isNull { vals[j] = parser.DNull continue } switch valTypes[j].(type) { case parser.DInt: var i int64 key, i = encoding.DecodeVarint(key) vals[j] = parser.DInt(i) case parser.DFloat: var f float64 key, f = encoding.DecodeFloat(key, nil) vals[j] = parser.DFloat(f) case parser.DString: var r string key, r = encoding.DecodeString(key, nil) vals[j] = parser.DString(r) default: return nil, util.Errorf("TODO(pmattis): decoded index key: %s", valTypes[j].Type()) } } return key, nil }
// decodeTableKey decodes a single element of a table key from b, returning the // remaining (not yet decoded) bytes. func decodeTableKey(b []byte, v reflect.Value) ([]byte, error) { switch t := v.Addr().Interface().(type) { case *[]byte: b, *t = roachencoding.DecodeBytes(b, nil) return b, nil case *string: var r []byte b, r = roachencoding.DecodeBytes(b, nil) *t = string(r) return b, nil } switch v.Kind() { case reflect.Bool: var i int64 b, i = roachencoding.DecodeVarint(b) v.SetBool(i != 0) return b, nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: var i int64 b, i = roachencoding.DecodeVarint(b) v.SetInt(i) return b, nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: var i uint64 b, i = roachencoding.DecodeUvarint(b) v.SetUint(i) return b, nil case reflect.Float32, reflect.Float64: var f float64 b, f = roachencoding.DecodeNumericFloat(b) v.SetFloat(f) return b, nil case reflect.String: var r []byte b, r = roachencoding.DecodeBytes(b, nil) v.SetString(string(r)) return b, nil } return nil, fmt.Errorf("unable to decode key: %s", v) }
// prettyKey pretty-prints the specified key, skipping over the first skip // fields. func prettyKey(key roachpb.Key, skip int) string { if !bytes.HasPrefix(key, keys.TableDataPrefix) { return fmt.Sprintf("index key missing table data prefix: %q vs %q", key, keys.TableDataPrefix) } key = key[len(keys.TableDataPrefix):] var buf bytes.Buffer for k := 0; len(key) > 0; k++ { var d interface{} var err error switch encoding.PeekType(key) { case encoding.Null: key, _ = encoding.DecodeIfNull(key) d = parser.DNull case encoding.NotNull: key, _ = encoding.DecodeIfNotNull(key) d = "#" case encoding.Int: var i int64 key, i, err = encoding.DecodeVarint(key) d = parser.DInt(i) case encoding.Float: var f float64 key, f, err = encoding.DecodeFloat(key, nil) d = parser.DFloat(f) case encoding.Bytes: var s string key, s, err = encoding.DecodeString(key, nil) d = parser.DString(s) case encoding.Time: var t time.Time key, t, err = encoding.DecodeTime(key) d = parser.DTimestamp{Time: t} default: // This shouldn't ever happen, but if it does let the loop exit. key = nil d = "unknown" } if skip > 0 { skip-- continue } if err != nil { fmt.Fprintf(&buf, "/<%v>", err) continue } fmt.Fprintf(&buf, "/%s", d) } return buf.String() }
func decodeKeyPrint(key roachpb.Key) string { var buf bytes.Buffer for k := 0; len(key) > 0; k++ { var err error switch encoding.PeekType(key) { case encoding.Null: key, _ = encoding.DecodeIfNull(key) fmt.Fprintf(&buf, "/NULL") case encoding.NotNull: key, _ = encoding.DecodeIfNotNull(key) fmt.Fprintf(&buf, "/#") case encoding.Int: var i int64 key, i, err = encoding.DecodeVarint(key) if err == nil { fmt.Fprintf(&buf, "/%d", i) } case encoding.Float: var f float64 key, f, err = encoding.DecodeFloat(key, nil) if err == nil { fmt.Fprintf(&buf, "/%f", f) } case encoding.Bytes: var s string key, s, err = encoding.DecodeString(key, nil) if err == nil { fmt.Fprintf(&buf, "/%q", s) } case encoding.Time: var t time.Time key, t, err = encoding.DecodeTime(key) if err == nil { fmt.Fprintf(&buf, "/%s", t.UTC().Format(time.UnixDate)) } default: // This shouldn't ever happen, but if it does let the loop exit. fmt.Fprintf(&buf, "/%q", []byte(key)) key = nil } if err != nil { fmt.Fprintf(&buf, "/<%v>", err) continue } } return buf.String() }
func decodeIndexKey(desc *structured.TableDescriptor, index structured.IndexDescriptor, vals map[string]driver.Value, key []byte) ([]byte, error) { if !bytes.HasPrefix(key, keys.TableDataPrefix) { return nil, fmt.Errorf("%s: invalid key prefix: %q", desc.Name, key) } key = bytes.TrimPrefix(key, keys.TableDataPrefix) var tableID uint64 key, tableID = encoding.DecodeUvarint(key) if uint32(tableID) != desc.ID { return nil, fmt.Errorf("%s: unexpected table ID: %d != %d", desc.Name, desc.ID, tableID) } var indexID uint64 key, indexID = encoding.DecodeUvarint(key) if uint32(indexID) != index.ID { return nil, fmt.Errorf("%s: unexpected index ID: %d != %d", desc.Name, index.ID, indexID) } for _, id := range index.ColumnIDs { col, err := findColumnByID(desc, id) if err != nil { return nil, err } switch col.Type.Kind { case structured.ColumnType_BIT, structured.ColumnType_INT: var i int64 key, i = encoding.DecodeVarint(key) vals[col.Name] = i case structured.ColumnType_FLOAT: var f float64 key, f = encoding.DecodeNumericFloat(key) vals[col.Name] = f case structured.ColumnType_CHAR, structured.ColumnType_BINARY, structured.ColumnType_TEXT, structured.ColumnType_BLOB: var r []byte key, r = encoding.DecodeBytes(key, nil) vals[col.Name] = r default: return nil, fmt.Errorf("TODO(pmattis): decoded index key: %s", col.Type.Kind) } } return key, nil }
// decodeIndexKey decodes the values that are a part of the specified index // key. Vals is a slice returned from makeIndexKeyVals. The remaining bytes in // the index key are returned which will either be an encoded column ID for the // primary key index, the primary key suffix for non-unique secondary indexes // or unique secondary indexes containing NULL or empty. func decodeIndexKey(desc *structured.TableDescriptor, index structured.IndexDescriptor, vals []parser.Datum, key []byte) ([]byte, error) { if !bytes.HasPrefix(key, keys.TableDataPrefix) { return nil, fmt.Errorf("%s: invalid key prefix: %q", desc.Name, key) } key = bytes.TrimPrefix(key, keys.TableDataPrefix) var tableID uint64 key, tableID = encoding.DecodeUvarint(key) if structured.ID(tableID) != desc.ID { return nil, fmt.Errorf("%s: unexpected table ID: %d != %d", desc.Name, desc.ID, tableID) } var indexID uint64 key, indexID = encoding.DecodeUvarint(key) if structured.IndexID(indexID) != index.ID { return nil, fmt.Errorf("%s: unexpected index ID: %d != %d", desc.Name, index.ID, indexID) } for j := range vals { switch vals[j].(type) { case parser.DInt: var i int64 key, i = encoding.DecodeVarint(key) vals[j] = parser.DInt(i) case parser.DFloat: var f float64 key, f = encoding.DecodeNumericFloat(key) vals[j] = parser.DFloat(f) case parser.DString: var r []byte key, r = encoding.DecodeBytes(key, nil) vals[j] = parser.DString(r) default: return nil, util.Errorf("TODO(pmattis): decoded index key: %s", vals[j].Type()) } } return key, nil }
func localRangeIDKeyPrint(key roachpb.Key) string { var buf bytes.Buffer if encoding.PeekType(key) != encoding.Int { return fmt.Sprintf("/err<%q>", []byte(key)) } // get range id key, i, err := encoding.DecodeVarint(key) if err != nil { return fmt.Sprintf("/err<%v:%q>", err, []byte(key)) } fmt.Fprintf(&buf, "/%d", i) // get suffix hasSuffix := false for _, s := range rangeIDSuffixDict { if bytes.HasPrefix(key, s.suffix) { fmt.Fprintf(&buf, "/%s", s.name) key = key[len(s.suffix):] if s.ppFunc != nil && len(key) != 0 { fmt.Fprintf(&buf, "%s", s.ppFunc(key)) return buf.String() } hasSuffix = true break } } // get encode values if hasSuffix { fmt.Fprintf(&buf, "%s", decodeKeyPrint(key)) } else { fmt.Fprintf(&buf, "%q", []byte(key)) } return buf.String() }
// decodeKeyVals decodes the values that are part of the key. Vals is a slice // returned from makeKeyVals. The remaining bytes in the key after decoding the // values are returned. func decodeKeyVals(vals []parser.Datum, key []byte) ([]byte, error) { for j := range vals { switch vals[j].(type) { case parser.DInt: var i int64 key, i = encoding.DecodeVarint(key) vals[j] = parser.DInt(i) case parser.DFloat: var f float64 key, f = encoding.DecodeNumericFloat(key) vals[j] = parser.DFloat(f) case parser.DString: var r []byte key, r = encoding.DecodeBytes(key, nil) vals[j] = parser.DString(r) default: return nil, util.Errorf("TODO(pmattis): decoded index key: %s", vals[j].Type()) } } return key, nil }