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 |
|
| Function | Implemented |
|
||||||
| -------- | ----------- |
|
| -------- | ----------- |
|
||||||
| IIF | No |
|
| IIF | Yes |
|
||||||
|
|
||||||
### Date and time Functions
|
### Date and time Functions
|
||||||
|
|
||||||
|
@ -134,6 +134,8 @@ const (
|
|||||||
FunctionCallSetIntersect FunctionCallType = "SetIntersect"
|
FunctionCallSetIntersect FunctionCallType = "SetIntersect"
|
||||||
FunctionCallSetUnion FunctionCallType = "SetUnion"
|
FunctionCallSetUnion FunctionCallType = "SetUnion"
|
||||||
|
|
||||||
|
FunctionCallIif FunctionCallType = "Iif"
|
||||||
|
|
||||||
FunctionCallMathAbs FunctionCallType = "MathAbs"
|
FunctionCallMathAbs FunctionCallType = "MathAbs"
|
||||||
FunctionCallMathAcos FunctionCallType = "MathAcos"
|
FunctionCallMathAcos FunctionCallType = "MathAcos"
|
||||||
FunctionCallMathAsin FunctionCallType = "MathAsin"
|
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 "}" {
|
SelectObject <- "{" ws field:SelectObjectField ws other_fields:(ws "," ws coll:SelectObjectField {return coll, nil })* ws "}" {
|
||||||
return makeSelectObject(field, other_fields)
|
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 {
|
SelectObjectField <- name:(Identifier / "\"" key:Identifier "\"" { return key, nil }) ws ":" ws selectItem:SelectItem {
|
||||||
@ -442,6 +447,7 @@ BooleanLiteral <- ("true"i / "false"i) {
|
|||||||
FunctionCall <- StringFunctions
|
FunctionCall <- StringFunctions
|
||||||
/ TypeCheckingFunctions
|
/ TypeCheckingFunctions
|
||||||
/ ArrayFunctions
|
/ ArrayFunctions
|
||||||
|
/ ConditionalFunctions
|
||||||
/ InFunction
|
/ InFunction
|
||||||
/ AggregateFunctions
|
/ AggregateFunctions
|
||||||
/ MathFunctions
|
/ MathFunctions
|
||||||
@ -489,6 +495,8 @@ ArrayFunctions <- ArrayConcatExpression
|
|||||||
/ SetIntersectExpression
|
/ SetIntersectExpression
|
||||||
/ SetUnionExpression
|
/ SetUnionExpression
|
||||||
|
|
||||||
|
ConditionalFunctions <- IifExpression
|
||||||
|
|
||||||
MathFunctions <- MathAbsExpression
|
MathFunctions <- MathAbsExpression
|
||||||
/ MathAcosExpression
|
/ MathAcosExpression
|
||||||
/ MathAsinExpression
|
/ MathAsinExpression
|
||||||
@ -681,6 +689,10 @@ SetUnionExpression <- "SetUnion"i ws "(" ws set1:SelectItem ws "," ws set2:Selec
|
|||||||
return createFunctionCall(parsers.FunctionCallSetUnion, []interface{}{set1, set2})
|
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}) }
|
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}) }
|
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}) }
|
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:
|
case parsers.FunctionCallSetUnion:
|
||||||
return r.set_Union(functionCall.Arguments)
|
return r.set_Union(functionCall.Arguments)
|
||||||
|
|
||||||
|
case parsers.FunctionCallIif:
|
||||||
|
return r.misc_Iif(functionCall.Arguments)
|
||||||
|
|
||||||
case parsers.FunctionCallMathAbs:
|
case parsers.FunctionCallMathAbs:
|
||||||
return r.math_Abs(functionCall.Arguments)
|
return r.math_Abs(functionCall.Arguments)
|
||||||
case parsers.FunctionCallMathAcos:
|
case parsers.FunctionCallMathAcos:
|
||||||
|
@ -16,3 +16,16 @@ func (r rowContext) misc_In(arguments []interface{}) bool {
|
|||||||
|
|
||||||
return false
|
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