<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OpenText Analytics Database 26.2.x – User-defined extensions</title>
    <link>/en/extending/udxs/</link>
    <description>Recent content in User-defined extensions on OpenText Analytics Database 26.2.x</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/en/extending/udxs/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Extending: Loading UDxs</title>
      <link>/en/extending/udxs/loading-udxs/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/udxs/loading-udxs/</guid>
      <description>
        
        
        &lt;p&gt;User-defined extensions (UDxs) are contained in libraries. A library can contain multiple UDxs. To add UDxs to OpenText™ Analytics Database, you must:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Deploy the library (once per library).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create each UDx (once per UDx).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you are using UDxs written in Java, you must also set up a Java runtime environment. See &lt;a href=&#34;../../../en/extending/udxs/installing-java-on-hosts/#&#34;&gt;Installing Java on OpenText Analytics Database hosts&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;deploying-libraries&#34;&gt;Deploying libraries&lt;/h2&gt;
&lt;p&gt;To deploy a library to your database:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Copy the UDx shared library file (&lt;code&gt;.so&lt;/code&gt;), Python file, Java JAR file, or R functions file that contains your function to a node on your database cluster. You do not need to copy it to every node.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Connect to the node where you copied the library (for example, using &lt;a class=&#34;glosslink&#34; href=&#34;../../../en/glossary/vsql/&#34; title=&#34;For more information, see Installing the vsql Client and the more general topic, Using vsql.&#34;&gt;vsql&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add your library to the database catalog using the &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-library/#&#34;&gt;CREATE LIBRARY&lt;/a&gt; statement.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE LIBRARY &lt;span class=&#34;code-variable&#34;&gt;libname&lt;/span&gt; AS &amp;#39;/&lt;span class=&#34;code-variable&#34;&gt;path_to_lib&lt;/span&gt;/&lt;span class=&#34;code-variable&#34;&gt;filename&lt;/span&gt;&amp;#39;
   LANGUAGE &amp;#39;&lt;span class=&#34;code-variable&#34;&gt;language&lt;/span&gt;&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;&lt;code&gt;libname&lt;/code&gt;&lt;/em&gt; is the name you want to use to reference the library. &lt;em&gt;&lt;code&gt;path_to_lib/filename&lt;/code&gt;&lt;/em&gt; is the fully-qualified path to the library or JAR file you copied to the host. &lt;em&gt;&lt;code&gt;language&lt;/code&gt;&lt;/em&gt; is the implementation language.&lt;/p&gt;
&lt;p&gt;For example, if you created a JAR file named &lt;code&gt;TokenizeStringLib.jar&lt;/code&gt; and copied it to the dbadmin account&#39;s home directory, you would use this command to load the library:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE LIBRARY tokenizelib AS &amp;#39;/home/dbadmin/TokenizeStringLib.jar&amp;#39;
   LANGUAGE &amp;#39;Java&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can load any number of libraries into the database.&lt;/p&gt;
&lt;h2 id=&#34;privileges&#34;&gt;Privileges&lt;/h2&gt;
&lt;p&gt;Superusers can create, modify, and drop any library. Users with the &lt;a href=&#34;../../../en/admin/db-users-and-privileges/db-roles/predefined-db-roles/udxdeveloper/#&#34;&gt;UDXDEVELOPER&lt;/a&gt; role or explicit grants can also act on libraries, as shown in the following table:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;th &gt;
Operation&lt;/th&gt; 

&lt;th &gt;
Requires&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-library/#&#34;&gt;CREATE LIBRARY&lt;/a&gt;&lt;/td&gt; 

&lt;td &gt;
UDXDEVELOPER&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
Replace a library (CREATE OR REPLACE LIBRARY)&lt;/td&gt; 

&lt;td &gt;






&lt;p&gt;UDXDEVELOPER and one of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;owner of library being replaced&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DROP privilege on the target library&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/drop-statements/drop-library/#&#34;&gt;DROP LIBRARY&lt;/a&gt;&lt;/td&gt; 

&lt;td &gt;






&lt;p&gt;UDXDEVELOPER and one of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;owner of library being dropped&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DROP privilege on the target library&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/alter-statements/alter-library/#&#34;&gt;ALTER LIBRARY&lt;/a&gt;&lt;/td&gt; 

&lt;td &gt;
UDXDEVELOPER and owner&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a name=&#34;Creating&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;creating-udx-functions&#34;&gt;Creating UDx functions&lt;/h2&gt;
&lt;p&gt;After the library is loaded, define individual UDxs using SQL statements such as &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-function-scalar/&#34;&gt;CREATE FUNCTION&lt;/a&gt; and &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-source/#&#34;&gt;CREATE SOURCE&lt;/a&gt;. These statements assign SQL function names to the extension classes in the library. They add the UDx to the database catalog and remain available after a database restart.&lt;/p&gt;
&lt;p&gt;The statement you use depends on the type of UDx you are declaring, as shown in the following table:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;th &gt;
UDx Type&lt;/th&gt; 

&lt;th &gt;
SQL Statement&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
Aggregate Function (UDAF)&lt;/td&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-aggregate-function/#&#34;&gt;CREATE AGGREGATE FUNCTION&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
Analytic Function (UDAnF)&lt;/td&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-analytic-function/#&#34;&gt;CREATE ANALYTIC FUNCTION&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
Scalar Function (UDSF)&lt;/td&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-function-scalar/#&#34;&gt;CREATE FUNCTION (scalar)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
Transform Function (UDTF)&lt;/td&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-transform-function/#&#34;&gt;CREATE TRANSFORM FUNCTION&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
Load (UDL): Source&lt;/td&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-source/#&#34;&gt;CREATE SOURCE&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
Load (UDL): Filter&lt;/td&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-filter/#&#34;&gt;CREATE FILTER&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;
Load (UDL): Parser&lt;/td&gt; 

&lt;td &gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-parser/#&#34;&gt;CREATE PARSER&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;If a UDx of the given name already exists, you can replace it or instruct the database to not replace it. To replace it, use the OR REPLACE syntax, as in the following example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; CREATE OR REPLACE TRANSFORM FUNCTION tokenize
   AS LANGUAGE &amp;#39;C++&amp;#39; NAME &amp;#39;TokenFactory&amp;#39; LIBRARY TransformFunctions;
CREATE TRANSFORM FUNCTION
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You might want to replace an existing function to change between fenced and unfenced modes.&lt;/p&gt;
&lt;p&gt;Alternatively, you can use IF NOT EXISTS to prevent the function from being created again if it already exists. You might want to use this in upgrade or test scripts that require, and therefore load, UDxs. By using IF NOT EXISTS, you preserve the original definition including fenced status. The following example shows this syntax:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;--- original creation:
=&amp;gt; CREATE TRANSFORM FUNCTION tokenize
   AS LANGUAGE &amp;#39;C++&amp;#39; NAME &amp;#39;TokenFactory&amp;#39; LIBRARY TransformFunctions NOT FENCED;
CREATE TRANSFORM FUNCTION

--- function is not replaced (and is still unfenced):
=&amp;gt; CREATE TRANSFORM FUNCTION IF NOT EXISTS tokenize
   AS LANGUAGE &amp;#39;C++&amp;#39; NAME &amp;#39;TokenFactory&amp;#39; LIBRARY TransformFunctions FENCED;
CREATE TRANSFORM FUNCTION
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After you add the UDx to the database, you can use your extension within SQL statements. The database superuser can grant access privileges to the UDx for users. See &lt;a href=&#34;../../../en/sql-reference/statements/grant-statements/grant-user-defined-extension/#&#34;&gt;GRANT (user defined extension)&lt;/a&gt; for details.&lt;/p&gt;
&lt;p&gt;When you call a UDx, the database creates an instance of the UDx class on each node in the cluster and provides it with the data it needs to process.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Extending: Installing Java on OpenText Analytics Database hosts</title>
      <link>/en/extending/udxs/installing-java-on-hosts/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/udxs/installing-java-on-hosts/</guid>
      <description>
        
        
        &lt;p&gt;If you are using UDxs written in Java, follow the instructions in this section.&lt;/p&gt;
&lt;p&gt;You must install a Java Virtual Machine (JVM) on every host in your cluster in order for OpenText™ Analytics Database to be able to execute your Java UDxs.&lt;/p&gt;
&lt;p&gt;Installing Java on your Vertica cluster is a two-step process:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install a Java runtime on all of the hosts in your cluster.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set the JavaBinaryForUDx configuration parameter to tell Vertica the location of the Java executable.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;installing-a-java-runtime&#34;&gt;Installing a Java runtime&lt;/h2&gt;
&lt;p&gt;For Java-based features, Vertica requires a 64-bit Java 6 (Java version 1.6). Vertica supports runtimes from either Oracle or &lt;a href=&#34;http://openjdk.java.net/&#34;&gt;OpenJDK&lt;/a&gt;. You can choose to install either the Java Runtime Environment (JRE) or Java Development Kit (JDK), since the JDK also includes the JRE.&lt;/p&gt;
&lt;p&gt;Many Linux distributions include a package for the OpenJDK runtime. See your Linux distribution&#39;s documentation for information about installing and configuring OpenJDK.&lt;/p&gt;
&lt;p&gt;To install the Oracle Java runtime, see the &lt;a href=&#34;http://www.oracle.com/technetwork/java/javase/downloads/index.html&#34;&gt;Java Standard Edition (SE) Download Page&lt;/a&gt;. You usually run the installation package as root in order to install it. See the download page for instructions.&lt;/p&gt;
&lt;p&gt;Once you have installed a JVM on each host, ensure that the &lt;code&gt;java&lt;/code&gt; command is in the search path and calls the correct JVM by running the command:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ java -version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This command should print something similar to:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;java version &amp;#34;1.8.0_102&amp;#34;
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

Any previously installed Java VM on your hosts may interfere with a newly installed Java runtime. See your Linux distribution&#39;s documentation for instructions on configuring which JVM is the default. Unless absolutely required, you should uninstall any incompatible version of Java before installing the Java 6 or Java 7 runtime.

&lt;/div&gt;
&lt;h2 id=&#34;setting-the-javabinaryforudx-configuration-parameter&#34;&gt;Setting the JavaBinaryForUDx configuration parameter&lt;/h2&gt;
&lt;p&gt;The JavaBinaryForUDx configuration parameter tells Vertica where to look for the JRE to execute Java UDxs. After you have installed the JRE on all of the nodes in your cluster, set this parameter to the absolute path of the Java executable. You can use the symbolic link that some Java installers create (for example &lt;code&gt;/usr/bin/java&lt;/code&gt;). If the Java executable is in your shell search path, you can get the path of the Java executable by running the following command from the Linux command line shell:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ which java
/usr/bin/java
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the &lt;code&gt;java&lt;/code&gt; command is not in the shell search path, use the path to the Java executable in the directory where you installed the JRE. Suppose you installed the JRE in &lt;code&gt;/usr/java/default&lt;/code&gt; (which is where the installation package supplied by Oracle installs the Java 1.6 JRE). In this case the Java executable is &lt;code&gt;/usr/java/default/bin/java&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You set the configuration parameter by executing the following statement as a &lt;a class=&#34;glosslink&#34; href=&#34;../../../en/glossary/db-superuser/&#34; title=&#34;&#34;&gt;database superuser&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER DATABASE DEFAULT SET PARAMETER JavaBinaryForUDx = &amp;#39;/usr/bin/java&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See &lt;a href=&#34;../../../en/sql-reference/statements/alter-statements/alter-db/#&#34;&gt;ALTER DATABASE&lt;/a&gt; for more information on setting configuration parameters.&lt;/p&gt;
&lt;p&gt;To view the current setting of the configuration parameter, query the &lt;a href=&#34;../../../en/sql-reference/system-tables/v-monitor-schema/config-parameters/#&#34;&gt;CONFIGURATION_PARAMETERS&lt;/a&gt; system table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; \x
Expanded display is on.
=&amp;gt; SELECT * FROM CONFIGURATION_PARAMETERS WHERE parameter_name = &amp;#39;JavaBinaryForUDx&amp;#39;;
-[ RECORD 1 ]-----------------+----------------------------------------------------------
node_name                     | ALL
parameter_name                | JavaBinaryForUDx
current_value                 | /usr/bin/java
default_value                 |
change_under_support_guidance | f
change_requires_restart       | f
description                   | Path to the java binary for executing UDx written in Java
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once you have set the configuration parameter, Vertica can find the Java executable on each node in your cluster.

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

Since the location of the Java executable is set by a single configuration parameter for the entire cluster, you must ensure that the Java executable is installed in the same path on all of the hosts in the cluster.

&lt;/div&gt;&lt;/p&gt;


      </description>
    </item>
    
    <item>
      <title>Extending: UDx restrictions</title>
      <link>/en/extending/udxs/udx-restrictions/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/udxs/udx-restrictions/</guid>
      <description>
        
        
        &lt;p&gt;Some UDx types have special considerations or restrictions.&lt;/p&gt;
&lt;p&gt;UDxs written in Java and R do not support complex types.&lt;/p&gt;
&lt;h2 id=&#34;aggregate-functions&#34;&gt;Aggregate functions&lt;/h2&gt;
&lt;p&gt;You cannot use the DISTINCT clause in queries with more than one aggregate function or provide inputs or return values containing complex types.&lt;/p&gt;
&lt;h2 id=&#34;analytic-functions&#34;&gt;Analytic functions&lt;/h2&gt;
&lt;p&gt;UDAnFs do not support &lt;a href=&#34;../../../en/data-analysis/sql-analytics/window-framing/windows-with-physical-offset-rows/&#34;&gt;framing windows using ROWS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Only UDAnFs written in C++ can use complex types.&lt;/p&gt;
&lt;p&gt;As with OpenText™ Analytics Database&#39;s built-in analytic functions, UDAnFs cannot be used with &lt;a href=&#34;../../../en/sql-reference/functions/match-and-search-functions/match-clause-functions/#&#34;&gt;MATCH clause functions&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;scalar-functions&#34;&gt;Scalar functions&lt;/h2&gt;
&lt;p&gt;If the result of applying a UDSF is an invalid record, COPY aborts the load even if CopyFaultTolerantExpressions is set to true.&lt;/p&gt;
&lt;p&gt;A ROW returned from a UDSF cannot be used as an argument to COUNT.&lt;/p&gt;

&lt;h2 id=&#34;transform-functions&#34;&gt;Transform functions&lt;/h2&gt;
&lt;p&gt;A query that includes a UDTF cannot:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Include statements other than the &lt;a href=&#34;../../../en/sql-reference/statements/select/#&#34;&gt;SELECT&lt;/a&gt; statement that calls the UDTF and a PARTITION BY expression unless the UDTF is marked as a &lt;a href=&#34;../../../en/extending/developing-udxs/transform-functions-udtfs/partitioning-options-udtfs/#One-to-Many UDTF&#34;&gt;one-to-many UDTF&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Call an &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/&#34;&gt;analytic function&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Call another UDTF&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Include one of the following clauses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/statements/select/timeseries-clause/&#34;&gt;TIMESERIES&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/match-and-search-functions/match-clause-functions/&#34;&gt;Pattern matching&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/data-analysis/time-series-analytics/gap-filling-and-interpolation-gfi/&#34;&gt;Gap filling and interpolation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;load-functions&#34;&gt;Load functions&lt;/h2&gt;
&lt;p&gt;Installing an untrusted UDL function can compromise the security of the server. UDxs can contain arbitrary code. In particular, user-defined parser functions can read data from any arbitrary location. It is up to the developer of the function to enforce proper security limitations. Superusers must not grant access to UDxs to untrusted users.&lt;/p&gt;

&lt;p&gt;You cannot ALTER UDL functions.&lt;/p&gt;
&lt;p&gt;UDFilter and UDSource functions do not support complex types.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Extending: Fenced and unfenced modes</title>
      <link>/en/extending/udxs/fenced-and-unfenced-modes/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/udxs/fenced-and-unfenced-modes/</guid>
      <description>
        
        
        &lt;p&gt;User-defined extensions (UDxs) written in the C++ programming language have the option of running in fenced or unfenced mode. Fenced mode runs the UDx code outside of the main OpenText™ Analytics Database process in a separate zygote process. UDxs that use unfenced mode run directly within the OpenText™ Analytics Database process.&lt;/p&gt;
&lt;h2 id=&#34;fenced-mode&#34;&gt;Fenced mode&lt;/h2&gt;
&lt;p&gt;You can run most C++ UDxs in fenced mode. Fenced mode uses a separate zygote process, so fenced UDx crashes do not impact the core database process. There is a small performance impact when running UDx code in fenced mode. On average, using fenced mode adds about 10% more time to execution compared to unfenced mode.&lt;/p&gt;
&lt;p&gt;Fenced mode is currently available for all C++ UDxs with the exception of user-defined aggregates. All UDxs developed in the Python, R, and Java programming languages must run in fenced mode, since the Python, R, and Java runtimes cannot run directly within the database process.&lt;/p&gt;
&lt;p&gt;Using fenced mode does not affect the development of your UDx. Fenced mode is enabled by default for UDxs that support fenced mode. Optionally, you can issue the &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/&#34;&gt;CREATE FUNCTION&lt;/a&gt; command with the &lt;code&gt;NOT FENCED&lt;/code&gt; modifier to disable fenced mode for the function. Additionally, you can enable or disable fenced mode on any fenced mode-supported C++ UDx by using the &lt;a href=&#34;../../../en/sql-reference/statements/alter-statements/alter-function-statements/&#34;&gt;ALTER FUNCTION&lt;/a&gt; command.&lt;/p&gt;
&lt;h2 id=&#34;unfenced-mode&#34;&gt;Unfenced mode&lt;/h2&gt;
&lt;p&gt;Unfenced UDxs run within the database, so they have little overhead, and can perform almost as fast as the database&#39;s own built-in functions. However, because they run within the database directly, any bugs in their code (memory leaks, for example) can destabilize the main database process and bring one or more database nodes down.

&lt;div class=&#34;admonition important&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Important&lt;/h4&gt;
Always carefully review code downloaded from third-party sources and test UDxs in a test or staging environment before deciding to run them in unfenced mode in production.
&lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&#34;about-the-zygote-process&#34;&gt;About the zygote process&lt;/h2&gt;
&lt;p&gt;The OpenText™ Analytics Database zygote process starts when the database starts. Each node has a single zygote process. Side processes are created &amp;quot;on demand&amp;quot;. The zygote listens for requests and spawns a UDx side session that runs the UDx in fenced mode when a UDx is called by the user.&lt;/p&gt;
&lt;h2 id=&#34;about-fenced-mode-logging&#34;&gt;About fenced mode logging:&lt;/h2&gt;
&lt;p&gt;UDx code that runs in fenced mode is logged in the &lt;code&gt;UDxZygote.log&lt;/code&gt; and is stored in the &lt;code&gt;UDxLogs&lt;/code&gt; directory in the catalog directory of the database. Log entries for the side process are denoted by the UDx language (for example, C++), node, zygote process ID, and the UDxSideProcess ID.&lt;/p&gt;
&lt;p&gt;For example, for the following query returns the current fenced processes:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM UDX_FENCED_PROCESSES;
    node_name     |   process_type   |            session_id            |  pid  | port  | status
------------------+------------------+----------------------------------+-------+-------+--------
 v_vmart_node0001 | UDxZygoteProcess |                                  | 27468 | 51900 | UP
 v_vmart_node0001 | UDxSideProcess   | localhost.localdoma-27465:0x800b |  5677 | 44123 | UP
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Below is the corresponding log file for the fenced processes returned in the previous query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;2016-05-16 11:24:43.990 [C++-localhost.localdoma-27465:0x800b-5677]  0x2b3ff17e7fd0 UDx side process started
 11:24:43.996 [C++-localhost.localdoma-27465:0x800b-5677]  0x2b3ff17e7fd0 Finished setting up signal handlers.
 11:24:43.996 [C++-localhost.localdoma-27465:0x800b-5677]  0x2b3ff17e7fd0 My port: 44123
 11:24:43.996 [C++-localhost.localdoma-27465:0x800b-5677]  0x2b3ff17e7fd0 My address: 0.0.0.0
 11:24:43.996 [C++-localhost.localdoma-27465:0x800b-5677]  0x2b3ff17e7fd0 Vertica port: 51900
 11:24:43.996 [C++-localhost.localdoma-27465:0x800b-5677]  0x2b3ff17e7fd0 Vertica address: 127.0.0.1
 11:25:19.749 [C++-localhost.localdoma-27465:0x800b-5677]  0x41837940 Setting memory resource limit to -1
 11:30:11.523 [C++-localhost.localdoma-27465:0x800b-5677]  0x41837940 Exiting UDx side process
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The last line indicates that the side process was killed. In this case it was killed when the user session (vsql) closed.&lt;/p&gt;
&lt;h2 id=&#34;about-fenced-mode-configuration-parameters&#34;&gt;About fenced mode configuration parameters&lt;/h2&gt;
&lt;p&gt;Fenced mode supports the following &lt;a href=&#34;../../../en/admin/configuring-db/config-parameter-management/&#34;&gt;configuration parameters&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;FencedUDxMemoryLimitMB&lt;/code&gt;: The maximum memory size, in MB, to use for fenced mode processes. The default is &lt;code&gt;-1&lt;/code&gt; (no limit). The side process is killed if this limit is exceeded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ForceUDxFencedMode&lt;/code&gt;: When set to &lt;code&gt;1&lt;/code&gt;, force all UDxs that support fenced mode to run in fenced mode even if their definitions specify NOT FENCED. The default is &lt;code&gt;0&lt;/code&gt; (disabled).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;UDxFencedBlockTimeout&lt;/code&gt;: The maximum time, in seconds, that the database server waits for a UDx to return before aborting with ERROR 3399. The default is &lt;code&gt;60&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;UDxJVMIdleTimeout&lt;/code&gt;: The maximum time, in seconds, that a Java UDx JVM is allowed to remain idle (no active tasks and no incoming requests) before it exits automatically. When this timeout is reached, the JVM shuts down gracefully and logs the inactivity event in the Java UDx logs. The default is 120.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;see-also&#34;&gt;See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-library/#&#34;&gt;CREATE LIBRARY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-function-scalar/&#34;&gt;CREATE FUNCTION&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-transform-function/#&#34;&gt;CREATE TRANSFORM FUNCTION&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-analytic-function/#&#34;&gt;CREATE ANALYTIC FUNCTION&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/sql-reference/statements/alter-statements/alter-function-statements/alter-function-scalar/#&#34;&gt;ALTER FUNCTION (scalar)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/sql-reference/system-tables/v-monitor-schema/udx-fenced-processes/#&#34;&gt;UDX_FENCED_PROCESSES&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Extending: Updating UDx libraries</title>
      <link>/en/extending/udxs/updating-udx-libraries/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/udxs/updating-udx-libraries/</guid>
      <description>
        
        
        &lt;p&gt;There are two cases where you need to update libraries that you have already deployed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;When you have upgraded OpenText™ Analytics Database to a new version that contains changes to the SDK API. For your libraries to work with the new server version, you need to recompile them with new version of the SDK. See &lt;a href=&#34;../../../en/extending/udxs/updating-udx-libraries/udx-library-compatibility-with-new-server-versions/#&#34;&gt;UDx library compatibility with new server versions&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When you have made changes to your UDxs and you want to deploy these changes. Before updating your UDx library, you need to determine if you have changed the signature of any of the functions contained in the library. If you have, you need to drop the functions from the database catalog before you update the library.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Extending: Listing the UDxs contained in a library</title>
      <link>/en/extending/udxs/listing-udxs-contained-library/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/udxs/listing-udxs-contained-library/</guid>
      <description>
        
        
        &lt;p&gt;Once a library has been loaded using the &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-library/#&#34;&gt;CREATE LIBRARY&lt;/a&gt; statement, you can find the UDxs and UDLs it contains by querying the &lt;a href=&#34;../../../en/sql-reference/system-tables/v-monitor-schema/user-library-manifest/#&#34;&gt;USER_LIBRARY_MANIFEST&lt;/a&gt; system table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE LIBRARY ScalarFunctions AS &amp;#39;/home/dbadmin/ScalarFunctions.so&amp;#39;;
CREATE LIBRARY
=&amp;gt; \x
Expanded display is on.
=&amp;gt; SELECT * FROM USER_LIBRARY_MANIFEST WHERE lib_name = &amp;#39;ScalarFunctions&amp;#39;;
-[ RECORD 1 ]-------------------
schema_name | public
lib_name    | ScalarFunctions
lib_oid     | 45035996273792402
obj_name    | RemoveSpaceFactory
obj_type    | Scalar Function
arg_types   | Varchar
return_type | Varchar
-[ RECORD 2 ]-------------------
schema_name | public
lib_name    | ScalarFunctions
lib_oid     | 45035996273792402
obj_name    | Div2intsInfo
obj_type    | Scalar Function
arg_types   | Integer, Integer
return_type | Integer
-[ RECORD 3 ]-------------------
schema_name | public
lib_name    | ScalarFunctions
lib_oid     | 45035996273792402
obj_name    | Add2intsInfo
obj_type    | Scalar Function
arg_types   | Integer, Integer
return_type | Integer
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;obj_name&lt;/code&gt; column lists the factory classes contained in the library. These are the names you use to define UDxs and UDLs in the database catalog using statements such as &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-function-scalar/&#34;&gt;CREATE FUNCTION&lt;/a&gt; and &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-function-statements/create-source/#&#34;&gt;CREATE SOURCE&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Extending: Using wildcards in your UDx</title>
      <link>/en/extending/udxs/using-wildcards-your-udx/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/extending/udxs/using-wildcards-your-udx/</guid>
      <description>
        
        
        &lt;p&gt;OpenText™ Analytics Database supports wildcard * characters in the place of column names in user-defined functions.&lt;/p&gt;
&lt;p&gt;You can use wildcards when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Your query contains a table in the FROM clause.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You are using a OpenText™ Analytics Database-supported development language.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Your UDx is running in fenced or unfenced mode.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;supported-sql-statements&#34;&gt;Supported SQL statements&lt;/h2&gt;
&lt;p&gt;The following SQL statements can accept wildcards:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DELETE&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;INSERT&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SELECT&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UPDATE&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;unsupported-configurations&#34;&gt;Unsupported configurations&lt;/h2&gt;
&lt;p&gt;The following situations do not support wildcards:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You cannot pass a wildcard in the OVER clause of a query&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You cannot us a wildcard with a DROP statement&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You cannot use wildcards with any other arguments&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;These examples show wildcards and user-defined functions in a range of data manipulation operations.&lt;/p&gt;
&lt;p&gt;DELETE statements:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; DELETE FROM tablename WHERE udf(tablename.*) = 5;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;INSERT statements:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; INSERT INTO table1 SELECT udf(*) FROM table2;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;SELECT statements:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT udf(*) FROM tablename;
=&amp;gt; SELECT udf(tablename.*) FROM tablename;
=&amp;gt; SELECT udf(f.*) FROM table f;
=&amp;gt; SELECT udf(*) FROM table1,table2;
=&amp;gt; SELECT udf1( udf2(*) ) FROM table1,table2;
=&amp;gt; SELECT udf( db.schema.table.*) FROM tablename;
=&amp;gt; SELECT udf(sub.*) FROM (select col1, col2 FROM table) sub;
=&amp;gt; SELECT x FROM tablename WHERE udf(*) = y;
=&amp;gt; WITH sub as (SELECT * FROM tablename) select x, udf(*) FROM sub;
=&amp;gt; SELECT udf( * using parameters x=1) FROM tablename;
=&amp;gt; SELECT udf(table1.*, table2.col2) FROM table1,table2;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;UPDATE statements:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; UPDATE tablename set col1 = 4 FROM tablename WHERE udf(*) = 3;
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
  </channel>
</rss>
