mirror of https://github.com/pikami/cosmium.git
Implement ARRAY_CONCAT, ARRAY_LENGTH, ARRAY_SLICE, SetIntersect, SetUnion functions
This commit is contained in:
parent
b29608e4c8
commit
1c5e5ce85d
|
@ -111,6 +111,12 @@ const (
|
|||
FunctionCallIsPrimitive FunctionCallType = "IsPrimitive"
|
||||
FunctionCallIsString FunctionCallType = "IsString"
|
||||
|
||||
FunctionCallArrayConcat FunctionCallType = "ArrayConcat"
|
||||
FunctionCallArrayLength FunctionCallType = "ArrayLength"
|
||||
FunctionCallArraySlice FunctionCallType = "ArraySlice"
|
||||
FunctionCallSetIntersect FunctionCallType = "SetIntersect"
|
||||
FunctionCallSetUnion FunctionCallType = "SetUnion"
|
||||
|
||||
FunctionCallIn FunctionCallType = "In"
|
||||
)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -312,19 +312,9 @@ BooleanLiteral <- ("true"i / "false"i) {
|
|||
|
||||
FunctionCall <- StringFunctions
|
||||
/ TypeCheckingFunctions
|
||||
/ ArrayFunctions
|
||||
/ InFunction
|
||||
|
||||
TypeCheckingFunctions <- IsDefined
|
||||
/ IsArray
|
||||
/ IsBool
|
||||
/ IsFiniteNumber
|
||||
/ IsInteger
|
||||
/ IsNull
|
||||
/ IsNumber
|
||||
/ IsObject
|
||||
/ IsPrimitive
|
||||
/ IsString
|
||||
|
||||
StringFunctions <- StringEqualsExpression
|
||||
/ ToStringExpression
|
||||
/ ConcatExpression
|
||||
|
@ -342,6 +332,23 @@ StringFunctions <- StringEqualsExpression
|
|||
/ SubstringExpression
|
||||
/ TrimExpression
|
||||
|
||||
TypeCheckingFunctions <- IsDefined
|
||||
/ IsArray
|
||||
/ IsBool
|
||||
/ IsFiniteNumber
|
||||
/ IsInteger
|
||||
/ IsNull
|
||||
/ IsNumber
|
||||
/ IsObject
|
||||
/ IsPrimitive
|
||||
/ IsString
|
||||
|
||||
ArrayFunctions <- ArrayConcatExpression
|
||||
/ ArrayLengthExpression
|
||||
/ ArraySliceExpression
|
||||
/ SetIntersectExpression
|
||||
/ SetUnionExpression
|
||||
|
||||
UpperExpression <- "UPPER"i ws "(" ex:SelectItem ")" {
|
||||
return createFunctionCall(parsers.FunctionCallUpper, []interface{}{ex})
|
||||
}
|
||||
|
@ -465,6 +472,26 @@ IsString <- "IS_STRING"i ws "(" ws ex:SelectItem ws ")" {
|
|||
return createFunctionCall(parsers.FunctionCallIsString, []interface{}{ex})
|
||||
}
|
||||
|
||||
ArrayConcatExpression <- "ARRAY_CONCAT"i ws "(" ws arrays:SelectItem others:(ws "," ws ex:SelectItem { return ex, nil })+ ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallArrayConcat, append([]interface{}{arrays}, others.([]interface{})...))
|
||||
}
|
||||
|
||||
ArrayLengthExpression <- "ARRAY_LENGTH"i ws "(" ws array:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallArrayLength, []interface{}{array})
|
||||
}
|
||||
|
||||
ArraySliceExpression <- "ARRAY_SLICE"i ws "(" ws array:SelectItem ws "," ws start:SelectItem length:(ws "," ws ex:SelectItem { return ex, nil })? ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallArraySlice, []interface{}{array, start, length})
|
||||
}
|
||||
|
||||
SetIntersectExpression <- "SetIntersect"i ws "(" ws set1:SelectItem ws "," ws set2:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallSetIntersect, []interface{}{set1, set2})
|
||||
}
|
||||
|
||||
SetUnionExpression <- "SetUnion"i ws "(" ws set1:SelectItem ws "," ws set2:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallSetUnion, []interface{}{set1, set2})
|
||||
}
|
||||
|
||||
InFunction <- ex1:SelectProperty ws "IN"i ws "(" ws ex2:SelectItem others:(ws "," ws ex:SelectItem { return ex, nil })* ws ")" {
|
||||
arguments := append([]interface{}{ex1, ex2}, others.([]interface{})...)
|
||||
return parsers.FunctionCall{Type: parsers.FunctionCallIn, Arguments: arguments}, nil
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
package nosql_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/pikami/cosmium/parsers"
|
||||
)
|
||||
|
||||
func Test_Parse_ArrayFunctions(t *testing.T) {
|
||||
|
||||
t.Run("Should parse function ARRAY_CONCAT()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT ARRAY_CONCAT(c.a1, c.a2) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallArrayConcat,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "a1"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "a2"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function ARRAY_LENGTH()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT ARRAY_LENGTH(c.array) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallArrayLength,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "array"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function ARRAY_SLICE()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT ARRAY_SLICE(c.array, 0, 2) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallArraySlice,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "array"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 0,
|
||||
},
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function SetIntersect()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT SetIntersect(c.set1, c.set2) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallSetIntersect,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "set1"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "set2"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function SetUnion()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT SetUnion(c.set1, c.set2) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallSetUnion,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "set1"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "set2"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package memoryexecutor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/pikami/cosmium/parsers"
|
||||
)
|
||||
|
||||
func array_Concat(arguments []interface{}, queryParameters map[string]interface{}, row RowType) []interface{} {
|
||||
var result []interface{}
|
||||
for _, arg := range arguments {
|
||||
array := parseArray(arg, queryParameters, row)
|
||||
result = append(result, array...)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func array_Length(arguments []interface{}, queryParameters map[string]interface{}, row RowType) int {
|
||||
array := parseArray(arguments[0], queryParameters, row)
|
||||
if array == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return len(array)
|
||||
}
|
||||
|
||||
func array_Slice(arguments []interface{}, queryParameters map[string]interface{}, row RowType) []interface{} {
|
||||
var ok bool
|
||||
var start int
|
||||
var length int
|
||||
array := parseArray(arguments[0], queryParameters, row)
|
||||
startEx := getFieldValue(arguments[1].(parsers.SelectItem), queryParameters, row)
|
||||
|
||||
if arguments[2] != nil {
|
||||
lengthEx := getFieldValue(arguments[2].(parsers.SelectItem), queryParameters, row)
|
||||
|
||||
if length, ok = lengthEx.(int); !ok {
|
||||
fmt.Println("array_Slice - got length parameters of wrong type")
|
||||
return []interface{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if start, ok = startEx.(int); !ok {
|
||||
fmt.Println("array_Slice - got start parameters of wrong type")
|
||||
return []interface{}{}
|
||||
}
|
||||
|
||||
if start < 0 {
|
||||
start = len(array) + start
|
||||
}
|
||||
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
|
||||
if array == nil || start >= len(array) {
|
||||
return []interface{}{}
|
||||
}
|
||||
|
||||
end := start + length
|
||||
if end > len(array) {
|
||||
end = len(array)
|
||||
}
|
||||
return array[start:end]
|
||||
}
|
||||
|
||||
func set_Intersect(arguments []interface{}, queryParameters map[string]interface{}, row RowType) []interface{} {
|
||||
set1 := parseArray(arguments[0], queryParameters, row)
|
||||
set2 := parseArray(arguments[1], queryParameters, row)
|
||||
|
||||
intersection := make(map[interface{}]struct{})
|
||||
if set1 == nil || set2 == nil {
|
||||
return []interface{}{}
|
||||
}
|
||||
|
||||
for _, item := range set1 {
|
||||
intersection[item] = struct{}{}
|
||||
}
|
||||
|
||||
var result []interface{}
|
||||
for _, item := range set2 {
|
||||
if _, exists := intersection[item]; exists {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func set_Union(arguments []interface{}, queryParameters map[string]interface{}, row RowType) []interface{} {
|
||||
set1 := parseArray(arguments[0], queryParameters, row)
|
||||
set2 := parseArray(arguments[1], queryParameters, row)
|
||||
|
||||
var result []interface{}
|
||||
union := make(map[interface{}]struct{})
|
||||
for _, item := range set1 {
|
||||
if _, ok := union[item]; !ok {
|
||||
union[item] = struct{}{}
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
for _, item := range set2 {
|
||||
if _, ok := union[item]; !ok {
|
||||
union[item] = struct{}{}
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func parseArray(argument interface{}, queryParameters map[string]interface{}, row RowType) []interface{} {
|
||||
exItem := argument.(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
arrValue := reflect.ValueOf(ex)
|
||||
if arrValue.Kind() != reflect.Slice {
|
||||
fmt.Println("parseArray got parameters of wrong type")
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]interface{}, arrValue.Len())
|
||||
|
||||
for i := 0; i < arrValue.Len(); i++ {
|
||||
result[i] = arrValue.Index(i).Interface()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
package memoryexecutor_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/pikami/cosmium/parsers"
|
||||
memoryexecutor "github.com/pikami/cosmium/query_executors/memory_executor"
|
||||
)
|
||||
|
||||
func Test_Execute_ArrayFunctions(t *testing.T) {
|
||||
mockData := []memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "123", "arr1": []int{1, 2, 3}, "arr2": []int{3, 4, 5}},
|
||||
map[string]interface{}{"id": "456", "arr1": []int{4, 5, 6}, "arr2": []int{5, 6, 7, 8}},
|
||||
map[string]interface{}{"id": "789", "arr1": []int{7, 8, 9}, "arr2": []int{7, 8, 9, 10, 11}},
|
||||
}
|
||||
|
||||
t.Run("Should execute function CONCAT()", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
{
|
||||
Alias: "Concat",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallArrayConcat,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr1"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr2"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "123", "Concat": []interface{}{1, 2, 3, 3, 4, 5}},
|
||||
map[string]interface{}{"id": "456", "Concat": []interface{}{4, 5, 6, 5, 6, 7, 8}},
|
||||
map[string]interface{}{"id": "789", "Concat": []interface{}{7, 8, 9, 7, 8, 9, 10, 11}},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function ARRAY_LENGTH()", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
{
|
||||
Alias: "Length",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallArrayLength,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr2"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "123", "Length": 3},
|
||||
map[string]interface{}{"id": "456", "Length": 4},
|
||||
map[string]interface{}{"id": "789", "Length": 5},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function ARRAY_SLICE()", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
{
|
||||
Alias: "Slice",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallArraySlice,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr2"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "123", "Slice": []interface{}{4, 5}},
|
||||
map[string]interface{}{"id": "456", "Slice": []interface{}{6, 7}},
|
||||
map[string]interface{}{"id": "789", "Slice": []interface{}{8, 9}},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function SET_INTERSECT()", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
{
|
||||
Alias: "Intersection",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallSetIntersect,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr1"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr2"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "123", "Intersection": []interface{}{3}},
|
||||
map[string]interface{}{"id": "456", "Intersection": []interface{}{5, 6}},
|
||||
map[string]interface{}{"id": "789", "Intersection": []interface{}{7, 8, 9}},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function SET_UNION()", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
{
|
||||
Alias: "Union",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallSetUnion,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr1"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr2"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "123", "Union": []interface{}{1, 2, 3, 4, 5}},
|
||||
map[string]interface{}{"id": "456", "Union": []interface{}{4, 5, 6, 7, 8}},
|
||||
map[string]interface{}{"id": "789", "Union": []interface{}{7, 8, 9, 10, 11}},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
|
@ -236,6 +236,17 @@ func getFieldValue(field parsers.SelectItem, queryParameters map[string]interfac
|
|||
case parsers.FunctionCallIsString:
|
||||
return typeChecking_IsString(typedValue.Arguments, queryParameters, row)
|
||||
|
||||
case parsers.FunctionCallArrayConcat:
|
||||
return array_Concat(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallArrayLength:
|
||||
return array_Length(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallArraySlice:
|
||||
return array_Slice(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallSetIntersect:
|
||||
return set_Intersect(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallSetUnion:
|
||||
return set_Union(typedValue.Arguments, queryParameters, row)
|
||||
|
||||
case parsers.FunctionCallIn:
|
||||
return misc_In(typedValue.Arguments, queryParameters, row)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue