feat: sql expressions always return a value, along with the correct error types

Signed-off-by: Calum Murray <cmurray@redhat.com>
This commit is contained in:
Calum Murray 2024-06-13 15:38:28 -04:00
parent 9a191207f0
commit 1f881a4c26
No known key found for this signature in database
GPG Key ID: D9837BD1D90C1512
4 changed files with 21 additions and 15 deletions

View File

@ -9,6 +9,7 @@ import (
"fmt" "fmt"
cesql "github.com/cloudevents/sdk-go/sql/v2" 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/runtime"
"github.com/cloudevents/sdk-go/sql/v2/utils" "github.com/cloudevents/sdk-go/sql/v2/utils"
cloudevents "github.com/cloudevents/sdk-go/v2" cloudevents "github.com/cloudevents/sdk-go/v2"
@ -22,7 +23,7 @@ type functionInvocationExpression struct {
func (expr functionInvocationExpression) Evaluate(event cloudevents.Event) (interface{}, error) { func (expr functionInvocationExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
fn := runtime.ResolveFunction(expr.name, len(expr.argumentsExpression)) fn := runtime.ResolveFunction(expr.name, len(expr.argumentsExpression))
if fn == nil { 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)) args := make([]interface{}, len(expr.argumentsExpression))
@ -37,7 +38,7 @@ func (expr functionInvocationExpression) Evaluate(event cloudevents.Event) (inte
argType := fn.ArgType(i) argType := fn.ArgType(i)
if argType == nil { 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) arg, err = utils.Cast(arg, *argType)
@ -50,8 +51,15 @@ func (expr functionInvocationExpression) Evaluate(event cloudevents.Event) (inte
result, err := fn.Run(event, args) result, err := fn.Run(event, args)
if result == nil { 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 defaultVal, err
} }
return result, err return result, err
} }

View File

@ -6,9 +6,8 @@
package expression package expression
import ( import (
"fmt"
cesql "github.com/cloudevents/sdk-go/sql/v2" 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" "github.com/cloudevents/sdk-go/sql/v2/utils"
cloudevents "github.com/cloudevents/sdk-go/v2" cloudevents "github.com/cloudevents/sdk-go/v2"
) )
@ -20,7 +19,7 @@ type identifierExpression struct {
func (l identifierExpression) Evaluate(event cloudevents.Event) (interface{}, error) { func (l identifierExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
value := utils.GetAttribute(event, l.identifier) value := utils.GetAttribute(event, l.identifier)
if value == nil { if value == nil {
return nil, fmt.Errorf("missing attribute '%s'", l.identifier) return false, sqlerrors.NewMissingAttributeError(l.identifier)
} }
return value, nil return value, nil

View File

@ -6,9 +6,8 @@
package expression package expression
import ( import (
"errors"
cesql "github.com/cloudevents/sdk-go/sql/v2" 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" "github.com/cloudevents/sdk-go/sql/v2/utils"
cloudevents "github.com/cloudevents/sdk-go/v2" cloudevents "github.com/cloudevents/sdk-go/v2"
) )
@ -21,22 +20,22 @@ type mathExpression struct {
func (s mathExpression) Evaluate(event cloudevents.Event) (interface{}, error) { func (s mathExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
leftVal, err := s.left.Evaluate(event) leftVal, err := s.left.Evaluate(event)
if err != nil { if err != nil {
return 0, err return int32(0), err
} }
rightVal, err := s.right.Evaluate(event) rightVal, err := s.right.Evaluate(event)
if err != nil { if err != nil {
return 0, err return int32(0), err
} }
leftVal, err = utils.Cast(leftVal, cesql.IntegerType) leftVal, err = utils.Cast(leftVal, cesql.IntegerType)
if err != nil { if err != nil {
return 0, err return int32(0), err
} }
rightVal, err = utils.Cast(rightVal, cesql.IntegerType) rightVal, err = utils.Cast(rightVal, cesql.IntegerType)
if err != nil { if err != nil {
return 0, err return int32(0), err
} }
return s.fn(leftVal.(int32), rightVal.(int32)) 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) { fn: func(x, y int32) (int32, error) {
if y == 0 { if y == 0 {
return 0, errors.New("math error: division by zero") return 0, sqlerrors.NewMathError("division by zero")
} }
return x % y, nil return x % y, nil
}, },
@ -101,7 +100,7 @@ func NewDivisionExpression(left cesql.Expression, right cesql.Expression) cesql.
}, },
fn: func(x, y int32) (int32, error) { fn: func(x, y int32) (int32, error) {
if y == 0 { if y == 0 {
return 0, errors.New("math error: division by zero") return 0, sqlerrors.NewMathError("division by zero")
} }
return x / y, nil return x / y, nil
}, },

View File

@ -16,12 +16,12 @@ type negateExpression baseUnaryExpression
func (l negateExpression) Evaluate(event cloudevents.Event) (interface{}, error) { func (l negateExpression) Evaluate(event cloudevents.Event) (interface{}, error) {
val, err := l.child.Evaluate(event) val, err := l.child.Evaluate(event)
if err != nil { if err != nil {
return 0, err return int32(0), err
} }
val, err = utils.Cast(val, cesql.IntegerType) val, err = utils.Cast(val, cesql.IntegerType)
if err != nil { if err != nil {
return 0, err return int32(0), err
} }
return -(val.(int32)), nil return -(val.(int32)), nil