C++言語のシェイパーとサイザー

この例では、次のファイル名を使用する: 'shaper.cpp

コード

この例のコードは、シェイパーとサイザーの両方を示しており、それぞれが同じコードを使用し、基本的に同じタスクを実行する。 このコードは、与えられた入力を出力として返す。 これはリテラル・フィールドの取得を示すものではなく、シェイパー/サイザーの機能だけを示すものである。 この例では、ファンクション・ロジックとシェイパー・ロジックの両方にハンドラを使用しています。 シェイパーにハンドラーを使わないこともできるが、そうする理由はない。
#include <nzaefactory.hpp>
using namespace nz::ae;
static int run(nz::ae::NzaeFunction *aeFunc);
static int doShaper(nz::ae::NzaeShaper *aeShaper);
int main(int argc, char * argv[])
{
NzaeApiGenerator helper;
// The following line is only needed if a launcher is not used
helper.setName("testcapi");
int i = 0;
while (i < 1) {
nz::ae::NzaeApi &api = helper.getApi(nz::ae::NzaeApi::ANY);
if (api.apiType == nz::ae::NzaeApi::FUNCTION) {
run(api.aeFunction);
i++;
}
else {
doShaper(api.aeShaper);
}
if (!helper.isRemote())
break;
}
return 0;
}
class MyHandler : public nz::ae::NzaeFunctionMessageHandler
{
public:
void evaluate(NzaeFunction& api, NzaeRecord &input, NzaeRecord &result) {
const NzaeMetadata& m = api.getMetadata();
nz::ae::NzaeField &field = input.get(0);
if (!field.isNull() ) {
nz::ae::NzaeField &f = result.get(0);
if (field.type() == NzaeDataTypes::NZUDSUDX_NUMERIC32 ||
field.type() == NzaeDataTypes::NZUDSUDX_NUMERIC64 ||
field.type() == NzaeDataTypes::NZUDSUDX_NUMERIC128)
{
NzaeNumericField &nf = (NzaeNumericField&)field;
if (m.getInputSize(0) != nf.precision() ||
m.getInputScale(0) != nf.scale()) {
NzaeNumeric128Field* np = nf.toNumeric128(38, 5);
f.assign(*np);
delete np;
}
else
f.assign(field);
}
else {
f.assign(field);
}
}
}
};
class MyHandler2 : public nz::ae::NzaeShaperMessageHandler
{
public:
void shaper(NzaeShaper& api){
const NzaeMetadata& m = api.getMetadata();
char name[2];
if (api.catalogIsUpper())
name[0] = 'I';
else
name[0] = 'i';
name[1] = 0;
if (m.getInputType(0) == NzaeDataTypes::NZUDSUDX_FIXED ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_VARIABLE ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NATIONAL_FIXED ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NATIONAL_VARIABLE) {
api.addOutputColumnString(m.getInputType(0), name,
m.getInputSize(0));
}
else if (m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NUMERIC128 ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NUMERIC64 ||
m.getInputType(0) == NzaeDataTypes::NZUDSUDX_NUMERIC32) {
api.addOutputColumnNumeric(m.getInputType(0), name, \
m.getInputSize(0), m.getInputScale(0));
}
else {
api.addOutputColumn(m.getInputType(0), name);
}
}
};
static int doShaper(nz::ae::NzaeShaper *aeShaper)
{
aeShaper->run(new MyHandler2());
return 0;
}
static int run(nz::ae::NzaeFunction *aeFunc)
{
aeFunc->run(new MyHandler());
return 0;
}

メインでは、APIオブジェクトはローカルモードで取得されなければならないことに注意してほしい。 さらに、このコードでは、シェイパーがインクリメントされないように、リモート・モード用のループ・ロジックが変更されている。これにより、プログラムの同じインスタンスが、シェイパーとリモート・モードでの関数呼び出しの両方を処理してから終了することができる。 最後に、シェイパー・メッセージ・ハンドラーを追加する。

コンパイル

標準コンパイルを使用する:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language cpp --template compile \
--exe shaperae --compargs "-g -Wall" --linkargs "-g" shaper.cpp \
--version 3

登録

例をUDFとUDTFとして登録する:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "shaperae(VARARGS)" \
--return "table(ANY)" --language cpp --template udtf --exe shaperae \
--version 3
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "sizerae(VARCHAR(ANY))" \
--return "varchar(ANY)" --language cpp --template udf --exe shaperae \
--version 3

実行中

nzsqlでクエリを実行する:
SELECT sizerae('test');
SIZERAE
---------
test
(1 row)
SELECT * FROM TABLE WITH FINAL(shaperae('test'));
I
------
test
(1 row)
SELECT * FROM TABLE WITH FINAL(shaperae(1.1));
I
-----
1.1
(1 row)