mirror of
https://github.com/pikami/cosmium.git
synced 2025-12-19 17:00:37 +00:00
Implement ARRAY_CONCAT, ARRAY_LENGTH, ARRAY_SLICE, SetIntersect, SetUnion functions
This commit is contained 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
|
||||
|
||||
156
parsers/nosql/nosql_array_functions_test.go
Normal file
156
parsers/nosql/nosql_array_functions_test.go
Normal file
@@ -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"},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user