func setAppliedIndex( ctx context.Context, eng engine.ReadWriter, ms *enginepb.MVCCStats, rangeID roachpb.RangeID, appliedIndex, leaseAppliedIndex uint64, ) error { var value roachpb.Value value.SetInt(int64(appliedIndex)) if err := engine.MVCCPut(ctx, eng, ms, keys.RaftAppliedIndexKey(rangeID), hlc.ZeroTimestamp, value, nil /* txn */); err != nil { return err } value.SetInt(int64(leaseAppliedIndex)) return engine.MVCCPut(ctx, eng, ms, keys.LeaseAppliedIndexKey(rangeID), hlc.ZeroTimestamp, value, nil /* txn */) }
func setLastIndex( ctx context.Context, eng engine.ReadWriter, rangeID roachpb.RangeID, lastIndex uint64, ) error { var value roachpb.Value value.SetInt(int64(lastIndex)) return engine.MVCCPut(ctx, eng, nil, keys.RaftLastIndexKey(rangeID), hlc.ZeroTimestamp, value, nil /* txn */) }
// GetInitialValues returns the set of initial K/V values which should be added to // a bootstrapping CockroachDB cluster in order to create the tables contained // in the schema. func (ms MetadataSchema) GetInitialValues() []roachpb.KeyValue { var ret []roachpb.KeyValue // Save the ID generator value, which will generate descriptor IDs for user // objects. value := roachpb.Value{} value.SetInt(int64(keys.MaxReservedDescID + 1)) ret = append(ret, roachpb.KeyValue{ Key: keys.DescIDGenerator, Value: value, }) // addDescriptor generates the needed KeyValue objects to install a // descriptor on a new cluster. addDescriptor := func(parentID ID, desc DescriptorProto) { // Create name metadata key. value := roachpb.Value{} value.SetInt(int64(desc.GetID())) ret = append(ret, roachpb.KeyValue{ Key: MakeNameMetadataKey(parentID, desc.GetName()), Value: value, }) // Create descriptor metadata key. value = roachpb.Value{} wrappedDesc := WrapDescriptor(desc) if err := value.SetProto(wrappedDesc); err != nil { log.Fatalf(context.TODO(), "could not marshal %v", desc) } ret = append(ret, roachpb.KeyValue{ Key: MakeDescMetadataKey(desc.GetID()), Value: value, }) } // Generate initial values for system databases and tables, which have // static descriptors that were generated elsewhere. for _, sysObj := range ms.descs { addDescriptor(sysObj.parentID, sysObj.desc) } // Other key/value generation that doesn't fit into databases and // tables. This can be used to add initial entries to a table. ret = append(ret, ms.otherKV...) // Sort returned key values; this is valuable because it matches the way the // objects would be sorted if read from the engine. sort.Sort(roachpb.KeyValueByKey(ret)) return ret }
// MarshalColumnValue returns a Go primitive value equivalent of val, of the // type expected by col. If val's type is incompatible with col, or if // col's type is not yet implemented, an error is returned. func MarshalColumnValue(col ColumnDescriptor, val parser.Datum) (roachpb.Value, error) { var r roachpb.Value if val == parser.DNull { return r, nil } switch col.Type.Kind { case ColumnType_BOOL: if v, ok := val.(*parser.DBool); ok { r.SetBool(bool(*v)) return r, nil } case ColumnType_INT: if v, ok := val.(*parser.DInt); ok { r.SetInt(int64(*v)) return r, nil } case ColumnType_FLOAT: if v, ok := val.(*parser.DFloat); ok { r.SetFloat(float64(*v)) return r, nil } case ColumnType_DECIMAL: if v, ok := val.(*parser.DDecimal); ok { err := r.SetDecimal(&v.Dec) return r, err } case ColumnType_STRING: if v, ok := val.(*parser.DString); ok { r.SetString(string(*v)) return r, nil } case ColumnType_BYTES: if v, ok := val.(*parser.DBytes); ok { r.SetString(string(*v)) return r, nil } if v, ok := val.(*parser.DString); ok { r.SetString(string(*v)) return r, nil } case ColumnType_DATE: if v, ok := val.(*parser.DDate); ok { r.SetInt(int64(*v)) return r, nil } case ColumnType_TIMESTAMP: if v, ok := val.(*parser.DTimestamp); ok { r.SetTime(v.Time) return r, nil } case ColumnType_TIMESTAMPTZ: if v, ok := val.(*parser.DTimestampTZ); ok { r.SetTime(v.Time) return r, nil } case ColumnType_INTERVAL: if v, ok := val.(*parser.DInterval); ok { err := r.SetDuration(v.Duration) return r, err } default: return r, errors.Errorf("unsupported column type: %s", col.Type.Kind) } return r, fmt.Errorf("value type %s doesn't match type %s of column %q", val.ResolvedType(), col.Type.Kind, col.Name) }
// marshalValue returns a roachpb.Value initialized from the source // interface{}, returning an error if the types are not compatible. func marshalValue(v interface{}) (roachpb.Value, error) { var r roachpb.Value // Handle a few common types via a type switch. switch t := v.(type) { case *roachpb.Value: return *t, nil case nil: return r, nil case bool: r.SetBool(t) return r, nil case string: r.SetBytes([]byte(t)) return r, nil case []byte: r.SetBytes(t) return r, nil case inf.Dec: err := r.SetDecimal(&t) return r, err case roachpb.Key: r.SetBytes([]byte(t)) return r, nil case time.Time: r.SetTime(t) return r, nil case duration.Duration: err := r.SetDuration(t) return r, err case proto.Message: err := r.SetProto(t) return r, err case roachpb.Value: panic("unexpected type roachpb.Value (use *roachpb.Value)") } // Handle all of the Go primitive types besides struct and pointers. This // switch also handles types based on a primitive type (e.g. "type MyInt // int"). switch v := reflect.ValueOf(v); v.Kind() { case reflect.Bool: r.SetBool(v.Bool()) return r, nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: r.SetInt(v.Int()) return r, nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: r.SetInt(int64(v.Uint())) return r, nil case reflect.Float32, reflect.Float64: r.SetFloat(v.Float()) return r, nil case reflect.String: r.SetBytes([]byte(v.String())) return r, nil } return r, fmt.Errorf("unable to marshal %T: %v", v, v) }
func inlineValueIntEncodedSize(v int64) int { var value roachpb.Value value.SetInt(v) meta := enginepb.MVCCMetadata{RawBytes: value.RawBytes} return meta.Size() }