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:
Pijus Kamandulis
2024-02-24 22:29:33 +02:00
parent 2431307a12
commit b29608e4c8
7 changed files with 1789 additions and 368 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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 ")" {

View File

@@ -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,
},
},
},
},
},
)
})
}