|
@@ -15,8 +15,16 @@
|
|
package function
|
|
package function
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
+ "fmt"
|
|
|
|
+
|
|
"github.com/lf-edge/ekuiper/pkg/api"
|
|
"github.com/lf-edge/ekuiper/pkg/api"
|
|
"github.com/lf-edge/ekuiper/pkg/ast"
|
|
"github.com/lf-edge/ekuiper/pkg/ast"
|
|
|
|
+ "github.com/lf-edge/ekuiper/pkg/cast"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+var (
|
|
|
|
+ errorArrayArgumentError = fmt.Errorf("first argument should be array of interface{}")
|
|
|
|
+ errorArrayIndex = fmt.Errorf("index out of range")
|
|
)
|
|
)
|
|
|
|
|
|
func registerArrayFunc() {
|
|
func registerArrayFunc() {
|
|
@@ -29,4 +37,75 @@ func registerArrayFunc() {
|
|
return nil
|
|
return nil
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
+ builtins["array_position"] = builtinFunc{
|
|
|
|
+ fType: ast.FuncTypeScalar,
|
|
|
|
+ exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
|
|
|
|
+ array, ok := args[0].([]interface{})
|
|
|
|
+ if !ok {
|
|
|
|
+ return errorArrayArgumentError, false
|
|
|
|
+ }
|
|
|
|
+ for i, item := range array {
|
|
|
|
+ if item == args[1] {
|
|
|
|
+ return i + 1, true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return 0, true
|
|
|
|
+ },
|
|
|
|
+ val: func(ctx api.FunctionContext, args []ast.Expr) error {
|
|
|
|
+ return ValidateLen(2, len(args))
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ builtins["element_at"] = builtinFunc{
|
|
|
|
+ fType: ast.FuncTypeScalar,
|
|
|
|
+ exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
|
|
|
|
+ switch args[0].(type) {
|
|
|
|
+ case []interface{}:
|
|
|
|
+ array := args[0].([]interface{})
|
|
|
|
+ index, err := cast.ToInt(args[1], cast.STRICT)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err, false
|
|
|
|
+ }
|
|
|
|
+ if index == 0 {
|
|
|
|
+ return fmt.Errorf("index should be larger or smaller than 0"), false
|
|
|
|
+ }
|
|
|
|
+ if index-1 >= len(array) || (-index)-1 >= len(array) {
|
|
|
|
+ return errorArrayIndex, false
|
|
|
|
+ }
|
|
|
|
+ if index > 0 {
|
|
|
|
+ return array[index-1], true
|
|
|
|
+ }
|
|
|
|
+ return array[len(array)+index], true
|
|
|
|
+ case map[string]interface{}:
|
|
|
|
+ m := args[0].(map[string]interface{})
|
|
|
|
+ key, ok := args[1].(string)
|
|
|
|
+ if !ok {
|
|
|
|
+ return fmt.Errorf("second argument should be string"), false
|
|
|
|
+ }
|
|
|
|
+ return m[key], true
|
|
|
|
+ default:
|
|
|
|
+ return fmt.Errorf("first argument should be []interface{} or map[string]interface{}"), false
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ val: func(ctx api.FunctionContext, args []ast.Expr) error {
|
|
|
|
+ return ValidateLen(2, len(args))
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ builtins["array_contains"] = builtinFunc{
|
|
|
|
+ fType: ast.FuncTypeScalar,
|
|
|
|
+ exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
|
|
|
|
+ array, ok := args[0].([]interface{})
|
|
|
|
+ if !ok {
|
|
|
|
+ return errorArrayArgumentError, false
|
|
|
|
+ }
|
|
|
|
+ for _, item := range array {
|
|
|
|
+ if item == args[1] {
|
|
|
|
+ return true, true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false, true
|
|
|
|
+ },
|
|
|
|
+ val: func(ctx api.FunctionContext, args []ast.Expr) error {
|
|
|
|
+ return ValidateLen(2, len(args))
|
|
|
|
+ },
|
|
|
|
+ }
|
|
}
|
|
}
|