From 1f881a4c261ef6acf775c6650a1414c3387bc1ce Mon Sep 17 00:00:00 2001 From: Calum Murray Date: Thu, 13 Jun 2024 15:38:28 -0400 Subject: [PATCH] feat: sql expressions always return a value, along with the correct error types Signed-off-by: Calum Murray --- .../expression/function_invocation_expression.go | 12 ++++++++++-- sql/v2/expression/identifier_expression.go | 5 ++--- sql/v2/expression/math_expressions.go | 15 +++++++-------- sql/v2/expression/negate_expression.go | 4 ++-- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/sql/v2/expression/function_invocation_expression.go b/sql/v2/expression/function_invocation_expression.go index 63811453..577272f2 100644 --- a/sql/v2/expression/function_invocation_expression.go +++ b/sql/v2/expression/function_invocation_expression.go @@ -9,6 +9,7 @@ import ( "fmt" cesql "github.com/cloudevents/sdk-go/sql/v2" + sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors" "github.com/cloudevents/sdk-go/sql/v2/runtime" "github.com/cloudevents/sdk-go/sql/v2/utils" cloudevents "github.com/cloudevents/sdk-go/v2" @@ -22,7 +23,7 @@ type functionInvocationExpression struct { func (expr functionInvocationExpression) Evaluate(event cloudevents.Event) (interface{}, error) { fn := runtime.ResolveFunction(expr.name, len(expr.argumentsExpression)) if fn == nil { - return false, fmt.Errorf("cannot resolve function %s", expr.name) + return false, sqlerrors.NewMissingFunctionError(expr.name) } args := make([]interface{}, len(expr.argumentsExpression)) @@ -37,7 +38,7 @@ func (expr functionInvocationExpression) Evaluate(event cloudevents.Event) (inte argType := fn.ArgType(i) if argType == nil { - return defaultVal, fmt.Errorf("cannot resolve arg type at index %d", i) + return defaultVal, sqlerrors.NewFunctionEvaluationError(fmt.Errorf("cannot resolve arg type at index %d for function %s", i, fn.Name())) } arg, err = utils.Cast(arg, *argType) @@ -50,8 +51,15 @@ func (expr functionInvocationExpression) Evaluate(event cloudevents.Event) (inte result, err := fn.Run(event, args) if result == nil { + if err != nil { + err = sqlerrors.NewFunctionEvaluationError(fmt.Errorf("function %s encountered error %w and did not return any value, defaulting to the default value for the function", fn.Name(), err)) + } else { + err = sqlerrors.NewFunctionEvaluationError(fmt.Errorf("function %s did not return any value, defaulting to the default value for the function", fn.Name())) + } + return defaultVal, err } + return result, err } diff --git a/sql/v2/expression/identifier_expression.go b/sql/v2/expression/identifier_expression.go index 265a3b46..fe85052f 100644 --- a/sql/v2/expression/identifier_expression.go +++ b/sql/v2/expression/identifier_expression.go @@ -6,9 +6,8 @@ package expression import ( - "fmt" - cesql "github.com/cloudevents/sdk-go/sql/v2" + sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors" "github.com/cloudevents/sdk-go/sql/v2/utils" cloudevents "github.com/cloudevents/sdk-go/v2" ) @@ -20,7 +19,7 @@ type identifierExpression struct { func (l identifierExpression) Evaluate(event cloudevents.Event) (interface{}, error) { value := utils.GetAttribute(event, l.identifier) if value == nil { - return nil, fmt.Errorf("missing attribute '%s'", l.identifier) + return false, sqlerrors.NewMissingAttributeError(l.identifier) } return value, nil diff --git a/sql/v2/expression/math_expressions.go b/sql/v2/expression/math_expressions.go index bce24944..50b45d70 100644 --- a/sql/v2/expression/math_expressions.go +++ b/sql/v2/expression/math_expressions.go @@ -6,9 +6,8 @@ package expression import ( - "errors" - cesql "github.com/cloudevents/sdk-go/sql/v2" + sqlerrors "github.com/cloudevents/sdk-go/sql/v2/errors" "github.com/cloudevents/sdk-go/sql/v2/utils" cloudevents "github.com/cloudevents/sdk-go/v2" ) @@ -21,22 +20,22 @@ type mathExpression struct { func (s mathExpression) Evaluate(event cloudevents.Event) (interface{}, error) { leftVal, err := s.left.Evaluate(event) if err != nil { - return 0, err + return int32(0), err } rightVal, err := s.right.Evaluate(event) if err != nil { - return 0, err + return int32(0), err } leftVal, err = utils.Cast(leftVal, cesql.IntegerType) if err != nil { - return 0, err + return int32(0), err } rightVal, err = utils.Cast(rightVal, cesql.IntegerType) if err != nil { - return 0, err + return int32(0), err } return s.fn(leftVal.(int32), rightVal.(int32)) @@ -86,7 +85,7 @@ func NewModuleExpression(left cesql.Expression, right cesql.Expression) cesql.Ex }, fn: func(x, y int32) (int32, error) { if y == 0 { - return 0, errors.New("math error: division by zero") + return 0, sqlerrors.NewMathError("division by zero") } return x % y, nil }, @@ -101,7 +100,7 @@ func NewDivisionExpression(left cesql.Expression, right cesql.Expression) cesql. }, fn: func(x, y int32) (int32, error) { if y == 0 { - return 0, errors.New("math error: division by zero") + return 0, sqlerrors.NewMathError("division by zero") } return x / y, nil }, diff --git a/sql/v2/expression/negate_expression.go b/sql/v2/expression/negate_expression.go index 29bd0de9..d271f324 100644 --- a/sql/v2/expression/negate_expression.go +++ b/sql/v2/expression/negate_expression.go @@ -16,12 +16,12 @@ type negateExpression baseUnaryExpression func (l negateExpression) Evaluate(event cloudevents.Event) (interface{}, error) { val, err := l.child.Evaluate(event) if err != nil { - return 0, err + return int32(0), err } val, err = utils.Cast(val, cesql.IntegerType) if err != nil { - return 0, err + return int32(0), err } return -(val.(int32)), nil