From ef91bb4a3b2a4863f8a7b7b9c7ff2039f0b7feff Mon Sep 17 00:00:00 2001 From: Asdine El Hrychy Date: Sun, 21 Jan 2024 17:43:04 +0400 Subject: [PATCH] add ConvertAsIndexType --- internal/database/constraint.go | 15 +++------------ internal/database/iteration.go | 11 +++-------- internal/encoding/conversion.go | 23 +++++++++++++++++++++-- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/internal/database/constraint.go b/internal/database/constraint.go index 1ef84090..48cdcba9 100644 --- a/internal/database/constraint.go +++ b/internal/database/constraint.go @@ -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 { diff --git a/internal/database/iteration.go b/internal/database/iteration.go index 27b8bd91..c7ca8f26 100644 --- a/internal/database/iteration.go +++ b/internal/database/iteration.go @@ -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 diff --git a/internal/encoding/conversion.go b/internal/encoding/conversion.go index a43568d6..a53e0949 100644 --- a/internal/encoding/conversion.go +++ b/internal/encoding/conversion.go @@ -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 +}