非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>