Hi,

I want to define a Beam SQL user defined function that accepts a variable
list of arguments (which may be empty).

What I essentially would like to have is

public class ParseUserAgentJson implements BeamSqlUdf {

   public static String eval( String input,
                              String... fields) { ... }

}

When I do this I get this on the case where the list is empty

*Caused by:
org.apache.beam.vendor.calcite.v1_20_0.org.apache.calcite.sql.validate.SqlValidatorException:
No match found for function signature ParseUserAgentJson(<CHARACTER>)*
* at
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)*
* at
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)*
* at
java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)*
* at
java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)*


So I tried
public static String eval( @Parameter(name = "userAgent") String input,

                           @Parameter(name = "Fields", optional =
true) String ... fields
)

Which gives


*java.lang.AssertionError: No assign rules for OTHER defined*

* at
org.apache.beam.vendor.calcite.v1_20_0.org.apache.calcite.sql.type.SqlTypeAssignmentRules.canCastFrom(SqlTypeAssignmentRules.java:389)*
* at
org.apache.beam.vendor.calcite.v1_20_0.org.apache.calcite.sql.type.SqlTypeUtil.canCastFrom(SqlTypeUtil.java:864)*
* at
org.apache.beam.vendor.calcite.v1_20_0.org.apache.calcite.sql.SqlUtil.lambda$filterRoutinesByParameterType$4(SqlUtil.java:620)*


It seems this is Calcite that is unable to do the "Variable arguments"
trick.

So right now I have this workaround which works but limits it to a maximum
of 10 arguments:

public static String eval( // NOSONAR java:S107 Methods should not have too
many parameters

    @Parameter(name = "userAgent") String input,
    @Parameter(name = "Field  1", optional = true) String field1,
    @Parameter(name = "Field  2", optional = true) String field2,
    @Parameter(name = "Field  3", optional = true) String field3,
    @Parameter(name = "Field  4", optional = true) String field4,
    @Parameter(name = "Field  5", optional = true) String field5,
    @Parameter(name = "Field  6", optional = true) String field6,
    @Parameter(name = "Field  7", optional = true) String field7,
    @Parameter(name = "Field  8", optional = true) String field8,
    @Parameter(name = "Field  9", optional = true) String field9,
    @Parameter(name = "Field 10", optional = true) String field10
) {


My question: Is there a better way to do this?

-- 
Best regards / Met vriendelijke groeten,

Niels Basjes

Reply via email to