[ 
https://issues.apache.org/jira/browse/PHOENIX-3355?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15630696#comment-15630696
 ] 

Eric Lomore commented on PHOENIX-3355:
--------------------------------------

[~maryannxue], I am running into a few more issues, would you mind taking a 
look? 

Functions with the expected constructor with parameter List.class now work as 
expected. But those that do not cannot instantiate properly.

{code}
    private void constructUDFFunction() throws IOException {
            Constructor<?> constructor = clazz.getConstructor(List.class);
            udfFunction = 
(ScalarFunction)constructor.newInstance(this.children);
} {code}


For example, ToDateFunction stacktrace:
{code}Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodException: 
org.apache.phoenix.expression.function.ToDateFunction.<init>(java.util.List)
        at 
org.apache.phoenix.expression.function.UDFExpression.constructUDFFunction(UDFExpression.java:170)
        at 
org.apache.phoenix.expression.function.UDFExpression.<init>(UDFExpression.java:72)
        at 
org.apache.phoenix.calcite.CalciteUtils$19.newExpression(CalciteUtils.java:788)
        at 
org.apache.phoenix.calcite.CalciteUtils.convertChildren(CalciteUtils.java:1006)
        at 
org.apache.phoenix.calcite.CalciteUtils.access$000(CalciteUtils.java:138)
        at 
org.apache.phoenix.calcite.CalciteUtils$3.newExpression(CalciteUtils.java:324)
        at 
org.apache.phoenix.calcite.CalciteUtils.toExpression(CalciteUtils.java:1071)
        at 
org.apache.phoenix.calcite.rel.PhoenixTableScan.<init>(PhoenixTableScan.java:153)
        at 
org.apache.phoenix.calcite.rel.PhoenixTableScan.create(PhoenixTableScan.java:94)
        at 
org.apache.phoenix.calcite.rules.PhoenixFilterScanMergeRule.onMatch(PhoenixFilterScanMergeRule.java:46)
        at 
org.apache.calcite.plan.volcano.VolcanoRuleCall.onMatch(VolcanoRuleCall.java:213)
        ... 47 more
Caused by: java.lang.NoSuchMethodException: 
org.apache.phoenix.expression.function.ToDateFunction.<init>(java.util.List)
        at java.lang.Class.getConstructor0(Class.java:3082)
        at java.lang.Class.getConstructor(Class.java:1825)
        at 
org.apache.phoenix.expression.function.UDFExpression.constructUDFFunction(UDFExpression.java:165)
        ... 57 more
{code}

The only uniform way to instantiate on the phoenix side is through the parse 
node create function (ex. ToDateParseNode.create()).

{code}
public FunctionExpression create(List<Expression> children, StatementContext 
context) throws SQLException {
 // creates ExampleFunction
} {code}

We would still have to register PhoenixScalarFunction using the class name of a 
function, but in constructUDFFunction() it would need to refer to the 
ParseNode. Unfortunately, I'm a bit stuck on where to go from here. We would be 
using a parse node but not at parse time which introduces some complications. 
See my latest commit here:
https://github.com/bloomberg/phoenix/commit/24652257e1f2c039b62288387d911c47e30399c6
You'll notice StatementContext is null which cannot be the case, but I don't 
see a way around this.

> Register Phoenix built-in functions as Calcite functions
> --------------------------------------------------------
>
>                 Key: PHOENIX-3355
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-3355
>             Project: Phoenix
>          Issue Type: Bug
>            Reporter: James Taylor
>            Assignee: Eric Lomore
>              Labels: calcite
>         Attachments: PHOENIX-3355.wip, PHOENIX-3355.wip2
>
>
> We should register all Phoenix built-in functions that don't exist in Calcite.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to