Added support for 'ARRAY_CONTAINS', 'ARRAY_CONTAINS_ANY' and 'ARRAY_CONTAINS_ALL' functions

This commit is contained in:
Pijus Kamandulis
2024-12-26 20:27:59 +02:00
parent f5b8453995
commit 8e3db3e44d
9 changed files with 2025 additions and 1118 deletions

View File

@@ -4,6 +4,7 @@ import (
"testing"
"github.com/pikami/cosmium/parsers"
testutils "github.com/pikami/cosmium/test_utils"
)
func Test_Parse_ArrayFunctions(t *testing.T) {
@@ -36,6 +37,119 @@ func Test_Parse_ArrayFunctions(t *testing.T) {
)
})
t.Run("Should parse function ARRAY_CONTAINS()", func(t *testing.T) {
testQueryParse(
t,
`SELECT ARRAY_CONTAINS(c.a1, "value") FROM c`,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallArrayContains,
Arguments: []interface{}{
parsers.SelectItem{
Path: []string{"c", "a1"},
Type: parsers.SelectItemTypeField,
},
testutils.SelectItem_Constant_String("value"),
nil,
},
},
},
},
Table: parsers.Table{Value: "c"},
},
)
})
t.Run("Should parse function ARRAY_CONTAINS() with partial match", func(t *testing.T) {
testQueryParse(
t,
`SELECT ARRAY_CONTAINS(["a", "b"], "value", true) FROM c`,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallArrayContains,
Arguments: []interface{}{
parsers.SelectItem{
Type: parsers.SelectItemTypeArray,
SelectItems: []parsers.SelectItem{
testutils.SelectItem_Constant_String("a"),
testutils.SelectItem_Constant_String("b"),
},
},
testutils.SelectItem_Constant_String("value"),
testutils.SelectItem_Constant_Bool(true),
},
},
},
},
Table: parsers.Table{Value: "c"},
},
)
})
t.Run("Should parse function ARRAY_CONTAINS_ANY()", func(t *testing.T) {
testQueryParse(
t,
`SELECT ARRAY_CONTAINS_ANY(["a", "b"], "value", true) FROM c`,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallArrayContainsAny,
Arguments: []interface{}{
parsers.SelectItem{
Type: parsers.SelectItemTypeArray,
SelectItems: []parsers.SelectItem{
testutils.SelectItem_Constant_String("a"),
testutils.SelectItem_Constant_String("b"),
},
},
testutils.SelectItem_Constant_String("value"),
testutils.SelectItem_Constant_Bool(true),
},
},
},
},
Table: parsers.Table{Value: "c"},
},
)
})
t.Run("Should parse function ARRAY_CONTAINS_ALL()", func(t *testing.T) {
testQueryParse(
t,
`SELECT ARRAY_CONTAINS_ALL(["a", "b"], "value", true) FROM c`,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallArrayContainsAll,
Arguments: []interface{}{
parsers.SelectItem{
Type: parsers.SelectItemTypeArray,
SelectItems: []parsers.SelectItem{
testutils.SelectItem_Constant_String("a"),
testutils.SelectItem_Constant_String("b"),
},
},
testutils.SelectItem_Constant_String("value"),
testutils.SelectItem_Constant_Bool(true),
},
},
},
},
Table: parsers.Table{Value: "c"},
},
)
})
t.Run("Should parse function ARRAY_LENGTH()", func(t *testing.T) {
testQueryParse(
t,
@@ -75,20 +189,8 @@ func Test_Parse_ArrayFunctions(t *testing.T) {
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,
},
},
testutils.SelectItem_Constant_Int(0),
testutils.SelectItem_Constant_Int(2),
},
},
},

File diff suppressed because it is too large Load Diff

View File

@@ -457,6 +457,9 @@ AggregateFunctions <- AvgAggregateExpression
/ SumAggregateExpression
ArrayFunctions <- ArrayConcatExpression
/ ArrayContainsExpression
/ ArrayContainsAnyExpression
/ ArrayContainsAllExpression
/ ArrayLengthExpression
/ ArraySliceExpression
/ SetIntersectExpression
@@ -626,6 +629,18 @@ ArrayConcatExpression <- "ARRAY_CONCAT"i ws "(" ws arrays:SelectItem others:(ws
return createFunctionCall(parsers.FunctionCallArrayConcat, append([]interface{}{arrays}, others.([]interface{})...))
}
ArrayContainsExpression <- "ARRAY_CONTAINS"i ws "(" ws array:SelectItem ws "," ws item:SelectItem partialMatch:(ws "," ws ex:SelectItem { return ex, nil })? ws ")" {
return createFunctionCall(parsers.FunctionCallArrayContains, []interface{}{array, item, partialMatch})
}
ArrayContainsAnyExpression <- "ARRAY_CONTAINS_ANY"i ws "(" ws array:SelectItem items:(ws "," ws ex:SelectItem { return ex, nil })+ ws ")" {
return createFunctionCall(parsers.FunctionCallArrayContainsAny, append([]interface{}{array}, items.([]interface{})...))
}
ArrayContainsAllExpression <- "ARRAY_CONTAINS_ALL"i ws "(" ws array:SelectItem items:(ws "," ws ex:SelectItem { return ex, nil })+ ws ")" {
return createFunctionCall(parsers.FunctionCallArrayContainsAll, append([]interface{}{array}, items.([]interface{})...))
}
ArrayLengthExpression <- "ARRAY_LENGTH"i ws "(" ws array:SelectItem ws ")" {
return createFunctionCall(parsers.FunctionCallArrayLength, []interface{}{array})
}