mirror of
https://github.com/pikami/cosmium.git
synced 2025-12-19 17:00:37 +00:00
Implement IS_ARRAY, IS_BOOL, IS_FINITE_NUMBER, IS_INTEGER, IS_NULL, IS_NUMBER, IS_OBJECT, IS_PRIMITIVE, IS_STRING functions
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -310,7 +310,20 @@ BooleanLiteral <- ("true"i / "false"i) {
|
||||
return parsers.Constant{Type: parsers.ConstantTypeBoolean, Value: boolValue}, nil
|
||||
}
|
||||
|
||||
FunctionCall <- StringFunctions / IsDefined / InFunction
|
||||
FunctionCall <- StringFunctions
|
||||
/ TypeCheckingFunctions
|
||||
/ InFunction
|
||||
|
||||
TypeCheckingFunctions <- IsDefined
|
||||
/ IsArray
|
||||
/ IsBool
|
||||
/ IsFiniteNumber
|
||||
/ IsInteger
|
||||
/ IsNull
|
||||
/ IsNumber
|
||||
/ IsObject
|
||||
/ IsPrimitive
|
||||
/ IsString
|
||||
|
||||
StringFunctions <- StringEqualsExpression
|
||||
/ ToStringExpression
|
||||
@@ -413,7 +426,43 @@ ThreeArgumentStringFunction <- ("CONTAINS"i / "ENDSWITH"i / "STARTSWITH"i / "IND
|
||||
}
|
||||
|
||||
IsDefined <- "IS_DEFINED"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return parsers.FunctionCall{Type: parsers.FunctionCallIsDefined, Arguments: []interface{}{ex}}, nil
|
||||
return createFunctionCall(parsers.FunctionCallIsDefined, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsArray <- "IS_ARRAY"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsArray, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsBool <- "IS_BOOL"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsBool, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsFiniteNumber <- "IS_FINITE_NUMBER"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsFiniteNumber, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsInteger <- "IS_INTEGER"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsInteger, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsNull <- "IS_NULL"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsNull, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsNumber <- "IS_NUMBER"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsNumber, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsObject <- "IS_OBJECT"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsObject, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsPrimitive <- "IS_PRIMITIVE"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsPrimitive, []interface{}{ex})
|
||||
}
|
||||
|
||||
IsString <- "IS_STRING"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIsString, []interface{}{ex})
|
||||
}
|
||||
|
||||
InFunction <- ex1:SelectProperty ws "IN"i ws "(" ws ex2:SelectItem others:(ws "," ws ex:SelectItem { return ex, nil })* ws ")" {
|
||||
|
||||
@@ -43,4 +43,328 @@ func Test_Execute_TypeCheckingFunctions(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_ARRAY", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_ARRAY(c.arr) FROM c WHERE IS_ARRAY(c.arr)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsArray,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsArray,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "arr"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_BOOL", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_BOOL(c.flag) FROM c WHERE IS_BOOL(c.flag)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsBool,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "flag"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsBool,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "flag"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_FINITE_NUMBER", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_FINITE_NUMBER(c.value) FROM c WHERE IS_FINITE_NUMBER(c.amount)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsFiniteNumber,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsFiniteNumber,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "amount"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_INTEGER", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_INTEGER(c.number) FROM c WHERE IS_INTEGER(c.number)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsInteger,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "number"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsInteger,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "number"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_NULL", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_NULL(c.value) FROM c WHERE IS_NULL(c.value)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsNull,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsNull,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_NUMBER", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_NUMBER(c.value) FROM c WHERE IS_NUMBER(c.value)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsNumber,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsNumber,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_OBJECT", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_OBJECT(c.obj) FROM c WHERE IS_OBJECT(c.obj)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsObject,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsObject,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_PRIMITIVE", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_PRIMITIVE(c.value) FROM c WHERE IS_PRIMITIVE(c.value)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsPrimitive,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsPrimitive,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function IS_STRING", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IS_STRING(c.value) FROM c WHERE IS_STRING(c.value)`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsString,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
Filters: parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsString,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "value"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user