<html>
<head>
    <base href="https://docs.jboss.org/author">
            <link rel="stylesheet" href="/author/s/en/2172/19/5/_/styles/combined.css?spaceKey=TEIID&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://docs.jboss.org/author/display/TEIID/Support+for+User-Defined+Functions+%28Non-Pushdown%29">Support for User-Defined Functions (Non-Pushdown)</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://docs.jboss.org/author/display/~shawkins">Steven Hawkins</a>
    </h4>
        <br/>
                         <h4>Changes (8)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >* After coding the functions you should compile the Java code into a Java Archive (JAR) file. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h3. Using Designer <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3. Designer Specific <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">The JAR file needs be attached along with the VDB file under &quot;lib&quot; directory on the VDB archive file. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The JAR file may be placed in your VDB under the &quot;/lib&quot; directory.  It will automatically be used for the VDB classloader classpath when deployed. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h3. Dynamic VDB <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3. AS Module <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Create a JBoss AS module with the JAR file under _&lt;jboss-as&gt;/modules_ directory and define the module on the \-vdb.xml file as shown below example <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >     ... <br>&lt;/vdb&gt; <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words"><span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">{code}</span>The</span> lib property value may contain a space delimited list of module names if more than one dependency is needed. <br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>To define a non-pushdown function, a Java function must be provided that matches the metadata supplied either in the Designer or Dynamic VDB defined metadata.&nbsp; User Defined Function (or UDF) and User Defined Aggregate Function (or UDAF) may be called at runtime just like any other function or aggregate function respectively.</p>


<h2><a name="SupportforUser-DefinedFunctions%28Non-Pushdown%29-MetadatainDesigner"></a>Metadata in Designer</h2>

<p>A user defined function created on any VDB on view model by creating a Function just as a base table. You would require all the information defined on <a href="/author/display/TEIID/User+Defined+Functions" title="User Defined Functions">User Defined Functions</a> to create a UDF. Make sure you provide the JAVA code implementation details in the properties dialog for the UDF.</p>

<h2><a name="SupportforUser-DefinedFunctions%28Non-Pushdown%29-MetadataforDynamicVDBs"></a>Metadata for Dynamic VDBs</h2>

<p>When defining the metadata using DDL in the Dynamic VDBs, user can define a UDF or UDAF (User Defined Aggregate Function) as shown below.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: xml; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
&lt;vdb name="{vdb-name}" version="1"&gt;
    &lt;model name="{model-name}" type="VIRTUAL"&gt;
         &lt;metadata type="DDL"&gt;&lt;![CDATA[
             CREATE VIRTUAL FUNCTION celsiusToFahrenheit(celsius decimal) RETURNS decimal OPTIONS (JAVA_CLASS 'org.something.TempConv',  JAVA_METHOD 'celsiusToFahrenheit');
             CREATE VIRTUAL FUNCTION sumAll(arg integer) RETURNS integer OPTIONS (JAVA_CLASS 'org.something.SumAll',  JAVA_METHOD 'addInput', AGGREGATE 'true', VARARGS 'true', "NULL-ON-NULL" 'true'); ]]&gt; &lt;/metadata&gt;
    &lt;/model&gt;
&lt;/vdb&gt;
</pre>
</div></div>

<p>You must create a Java method that contains the function’s logic. This Java method should accept the necessary arguments, which the Teiid System will pass to it at runtime, and function should return the calculated or altered value.</p>

<p>See <a href="/author/display/TEIID/DDL+Metadata" title="DDL Metadata">DDL Metadata</a> for all possible options related to functions defined via DDL.</p>



<h3><a name="SupportforUser-DefinedFunctions%28Non-Pushdown%29-WritingtheJavaCoderequiredbytheUDF"></a>Writing the Java Code required by the UDF</h3>

<p>The number of input arguments and types must match the function metadata defined in Designer or on Dynamic VDB metadata.</p>

<p>Code Requirements For UDFs</p>


<ul>
        <li>The java class containing the function method must be defined public.</li>
</ul>


<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/author/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>One implementation class can contain more than one UDF implementation methods.</td></tr></table></div>

<ul>
        <li>The function method must be public and static.</li>
