mirror of
https://github.com/pikami/cosmium.git
synced 2025-05-25 17:52:58 +01:00
Implement IIF function; Fix empty object select
This commit is contained in:
parent
30195fae96
commit
7e0c10479b
@ -79,7 +79,7 @@ Cosmium strives to support the core features of Cosmos DB, including:
|
||||
|
||||
| Function | Implemented |
|
||||
| -------- | ----------- |
|
||||
| IIF | No |
|
||||
| IIF | Yes |
|
||||
|
||||
### Date and time Functions
|
||||
|
||||
|
@ -134,6 +134,8 @@ const (
|
||||
FunctionCallSetIntersect FunctionCallType = "SetIntersect"
|
||||
FunctionCallSetUnion FunctionCallType = "SetUnion"
|
||||
|
||||
FunctionCallIif FunctionCallType = "Iif"
|
||||
|
||||
FunctionCallMathAbs FunctionCallType = "MathAbs"
|
||||
FunctionCallMathAcos FunctionCallType = "MathAcos"
|
||||
FunctionCallMathAsin FunctionCallType = "MathAsin"
|
||||
|
@ -163,4 +163,27 @@ func Test_Parse(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse IIF function", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IIF(true, c.pk, c.id) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIif,
|
||||
Arguments: []interface{}{
|
||||
testutils.SelectItem_Constant_Bool(true),
|
||||
testutils.SelectItem_Path("c", "pk"),
|
||||
testutils.SelectItem_Path("c", "id"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -289,6 +289,11 @@ SelectArray <- "[" ws columns:ColumnList ws "]" {
|
||||
|
||||
SelectObject <- "{" ws field:SelectObjectField ws other_fields:(ws "," ws coll:SelectObjectField {return coll, nil })* ws "}" {
|
||||
return makeSelectObject(field, other_fields)
|
||||
} / "{" ws "}" {
|
||||
return parsers.SelectItem{
|
||||
SelectItems: []parsers.SelectItem{},
|
||||
Type: parsers.SelectItemTypeObject,
|
||||
}, nil
|
||||
}
|
||||
|
||||
SelectObjectField <- name:(Identifier / "\"" key:Identifier "\"" { return key, nil }) ws ":" ws selectItem:SelectItem {
|
||||
@ -442,6 +447,7 @@ BooleanLiteral <- ("true"i / "false"i) {
|
||||
FunctionCall <- StringFunctions
|
||||
/ TypeCheckingFunctions
|
||||
/ ArrayFunctions
|
||||
/ ConditionalFunctions
|
||||
/ InFunction
|
||||
/ AggregateFunctions
|
||||
/ MathFunctions
|
||||
@ -489,6 +495,8 @@ ArrayFunctions <- ArrayConcatExpression
|
||||
/ SetIntersectExpression
|
||||
/ SetUnionExpression
|
||||
|
||||
ConditionalFunctions <- IifExpression
|
||||
|
||||
MathFunctions <- MathAbsExpression
|
||||
/ MathAcosExpression
|
||||
/ MathAsinExpression
|
||||
@ -681,6 +689,10 @@ SetUnionExpression <- "SetUnion"i ws "(" ws set1:SelectItem ws "," ws set2:Selec
|
||||
return createFunctionCall(parsers.FunctionCallSetUnion, []interface{}{set1, set2})
|
||||
}
|
||||
|
||||
IifExpression <- "IIF"i ws "(" ws condition:SelectItem ws "," ws trueValue:SelectItem ws "," ws falseValue:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIif, []interface{}{condition, trueValue, falseValue})
|
||||
}
|
||||
|
||||
MathAbsExpression <- "ABS"i ws "(" ws ex:SelectItem ws ")" { return createFunctionCall(parsers.FunctionCallMathAbs, []interface{}{ex}) }
|
||||
MathAcosExpression <- "ACOS"i ws "(" ws ex:SelectItem ws ")" { return createFunctionCall(parsers.FunctionCallMathAcos, []interface{}{ex}) }
|
||||
MathAsinExpression <- "ASIN"i ws "(" ws ex:SelectItem ws ")" { return createFunctionCall(parsers.FunctionCallMathAsin, []interface{}{ex}) }
|
||||
|
@ -178,4 +178,21 @@ func Test_Parse_Select(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse SELECT empty object", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT {} AS obj FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Alias: "obj",
|
||||
Type: parsers.SelectItemTypeObject,
|
||||
SelectItems: []parsers.SelectItem{},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -209,6 +209,9 @@ func (r rowContext) selectItem_SelectItemTypeFunctionCall(functionCall parsers.F
|
||||
case parsers.FunctionCallSetUnion:
|
||||
return r.set_Union(functionCall.Arguments)
|
||||
|
||||
case parsers.FunctionCallIif:
|
||||
return r.misc_Iif(functionCall.Arguments)
|
||||
|
||||
case parsers.FunctionCallMathAbs:
|
||||
return r.math_Abs(functionCall.Arguments)
|
||||
case parsers.FunctionCallMathAcos:
|
||||
|
@ -16,3 +16,16 @@ func (r rowContext) misc_In(arguments []interface{}) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (r rowContext) misc_Iif(arguments []interface{}) interface{} {
|
||||
if len(arguments) != 3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
condition := r.resolveSelectItem(arguments[0].(parsers.SelectItem))
|
||||
if condition != nil && condition == true {
|
||||
return r.resolveSelectItem(arguments[1].(parsers.SelectItem))
|
||||
}
|
||||
|
||||
return r.resolveSelectItem(arguments[2].(parsers.SelectItem))
|
||||
}
|
||||
|
@ -210,4 +210,35 @@ func Test_Execute(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IIF()", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
testutils.SelectItem_Path("c", "id"),
|
||||
{
|
||||
Alias: "coolness",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIif,
|
||||
Arguments: []interface{}{
|
||||
testutils.SelectItem_Path("c", "isCool"),
|
||||
testutils.SelectItem_Constant_String("real cool"),
|
||||
testutils.SelectItem_Constant_String("not cool"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "12345", "coolness": "not cool"},
|
||||
map[string]interface{}{"id": "67890", "coolness": "real cool"},
|
||||
map[string]interface{}{"id": "456", "coolness": "real cool"},
|
||||
map[string]interface{}{"id": "123", "coolness": "real cool"},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -205,4 +205,27 @@ func Test_Execute_Select(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute SELECT empty object", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Alias: "obj",
|
||||
Type: parsers.SelectItemTypeObject,
|
||||
SelectItems: []parsers.SelectItem{},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"obj": map[string]interface{}{}},
|
||||
map[string]interface{}{"obj": map[string]interface{}{}},
|
||||
map[string]interface{}{"obj": map[string]interface{}{}},
|
||||
map[string]interface{}{"obj": map[string]interface{}{}},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user