Skip to content

Commit

Permalink
add ConvertAsIndexType
Browse files Browse the repository at this point in the history
asdine committed Jan 21, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent f8e7ecf commit ef91bb4
Showing 3 changed files with 27 additions and 22 deletions.
15 changes: 3 additions & 12 deletions internal/database/constraint.go
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import (
"fmt"
"strings"

"github.com/chaisql/chai/internal/encoding"
"github.com/chaisql/chai/internal/object"
"github.com/chaisql/chai/internal/stringutil"
"github.com/chaisql/chai/internal/tree"
@@ -158,18 +159,8 @@ func (f FieldConstraints) convertScalarAtPath(path object.Path, v types.Value, c
}

// no constraint have been found for this path.
// check if this is an integer and convert it to double.
if v.Type() == types.TypeInteger {
newV, _ := object.CastAsDouble(v)
return newV, nil
}

if v.Type() == types.TypeTimestamp {
newV, _ := object.CastAsText(v)
return newV, nil
}

return v, nil
// convert the value to the type that is stored in the index.
return encoding.ConvertAsIndexType(v, types.TypeAny)
}

func (f FieldConstraints) GetFieldConstraintForPath(path object.Path) *FieldConstraint {
11 changes: 3 additions & 8 deletions internal/database/iteration.go
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ package database
import (
"math"

"github.com/chaisql/chai/internal/encoding"
"github.com/chaisql/chai/internal/object"
"github.com/chaisql/chai/internal/tree"
"github.com/chaisql/chai/internal/types"
@@ -65,10 +66,6 @@ func (r *Range) Convert(constraints *FieldConstraints, v types.Value, p object.P
// is lossless.
// if a timestamp is encountered, ensure the field constraint is also a timestamp, otherwise convert it to text.
v, err := constraints.ConvertValueAtPath(p, v, func(v types.Value, path object.Path, targetType types.Type) (types.Value, error) {
if v.Type() == types.TypeInteger && targetType == types.TypeDouble {
return object.CastAsDouble(v)
}

if v.Type() == types.TypeDouble && targetType == types.TypeInteger {
f := types.AsFloat64(v)
if float64(int64(f)) == f {
@@ -102,10 +99,8 @@ func (r *Range) Convert(constraints *FieldConstraints, v types.Value, p object.P
// and thus have to set exclusive to false.
r.Exclusive = r.Min == nil || len(r.Min) == 0
}
}

if v.Type() == types.TypeTimestamp && targetType == types.TypeText {
return object.CastAsText(v)
} else {
return encoding.ConvertAsIndexType(v, targetType)
}

return v, nil
23 changes: 21 additions & 2 deletions internal/encoding/conversion.go
Original file line number Diff line number Diff line change
@@ -43,8 +43,6 @@ func convertIntegerFromStore(src types.Value, target types.Type) (types.Value, e
// ConvertAsStoreType converts the value to the type that is stored in the store
// when there is no constraint on the column.
func ConvertAsStoreType(src types.Value) (types.Value, error) {
// integers are stored as the smallest integer type that can hold the value
// even though they are read as doubles.
switch src.Type() {
case types.TypeTimestamp:
// without a type constraint, timestamp values must
@@ -54,3 +52,24 @@ func ConvertAsStoreType(src types.Value) (types.Value, error) {

return src, nil
}

// ConvertAsIndexType converts the value to the type that is stored in the index
// as a key.
func ConvertAsIndexType(src types.Value, target types.Type) (types.Value, error) {
switch src.Type() {
case types.TypeInteger:
if target == types.TypeAny || target == types.TypeDouble {
return object.CastAsDouble(src)
}
return src, nil
case types.TypeTimestamp:
// without a type constraint, timestamp values must
// always be stored as text to avoid mixed representations.
if target == types.TypeAny {
return object.CastAsText(src)
}
return src, nil
}

return src, nil
}

0 comments on commit ef91bb4

Please sign in to comment.