C++ 示例: BasicIntegerParser
BasicIntegerParser
示例解析由非数字字符分隔的整数字符串。有关使用持续加载的此解析器的版本,请参阅 C++ 示例: ContinuousIntegerParser。
加载和使用示例
按如下所示加载并使用 BasicIntegerParser
示例。
=> CREATE LIBRARY BasicIntegerParserLib AS '/home/dbadmin/BIP.so';
=> CREATE PARSER BasicIntegerParser AS
LANGUAGE 'C++' NAME 'BasicIntegerParserFactory' LIBRARY BasicIntegerParserLib;
=> CREATE TABLE t (i integer);
=> COPY t FROM stdin WITH PARSER BasicIntegerParser();
0
1
2
3
4
5
\.
实施
BasicIntegerParser
类仅实施 API 中的 process()
方法。(它还实施了一个用于类型转换的 helper 方法。)此方法处理每一行输入,查找每一行的数字。当它前进到新行时,它会移动 input.offset
标记并检查输入状态。然后它写入输出。
virtual StreamState process(ServerInterface &srvInterface, DataBuffer &input,
InputState input_state) {
// WARNING: This implementation is not trying for efficiency.
// It is trying for simplicity, for demonstration purposes.
size_t start = input.offset;
const size_t end = input.size;
do {
bool found_newline = false;
size_t numEnd = start;
for (; numEnd < end; numEnd++) {
if (input.buf[numEnd] < '0' || input.buf[numEnd] > '9') {
found_newline = true;
break;
}
}
if (!found_newline) {
input.offset = start;
if (input_state == END_OF_FILE) {
// If we're at end-of-file,
// emit the last integer (if any) and return DONE.
if (start != end) {
writer->setInt(0, strToInt(input.buf + start, input.buf + numEnd));
writer->next();
}
return DONE;
} else {
// Otherwise, we need more data.
return INPUT_NEEDED;
}
}
writer->setInt(0, strToInt(input.buf + start, input.buf + numEnd));
writer->next();
start = numEnd + 1;
} while (true);
}
};
在工厂中,plan()
方法是无操作的;没有要检查的参数。prepare()
方法使用 SDK 提供的宏实例化解析器:
virtual UDParser* prepare(ServerInterface &srvInterface,
PerColumnParamReader &perColumnParamReader,
PlanContext &planCtxt,
const SizedColumnTypes &returnType) {
return vt_createFuncObject<BasicIntegerParser>(srvInterface.allocator);
}
getParserReturnType()
方法声明了单个输出:
virtual void getParserReturnType(ServerInterface &srvInterface,
PerColumnParamReader &perColumnParamReader,
PlanContext &planCtxt,
const SizedColumnTypes &argTypes,
SizedColumnTypes &returnType) {
// We only and always have a single integer column
returnType.addInt(argTypes.getColumnName(0));
}
对于所有用 C++ 编写的 UDx,该示例以注册其工厂结束:
RegisterFactory(BasicIntegerParserFactory);