From cab2fd06f59256264fc06ae64eca1ba48daaad10 Mon Sep 17 00:00:00 2001 From: Sidhant Aggarwal <10743214+sidhant92@users.noreply.github.com> Date: Tue, 27 Aug 2024 13:26:55 +0530 Subject: [PATCH] implicit type conversion of data types --- internal/operator/abstract_operator.go | 7 +++- internal/operator/contains_all_operator.go | 16 ++++--- internal/operator/contains_any_operator.go | 16 ++++--- internal/operator/equals_operator.go | 15 +++++-- .../operator/greater_than_equal_operator.go | 12 ++++-- internal/operator/greater_than_operator.go | 12 ++++-- internal/operator/in_operator.go | 7 ++-- internal/operator/less_than_equal_operator.go | 12 ++++-- internal/operator/less_than_operator.go | 12 ++++-- internal/operator/not_equals_operator.go | 5 ++- internal/operator/numeric_operator.go | 41 ++++++++++++++++++ internal/service/operator_service.go | 13 +++--- .../boolean_expression_evaluator.go | 42 ++++++++++++++----- .../boolean_expression_evaluator_test.go | 26 ++++++++++-- pkg/constant/data_type.go | 32 ++++++++++++++ pkg/error/errors.go | 4 +- 16 files changed, 216 insertions(+), 56 deletions(-) create mode 100644 internal/operator/numeric_operator.go diff --git a/internal/operator/abstract_operator.go b/internal/operator/abstract_operator.go index 6c9d476..750306f 100644 --- a/internal/operator/abstract_operator.go +++ b/internal/operator/abstract_operator.go @@ -1,9 +1,12 @@ package operator -import "github.com/sidhant92/bool-parser-go/pkg/constant" +import ( + "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" +) type AbstractOperator interface { - Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) + Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) GetSymbol() string diff --git a/internal/operator/contains_all_operator.go b/internal/operator/contains_all_operator.go index c9c23dc..8b9724b 100644 --- a/internal/operator/contains_all_operator.go +++ b/internal/operator/contains_all_operator.go @@ -2,22 +2,26 @@ package operator import ( "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" "reflect" ) type ContainsAllOperator struct { } -func (e *ContainsAllOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { - var leftArray []interface{} - rv := reflect.ValueOf(left) +func (e *ContainsAllOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { + var leftArray []domain.EvaluatedNode + rv := reflect.ValueOf(leftOperand) if rv.Kind() == reflect.Slice { for i := 0; i < rv.Len(); i++ { - leftArray = append(leftArray, rv.Index(i).Interface()) + leftArray = append(leftArray, domain.EvaluatedNode{ + Value: rv.Index(i).Interface(), + DataType: leftOperandDataType, + }) } } - for _, value := range right { - res, err := GetOperator(constant.IN).Evaluate(constant.PRIMITIVE, dataType, validated, value, leftArray...) + for _, rightOperand := range rightOperands { + res, err := GetOperator(constant.IN).Evaluate(constant.PRIMITIVE, rightOperand.Value, rightOperand.DataType, leftArray) if err != nil { return false, err } diff --git a/internal/operator/contains_any_operator.go b/internal/operator/contains_any_operator.go index f5aeb85..f313c3c 100644 --- a/internal/operator/contains_any_operator.go +++ b/internal/operator/contains_any_operator.go @@ -2,22 +2,26 @@ package operator import ( "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" "reflect" ) type ContainsAnyOperator struct { } -func (e *ContainsAnyOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { - var leftArray []interface{} - rv := reflect.ValueOf(left) +func (e *ContainsAnyOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { + var leftArray []domain.EvaluatedNode + rv := reflect.ValueOf(leftOperand) if rv.Kind() == reflect.Slice { for i := 0; i < rv.Len(); i++ { - leftArray = append(leftArray, rv.Index(i).Interface()) + leftArray = append(leftArray, domain.EvaluatedNode{ + Value: rv.Index(i).Interface(), + DataType: leftOperandDataType, + }) } } - for _, value := range right { - res, err := GetOperator(constant.IN).Evaluate(constant.PRIMITIVE, dataType, validated, value, leftArray...) + for _, rightOperand := range rightOperands { + res, err := GetOperator(constant.IN).Evaluate(constant.PRIMITIVE, rightOperand.Value, rightOperand.DataType, leftArray) if err != nil { return false, err } diff --git a/internal/operator/equals_operator.go b/internal/operator/equals_operator.go index e026312..d3e6f01 100644 --- a/internal/operator/equals_operator.go +++ b/internal/operator/equals_operator.go @@ -3,20 +3,29 @@ package operator import ( "github.com/sidhant92/bool-parser-go/internal/datatype" "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" ) type EqualsOperator struct { } -func (e *EqualsOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { - dt := datatype.GetDataType(dataType) - res, err := dt.Compare(left, right[0], validated) +func (e *EqualsOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { + comparableDataType := getComparableDataType(leftOperandDataType, rightOperands[0].DataType) + dt := datatype.GetDataType(comparableDataType) + res, err := dt.Compare(leftOperand, rightOperands[0].Value, true) if err != nil { return false, err } return res == 0, nil } +func getComparableDataType(leftOperandDataType constant.DataType, rightOperandDataType constant.DataType) constant.DataType { + if constant.DataTypeAttributes[leftOperandDataType].Priority > constant.DataTypeAttributes[rightOperandDataType].Priority { + return leftOperandDataType + } + return rightOperandDataType +} + func (e *EqualsOperator) GetSymbol() string { return "=" } diff --git a/internal/operator/greater_than_equal_operator.go b/internal/operator/greater_than_equal_operator.go index e1bc050..ee6c240 100644 --- a/internal/operator/greater_than_equal_operator.go +++ b/internal/operator/greater_than_equal_operator.go @@ -3,14 +3,20 @@ package operator import ( "github.com/sidhant92/bool-parser-go/internal/datatype" "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" ) type GreaterThanEqualOperator struct { } -func (e *GreaterThanEqualOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { - dt := datatype.GetDataType(dataType) - res, err := dt.Compare(left, right[0], validated) +func (e *GreaterThanEqualOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { + err := Validate(leftOperand, leftOperandDataType, rightOperands[0].Value, rightOperands[0].DataType) + if err != nil { + return false, err + } + comparableDataType := GetComparableDataType(leftOperandDataType, rightOperands[0].DataType) + dt := datatype.GetDataType(comparableDataType) + res, err := dt.Compare(leftOperand, rightOperands[0].Value, true) if err != nil { return false, err } diff --git a/internal/operator/greater_than_operator.go b/internal/operator/greater_than_operator.go index 94ee46c..e2c907c 100644 --- a/internal/operator/greater_than_operator.go +++ b/internal/operator/greater_than_operator.go @@ -3,14 +3,20 @@ package operator import ( "github.com/sidhant92/bool-parser-go/internal/datatype" "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" ) type GreaterThanOperator struct { } -func (e *GreaterThanOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { - dt := datatype.GetDataType(dataType) - res, err := dt.Compare(left, right[0], validated) +func (e *GreaterThanOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { + err := Validate(leftOperand, leftOperandDataType, rightOperands[0].Value, rightOperands[0].DataType) + if err != nil { + return false, err + } + comparableDataType := GetComparableDataType(leftOperandDataType, rightOperands[0].DataType) + dt := datatype.GetDataType(comparableDataType) + res, err := dt.Compare(leftOperand, rightOperands[0].Value, true) if err != nil { return false, err } diff --git a/internal/operator/in_operator.go b/internal/operator/in_operator.go index 912991e..71ebae4 100644 --- a/internal/operator/in_operator.go +++ b/internal/operator/in_operator.go @@ -2,14 +2,15 @@ package operator import ( "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" ) type InOperator struct { } -func (e *InOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { - for _, value := range right { - res, err := GetOperator(constant.EQUALS).Evaluate(containerDataType, dataType, validated, left, value) +func (e *InOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { + for _, value := range rightOperands { + res, err := GetOperator(constant.EQUALS).Evaluate(containerDataType, leftOperand, leftOperandDataType, []domain.EvaluatedNode{value}) if err != nil { return false, err } diff --git a/internal/operator/less_than_equal_operator.go b/internal/operator/less_than_equal_operator.go index d9ce04b..99a7254 100644 --- a/internal/operator/less_than_equal_operator.go +++ b/internal/operator/less_than_equal_operator.go @@ -3,14 +3,20 @@ package operator import ( "github.com/sidhant92/bool-parser-go/internal/datatype" "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" ) type LessThanEqualOperator struct { } -func (e *LessThanEqualOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { - dt := datatype.GetDataType(dataType) - res, err := dt.Compare(left, right[0], validated) +func (e *LessThanEqualOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { + err := Validate(leftOperand, leftOperandDataType, rightOperands[0].Value, rightOperands[0].DataType) + if err != nil { + return false, err + } + comparableDataType := GetComparableDataType(leftOperandDataType, rightOperands[0].DataType) + dt := datatype.GetDataType(comparableDataType) + res, err := dt.Compare(leftOperand, rightOperands[0].Value, true) if err != nil { return false, err } diff --git a/internal/operator/less_than_operator.go b/internal/operator/less_than_operator.go index 9106478..dc64224 100644 --- a/internal/operator/less_than_operator.go +++ b/internal/operator/less_than_operator.go @@ -3,14 +3,20 @@ package operator import ( "github.com/sidhant92/bool-parser-go/internal/datatype" "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" ) type LessThanOperator struct { } -func (e *LessThanOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { - dt := datatype.GetDataType(dataType) - res, err := dt.Compare(left, right[0], validated) +func (e *LessThanOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { + err := Validate(leftOperand, leftOperandDataType, rightOperands[0].Value, rightOperands[0].DataType) + if err != nil { + return false, err + } + comparableDataType := GetComparableDataType(leftOperandDataType, rightOperands[0].DataType) + dt := datatype.GetDataType(comparableDataType) + res, err := dt.Compare(leftOperand, rightOperands[0].Value, true) if err != nil { return false, err } diff --git a/internal/operator/not_equals_operator.go b/internal/operator/not_equals_operator.go index 9734e86..c02690a 100644 --- a/internal/operator/not_equals_operator.go +++ b/internal/operator/not_equals_operator.go @@ -2,14 +2,15 @@ package operator import ( "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" ) type NotEqualsOperator struct { } -func (e *NotEqualsOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) { +func (e *NotEqualsOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { eq := GetOperator(constant.EQUALS) - res, err := eq.Evaluate(containerDataType, dataType, validated, left, right[0]) + res, err := eq.Evaluate(containerDataType, leftOperand, leftOperandDataType, rightOperands) if err != nil { return false, err } diff --git a/internal/operator/numeric_operator.go b/internal/operator/numeric_operator.go new file mode 100644 index 0000000..0896675 --- /dev/null +++ b/internal/operator/numeric_operator.go @@ -0,0 +1,41 @@ +package operator + +import ( + "github.com/sidhant92/bool-parser-go/internal/datatype" + "github.com/sidhant92/bool-parser-go/pkg/constant" + errors2 "github.com/sidhant92/bool-parser-go/pkg/error" + "log" +) + +func GetComparableDataType(leftOperandDataType constant.DataType, rightOperandDataType constant.DataType) constant.DataType { + if (constant.DataTypeAttributes[leftOperandDataType].Numeric && !constant.DataTypeAttributes[rightOperandDataType].Numeric) || (!constant.DataTypeAttributes[leftOperandDataType].Numeric && constant.DataTypeAttributes[rightOperandDataType].Numeric) { + if constant.DataTypeAttributes[leftOperandDataType].Numeric { + return leftOperandDataType + } + return rightOperandDataType + } + if constant.DataTypeAttributes[leftOperandDataType].Priority > constant.DataTypeAttributes[rightOperandDataType].Priority { + return leftOperandDataType + } + return rightOperandDataType +} + +func Validate(leftOperand interface{}, leftOperandDataType constant.DataType, rightOperand interface{}, rightOperandDataType constant.DataType) error { + if constant.DataTypeAttributes[leftOperandDataType].Numeric && constant.DataTypeAttributes[rightOperandDataType].Numeric { + return nil + } + if !constant.DataTypeAttributes[leftOperandDataType].Numeric && !constant.DataTypeAttributes[rightOperandDataType].Numeric { + return nil + } + rightDataType := datatype.GetDataType(rightOperandDataType) + if !constant.DataTypeAttributes[leftOperandDataType].Numeric && !rightDataType.IsValid(leftOperand) { + log.Printf("Incompatible data types %s and %s", leftOperandDataType, rightOperandDataType) + return errors2.INCOMPATIBLE_DATA_TYPE + } + leftDataType := datatype.GetDataType(leftOperandDataType) + if !constant.DataTypeAttributes[rightOperandDataType].Numeric && !leftDataType.IsValid(rightOperand) { + log.Printf("Incompatible data types %s and %s", leftOperandDataType, rightOperandDataType) + return errors2.INCOMPATIBLE_DATA_TYPE + } + return nil +} diff --git a/internal/service/operator_service.go b/internal/service/operator_service.go index 7b192c9..2665002 100644 --- a/internal/service/operator_service.go +++ b/internal/service/operator_service.go @@ -4,6 +4,7 @@ import ( "github.com/sidhant92/bool-parser-go/internal/containerdatatype" op "github.com/sidhant92/bool-parser-go/internal/operator" "github.com/sidhant92/bool-parser-go/pkg/constant" + "github.com/sidhant92/bool-parser-go/pkg/domain" errors2 "github.com/sidhant92/bool-parser-go/pkg/error" "log" "slices" @@ -21,21 +22,21 @@ func (o *OperatorService) GetOperatorFromSymbol(symbol string) constant.Operator panic("Unknown Operator " + symbol) } -func (o *OperatorService) Evaluate(operator constant.Operator, containerDataType constant.ContainerDataType, dataType constant.DataType, leftOperand interface{}, rightOperand ...interface{}) (bool, error) { +func (o *OperatorService) Evaluate(operator constant.Operator, containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) { var abstractOperator = op.GetOperator(operator) if !slices.Contains(abstractOperator.GetAllowedContainerTypes(), containerDataType) { log.Printf("Invalid container type %s for the the operator %s", containerDataType, operator) return false, errors2.INVALID_CONTAINER_DATA_TYPE } - if !slices.Contains(abstractOperator.GetAllowedDataTypes(), dataType) { - log.Printf("Invalid data type %s for the the operator %s", dataType, operator) + if !slices.Contains(abstractOperator.GetAllowedDataTypes(), leftOperandDataType) { + log.Printf("Invalid data type %s for the the operator %s for the operand %v", leftOperandDataType, operator, leftOperand) return false, errors2.INVALID_DATA_TYPE } - if !containerdatatype.GetContainerDataType(containerDataType).IsValid(dataType, leftOperand) { - log.Printf("validation failed for the operator %s for the the operand %v", operator, leftOperand) + if !containerdatatype.GetContainerDataType(containerDataType).IsValid(leftOperandDataType, leftOperand) { + log.Printf("validation failed for the operator %s for the the operand %v for data type %s", operator, leftOperand, leftOperandDataType) return false, errors2.INVALID_DATA_TYPE } - res, err := abstractOperator.Evaluate(containerDataType, dataType, true, leftOperand, rightOperand...) + res, err := abstractOperator.Evaluate(containerDataType, leftOperand, leftOperandDataType, rightOperands) if err != nil { return false, err } diff --git a/pkg/application/boolean_expression_evaluator.go b/pkg/application/boolean_expression_evaluator.go index f127a7d..faf0e4a 100644 --- a/pkg/application/boolean_expression_evaluator.go +++ b/pkg/application/boolean_expression_evaluator.go @@ -83,7 +83,12 @@ func (b *BooleanExpressionEvaluator) evaluateComparisonNode(node logical.Compari value = res dataType = util.GetDataType(value) } - return b.OperatorService.Evaluate(node.Operator, constant.PRIMITIVE, dataType, fieldData, value) + fieldDataType := util.GetDataType(fieldData) + values := []domain.EvaluatedNode{{ + Value: value, + DataType: dataType, + }} + return b.OperatorService.Evaluate(node.Operator, constant.PRIMITIVE, fieldData, fieldDataType, values) } func (b *BooleanExpressionEvaluator) resolveArrayElements(items []interface{}, data map[string]interface{}) []domain.EvaluatedNode { @@ -107,11 +112,20 @@ func (b *BooleanExpressionEvaluator) evaluateNumericRangeNode(node logical.Numer if fieldData == nil { return false, errors2.KEY_DATA_NOT_PRESENT } - leftRes, err := b.OperatorService.Evaluate(constant.GREATER_THAN_EQUAL, constant.PRIMITIVE, node.FromDataType, fieldData, node.FromValue) + dataType := util.GetDataType(fieldData) + fromValues := []domain.EvaluatedNode{{ + Value: node.FromValue, + DataType: node.FromDataType, + }} + leftRes, err := b.OperatorService.Evaluate(constant.GREATER_THAN_EQUAL, constant.PRIMITIVE, fieldData, dataType, fromValues) if err != nil { return false, err } - rightRes, err := b.OperatorService.Evaluate(constant.LESS_THAN_EQUAL, constant.PRIMITIVE, node.ToDataType, fieldData, node.ToValue) + toValues := []domain.EvaluatedNode{{ + Value: node.ToValue, + DataType: node.ToDataType, + }} + rightRes, err := b.OperatorService.Evaluate(constant.LESS_THAN_EQUAL, constant.PRIMITIVE, fieldData, dataType, toValues) if err != nil { return false, err } @@ -123,13 +137,16 @@ func (b *BooleanExpressionEvaluator) evaluateInNode(node logical.InNode, data ma if fieldData == nil { return false, errors2.KEY_DATA_NOT_PRESENT } + dataType := util.GetDataType(fieldData) items := b.resolveArrayElements(node.Items, data) - dataType := items[0].DataType - var values []interface{} + var values []domain.EvaluatedNode for _, item := range items { - values = append(values, item.Value) + values = append(values, domain.EvaluatedNode{ + Value: item.Value, + DataType: item.DataType, + }) } - res, err := b.OperatorService.Evaluate(constant.IN, constant.PRIMITIVE, dataType, fieldData, values...) + res, err := b.OperatorService.Evaluate(constant.IN, constant.PRIMITIVE, fieldData, dataType, values) if err != nil { return false, err } @@ -187,13 +204,16 @@ func (b *BooleanExpressionEvaluator) evaluateArrayNode(node logical.ArrayNode, d if fieldData == nil { return false, errors2.KEY_DATA_NOT_PRESENT } + dataType := util.GetDataType(fieldData) items := b.resolveArrayElements(node.Items, data) - var values []interface{} + var values []domain.EvaluatedNode for _, item := range items { - values = append(values, item.Value) + values = append(values, domain.EvaluatedNode{ + Value: item.Value, + DataType: item.DataType, + }) } - dataType := items[0].DataType - res, err := b.OperatorService.Evaluate(node.Operator, constant.LIST, dataType, fieldData, values...) + res, err := b.OperatorService.Evaluate(node.Operator, constant.LIST, fieldData, dataType, values) if err != nil { return false, err } diff --git a/pkg/application/boolean_expression_evaluator_test.go b/pkg/application/boolean_expression_evaluator_test.go index 8a9715a..eb55215 100644 --- a/pkg/application/boolean_expression_evaluator_test.go +++ b/pkg/application/boolean_expression_evaluator_test.go @@ -60,7 +60,7 @@ func TestInvalidDataType(t *testing.T) { } _, err := evaluator.Evaluate("name > 123", data) assert.NotNil(t, err) - assert.ErrorIs(t, err, errors2.INVALID_DATA_TYPE) + assert.ErrorIs(t, err, errors2.INCOMPATIBLE_DATA_TYPE) } func TestSimpleFalseIncorrectExpression(t *testing.T) { @@ -189,6 +189,24 @@ func TestNumericLessThanEqualIncorrectExpression(t *testing.T) { assert.False(t, res) } +func TestDifferentDataTypeComparison(t *testing.T) { + data := map[string]interface{}{ + "age": 26.3, + } + res, err := evaluator.Evaluate("age > 20", data) + assert.Nil(t, err) + assert.True(t, res) +} + +func TestDifferentDataTypeComparison1(t *testing.T) { + data := map[string]interface{}{ + "age": 26, + } + res, err := evaluator.Evaluate("age > 20.6", data) + assert.Nil(t, err) + assert.True(t, res) +} + func TestNumericNotEqualCorrectExpression(t *testing.T) { data := map[string]interface{}{ "age": 24, @@ -375,9 +393,9 @@ func TestWrongDataType1(t *testing.T) { data := map[string]interface{}{ "age": "sf", } - _, err := evaluator.Evaluate("age = 24", data) - assert.NotNil(t, err) - assert.ErrorIs(t, err, errors2.INVALID_DATA_TYPE) + res, err := evaluator.Evaluate("age = 24", data) + assert.Nil(t, err) + assert.False(t, res) } func TestKeyMissing(t *testing.T) { diff --git a/pkg/constant/data_type.go b/pkg/constant/data_type.go index ed6da20..6205b6d 100644 --- a/pkg/constant/data_type.go +++ b/pkg/constant/data_type.go @@ -10,3 +10,35 @@ const ( VERSION DataType = "VERSION" BOOLEAN DataType = "BOOL" ) + +type DataTypeAttribute struct { + Priority int + Numeric bool +} + +var DataTypeAttributes = map[DataType]DataTypeAttribute { + STRING: { + Priority: 6, + Numeric: false, + }, + INTEGER: { + Priority: 3, + Numeric: true, + }, + LONG: { + Priority: 4, + Numeric: true, + }, + DECIMAL: { + Priority: 5, + Numeric: true, + }, + VERSION: { + Priority: 2, + Numeric: true, + }, + BOOLEAN: { + Priority: 1, + Numeric: false, + }, +} diff --git a/pkg/error/errors.go b/pkg/error/errors.go index 46e0a67..d721840 100644 --- a/pkg/error/errors.go +++ b/pkg/error/errors.go @@ -10,4 +10,6 @@ var INVALID_UNARY_OPERAND = errors.New("invalid unary operand") var KEY_DATA_NOT_PRESENT = errors.New("key data not present") -var INVALID_EXPRESSION = errors.New("invalid expression") \ No newline at end of file +var INVALID_EXPRESSION = errors.New("invalid expression") + +var INCOMPATIBLE_DATA_TYPE = errors.New("incompatible data type")