定数モードのUDFテーブルを実装するメソッドはすべてのAMP vproc上で実行され、各コピーに同じ入力引数が渡されます。各コピーは、メソッドが終了したことを示すまでは繰り返し呼び出されます。
テーブルUDFの設計時に、すべてのAMP vprocですべてのメソッドが処理に参加することに意味があるかどうかを判別する必要があります。
例えば、標準的な定数モードのUDFテーブルは通常、データベースの外部からデータを読み取って結果行を生成します。外部データが1ノードだけで利用可能な場合は、1つのvproc上の1つのメソッドのコピーだけに何かの有用な機能を持たせるほうが実用的です。一方、外部データが各ノードで利用可能な場合は、すべてのAMP vprocからデータを読み取れるようにしておくほうが望ましいと言えます。
| ユーザー | 結果 |
|---|---|
| メソッドのすべてのコピーが処理に参加するようにする | ガイドラインとして以下のコード抜粋を使用してメソッドを実装します。Tbl tbl = new Tbl();
int[] phase = new int[1];
if ( tbl.getPhase(phase) != Tbl.TBL_MODE_CONST )
{
/* set SQLSTATE to an error and return */
throw new SQLException("Wrong mode", "38U06");
return;
}
/* depending on the phase decide what to do */
switch(phase[0])
{
case Tbl.TBL_PRE_INIT:
{
break;
}
case Tbl.TBL_INIT:
{
/* Perform preprocessing or initializations here. */
...
break;
}
case Tbl.TBL_BUILD:
{
/* Read from files and build the result row here. */
/* On EOF, set SQLSTATE to "02000" (no row to build). */
...
break;
}
case Tbl.TBL_END:
{
/* Everyone done. */
...
break;
}
case Tbl.TBL_ABORT:
{
/* A copy called Tbl.abort(). */
...
break;
}
}
|
| どのAMP上でも実行可能であり、参加するコピーを1つだけ必要とするメソッド | メソッドのすべてのコピーからTbl.firstParticipant()を呼び出します。呼び出しを行なった最初のコピーが、参加するコピーです。他のすべてのコピーは、Tbl.optOut()を呼び出して戻る必要があります。 ガイドラインとして以下のコード抜粋を使用してメソッドを実装します。 Tbl tbl = new Tbl();
int[] phase = new int[1];
if ( tbl.getPhase(phase) != Tbl.TBL_MODE_CONST )
{
/* set SQLSTATE to an error and return */
throw new SQLException("Wrong mode", "38U06");
return;
}
/* depending on the phase decide what to do */
switch(phase[0])
{
case Tbl.TBL_PRE_INIT:
{
if (tbl.firstParticipant()) {
return; /* participant */
} else {
if (!tbl.optOut()) { /* not a participant */
throw new SQLException("Opt out failure", "38U06");
}
return;
}
break;
}
case Tbl.TBL_INIT:
{
/* Perform preprocessing or initializations here. */
...
break;
}
case Tbl.TBL_BUILD:
{
/* Read from files and build the result row here. */
/* On EOF, set SQLSTATE to "02000" (no row to build). */
...
break;
}
case Tbl.TBL_END:
{
/* Everything is done. */
...
break;
}
case Tbl.TBL_ABORT:
{
/* A copy called Tbl.abort(). */
...
break;
}
}
|
| メソッドの1つのコピーを、他のAMP vproc上で実行するすべてのコピーの制御コピーにする | Tbl.control()を呼び出して、UDFテーブルの1つのコピーを制御コピーとして指定します。Tbl.setCtrlCtx()を呼び出して、他のコピーにデータを配布します。 ガイドラインとして以下のコード抜粋を使用してメソッドを実装します。 class ctrl_ctx implements Serializable {
int ctrl_AMP;
int qfd;
...
} ;
public class UDFExample {
public static void getStoreData(int storeData,
int[] storeNo,
int[] itemNo)
{
ctrl_ctx options;
Tbl tbl = new Tbl();
int[] phase = new int[1];
if ( tbl.getPhase(phase) != Tbl.TBL_MODE_CONST )
{
/* set SQLSTATE to an error and return */
throw new SQLException("Wrong mode", "38U06");
return;
}
/* Depending on the phase decide what to do. */
switch(phase[0])
{
case Tbl.TBL_PRE_INIT:
AMPInfo localCfg = new AMPInfo();
/* Run controlling copy on lowest AMP on node. */
if (localCfg.lowestAMPOnNode())
{
/* Run on node that can access external file. */
...
if ( tbl.control() )
{
/* Use scratchpad to distribute data to */
/* copies during the Tbl.TBL_INIT phase. */
options.ctrl_AMP = localCfg.getAMPId();
tbl.setCtrlCtx(options);
...
}
}
break;
case Tbl.TBL_INIT:
/* Get the data from the controlling copy. */
options = tbl.getCtrlCtx();
...
break;
case Tbl.TBL_BUILD:
/* Build result row or set SQLSTATE */
/* to "02000" if no data. */
...
break;
case Tbl.TBL_END:
/* Everyone done. */
...
break;
case Tbl.TBL_ABORT:
/* A copy called Tbl.abort(). */
...
break;
}
}
}
|