mirror of
https://github.com/dolthub/dolt.git
synced 2025-12-30 08:50:01 -06:00
Respond to PR feedback.
This commit is contained in:
@@ -23,117 +23,117 @@ import (
|
||||
type Encoding byte
|
||||
|
||||
const (
|
||||
EncodingNull Encoding = 0
|
||||
EncodingInt8 Encoding = 1
|
||||
EncodingUint8 Encoding = 2
|
||||
EncodingInt16 Encoding = 3
|
||||
EncodingUint16 Encoding = 4
|
||||
EncodingInt32 Encoding = 7
|
||||
EncodingUint32 Encoding = 8
|
||||
EncodingInt64 Encoding = 9
|
||||
EncodingUint64 Encoding = 10
|
||||
EncodingFloat32 Encoding = 11
|
||||
EncodingFloat64 Encoding = 12
|
||||
EncodingBit64 Encoding = 13
|
||||
EncodingHash128 Encoding = 14
|
||||
EncodingYear Encoding = 15
|
||||
EncodingDate Encoding = 16
|
||||
EncodingTime Encoding = 17
|
||||
EncodingDatetime Encoding = 18
|
||||
EncodingEnum Encoding = 19
|
||||
EncodingSet Encoding = 20
|
||||
EncodingBytesAddr Encoding = 21
|
||||
EncodingCommitAddr Encoding = 22
|
||||
EncodingStringAddr Encoding = 23
|
||||
EncodingJSONAddr Encoding = 24
|
||||
EncodingCell Encoding = 25
|
||||
EncodingGeomAddr Encoding = 26
|
||||
EncodingExtendedAddr Encoding = 27
|
||||
EncodingString Encoding = 128
|
||||
EncodingBytes Encoding = 129
|
||||
EncodingDecimal Encoding = 130
|
||||
EncodingJSON Encoding = 131
|
||||
EncodingGeometry Encoding = 133
|
||||
EncodingExtended Encoding = 134
|
||||
EncodingStringToast Encoding = 135
|
||||
EncodingBytesToast Encoding = 136
|
||||
EncodingExtendedToast Encoding = 137
|
||||
EncodingNull Encoding = 0
|
||||
EncodingInt8 Encoding = 1
|
||||
EncodingUint8 Encoding = 2
|
||||
EncodingInt16 Encoding = 3
|
||||
EncodingUint16 Encoding = 4
|
||||
EncodingInt32 Encoding = 7
|
||||
EncodingUint32 Encoding = 8
|
||||
EncodingInt64 Encoding = 9
|
||||
EncodingUint64 Encoding = 10
|
||||
EncodingFloat32 Encoding = 11
|
||||
EncodingFloat64 Encoding = 12
|
||||
EncodingBit64 Encoding = 13
|
||||
EncodingHash128 Encoding = 14
|
||||
EncodingYear Encoding = 15
|
||||
EncodingDate Encoding = 16
|
||||
EncodingTime Encoding = 17
|
||||
EncodingDatetime Encoding = 18
|
||||
EncodingEnum Encoding = 19
|
||||
EncodingSet Encoding = 20
|
||||
EncodingBytesAddr Encoding = 21
|
||||
EncodingCommitAddr Encoding = 22
|
||||
EncodingStringAddr Encoding = 23
|
||||
EncodingJSONAddr Encoding = 24
|
||||
EncodingCell Encoding = 25
|
||||
EncodingGeomAddr Encoding = 26
|
||||
EncodingExtendedAddr Encoding = 27
|
||||
EncodingString Encoding = 128
|
||||
EncodingBytes Encoding = 129
|
||||
EncodingDecimal Encoding = 130
|
||||
EncodingJSON Encoding = 131
|
||||
EncodingGeometry Encoding = 133
|
||||
EncodingExtended Encoding = 134
|
||||
EncodingStringAdaptive Encoding = 135
|
||||
EncodingBytesAdaptive Encoding = 136
|
||||
EncodingExtendedAdaptive Encoding = 137
|
||||
)
|
||||
|
||||
var EnumNamesEncoding = map[Encoding]string{
|
||||
EncodingNull: "Null",
|
||||
EncodingInt8: "Int8",
|
||||
EncodingUint8: "Uint8",
|
||||
EncodingInt16: "Int16",
|
||||
EncodingUint16: "Uint16",
|
||||
EncodingInt32: "Int32",
|
||||
EncodingUint32: "Uint32",
|
||||
EncodingInt64: "Int64",
|
||||
EncodingUint64: "Uint64",
|
||||
EncodingFloat32: "Float32",
|
||||
EncodingFloat64: "Float64",
|
||||
EncodingBit64: "Bit64",
|
||||
EncodingHash128: "Hash128",
|
||||
EncodingYear: "Year",
|
||||
EncodingDate: "Date",
|
||||
EncodingTime: "Time",
|
||||
EncodingDatetime: "Datetime",
|
||||
EncodingEnum: "Enum",
|
||||
EncodingSet: "Set",
|
||||
EncodingBytesAddr: "BytesAddr",
|
||||
EncodingCommitAddr: "CommitAddr",
|
||||
EncodingStringAddr: "StringAddr",
|
||||
EncodingJSONAddr: "JSONAddr",
|
||||
EncodingCell: "Cell",
|
||||
EncodingGeomAddr: "GeomAddr",
|
||||
EncodingExtendedAddr: "ExtendedAddr",
|
||||
EncodingString: "String",
|
||||
EncodingBytes: "Bytes",
|
||||
EncodingDecimal: "Decimal",
|
||||
EncodingJSON: "JSON",
|
||||
EncodingGeometry: "Geometry",
|
||||
EncodingExtended: "Extended",
|
||||
EncodingStringToast: "StringToast",
|
||||
EncodingBytesToast: "BytesToast",
|
||||
EncodingExtendedToast: "ExtendedToast",
|
||||
EncodingNull: "Null",
|
||||
EncodingInt8: "Int8",
|
||||
EncodingUint8: "Uint8",
|
||||
EncodingInt16: "Int16",
|
||||
EncodingUint16: "Uint16",
|
||||
EncodingInt32: "Int32",
|
||||
EncodingUint32: "Uint32",
|
||||
EncodingInt64: "Int64",
|
||||
EncodingUint64: "Uint64",
|
||||
EncodingFloat32: "Float32",
|
||||
EncodingFloat64: "Float64",
|
||||
EncodingBit64: "Bit64",
|
||||
EncodingHash128: "Hash128",
|
||||
EncodingYear: "Year",
|
||||
EncodingDate: "Date",
|
||||
EncodingTime: "Time",
|
||||
EncodingDatetime: "Datetime",
|
||||
EncodingEnum: "Enum",
|
||||
EncodingSet: "Set",
|
||||
EncodingBytesAddr: "BytesAddr",
|
||||
EncodingCommitAddr: "CommitAddr",
|
||||
EncodingStringAddr: "StringAddr",
|
||||
EncodingJSONAddr: "JSONAddr",
|
||||
EncodingCell: "Cell",
|
||||
EncodingGeomAddr: "GeomAddr",
|
||||
EncodingExtendedAddr: "ExtendedAddr",
|
||||
EncodingString: "String",
|
||||
EncodingBytes: "Bytes",
|
||||
EncodingDecimal: "Decimal",
|
||||
EncodingJSON: "JSON",
|
||||
EncodingGeometry: "Geometry",
|
||||
EncodingExtended: "Extended",
|
||||
EncodingStringAdaptive: "StringAdaptive",
|
||||
EncodingBytesAdaptive: "BytesAdaptive",
|
||||
EncodingExtendedAdaptive: "ExtendedAdaptive",
|
||||
}
|
||||
|
||||
var EnumValuesEncoding = map[string]Encoding{
|
||||
"Null": EncodingNull,
|
||||
"Int8": EncodingInt8,
|
||||
"Uint8": EncodingUint8,
|
||||
"Int16": EncodingInt16,
|
||||
"Uint16": EncodingUint16,
|
||||
"Int32": EncodingInt32,
|
||||
"Uint32": EncodingUint32,
|
||||
"Int64": EncodingInt64,
|
||||
"Uint64": EncodingUint64,
|
||||
"Float32": EncodingFloat32,
|
||||
"Float64": EncodingFloat64,
|
||||
"Bit64": EncodingBit64,
|
||||
"Hash128": EncodingHash128,
|
||||
"Year": EncodingYear,
|
||||
"Date": EncodingDate,
|
||||
"Time": EncodingTime,
|
||||
"Datetime": EncodingDatetime,
|
||||
"Enum": EncodingEnum,
|
||||
"Set": EncodingSet,
|
||||
"BytesAddr": EncodingBytesAddr,
|
||||
"CommitAddr": EncodingCommitAddr,
|
||||
"StringAddr": EncodingStringAddr,
|
||||
"JSONAddr": EncodingJSONAddr,
|
||||
"Cell": EncodingCell,
|
||||
"GeomAddr": EncodingGeomAddr,
|
||||
"ExtendedAddr": EncodingExtendedAddr,
|
||||
"String": EncodingString,
|
||||
"Bytes": EncodingBytes,
|
||||
"Decimal": EncodingDecimal,
|
||||
"JSON": EncodingJSON,
|
||||
"Geometry": EncodingGeometry,
|
||||
"Extended": EncodingExtended,
|
||||
"StringToast": EncodingStringToast,
|
||||
"BytesToast": EncodingBytesToast,
|
||||
"ExtendedToast": EncodingExtendedToast,
|
||||
"Null": EncodingNull,
|
||||
"Int8": EncodingInt8,
|
||||
"Uint8": EncodingUint8,
|
||||
"Int16": EncodingInt16,
|
||||
"Uint16": EncodingUint16,
|
||||
"Int32": EncodingInt32,
|
||||
"Uint32": EncodingUint32,
|
||||
"Int64": EncodingInt64,
|
||||
"Uint64": EncodingUint64,
|
||||
"Float32": EncodingFloat32,
|
||||
"Float64": EncodingFloat64,
|
||||
"Bit64": EncodingBit64,
|
||||
"Hash128": EncodingHash128,
|
||||
"Year": EncodingYear,
|
||||
"Date": EncodingDate,
|
||||
"Time": EncodingTime,
|
||||
"Datetime": EncodingDatetime,
|
||||
"Enum": EncodingEnum,
|
||||
"Set": EncodingSet,
|
||||
"BytesAddr": EncodingBytesAddr,
|
||||
"CommitAddr": EncodingCommitAddr,
|
||||
"StringAddr": EncodingStringAddr,
|
||||
"JSONAddr": EncodingJSONAddr,
|
||||
"Cell": EncodingCell,
|
||||
"GeomAddr": EncodingGeomAddr,
|
||||
"ExtendedAddr": EncodingExtendedAddr,
|
||||
"String": EncodingString,
|
||||
"Bytes": EncodingBytes,
|
||||
"Decimal": EncodingDecimal,
|
||||
"JSON": EncodingJSON,
|
||||
"Geometry": EncodingGeometry,
|
||||
"Extended": EncodingExtended,
|
||||
"StringAdaptive": EncodingStringAdaptive,
|
||||
"BytesAdaptive": EncodingBytesAdaptive,
|
||||
"ExtendedAdaptive": EncodingExtendedAdaptive,
|
||||
}
|
||||
|
||||
func (v Encoding) String() string {
|
||||
|
||||
@@ -510,7 +510,7 @@ func (si *schemaImpl) getKeyColumnsDescriptor(vs val.ValueStore, convertAddressC
|
||||
switch encoding {
|
||||
case serial.EncodingExtendedAddr:
|
||||
handler = val.NewExtendedAddressTypeHandler(vs, extendedType)
|
||||
case serial.EncodingExtendedToast:
|
||||
case serial.EncodingExtendedAdaptive:
|
||||
handler = val.NewToastTypeHandler(vs, extendedType)
|
||||
default:
|
||||
// encoding == serial.EncodingExtended
|
||||
@@ -600,7 +600,7 @@ func (si *schemaImpl) GetValueDescriptor(vs val.ValueStore) val.TupleDesc {
|
||||
switch encoding {
|
||||
case serial.EncodingExtendedAddr:
|
||||
handlers = append(handlers, val.NewExtendedAddressTypeHandler(vs, extendedType))
|
||||
case serial.EncodingExtendedToast:
|
||||
case serial.EncodingExtendedAdaptive:
|
||||
handlers = append(handlers, val.NewToastTypeHandler(vs, extendedType))
|
||||
default:
|
||||
// encoding == serial.EncodingExtended
|
||||
|
||||
@@ -31,8 +31,8 @@ func EncodingFromSqlType(typ sql.Type) serial.Encoding {
|
||||
case types.ExtendedTypeSerializedWidth_64K:
|
||||
return serial.EncodingExtended
|
||||
case types.ExtendedTypeSerializedWidth_Unbounded:
|
||||
// Always uses Toast encoding for extended types, regardless of the setting of UseToastTypes below.
|
||||
return serial.EncodingExtendedToast
|
||||
// Always uses adaptive encoding for extended types, regardless of the setting of UseAdaptiveEncoding below.
|
||||
return serial.EncodingExtendedAdaptive
|
||||
default:
|
||||
panic(fmt.Errorf("unknown serialization width"))
|
||||
}
|
||||
@@ -40,10 +40,10 @@ func EncodingFromSqlType(typ sql.Type) serial.Encoding {
|
||||
return EncodingFromQueryType(typ.Type())
|
||||
}
|
||||
|
||||
// UseToastTypes indicates whether to use TOAST encoding for large/unbounded fields instead of address encoding.
|
||||
// Tests can set this variable to true in order to force Dolt to use TOAST encoding for TEXT and BLOB columns.
|
||||
// Doltgres also sets this to true in order to use TOAST encoding for extended types.
|
||||
var UseToastTypes = false
|
||||
// UseAdaptiveEncoding indicates whether to use adaptive encoding for large/unbounded fields instead of address encoding.
|
||||
// Tests can set this variable to true in order to force Dolt to use adaptive encoding for TEXT and BLOB columns.
|
||||
// Extended types will always use adaptive encoding for TEXT and BLOB types regardless of this value.
|
||||
var UseAdaptiveEncoding = false
|
||||
|
||||
// EncodingFromQueryType returns a serial.Encoding for a query.Type.
|
||||
func EncodingFromQueryType(typ query.Type) serial.Encoding {
|
||||
@@ -103,13 +103,13 @@ func EncodingFromQueryType(typ query.Type) serial.Encoding {
|
||||
case query.Type_JSON:
|
||||
return serial.EncodingJSONAddr
|
||||
case query.Type_BLOB:
|
||||
if UseToastTypes {
|
||||
return serial.EncodingBytesToast
|
||||
if UseAdaptiveEncoding {
|
||||
return serial.EncodingBytesAdaptive
|
||||
}
|
||||
return serial.EncodingBytesAddr
|
||||
case query.Type_TEXT:
|
||||
if UseToastTypes {
|
||||
return serial.EncodingStringToast
|
||||
if UseAdaptiveEncoding {
|
||||
return serial.EncodingStringAdaptive
|
||||
}
|
||||
return serial.EncodingStringAddr
|
||||
default:
|
||||
|
||||
@@ -106,7 +106,8 @@ func TestSchemaOverrides(t *testing.T) {
|
||||
// Provide additional test coverage for toast types by running Schema Override tests
|
||||
// using toast types instead of address types.
|
||||
func TestSchemaOverridesWithToastTypes(t *testing.T) {
|
||||
schema.UseToastTypes = true
|
||||
defer func() { schema.UseAdaptiveEncoding = false }()
|
||||
schema.UseAdaptiveEncoding = true
|
||||
harness := newDoltEnginetestHarness(t)
|
||||
RunSchemaOverridesTest(t, harness)
|
||||
}
|
||||
|
||||
@@ -489,7 +489,7 @@ func getSchemaFragmentsOfType(ctx *sql.Context, tbl *WritableDoltTable, fragType
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type for fragment, expected string, got %v. This should never happen", sqlRow[nameIdx])
|
||||
return nil, fmt.Errorf("unexpected type for fragment, expected string, got %v. This should never happen", sqlRow[fragmentIdx])
|
||||
}
|
||||
|
||||
frags = append(frags, schemaFragment{
|
||||
|
||||
@@ -37,6 +37,7 @@ func unwrapRow(t *testing.T, row sql.Row) (unwrappedRow sql.Row) {
|
||||
}
|
||||
return unwrappedRow
|
||||
}
|
||||
|
||||
func unwrapRows(t *testing.T, rows []sql.Row) (unwrappedRows []sql.Row) {
|
||||
for _, row := range rows {
|
||||
unwrappedRows = append(unwrappedRows, unwrapRow(t, row))
|
||||
|
||||
@@ -50,7 +50,7 @@ enum Encoding : uint8 {
|
||||
JSON = 131,
|
||||
Geometry = 133,
|
||||
Extended = 134,
|
||||
StringToast = 135,
|
||||
BytesToast = 136,
|
||||
ExtendedToast = 137
|
||||
StringAdaptive = 135,
|
||||
BytesAdaptive = 136,
|
||||
ExtendedAdaptive = 137
|
||||
}
|
||||
|
||||
@@ -84,9 +84,9 @@ func countAddresses(items [][]byte, td val.TupleDesc) (cnt int) {
|
||||
}
|
||||
return
|
||||
})
|
||||
val.IterToastFields(td, func(j int, t val.Type) {
|
||||
val.IterAdaptiveFields(td, func(j int, t val.Type) {
|
||||
// get offset of toast value within |tup|
|
||||
toastValue := val.ToastValue(val.Tuple(items[i]).GetField(j))
|
||||
toastValue := val.AdaptiveValue(val.Tuple(items[i]).GetField(j))
|
||||
if toastValue.IsOutlined() {
|
||||
cnt++
|
||||
}
|
||||
@@ -114,12 +114,13 @@ func writeAddressOffsets(b *fb.Builder, items [][]byte, sumSz int, td val.TupleD
|
||||
b.PrependUint16(uint16(o))
|
||||
cnt++
|
||||
})
|
||||
val.IterToastFields(td, func(j int, t val.Type) {
|
||||
val.IterAdaptiveFields(td, func(j int, t val.Type) {
|
||||
// get offset of toast value within |tup|
|
||||
toastValue := val.ToastValue(val.Tuple(items[i]).GetField(j))
|
||||
if toastValue.IsOutlined() {
|
||||
adaptiveValue := val.AdaptiveValue(val.Tuple(items[i]).GetField(j))
|
||||
if adaptiveValue.IsOutlined() {
|
||||
// Out-of-line adaptive values end in an address, so get the offset |hash.ByteLen| bytes before the end.
|
||||
o, _ := tup.GetOffset(j)
|
||||
o += off + 9 // address appears 9 bytes in.
|
||||
o += off + len(adaptiveValue) - hash.ByteLen
|
||||
b.PrependUint16(uint16(o))
|
||||
cnt++
|
||||
}
|
||||
|
||||
@@ -136,9 +136,9 @@ func GetField(ctx context.Context, td val.TupleDesc, i int, tup val.Tuple, ns No
|
||||
if ok {
|
||||
v = val.NewTextStorage(h, ns)
|
||||
}
|
||||
case val.BytesToastEnc:
|
||||
case val.BytesAdaptiveEnc:
|
||||
v, ok, err = td.GetBytesToastValue(i, ns, tup)
|
||||
case val.StringToastEnc:
|
||||
case val.StringAdaptiveEnc:
|
||||
v, ok, err = td.GetStringToastValue(i, ns, tup)
|
||||
case val.CommitAddrEnc:
|
||||
v, ok = td.GetCommitAddr(i, tup)
|
||||
@@ -300,7 +300,7 @@ func PutField(ctx context.Context, ns NodeStore, tb *val.TupleBuilder, i int, v
|
||||
return err
|
||||
}
|
||||
tb.PutExtendedAddr(i, hash.New(b))
|
||||
case val.BytesToastEnc:
|
||||
case val.BytesAdaptiveEnc:
|
||||
switch value := v.(type) {
|
||||
case []byte:
|
||||
err := tb.PutToastBytesFromInline(i, value)
|
||||
@@ -310,7 +310,7 @@ func PutField(ctx context.Context, ns NodeStore, tb *val.TupleBuilder, i int, v
|
||||
case *val.ByteArray:
|
||||
tb.PutToastBytesFromOutline(i, value)
|
||||
}
|
||||
case val.StringToastEnc:
|
||||
case val.StringAdaptiveEnc:
|
||||
switch value := v.(type) {
|
||||
case string:
|
||||
err := tb.PutToastStringFromInline(i, value)
|
||||
@@ -334,7 +334,7 @@ func getBlobAddrHash(ctx context.Context, ns NodeStore, v interface{}) (h hash.H
|
||||
}
|
||||
bytesWrapper, isBytesWrapper := v.(sql.BytesWrapper)
|
||||
if !isBytesWrapper {
|
||||
return hash.Hash{}, fmt.Errorf("expected implementation of sql.BytesWrapper, got %v", v)
|
||||
return hash.Hash{}, fmt.Errorf("expected implementation of sql.BytesWrapper, got %T", v)
|
||||
}
|
||||
if byteArray, isByteArray := v.(val.ByteArray); isByteArray {
|
||||
return byteArray.Addr, nil
|
||||
@@ -354,7 +354,7 @@ func getStringAddrHash(ctx context.Context, ns NodeStore, v interface{}) (h hash
|
||||
}
|
||||
stringWrapper, isStringWrapper := v.(sql.StringWrapper)
|
||||
if !isStringWrapper {
|
||||
return hash.Hash{}, fmt.Errorf("expected implementation of sql.StringWrapper, got %v", v)
|
||||
return hash.Hash{}, fmt.Errorf("expected implementation of sql.StringWrapper, got %T", v)
|
||||
}
|
||||
if textStorage, isTextStorage := v.(val.TextStorage); isTextStorage {
|
||||
return textStorage.Addr, nil
|
||||
|
||||
@@ -175,22 +175,22 @@ func TestRoundTripProllyFields(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "binary toast short",
|
||||
typ: val.Type{Enc: val.BytesToastEnc},
|
||||
typ: val.Type{Enc: val.BytesAdaptiveEnc},
|
||||
value: []byte("lorem ipsum"),
|
||||
},
|
||||
{
|
||||
name: "binary toast long",
|
||||
typ: val.Type{Enc: val.BytesToastEnc},
|
||||
typ: val.Type{Enc: val.BytesAdaptiveEnc},
|
||||
value: make([]byte, (1 << 12)),
|
||||
},
|
||||
{
|
||||
name: "string toast short",
|
||||
typ: val.Type{Enc: val.StringToastEnc},
|
||||
typ: val.Type{Enc: val.StringAdaptiveEnc},
|
||||
value: "lorem ipsum",
|
||||
},
|
||||
{
|
||||
name: "binary toast long",
|
||||
typ: val.Type{Enc: val.StringToastEnc},
|
||||
typ: val.Type{Enc: val.StringAdaptiveEnc},
|
||||
value: string(make([]byte, (1 << 12))),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -119,9 +119,9 @@ func IsAddrEncoding(enc Encoding) bool {
|
||||
|
||||
func IsToastEncoding(enc Encoding) bool {
|
||||
switch enc {
|
||||
case BytesToastEnc,
|
||||
StringToastEnc,
|
||||
ExtendedToastEnc:
|
||||
case BytesAdaptiveEnc,
|
||||
StringAdaptiveEnc,
|
||||
ExtendedAdaptiveEnc:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -132,7 +132,7 @@ func IsExtendedEncoding(enc Encoding) bool {
|
||||
switch enc {
|
||||
case ExtendedEnc,
|
||||
ExtendedAddrEnc,
|
||||
ExtendedToastEnc:
|
||||
ExtendedAdaptiveEnc:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -141,15 +141,15 @@ func IsExtendedEncoding(enc Encoding) bool {
|
||||
|
||||
// Variable Width Encodings
|
||||
const (
|
||||
StringEnc = Encoding(serial.EncodingString)
|
||||
ByteStringEnc = Encoding(serial.EncodingBytes)
|
||||
DecimalEnc = Encoding(serial.EncodingDecimal)
|
||||
JSONEnc = Encoding(serial.EncodingJSON)
|
||||
GeometryEnc = Encoding(serial.EncodingGeometry)
|
||||
ExtendedEnc = Encoding(serial.EncodingExtended)
|
||||
StringToastEnc = Encoding(serial.EncodingStringToast)
|
||||
BytesToastEnc = Encoding(serial.EncodingBytesToast)
|
||||
ExtendedToastEnc = Encoding(serial.EncodingExtendedToast)
|
||||
StringEnc = Encoding(serial.EncodingString)
|
||||
ByteStringEnc = Encoding(serial.EncodingBytes)
|
||||
DecimalEnc = Encoding(serial.EncodingDecimal)
|
||||
JSONEnc = Encoding(serial.EncodingJSON)
|
||||
GeometryEnc = Encoding(serial.EncodingGeometry)
|
||||
ExtendedEnc = Encoding(serial.EncodingExtended)
|
||||
StringAdaptiveEnc = Encoding(serial.EncodingStringAdaptive)
|
||||
BytesAdaptiveEnc = Encoding(serial.EncodingBytesAdaptive)
|
||||
ExtendedAdaptiveEnc = Encoding(serial.EncodingExtendedAdaptive)
|
||||
)
|
||||
|
||||
func sizeFromType(t Type) (ByteSize, bool) {
|
||||
@@ -652,7 +652,7 @@ func compareAddr(l, r hash.Hash) int {
|
||||
return l.Compare(r)
|
||||
}
|
||||
|
||||
func compareToastValue(l, r ToastValue) int {
|
||||
func compareToastValue(l, r AdaptiveValue) int {
|
||||
return bytes.Compare(l, r)
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ func (tb *TupleBuilder) BuildPermissive(pool pool.BuffPool, vs ValueStore) (tup
|
||||
// do this in a way that doesn't require the full field.
|
||||
for i, descType := range tb.Desc.Types {
|
||||
if IsToastEncoding(descType.Enc) {
|
||||
toastValue := ToastValue(tb.fields[i])
|
||||
toastValue := AdaptiveValue(tb.fields[i])
|
||||
outlineSize := toastValue.outlineSize()
|
||||
inlineSize := toastValue.inlineSize()
|
||||
|
||||
@@ -134,7 +134,7 @@ func (tb *TupleBuilder) BuildPermissive(pool pool.BuffPool, vs ValueStore) (tup
|
||||
// We have enough space, mark all the remaining columns as inline
|
||||
for j, descType := range tb.Desc.Types[i+1:] {
|
||||
if IsToastEncoding(descType.Enc) {
|
||||
toastValue := ToastValue(tb.fields[j+i+1])
|
||||
toastValue := AdaptiveValue(tb.fields[j+i+1])
|
||||
if !toastValue.isInlined() {
|
||||
inline, err := toastValue.convertToInline(ctx, tb.vs, nil)
|
||||
if err != nil {
|
||||
@@ -548,13 +548,13 @@ func (tb *TupleBuilder) PutCell(i int, v Cell) {
|
||||
|
||||
func (tb *TupleBuilder) PutToastBytesFromInline(i int, v []byte) error {
|
||||
// TODO: Add context
|
||||
tb.Desc.expectEncoding(i, BytesToastEnc)
|
||||
tb.Desc.expectEncoding(i, BytesAdaptiveEnc)
|
||||
if len(v) > int(MaxTupleDataSize) {
|
||||
return fmt.Errorf("byte array too large to fit inline (%d > %d). This shouldn't happen", len(v), MaxTupleDataSize)
|
||||
}
|
||||
sz := ByteSize(len(v)) + 2 // header byte, plus null terminator?
|
||||
tb.ensureCapacity(sz)
|
||||
field := ToastValue(tb.buf[tb.pos : tb.pos+int64(sz)])
|
||||
field := AdaptiveValue(tb.buf[tb.pos : tb.pos+int64(sz)])
|
||||
tb.fields[i] = field
|
||||
field[0] = 0 // Mark this as inline
|
||||
writeByteString(field[1:], v)
|
||||
@@ -566,13 +566,13 @@ func (tb *TupleBuilder) PutToastBytesFromInline(i int, v []byte) error {
|
||||
|
||||
func (tb *TupleBuilder) PutToastStringFromInline(i int, v string) error {
|
||||
// TODO: Add context
|
||||
tb.Desc.expectEncoding(i, StringToastEnc)
|
||||
tb.Desc.expectEncoding(i, StringAdaptiveEnc)
|
||||
if len(v) > int(MaxTupleDataSize) {
|
||||
return fmt.Errorf("byte array too large to fit inline (%d > %d). This shouldn't happen", len(v), MaxTupleDataSize)
|
||||
}
|
||||
sz := ByteSize(len(v)) + 2 // header byte, plus null terminator?
|
||||
tb.ensureCapacity(sz)
|
||||
field := ToastValue(tb.buf[tb.pos : tb.pos+int64(sz)])
|
||||
field := AdaptiveValue(tb.buf[tb.pos : tb.pos+int64(sz)])
|
||||
tb.fields[i] = field
|
||||
field[0] = 0 // Mark this as inline
|
||||
writeByteString(field[1:], []byte(v))
|
||||
@@ -583,7 +583,7 @@ func (tb *TupleBuilder) PutToastStringFromInline(i int, v string) error {
|
||||
}
|
||||
|
||||
func (tb *TupleBuilder) PutToastBytesFromOutline(i int, v *ByteArray) {
|
||||
tb.Desc.expectEncoding(i, BytesToastEnc)
|
||||
tb.Desc.expectEncoding(i, BytesAdaptiveEnc)
|
||||
// TODO: What's the correct size?
|
||||
sz := ByteSize(29)
|
||||
tb.ensureCapacity(sz)
|
||||
@@ -600,7 +600,7 @@ func (tb *TupleBuilder) PutToastBytesFromOutline(i int, v *ByteArray) {
|
||||
}
|
||||
|
||||
func (tb *TupleBuilder) PutToastStringFromOutline(i int, v *TextStorage) {
|
||||
tb.Desc.expectEncoding(i, StringToastEnc)
|
||||
tb.Desc.expectEncoding(i, StringAdaptiveEnc)
|
||||
// TODO: What's the correct size?
|
||||
sz := ByteSize(29)
|
||||
tb.ensureCapacity(sz)
|
||||
|
||||
@@ -272,7 +272,7 @@ var _ ValueStore = &TestValueStore{}
|
||||
func TestTupleBuilderToastTypes(t *testing.T) {
|
||||
ctx := sql.NewEmptyContext()
|
||||
types := []Type{
|
||||
{Enc: BytesToastEnc},
|
||||
{Enc: BytesAdaptiveEnc},
|
||||
}
|
||||
vs := &TestValueStore{}
|
||||
td := NewTupleDescriptor(types...)
|
||||
@@ -311,8 +311,8 @@ func TestTupleBuilderToastTypes(t *testing.T) {
|
||||
func TestTupleBuilderMultipleToastTypes(t *testing.T) {
|
||||
ctx := sql.NewEmptyContext()
|
||||
types := []Type{
|
||||
{Enc: BytesToastEnc},
|
||||
{Enc: BytesToastEnc},
|
||||
{Enc: BytesAdaptiveEnc},
|
||||
{Enc: BytesAdaptiveEnc},
|
||||
}
|
||||
vs := &TestValueStore{}
|
||||
td := NewTupleDescriptor(types...)
|
||||
|
||||
@@ -150,7 +150,7 @@ func compare(typ Type, left, right []byte) int {
|
||||
return compareAddr(readAddr(left), readAddr(right))
|
||||
case CellEnc:
|
||||
return compareCell(readCell(left), readCell(right))
|
||||
case BytesToastEnc, StringToastEnc:
|
||||
case BytesAdaptiveEnc, StringAdaptiveEnc:
|
||||
return compareToastValue(left, right)
|
||||
default:
|
||||
panic("unknown encoding")
|
||||
|
||||
@@ -110,10 +110,10 @@ func IterAddressFields(td TupleDesc, cb func(int, Type)) {
|
||||
}
|
||||
}
|
||||
|
||||
func IterToastFields(td TupleDesc, cb func(int, Type)) {
|
||||
func IterAdaptiveFields(td TupleDesc, cb func(int, Type)) {
|
||||
for i, typ := range td.Types {
|
||||
switch typ.Enc {
|
||||
case BytesToastEnc, StringToastEnc:
|
||||
case BytesAdaptiveEnc, StringAdaptiveEnc, ExtendedAdaptiveEnc:
|
||||
cb(i, typ)
|
||||
}
|
||||
}
|
||||
@@ -526,8 +526,8 @@ func (td TupleDesc) GetBytesAddr(i int, tup Tuple) (hash.Hash, bool) {
|
||||
|
||||
// GetBytesToastValue returns either a []byte or a BytesWrapper, but Go doesn't allow us to use a single type for that.
|
||||
func (td TupleDesc) GetBytesToastValue(i int, vs ValueStore, tup Tuple) (interface{}, bool, error) {
|
||||
td.expectEncoding(i, BytesToastEnc)
|
||||
toastValue := ToastValue(td.GetField(i, tup))
|
||||
td.expectEncoding(i, BytesAdaptiveEnc)
|
||||
toastValue := AdaptiveValue(td.GetField(i, tup))
|
||||
if len(toastValue) == 0 {
|
||||
return nil, false, nil
|
||||
}
|
||||
@@ -542,8 +542,8 @@ func (td TupleDesc) GetBytesToastValue(i int, vs ValueStore, tup Tuple) (interfa
|
||||
}
|
||||
|
||||
func (td TupleDesc) GetStringToastValue(i int, vs ValueStore, tup Tuple) (interface{}, bool, error) {
|
||||
td.expectEncoding(i, StringToastEnc)
|
||||
toastValue := ToastValue(td.GetField(i, tup))
|
||||
td.expectEncoding(i, StringAdaptiveEnc)
|
||||
toastValue := AdaptiveValue(td.GetField(i, tup))
|
||||
if len(toastValue) == 0 {
|
||||
return nil, false, nil
|
||||
}
|
||||
@@ -784,18 +784,18 @@ func (handler AddressTypeHandler) FormatValue(val any) (string, error) {
|
||||
return handler.childHandler.FormatValue(val)
|
||||
}
|
||||
|
||||
// A ToastValue is a byte sequence that can represent:
|
||||
// A AdaptiveValue is a byte sequence that can represent:
|
||||
// - An inlined string or bytes value
|
||||
// - An outlined (addressable) string or bytes value
|
||||
// - NULL (identified by the empty sequence)
|
||||
// Outlined ToastValues begin with a SQLite () variable-length encoding of the string length.
|
||||
// Note that this value is always greater than 21, because we only outline values when doing so reduces the length of
|
||||
// the tuple, and the outlined ToastValue consists of a 20 byte address + the string length (min 1 byte).
|
||||
// This means that we can use a shorter length value to indicate an inlined ToastValue. We choose 0 for simplicity.
|
||||
type ToastValue []byte
|
||||
// the tuple, and the outlined AdaptiveValue consists of a 20 byte address + the string length (min 1 byte).
|
||||
// This means that we can use a shorter length value to indicate an inlined AdaptiveValue. We choose 0 for simplicity.
|
||||
type AdaptiveValue []byte
|
||||
|
||||
// getMessageLength returns the length of the underlying value.
|
||||
func (v ToastValue) getMessageLength() int64 {
|
||||
func (v AdaptiveValue) getMessageLength() int64 {
|
||||
if v.IsNull() {
|
||||
return 0
|
||||
}
|
||||
@@ -807,7 +807,7 @@ func (v ToastValue) getMessageLength() int64 {
|
||||
}
|
||||
|
||||
// outlineSize computes the size of the value in the tuple if it were outlined.
|
||||
func (v ToastValue) outlineSize() int64 {
|
||||
func (v AdaptiveValue) outlineSize() int64 {
|
||||
if v.IsOutlined() {
|
||||
return int64(len(v))
|
||||
}
|
||||
@@ -816,7 +816,7 @@ func (v ToastValue) outlineSize() int64 {
|
||||
}
|
||||
|
||||
// inlineSize computes the size of the value in the tuple if it were inlined.
|
||||
func (v ToastValue) inlineSize() int64 {
|
||||
func (v AdaptiveValue) inlineSize() int64 {
|
||||
if v.isInlined() {
|
||||
return int64(len(v))
|
||||
}
|
||||
@@ -824,13 +824,13 @@ func (v ToastValue) inlineSize() int64 {
|
||||
return 1 + blobLength // header + message
|
||||
}
|
||||
|
||||
// IsNull returns whether this ToastValue represents a NULL value.
|
||||
func (v ToastValue) IsNull() bool {
|
||||
// IsNull returns whether this AdaptiveValue represents a NULL value.
|
||||
func (v AdaptiveValue) IsNull() bool {
|
||||
return len(v) == 0
|
||||
}
|
||||
|
||||
// IsOutlined returns whether this ToastValue represents a outlined addressable value.
|
||||
func (v ToastValue) IsOutlined() bool {
|
||||
// IsOutlined returns whether this AdaptiveValue represents a outlined addressable value.
|
||||
func (v AdaptiveValue) IsOutlined() bool {
|
||||
if v.IsNull() {
|
||||
return false
|
||||
}
|
||||
@@ -847,7 +847,7 @@ func makeVarInt(x uint64, dest []byte) (bytesWritten int, output []byte) {
|
||||
|
||||
// If a conversion is necessary, the converted value will be copied into `dest`. This is a performance
|
||||
// optimization when there is a pre-allocated buffer.
|
||||
func (v ToastValue) convertToOutline(ctx context.Context, vs ValueStore, dest []byte) (ToastValue, error) {
|
||||
func (v AdaptiveValue) convertToOutline(ctx context.Context, vs ValueStore, dest []byte) (AdaptiveValue, error) {
|
||||
if v.IsOutlined() {
|
||||
return v, nil
|
||||
}
|
||||
@@ -866,8 +866,8 @@ func (v ToastValue) convertToOutline(ctx context.Context, vs ValueStore, dest []
|
||||
return dest, nil
|
||||
}
|
||||
|
||||
// isInlined returns whether this ToastValue represents an inlined value.
|
||||
func (v ToastValue) isInlined() bool {
|
||||
// isInlined returns whether this AdaptiveValue represents an inlined value.
|
||||
func (v AdaptiveValue) isInlined() bool {
|
||||
if v.IsNull() {
|
||||
return false
|
||||
}
|
||||
@@ -876,7 +876,7 @@ func (v ToastValue) isInlined() bool {
|
||||
|
||||
// If a conversion is necessary, the converted value will be written into `dest`. This is a performance
|
||||
// optimization when there is a pre-allocated buffer.
|
||||
func (v ToastValue) convertToInline(ctx context.Context, vs ValueStore, dest []byte) (ToastValue, error) {
|
||||
func (v AdaptiveValue) convertToInline(ctx context.Context, vs ValueStore, dest []byte) (AdaptiveValue, error) {
|
||||
if v.isInlined() {
|
||||
return v, nil
|
||||
}
|
||||
@@ -896,7 +896,7 @@ func (v ToastValue) convertToInline(ctx context.Context, vs ValueStore, dest []b
|
||||
return dest, nil
|
||||
}
|
||||
|
||||
func (v ToastValue) convertToBytes(ctx context.Context, vs ValueStore, buf []byte) ([]byte, error) {
|
||||
func (v AdaptiveValue) convertToBytes(ctx context.Context, vs ValueStore, buf []byte) ([]byte, error) {
|
||||
// Only inlined values can be converted to bytes
|
||||
inlineValue, err := v.convertToInline(ctx, vs, buf)
|
||||
if err != nil {
|
||||
@@ -906,7 +906,7 @@ func (v ToastValue) convertToBytes(ctx context.Context, vs ValueStore, buf []byt
|
||||
return inlineValue[1:], nil
|
||||
}
|
||||
|
||||
func (v ToastValue) convertToByteArray(ctx context.Context, vs ValueStore, buf []byte) (*ByteArray, error) {
|
||||
func (v AdaptiveValue) convertToByteArray(ctx context.Context, vs ValueStore, buf []byte) (*ByteArray, error) {
|
||||
// Only outlined values can be converted to a ByteArray
|
||||
outlineValue, err := v.convertToOutline(ctx, vs, buf)
|
||||
if err != nil {
|
||||
@@ -917,7 +917,7 @@ func (v ToastValue) convertToByteArray(ctx context.Context, vs ValueStore, buf [
|
||||
return NewByteArray(address, vs).WithMaxByteLength(length), nil
|
||||
}
|
||||
|
||||
func (v ToastValue) convertToTextStorage(ctx context.Context, vs ValueStore, buf []byte) (*TextStorage, error) {
|
||||
func (v AdaptiveValue) convertToTextStorage(ctx context.Context, vs ValueStore, buf []byte) (*TextStorage, error) {
|
||||
// Only outlined values can be converted to a TextStorage
|
||||
outlineValue, err := v.convertToOutline(ctx, vs, buf)
|
||||
if err != nil {
|
||||
@@ -945,8 +945,8 @@ func NewToastTypeHandler(vs ValueStore, childHandler TupleTypeHandler) ToastType
|
||||
}
|
||||
|
||||
func (handler ToastTypeHandler) SerializedCompare(ctx context.Context, v1 []byte, v2 []byte) (int, error) {
|
||||
toastValue1 := ToastValue(v1)
|
||||
toastValue2 := ToastValue(v2)
|
||||
toastValue1 := AdaptiveValue(v1)
|
||||
toastValue2 := AdaptiveValue(v2)
|
||||
// Fast-path: two outlined values with equal hashes are equal.
|
||||
if toastValue1.IsOutlined() && toastValue2.IsOutlined() && bytes.Equal(toastValue1, toastValue2) {
|
||||
return 0, nil
|
||||
@@ -981,7 +981,7 @@ func (handler ToastTypeHandler) SerializeValue(ctx context.Context, val any) ([]
|
||||
}
|
||||
|
||||
func (handler ToastTypeHandler) DeserializeValue(ctx context.Context, val []byte) (any, error) {
|
||||
toastVal := ToastValue(val)
|
||||
toastVal := AdaptiveValue(val)
|
||||
if toastVal.IsNull() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user