mirror of
https://github.com/pikami/cosmium.git
synced 2025-12-19 17:00:37 +00:00
Implement LEFT,LENGTH,LTRIM,REPLACE,REPLICATE,REVERSE,RIGHT,RTRIM,SUBSTRING,TRIM functions
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -107,6 +107,10 @@ func makeOrderExpression(field interface{}, order interface{}) (parsers.OrderExp
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func createFunctionCall(functionType parsers.FunctionCallType, arguments []interface{}) (parsers.FunctionCall, error) {
|
||||
return parsers.FunctionCall{Type: functionType, Arguments: arguments}, nil
|
||||
}
|
||||
|
||||
func joinStrings(array []interface{}) string {
|
||||
var stringsArray []string
|
||||
for _, elem := range array {
|
||||
@@ -314,26 +318,76 @@ StringFunctions <- StringEqualsExpression
|
||||
/ ThreeArgumentStringFunctionExpression
|
||||
/ UpperExpression
|
||||
/ LowerExpression
|
||||
/ LeftExpression
|
||||
/ LengthExpression
|
||||
/ LTrimExpression
|
||||
/ ReplaceExpression
|
||||
/ ReplicateExpression
|
||||
/ ReverseExpression
|
||||
/ RightExpression
|
||||
/ RTrimExpression
|
||||
/ SubstringExpression
|
||||
/ TrimExpression
|
||||
|
||||
UpperExpression <- "UPPER"i ws "(" ex:SelectItem ")" {
|
||||
return parsers.FunctionCall{Type: parsers.FunctionCallUpper, Arguments: []interface{}{ex}}, nil
|
||||
return createFunctionCall(parsers.FunctionCallUpper, []interface{}{ex})
|
||||
}
|
||||
|
||||
LowerExpression <- "LOWER"i ws "(" ex:SelectItem ")" {
|
||||
return parsers.FunctionCall{Type: parsers.FunctionCallLower, Arguments: []interface{}{ex}}, nil
|
||||
return createFunctionCall(parsers.FunctionCallLower, []interface{}{ex})
|
||||
}
|
||||
|
||||
StringEqualsExpression <- StringEquals ws "(" ws ex1:SelectItem ws "," ws ex2:SelectItem ws ignoreCase:("," ws boolean:SelectItem { return boolean, nil })? ")" {
|
||||
return parsers.FunctionCall{Type: parsers.FunctionCallStringEquals, Arguments: []interface{}{ex1, ex2, ignoreCase}}, nil
|
||||
return createFunctionCall(parsers.FunctionCallStringEquals, []interface{}{ex1, ex2, ignoreCase})
|
||||
}
|
||||
|
||||
ToStringExpression <- "TOSTRING"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return parsers.FunctionCall{Type: parsers.FunctionCallToString, Arguments: []interface{}{ex}}, nil
|
||||
return createFunctionCall(parsers.FunctionCallToString, []interface{}{ex})
|
||||
}
|
||||
|
||||
ConcatExpression <- "CONCAT"i ws "(" ws ex1:SelectItem others:(ws "," ws ex:SelectItem { return ex, nil })+ ws ")" {
|
||||
arguments := append([]interface{}{ex1}, others.([]interface{})...)
|
||||
return parsers.FunctionCall{Type: parsers.FunctionCallConcat, Arguments: arguments}, nil
|
||||
return createFunctionCall(parsers.FunctionCallConcat, arguments)
|
||||
}
|
||||
|
||||
LeftExpression <- "LEFT"i ws "(" ws ex:SelectItem ws "," ws length:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallLeft, []interface{}{ex, length})
|
||||
}
|
||||
|
||||
LengthExpression <- "LENGTH"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallLength, []interface{}{ex})
|
||||
}
|
||||
|
||||
LTrimExpression <- "LTRIM"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallLTrim, []interface{}{ex})
|
||||
}
|
||||
|
||||
ReplaceExpression <- "REPLACE"i ws "(" ws ex1:SelectItem ws "," ws ex2:SelectItem ws "," ws ex3:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallReplace, []interface{}{ex1, ex2, ex3})
|
||||
}
|
||||
|
||||
ReplicateExpression <- "REPLICATE"i ws "(" ws ex1:SelectItem ws "," ws ex2:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallReplicate, []interface{}{ex1, ex2})
|
||||
}
|
||||
|
||||
ReverseExpression <- "REVERSE"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallReverse, []interface{}{ex})
|
||||
}
|
||||
|
||||
RightExpression <- "RIGHT"i ws "(" ws ex:SelectItem ws "," ws length:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallRight, []interface{}{ex, length})
|
||||
}
|
||||
|
||||
RTrimExpression <- "RTRIM"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallRTrim, []interface{}{ex})
|
||||
}
|
||||
|
||||
SubstringExpression <- "SUBSTRING"i ws "(" ws ex:SelectItem ws "," ws startPos:SelectItem ws "," ws length:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallSubstring, []interface{}{ex, startPos, length})
|
||||
}
|
||||
|
||||
TrimExpression <- "TRIM"i ws "(" ws ex:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallTrim, []interface{}{ex})
|
||||
}
|
||||
|
||||
ThreeArgumentStringFunctionExpression <- function:ThreeArgumentStringFunction ws "(" ws ex1:SelectItem ws "," ws ex2:SelectItem ws ignoreCase:("," ws boolean:SelectItem { return boolean, nil })? ")" {
|
||||
|
||||
@@ -336,4 +336,293 @@ func Test_Execute_StringFunctions(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function LEFT()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT LEFT(c.id, 5) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallLeft,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function LENGTH()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT LENGTH(c.id) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallLength,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function LTRIM()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT LTRIM(c.id) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallLTrim,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function REPLACE()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT REPLACE(c.id, "old", "new") FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallReplace,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeString,
|
||||
Value: "old",
|
||||
},
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeString,
|
||||
Value: "new",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function REPLICATE()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT REPLICATE(c.id, 3) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallReplicate,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function REVERSE()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT REVERSE(c.id) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallReverse,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function RIGHT()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT RIGHT(c.id, 3) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallRight,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function RTRIM()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT RTRIM(c.id) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallRTrim,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function SUBSTRING()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT SUBSTRING(c.id, 1, 5) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallSubstring,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
parsers.SelectItem{
|
||||
Type: parsers.SelectItemTypeConstant,
|
||||
Value: parsers.Constant{
|
||||
Type: parsers.ConstantTypeInteger,
|
||||
Value: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse function TRIM()", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT TRIM(c.id) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallTrim,
|
||||
Arguments: []interface{}{
|
||||
parsers.SelectItem{
|
||||
Path: []string{"c", "id"},
|
||||
Type: parsers.SelectItemTypeField,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{Value: "c"},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user