</ul>


<p>Code Requirements For UDAFs</p>
<ul>
        <li>The java class containing the function method must be defined public and extend org.teiid.UserDefinedAggregate</li>
        <li>The function method must be public.</li>
</ul>


<p>Other Considerations</p>


<ul>
        <li>Any exception can be thrown, but Teiid will rethrow the exception as a <tt>FunctionExecutionException</tt> .</li>
        <li>You may optionally add an additional <tt>org.teiid.CommandContext</tt> argument as the first parameter. The <tt>CommandContext</tt> interface provides access to information about the current command, such as the executing user, Subject, the vdb, the session id, etc. This <tt>CommandContext</tt> parameter should not be declared in the function metadata.</li>
</ul>



<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Sample UDF code</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
package org.something;

public class TempConv
{
   /**
   * Converts the given Celsius temperature to Fahrenheit, and returns the
   * value.
   * @param doubleCelsiusTemp
   * @return Fahrenheit
   */
   public static Double celsiusToFahrenheit(Double doubleCelsiusTemp)
   {
      if (doubleCelsiusTemp == null)
      {
         return null;
      }
      return (doubleCelsiusTemp)*9/5 + 32;
   }
}
</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Sample UDAF code</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
package org.something;

public static class SumAll implements UserDefinedAggregate&lt;Integer&gt; {

        private boolean isNull = true;
        private int result;

        public void addInput(Integer... vals) {
                isNull = false;
                for (int i : vals) {
                        result += i;
                }
        }

        @Override
        public Integer getResult(org.teiid.CommandContext commandContext) {
                if (isNull) {
                        return null;
                }
                return result;
        }

        @Override
        public void reset() {
                isNull = true;
                result = 0;
        }

}
</pre>
</div></div>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Sample CommandContext Usage</b></div><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
package org.something;

public class SessionInfo
{
   /**
   * @param context
   * @return the created Timestamp
   */
   public static Timestamp sessionCreated(CommandContext context)
   {
      return new Timestamp(context.getSession().getCreatedTime());
   }
}
</pre>
</div></div>

<p>The corresponding UDF would be declared as Timestamp sessionCreated().</p>


<h1><a name="SupportforUser-DefinedFunctions%28Non-Pushdown%29-PostCodeActivities"></a>Post Code Activities</h1>

<ul>
        <li>After coding the functions you should compile the Java code into a Java Archive (JAR) file.</li>
</ul>


<h3><a name="SupportforUser-DefinedFunctions%28Non-Pushdown%29-DesignerSpecific"></a>Designer Specific</h3>

<p>The JAR file may be placed in your VDB under the "/lib" directory.  It will automatically be used for the VDB classloader classpath when deployed.</p>

<h3><a name="SupportforUser-DefinedFunctions%28Non-Pushdown%29-ASModule"></a>AS Module</h3>

<p>Create a JBoss AS module with the JAR file under <em>&lt;jboss-as&gt;/modules</em> directory and define the module on the &#45;vdb.xml file as shown below example</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: xml; gutter: false" style="font-size:12px; font-family: ConfluenceInstalledFont,monospace;">
&lt;vdb name="{vdb-name}" version="1"&gt;
    &lt;property name ="lib" value ="{module-name}" /&gt;
     ...
&lt;/vdb&gt;
</pre>
</div></div>

<p>The lib property value may contain a space delimited list of module names if more than one dependency is needed.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;" class="grey">
                        <a href="https://docs.jboss.org/author/users/removespacenotification.action?spaceKey=TEIID">Stop watching space</a>
            <span style="padding: 0px 5px;">|</span>
                <a href="https://docs.jboss.org/author/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
        <a href="https://docs.jboss.org/author/display/TEIID/Support+for+User-Defined+Functions+%28Non-Pushdown%29">View Online</a>
        |
        <a href="https://docs.jboss.org/author/pages/diffpagesbyversion.action?pageId=18646185&revisedVersion=10&originalVersion=9">View Changes</a>
                |
        <a href="https://docs.jboss.org/author/display/TEIID/Support+for+User-Defined+Functions+%28Non-Pushdown%29?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>