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