mirror of https://github.com/pikami/cosmium.git
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:
parent
2431307a12
commit
b29608e4c8
|
@ -81,14 +81,12 @@ type FunctionCallType string
|
|||
|
||||
const (
|
||||
FunctionCallStringEquals FunctionCallType = "StringEquals"
|
||||
FunctionCallIsDefined FunctionCallType = "IsDefined"
|
||||
FunctionCallConcat FunctionCallType = "Concat"
|
||||
FunctionCallContains FunctionCallType = "Contains"
|
||||
FunctionCallEndsWith FunctionCallType = "EndsWith"
|
||||
FunctionCallStartsWith FunctionCallType = "StartsWith"
|
||||
FunctionCallIndexOf FunctionCallType = "IndexOf"
|
||||
FunctionCallToString FunctionCallType = "ToString"
|
||||
FunctionCallIn FunctionCallType = "In"
|
||||
FunctionCallUpper FunctionCallType = "Upper"
|
||||
FunctionCallLower FunctionCallType = "Lower"
|
||||
FunctionCallLeft FunctionCallType = "Left"
|
||||
|
@ -101,6 +99,19 @@ const (
|
|||
FunctionCallRTrim FunctionCallType = "RTrim"
|
||||
FunctionCallSubstring FunctionCallType = "Substring"
|
||||
FunctionCallTrim FunctionCallType = "Trim"
|
||||
|
||||
FunctionCallIsDefined FunctionCallType = "IsDefined"
|
||||
FunctionCallIsArray FunctionCallType = "IsArray"
|
||||
FunctionCallIsBool FunctionCallType = "IsBool"
|
||||
FunctionCallIsFiniteNumber FunctionCallType = "IsFiniteNumber"
|
||||
FunctionCallIsInteger FunctionCallType = "IsInteger"
|
||||
FunctionCallIsNull FunctionCallType = "IsNull"
|
||||
FunctionCallIsNumber FunctionCallType = "IsNumber"
|
||||
FunctionCallIsObject FunctionCallType = "IsObject"
|
||||
FunctionCallIsPrimitive FunctionCallType = "IsPrimitive"
|
||||
FunctionCallIsString FunctionCallType = "IsString"
|
||||
|
||||
FunctionCallIn FunctionCallType = "In"
|
||||
)
|
||||
|
||||
type FunctionCall struct {
|
||||
|
|
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -214,8 +214,28 @@ func getFieldValue(field parsers.SelectItem, queryParameters map[string]interfac
|
|||
return strings_Substring(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallTrim:
|
||||
return strings_Trim(typedValue.Arguments, queryParameters, row)
|
||||
|
||||
case parsers.FunctionCallIsDefined:
|
||||
return typeChecking_IsDefined(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsArray:
|
||||
return typeChecking_IsArray(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsBool:
|
||||
return typeChecking_IsBool(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsFiniteNumber:
|
||||
return typeChecking_IsFiniteNumber(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsInteger:
|
||||
return typeChecking_IsInteger(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsNull:
|
||||
return typeChecking_IsNull(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsNumber:
|
||||
return typeChecking_IsNumber(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsObject:
|
||||
return typeChecking_IsObject(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsPrimitive:
|
||||
return typeChecking_IsPrimitive(typedValue.Arguments, queryParameters, row)
|
||||
case parsers.FunctionCallIsString:
|
||||
return typeChecking_IsString(typedValue.Arguments, queryParameters, row)
|
||||
|
||||
case parsers.FunctionCallIn:
|
||||
return misc_In(typedValue.Arguments, queryParameters, row)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package memoryexecutor
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/pikami/cosmium/parsers"
|
||||
)
|
||||
|
||||
|
@ -10,3 +12,85 @@ func typeChecking_IsDefined(arguments []interface{}, queryParameters map[string]
|
|||
|
||||
return ex != nil
|
||||
}
|
||||
|
||||
func typeChecking_IsArray(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
_, isArray := ex.([]interface{})
|
||||
return isArray
|
||||
}
|
||||
|
||||
func typeChecking_IsBool(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
_, isBool := ex.(bool)
|
||||
return isBool
|
||||
}
|
||||
|
||||
func typeChecking_IsFiniteNumber(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
switch num := ex.(type) {
|
||||
case int:
|
||||
return true
|
||||
case float64:
|
||||
return !math.IsInf(num, 0) && !math.IsNaN(num)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func typeChecking_IsInteger(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
_, isInt := ex.(int)
|
||||
return isInt
|
||||
}
|
||||
|
||||
func typeChecking_IsNull(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
return ex == nil
|
||||
}
|
||||
|
||||
func typeChecking_IsNumber(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
_, isFloat := ex.(float64)
|
||||
_, isInt := ex.(int)
|
||||
return isFloat || isInt
|
||||
}
|
||||
|
||||
func typeChecking_IsObject(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
_, isObject := ex.(map[string]interface{})
|
||||
return isObject
|
||||
}
|
||||
|
||||
func typeChecking_IsPrimitive(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
switch ex.(type) {
|
||||
case bool, string, float64, int, nil:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func typeChecking_IsString(arguments []interface{}, queryParameters map[string]interface{}, row RowType) bool {
|
||||
exItem := arguments[0].(parsers.SelectItem)
|
||||
ex := getFieldValue(exItem, queryParameters, row)
|
||||
|
||||
_, isStr := ex.(string)
|
||||
return isStr
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package memoryexecutor_test
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/pikami/cosmium/parsers"
|
||||
|
@ -9,9 +10,14 @@ import (
|
|||
|
||||
func Test_Execute_TypeCheckingFunctions(t *testing.T) {
|
||||
mockData := []memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "123", "pk": "aaa"},
|
||||
map[string]interface{}{"id": "456"},
|
||||
map[string]interface{}{"id": "789", "pk": ""},
|
||||
map[string]interface{}{"id": "1", "obj": nil},
|
||||
map[string]interface{}{"id": "2", "obj": "str"},
|
||||
map[string]interface{}{"id": "3", "obj": 1},
|
||||
map[string]interface{}{"id": "4", "obj": 1.2},
|
||||
map[string]interface{}{"id": "5", "obj": true},
|
||||
map[string]interface{}{"id": "6", "obj": []interface{}{1, 2, 3}},
|
||||
map[string]interface{}{"id": "7", "obj": map[string]interface{}{"a": "a"}},
|
||||
map[string]interface{}{"id": "8", "obj": math.Inf(1)},
|
||||
}
|
||||
|
||||
t.Run("Should execute function IS_DEFINED(path)", func(t *testing.T) {
|
||||
|
@ -21,13 +27,13 @@ func Test_Execute_TypeCheckingFunctions(t *testing.T) {
|
|||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "defined",
|
||||
Alias: "IsDefined",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsDefined,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "pk"},
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
|
@ -38,9 +44,338 @@ func Test_Execute_TypeCheckingFunctions(t *testing.T) {
|
|||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "123", "defined": true},
|
||||
map[string]interface{}{"id": "456", "defined": false},
|
||||
map[string]interface{}{"id": "789", "defined": true},
|
||||
map[string]interface{}{"id": "1", "IsDefined": false},
|
||||
map[string]interface{}{"id": "2", "IsDefined": true},
|
||||
map[string]interface{}{"id": "3", "IsDefined": true},
|
||||
map[string]interface{}{"id": "4", "IsDefined": true},
|
||||
map[string]interface{}{"id": "5", "IsDefined": true},
|
||||
map[string]interface{}{"id": "6", "IsDefined": true},
|
||||
map[string]interface{}{"id": "7", "IsDefined": true},
|
||||
map[string]interface{}{"id": "8", "IsDefined": true},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_ARRAY(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsArray",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsArray,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsArray": false},
|
||||
map[string]interface{}{"id": "2", "IsArray": false},
|
||||
map[string]interface{}{"id": "3", "IsArray": false},
|
||||
map[string]interface{}{"id": "4", "IsArray": false},
|
||||
map[string]interface{}{"id": "5", "IsArray": false},
|
||||
map[string]interface{}{"id": "6", "IsArray": true},
|
||||
map[string]interface{}{"id": "7", "IsArray": false},
|
||||
map[string]interface{}{"id": "8", "IsArray": false},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_BOOL(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsBool",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsBool,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsBool": false},
|
||||
map[string]interface{}{"id": "2", "IsBool": false},
|
||||
map[string]interface{}{"id": "3", "IsBool": false},
|
||||
map[string]interface{}{"id": "4", "IsBool": false},
|
||||
map[string]interface{}{"id": "5", "IsBool": true},
|
||||
map[string]interface{}{"id": "6", "IsBool": false},
|
||||
map[string]interface{}{"id": "7", "IsBool": false},
|
||||
map[string]interface{}{"id": "8", "IsBool": false},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_FINITENUMBER(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsFiniteNumber",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsFiniteNumber,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsFiniteNumber": false},
|
||||
map[string]interface{}{"id": "2", "IsFiniteNumber": false},
|
||||
map[string]interface{}{"id": "3", "IsFiniteNumber": true},
|
||||
map[string]interface{}{"id": "4", "IsFiniteNumber": true},
|
||||
map[string]interface{}{"id": "5", "IsFiniteNumber": false},
|
||||
map[string]interface{}{"id": "6", "IsFiniteNumber": false},
|
||||
map[string]interface{}{"id": "7", "IsFiniteNumber": false},
|
||||
map[string]interface{}{"id": "8", "IsFiniteNumber": false},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_INTEGER(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsInteger",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsInteger,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsInteger": false},
|
||||
map[string]interface{}{"id": "2", "IsInteger": false},
|
||||
map[string]interface{}{"id": "3", "IsInteger": true},
|
||||
map[string]interface{}{"id": "4", "IsInteger": false},
|
||||
map[string]interface{}{"id": "5", "IsInteger": false},
|
||||
map[string]interface{}{"id": "6", "IsInteger": false},
|
||||
map[string]interface{}{"id": "7", "IsInteger": false},
|
||||
map[string]interface{}{"id": "8", "IsInteger": false},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_NULL(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsNull",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsNull,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsNull": true},
|
||||
map[string]interface{}{"id": "2", "IsNull": false},
|
||||
map[string]interface{}{"id": "3", "IsNull": false},
|
||||
map[string]interface{}{"id": "4", "IsNull": false},
|
||||
map[string]interface{}{"id": "5", "IsNull": false},
|
||||
map[string]interface{}{"id": "6", "IsNull": false},
|
||||
map[string]interface{}{"id": "7", "IsNull": false},
|
||||
map[string]interface{}{"id": "8", "IsNull": false},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_NUMBER(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsNumber",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsNumber,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsNumber": false},
|
||||
map[string]interface{}{"id": "2", "IsNumber": false},
|
||||
map[string]interface{}{"id": "3", "IsNumber": true},
|
||||
map[string]interface{}{"id": "4", "IsNumber": true},
|
||||
map[string]interface{}{"id": "5", "IsNumber": false},
|
||||
map[string]interface{}{"id": "6", "IsNumber": false},
|
||||
map[string]interface{}{"id": "7", "IsNumber": false},
|
||||
map[string]interface{}{"id": "8", "IsNumber": true},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_OBJECT(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsObject",
|
||||
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"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsObject": false},
|
||||
map[string]interface{}{"id": "2", "IsObject": false},
|
||||
map[string]interface{}{"id": "3", "IsObject": false},
|
||||
map[string]interface{}{"id": "4", "IsObject": false},
|
||||
map[string]interface{}{"id": "5", "IsObject": false},
|
||||
map[string]interface{}{"id": "6", "IsObject": false},
|
||||
map[string]interface{}{"id": "7", "IsObject": true},
|
||||
map[string]interface{}{"id": "8", "IsObject": false},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_PRIMITIVE(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsPrimitive",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsPrimitive,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsPrimitive": true},
|
||||
map[string]interface{}{"id": "2", "IsPrimitive": true},
|
||||
map[string]interface{}{"id": "3", "IsPrimitive": true},
|
||||
map[string]interface{}{"id": "4", "IsPrimitive": true},
|
||||
map[string]interface{}{"id": "5", "IsPrimitive": true},
|
||||
map[string]interface{}{"id": "6", "IsPrimitive": false},
|
||||
map[string]interface{}{"id": "7", "IsPrimitive": false},
|
||||
map[string]interface{}{"id": "8", "IsPrimitive": true},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IS_STRING(path)", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{Path: []string{"c", "id"}},
|
||||
{
|
||||
Alias: "IsString",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIsString,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "obj"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "1", "IsString": false},
|
||||
map[string]interface{}{"id": "2", "IsString": true},
|
||||
map[string]interface{}{"id": "3", "IsString": false},
|
||||
map[string]interface{}{"id": "4", "IsString": false},
|
||||
map[string]interface{}{"id": "5", "IsString": false},
|
||||
map[string]interface{}{"id": "6", "IsString": false},
|
||||
map[string]interface{}{"id": "7", "IsString": false},
|
||||
map[string]interface{}{"id": "8", "IsString": false},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue