10 Replies Latest reply on Apr 17, 2013 12:29 PM by shakirhusain

    Is it possible to define UDF with vararg to be used in a static VDB ?

    shakirhusain

      The purpose of the function is to accept list of numbers and convert it into a List object:

       

      public static List makeList(Object... items) {

        List returnList = null;

        if(items[0] instanceof Double) {

            returnList = new ArrayList<Double>();

          } if(items[0] instanceof Float) {

            returnList = new ArrayList<Float>();

          }

          for(Object item : items) {

            returnList.add(item);

          }

          return returnList;

      }

       

       

      makeList.png

       

      When I use this in SQL, I get the following exception when I try saving the SQL:

       

      ERROR: TEIID30068 The function 'MAKELIST(1, 2)' is an unknown form.  Check that the function name and number of arguments is correct.

       

      Is there a way to work around this issue?

       

      Thanks!

      Shakir

        • 1. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
          blafond

          For starters... select your scalar function and in the properties view, change the extension property:  function:Variable Arguments to TRUE.  This is a fairly new extension property added in Teiid Designer 8.0 release.

          • 2. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
            shakirhusain

            Thanks for the response!

             

            As you suggested, I set the function:Variable Arguments property to true.

            But, it didn't seem to thave any effect.

             

            I am still getting the same error, if I use more than one arguments in MAKELIST() function.

             

            TEIID30068 The function 'MAKELIST(1, 2)' is an unknown form.  Check that the function name and number of arguments is correct.


            • 3. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
              blafond

              Teiid's doc for UDF var args is:  http://docs.jboss.org/author/display/TEIID/DDL+Metadata and http://docs.jboss.org/author/display/TEIID/Support+for+User-Defined+Functions+%28Non-Pushdown%29

               

              Changing the datatype of "items" to "integer" intead of object might help.

              • 4. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
                shakirhusain

                In fact, it seems like while loading the VDB, it is not able to match the scalar function makeList(object items) : object result with the correspding java UDF with varargs :

                public static Object makeList(Object... items) {}

                 

                See the exception below:

                 

                14:27:12,091 ERROR [org.jboss.threads.executor] (teiid-async-threads - 3) Task execution failed for task org.teiid.jboss.VDBService$6@40a8d1e4: org.te

                iid.metadata.MetadataException: TEIID30388 UDF "makeList(object items) : object result" could not be loaded, since no method on class "com.lgc.petrel.

                functions.BulkManipulation" with name "makeList" has a matching type signature.

                        at org.teiid.query.function.FunctionTree.createFunctionDescriptor(FunctionTree.java:326) [teiid-engine-8.3.0.Final.jar:8.3.0.Final]

                        at org.teiid.query.function.FunctionTree.addFunction(FunctionTree.java:225) [teiid-engine-8.3.0.Final.jar:8.3.0.Final]

                        at org.teiid.query.function.FunctionTree.<init>(FunctionTree.java:99) [teiid-engine-8.3.0.Final.jar:8.3.0.Final]

                        at org.teiid.deployers.CompositeVDB.buildTransformationMetaData(CompositeVDB.java:86) [teiid-runtime-8.3.0.Final.jar:8.3.0.Final]

                        at org.teiid.deployers.CompositeVDB.metadataLoadFinished(CompositeVDB.java:254) [teiid-runtime-8.3.0.Final.jar:8.3.0.Final]

                        at org.teiid.deployers.VDBRepository.finishDeployment(VDBRepository.java:289) [teiid-runtime-8.3.0.Final.jar:8.3.0.Final]

                        at org.teiid.runtime.AbstractVDBDeployer.metadataLoaded(AbstractVDBDeployer.java:180) [teiid-runtime-8.3.0.Final.jar:8.3.0.Final]

                        at org.teiid.jboss.VDBService.access$900(VDBService.java:93) [teiid-jboss-integration-8.3.0.Final.jar:8.3.0.Final]

                        at org.teiid.jboss.VDBService$6.run(VDBService.java:398) [teiid-jboss-integration-8.3.0.Final.jar:8.3.0.Final]

                        at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33)

                        at org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:801)

                        at org.jboss.threads.QueueExecutor.access$100(QueueExecutor.java:45)

                        at org.jboss.threads.QueueExecutor$Worker.run(QueueExecutor.java:821)

                        at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_27]

                        at org.jboss.threads.JBossThread.run(JBossThread.java:122)

                Caused by: java.lang.NoSuchMethodException: makeList Args: [class org.teiid.query.util.CommandContext, class java.lang.Object]

                        at org.teiid.core.util.ReflectionHelper.findBestMethodWithSignature(ReflectionHelper.java:191) [teiid-common-core-8.3.0.Final.jar:8.3.0.Final]

                 

                 

                        at org.teiid.query.function.FunctionTree.createFunctionDescriptor(FunctionTree.java:320) [teiid-engine-8.3.0.Final.jar:8.3.0.Final]

                        ... 14 more

                • 5. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
                  van.halbert

                  I have the following working in a dynamicVDB in the Teiid drools-integration quickstart:

                   

                  CREATE VIRTUAL FUNCTION performRuleOnData(className string, returnMethodName string, returnIfNull string, VARIADIC z object ) RETURNS string OPTIONS (JAVA_CLASS 'org.jboss.teiid.businessrules.udf.RulesUDF',  JAVA_METHOD 'performRuleOnData', VARARGS 'true');

                   

                   

                  Check that your datatype is 'VARIADIC'.

                   

                   

                  Van

                  • 6. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
                    shakirhusain

                    ok.

                    I am still not sure, if vararg UDF support exists for static VDBs.

                     

                    Shakir

                    • 7. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
                      shawkins

                      Just to clarify a few things:

                       

                      > Check that your datatype is 'VARIADIC'.

                       

                      VARIADIC is the keyword for DDL metadata to declare varargs, so it does not apply to your Designer based usage - you can however follow through the quickstart to see how a vararg udf should work.

                       

                      > Changing the datatype of "items" to "integer" intead of object might help.

                       

                      The object type will work fine and it appears that you want this to accept multiple types, so object is appropriate.

                       

                      > TEIID30388 UDF "makeList(object items) : object result" could not be loaded, since no method on class "com.lgc.petrel.

                      functions.BulkManipulation" with name "makeList" has a matching type signature.

                       

                      This implies serveral things.  This should mean that your UDF class has loaded correctly.  However the signature shown should be (object... items) if the metadata were properly defined as varargs.  Can you post the VDB with the vararg property set in Designer so that we can verify it has been set correctly?

                       

                      Steve

                      • 8. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
                        shakirhusain

                        Thanks for your response!

                         

                         

                        Steve's suggestion : Can you post the VDB with the vararg property set in Designer so that we can verify it has been set correctly?

                         

                         

                        Let me summarize the entire thing below:

                         

                        I am using following versions of software:

                        JBoss AS 7.1.1

                        Teiid 8.3.0

                        Teiid Designer 8.0.0

                         

                        Here is my UDF:

                         

                        public static Object makeList(Object... items) {

                            List returnList = null;

                            if(items[0] instanceof Double) {

                              returnList = new ArrayList<Double>();

                            } if(items[0] instanceof Float) {

                              returnList = new ArrayList<Float>();

                            }

                              for(Object item : items) {

                              returnList.add(item);

                            }

                            return returnList;

                        }

                         

                        I define the corresponding function in Teiid Designer:

                        makeList.png

                        Its properties set as below:

                        Function_properties.png

                        This is the list of datatypes the designer is offering me to select from for the argument (There is nothing here to explicitly state vararg)

                        Data_type.png

                         

                        Here is the exception I get when I deploy the vdb:

                         

                        09:42:53,909 ERROR [org.jboss.threads.executor] (teiid-async-threads - 3) Task execution failed for task org.teiid.jboss.VDBService$6@4a6487f7: org.te

                        iid.metadata.MetadataException: TEIID30388 UDF "makeList(object items) : object result" could not be loaded, since no method on class "com.lgc.petrel.

                        functions.BulkManipulation" with name "makeList" has a matching type signature.

                                at org.teiid.query.function.FunctionTree.createFunctionDescriptor(FunctionTree.java:326) [teiid-engine-8.3.0.Final.jar:8.3.0.Final]

                                at org.teiid.query.function.FunctionTree.addFunction(FunctionTree.java:225) [teiid-engine-8.3.0.Final.jar:8.3.0.Final]

                                at org.teiid.query.function.FunctionTree.<init>(FunctionTree.java:99) [teiid-engine-8.3.0.Final.jar:8.3.0.Final]

                                at org.teiid.deployers.CompositeVDB.buildTransformationMetaData(CompositeVDB.java:86) [teiid-runtime-8.3.0.Final.jar:8.3.0.Final]

                                at org.teiid.deployers.CompositeVDB.metadataLoadFinished(CompositeVDB.java:254) [teiid-runtime-8.3.0.Final.jar:8.3.0.Final]

                                at org.teiid.deployers.VDBRepository.finishDeployment(VDBRepository.java:289) [teiid-runtime-8.3.0.Final.jar:8.3.0.Final]

                                at org.teiid.runtime.AbstractVDBDeployer.metadataLoaded(AbstractVDBDeployer.java:180) [teiid-runtime-8.3.0.Final.jar:8.3.0.Final]

                                at org.teiid.jboss.VDBService.access$900(VDBService.java:93) [teiid-jboss-integration-8.3.0.Final.jar:8.3.0.Final]

                                at org.teiid.jboss.VDBService$6.run(VDBService.java:398) [teiid-jboss-integration-8.3.0.Final.jar:8.3.0.Final]

                                at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33)

                                at org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:801)

                                at org.jboss.threads.QueueExecutor.access$100(QueueExecutor.java:45)

                                at org.jboss.threads.QueueExecutor$Worker.run(QueueExecutor.java:821)

                                at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_27]

                                at org.jboss.threads.JBossThread.run(JBossThread.java:122)

                        Caused by: java.lang.NoSuchMethodException: makeList Args: [class org.teiid.query.util.CommandContext, class java.lang.Object]

                                at org.teiid.core.util.ReflectionHelper.findBestMethodWithSignature(ReflectionHelper.java:191) [teiid-common-core-8.3.0.Final.jar:8.3.0.Final]

                         

                         

                        Am I missing something here?

                         

                        Shakir


                        • 9. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
                          shawkins

                          >  (There is nothing here to explicitly state vararg)

                           

                          There should not be, so that is fine.

                           

                          > Am I missing something here?

                           

                          I don't think you are missing something.  Either open a Designer JIRA so that someone else can walk through the scenario or post your VDB so that it can be confirmed if there is a Designer or other issue.

                           

                          Steve

                          • 10. Re: Is it possible to define UDF with vararg to be used in a static VDB ?
                            shakirhusain

                            I opened a Designer JIRA - TEIIDDES-1667

                             

                            Thanks!

                            Shakir