概述
自定义协议在一些特殊场景下比较有用,例如需要在自己的系统和Greenplum之间直接导入、导出数据。下面简单介绍一下开发一个自定义协议的步骤:
主要步骤
1、按照Greenplum预定义的API格式,实现几个C接口(import、export、validate_urls)。这些接口将被编译成so的导出函数,并最终注册到GP(需要用户自己定义GP函数进行注册,后面会讲到。)
CREATE FUNCTION myread() RETURNS integer
as '$libdir/gpextprotocol.so', 'demoprot_import'
LANGUAGE C STABLE;
CREATE FUNCTION mywrite() RETURNS integer
as '$libdir/gpextprotocol.so', 'demoprot_export'
LANGUAGE C STABLE;
#可选函数
CREATE OR REPLACE FUNCTION myvalidate() RETURNS void
AS '$libdir/gpextprotocol.so', 'demoprot_validate_urls'
LANGUAGE C STABLE;
3、基于上面定义这些数据库函数,定义自定义协议myprot。 其中myvalidatorfunc 是可选的。
CREATE TRUSTED PROTOCOL myprot(
writefunc='mywrite',
readfunc='myread',
validatorfunc='myvalidate');
GRANT ALL ON PROTOCOL myprot TO otheruser
5、基于上述协议,创建可读或可写的外部表。
PS:自定义协议的外部表对异常数据处理和标准协议外部表相同。
CREATE WRITABLE EXTERNAL TABLE ext_sales(LIKE sales)
LOCATION ('myprot://<meta>/<meta>/…')
FORMAT 'TEXT';
CREATE READABLE EXTERNAL TABLE ext_sales(LIKE sales)
LOCATION('myprot://<meta>/<meta>/…')
FORMAT 'TEXT';
自定义协议核心代码
导出函数
实现将数据从Greenplum导出到外部表的过程。
Greenplum 外部表调用框架代码会根据sql语句,将查询到的数据组织成指定格式(如TEXT或CSV)放到一个buffer中,用户调用API获取该buffer的地址,从中读取数据,并按照自己的业务逻辑将其发送到自定义外部表。
其处理流程大概如下:
初始化外部连接->向外部系统发数据->关闭外部系统连接。
export函数会被GP外部表框架多次调用(取决于数据量的多少),需要我们结合GP提供的API自己判断连接是否初始化(初始化成功后将连接信息保存到自定义数据区)、数据是否发送完成。
初始化连接
当export函数被调用时,首先调用 EXTPROTOCOL_GET_USER_CTX 获取自定义信息(可用于保存外部表连接的描述信息),如果为NULL,则需要执行初始化连接的动作,并调用 EXTPROTOCOL_SET_USER_CTX 保存上述信息。
发送数据
Datum
myprot_export(PG_FUNCTION_ARGS)
{
……
/*