非Pushdown関数を定義するには、VDB定義のMetadataに一致するJava関数を提供する必要があります。ユーザー定義関数(UDF)とユーザー定義集約関数(UDAF)は、それぞれ他の関数や集約関数と同様に、実行時に呼び出すことができます。

Function Metadata

UDFのプロパティ・ダイアログでJavaコード実装の詳細を提供することを忘れないでください。UDFまたはUDAFは以下のように定義できます:

CREATE FUNCTION views.md5(p string) RETURNS string OPTIONS (JAVA_CLASS 'com.datavirtuality.dv.core.teiid.md5.MD5Handler', JAVA_METHOD 'calculate') ;;
 
SELECT views.md5('test') FROM test_tables_pg.test_d;;
 
SELECT views.md5(e) FROM test_tables_pg.test_d;;
 
SELECT views.md5('test') ;;

関数のロジックを含むJavaメソッドを作成する必要があります。このJava メソッドは必要な引数を受け入れ、CData Virtuality Server は実行時に引数を渡し、関数は計算または変更された値を返します。

Writing the Java Code Required by the UDF

入力引数の数と型は、VDBのメタデータに定義されている関数のメタデータと一致している必要があります。

Code Requirements for UDFs

  • 関数メソッドを含むjavaクラスはpublicとして定義する必要があります;

One implementation class can contain more than one UDF implementation method.

  • 関数メソッドはpublicでstaticでなければなりません。

Example:
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;
}
}

Code Requirements For UDAFs

  • 関数メソッドを含むjavaクラスはpublicとして定義され、org.teiid.UserDefinedAggregateを拡張する必要があります;

  • 関数メソッドはpublicでなければなりません。

Example:
package org.something;
 
public static class SumAll implements UserDefinedAggregate<Integer> {
 
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;
}
 
}

Other Considerations

  • どんな例外でもスローできますが、CData Virtuality Server はFunctionExecutionExceptionとして例外を再スローします;

  • オプションで、org.teiid.CommandContextの引数を最初のパラメータとして追加することができます。CommandContextインターフェースは、実行ユーザー、サブジェクト、VDB、セッション ID など、現在のコマンドに関する情報へのアクセスを提供します。このCommandContextパラメータは、Function Metadata で宣言すべきではありません。

CommandContext の使用例
package org.something;
 
public class SessionInfo
{
/**
* @param context
* @return the created Timestamp
*/
public static Timestamp sessionCreated(CommandContext context)
{
return new Timestamp(context.getSession().getCreatedTime());
}
}

対応する UDF はtimestamp sessionCreated()として宣言されます。

Post-code Activities

  • 関数をコーディングした後、Java コードをJava アーカイブ(JAR)ファイルにコンパイルし、カスタムモジュールとしてCData Virtuality Server へ追加し、このモジュールをメインのteiid モジュールの依存関係としてインクルードします;

  • モジュール構成を変更する前にCData Virtuality Server を停止し、変更後に再起動する必要があります。

Adding Custom Module

JAR ファイルを<dvserver-folder>/modulesディレクトリに配置して WildFly モジュールを作成します(例:<dvserver-folder>/modules/system/layers/base/udfexample/main)。module.xmlファイルを以下のように同じフォルダに作成します(jar ファイルの名前はudfexample.jarとします):

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="udfexample">
<resources>
<resource-root path="udfexample.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>

Adding Module Dependency

サーバー起動時にモジュールをロードするには、/modules/system/layers/base/org/jboss/teiid/main/module.xmlファイルを修正して、メイン teiid モジュールへの依存として追加します。<dependencies>セクションを見つけ、以下のようにモジュールを追加します:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.jboss.teiid">
<resources>
.
.
.
</resources>
 
<dependencies>
<module name="javax.api" />
.
.
.
<module name="udfexample"/>
</dependencies>
</module>