intermediary patch

This commit is contained in:
Pijus Kamandulis 2025-08-22 18:22:27 +03:00
parent 51e3311ba4
commit c3ba4ebedf
6 changed files with 2089 additions and 1826 deletions

View File

@ -142,8 +142,6 @@ const (
FunctionCallSetIntersect FunctionCallType = "SetIntersect"
FunctionCallSetUnion FunctionCallType = "SetUnion"
FunctionCallIif FunctionCallType = "Iif"
FunctionCallMathAbs FunctionCallType = "MathAbs"
FunctionCallMathAcos FunctionCallType = "MathAcos"
FunctionCallMathAsin FunctionCallType = "MathAsin"
@ -187,7 +185,9 @@ const (
FunctionCallAggregateMin FunctionCallType = "AggregateMin"
FunctionCallAggregateSum FunctionCallType = "AggregateSum"
FunctionCallIn FunctionCallType = "In"
FunctionCallIif FunctionCallType = "Iif"
FunctionCallIn FunctionCallType = "In"
FunctionCallUDF FunctionCallType = "UDF"
)
var AggregateFunctions = []FunctionCallType{
@ -200,5 +200,6 @@ var AggregateFunctions = []FunctionCallType{
type FunctionCall struct {
Arguments []interface{}
UdfName string
Type FunctionCallType
}

View File

@ -186,4 +186,55 @@ func Test_Parse(t *testing.T) {
},
)
})
t.Run("Should parse SELECT with UDF function", func(t *testing.T) {
testQueryParse(
t,
`SELECT t.name, udf.CalculateTax(t.income, t.category) FROM t`,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
testutils.SelectItem_Path("t", "name"),
{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallUDF,
UdfName: "CalculateTax",
Arguments: []interface{}{
testutils.SelectItem_Path("t", "income"),
testutils.SelectItem_Path("t", "category"),
},
},
},
},
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("t")},
},
)
})
t.Run("Should parse WHERE with UDF function", func(t *testing.T) {
testQueryParse(
t,
`SELECT c.id FROM c WHERE udf.IsEligible(c.status) = true`,
parsers.SelectStmt{
SelectItems: []parsers.SelectItem{
testutils.SelectItem_Path("c", "id"),
},
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
Filters: parsers.ComparisonExpression{
Left: parsers.SelectItem{
Type: parsers.SelectItemTypeFunctionCall,
Value: parsers.FunctionCall{
Type: parsers.FunctionCallUDF,
UdfName: "IsEligible",
Arguments: []interface{}{
testutils.SelectItem_Path("c", "status"),
},
},
},
Operation: "=",
Right: testutils.SelectItem_Constant_Bool(true),
},
},
)
})
}

File diff suppressed because it is too large Load Diff

View File

@ -154,6 +154,14 @@ func createFunctionCall(functionType parsers.FunctionCallType, arguments []inter
return parsers.FunctionCall{Type: functionType, Arguments: arguments}, nil
}
func createUDFCall(functionName interface{}, arguments []interface{}) (parsers.FunctionCall, error) {
return parsers.FunctionCall{
Type: parsers.FunctionCallUDF,
UdfName: functionName.(string),
Arguments: arguments,
}, nil
}
func joinStrings(array []interface{}) string {
var stringsArray []string
for _, elem := range array {
@ -511,7 +519,8 @@ BooleanLiteral <- ("true"i / "false"i) {
return parsers.Constant{Type: parsers.ConstantTypeBoolean, Value: boolValue}, nil
}
FunctionCall <- StringFunctions
FunctionCall <- UDFFunction
/ StringFunctions
/ TypeCheckingFunctions
/ ArrayFunctions
/ ConditionalFunctions
@ -519,6 +528,20 @@ FunctionCall <- StringFunctions
/ AggregateFunctions
/ MathFunctions
UDFFunction <- "udf"i ws "." ws functionName:Identifier ws "(" ws arguments:UDFArgumentList? ws ")" {
if arguments == nil {
return createUDFCall(functionName, []interface{}{})
}
return createUDFCall(functionName, arguments.([]interface{}))
}
UDFArgumentList <- arg1:SelectItem others:(ws "," ws arg:SelectItem { return arg, nil })* {
if others == nil {
return []interface{}{arg1}, nil
}
return append([]interface{}{arg1}, others.([]interface{})...), nil
}
StringFunctions <- StringEqualsExpression
/ ToStringExpression
/ ConcatExpression

View File

@ -231,9 +231,6 @@ 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:
@ -320,6 +317,10 @@ func (r rowContext) selectItem_SelectItemTypeFunctionCall(functionCall parsers.F
case parsers.FunctionCallIn:
return r.misc_In(functionCall.Arguments)
case parsers.FunctionCallIif:
return r.misc_Iif(functionCall.Arguments)
case parsers.FunctionCallUDF:
return r.misc_UDF(functionCall.Arguments)
}
logger.Errorf("Unknown function call type: %v", functionCall.Type)

View File

@ -29,3 +29,7 @@ func (r rowContext) misc_Iif(arguments []interface{}) interface{} {
return r.resolveSelectItem(arguments[2].(parsers.SelectItem))
}
func (r rowContext) misc_UDF(arguments []interface{}) interface{} {
return "TODO"
}