外部函数注册和下推

介绍

openLooKeng系统可以在Connector中注册外部函数到function-namespace-manager中。 并且在Jdbc Connector中还支持下推到数据源执行。

在Connector中注册外部函数

openLooKeng可以通过Connector向系统注册外部函数。我们在Jdbc Connector实现了一个例子,下面我们通过例子来讲解。

用户可以在presto-mysql/src/main/java/io.prestosql/plugin/mysql/optimization/function中找到如何在Jdbc Connector向function-namespace-manager注册外部函数的代码。 在Connector中注册外部函数需要以下两个步骤。

  1. 扩展实现下面这个抽象函数类(例如MysqlExternalFunctionHub.java):
  1. public interface ExternalFunctionHub
  2. {
  3. Set<ExternalFunctionInfo> getExternalFunctions();
  4. RoutineCharacteristics.Language getExternalFunctionLanguage();
  5. CatalogSchemaName getExternalFunctionCatalogSchemaName();
  6. }

这些方法返回Connector需要向function-namespace-manager注册的函数信息。 关于如何实现ExternalFunctionHub,我们在MysqlExternalFunctionHub.java中提供了一个简单明了的例子。 例如对于ExternalFunctionHub#getExternalFunctions方法, 我们通过静态类实例注册的形式来实现ExternalFunctionInfo的实例集合的构造。当然你也可以自己定制代码,通过从外部读取文件等形式来构造ExternalFunctionInfo的实例集合, 也就是你只需要注册和返回一个ExternalFunctionInfo的实例集合即可。 在这里我们仅提供基本的通用框架。

另外,我们仅支持在外部函数中声明下列定义在io.prestosql.spi.type.StandardTypes中的类型。

Supported type
StandardTypes.TINYINT
StandardTypes.SMALLINT
StandardTypes.INTEGER
StandardTypes.BIGINT
StandardTypes.DECIMAL
StandardTypes.REAL
StandardTypes.DOUBLE
StandardTypes.BOOLEAN
StandardTypes.CHAR
StandardTypes.VARCHAR
StandardTypes.VARBINARY
StandardTypes.DATE
StandardTypes.TIME
StandardTypes.TIMESTAMP
StandardTypes.TIME_WITH_TIME_ZONE
StandardTypes.TIMESTAMP_WITH_TIME_ZONE
  1. 实现ExternalFunctionHub接口之后,你只需要将其通过实例注入的方式(参考MySqlClientModule.java),注入到JdbcClient(参考MysqlJdbcClient.java)。

配置外部函数注册的命名空间

在完成上述的注册过程之后,你就可以在Connector的Catalog文件中配置你所注册的外部函数需要写入的function-namespace-managercatalog.schema的函数命名空间。 例如在etc/catalog/mysql.properties配置catalog.schema函数命名空间为mysqlfun.default

  1. connector.externalfunction.namespace=mysqlfun.default

外部函数下推

外部函数注册完成后,当前openLooKeng可以通过Jdbc Connector下推到支持执行这些外部函数的数据源中执行,进而取回外部函数处理数据的结果。 一个Jdbc Connector在适配外部函数下推功能之前,首先需要适配Query Push Down功能。当前Query Push Down功能 可以很容易通过继承使用presto-base-jdbc/src/main/java/io.prestosql/plugin/jdbc/optimization提供的基础类来实现,在这里就不再赘述。 openLooKeng已经支持了包括datacenter、hana、oracle、mysql、greenplum等connector的Query Push Down功能。

基于Query Push Down功能的基础上,要支持外部函数下推,需要以下步骤。

  1. 扩展实现ApplyRemoteFunctionPushDown.java 首先你需要实现ApplyRemoteFunctionPushDown.java中的ApplyRemoteFunctionPushDown#rewriteRemoteFunction方法。此方法的作用是将openLooKeng中注册的外部函数, 重写为符合数据源SQL语法的字符串。你可以直接参考presto-mysql/src/main/java/io.prestosql/plugin/mysql/optimization/function/MySqlApplyRemoteFunctionPushDown.java中的实现。

  2. 扩展实现BaseJdbcRowExpressionConverter 扩展重载presto-base-jdbc/src/main/java/io.prestosql/plugin/jdbc/optimization/BaseJdbcRowExpressionConverter.java中的BaseJdbcRowExpressionConverter#visitCall方法。 你需要在此方法中处理识别外部函数,并调用ApplyRemoteFunctionPushDown#rewriteRemoteFunction方法得到符合数据源SQL语法的字符串返回。 具体细节可以参考presto-mysql/src/main/java/io.prestosql/plugin/mysql/optimization/MySqlRowExpressionConverter.java

3.配置当前Connector支持下推的函数命名空间 在上述代码开发完成后,你需要将当前Connector支持的函数命名空间配置在Connector的Catalog文件中。例如在etc/catalog/mysql.properties中配置:

  1. jdbc.pushdown.remotenamespace=mysqlfun.default

一个Connector实例可以声明自己支持多个函数命名空间中的函数,在jdbc.pushdown.remotenamespace配置项中使用’|’分割既可。例如:

  1. jdbc.pushdown.remotenamespace=mysqlfun1.default|mysqlfun2.default|mysqlfun3.default
  2. #表示当前Connector实例同时支持 mysqlfun1.default、mysqlfun2.default、mysqlfun3.default三个函数命名空间最终的函数下推到当前连接的数据源中执行。

在外部函数下推功能适配完成后,你就可以直接在输入openLooKeng的SQL 语句中直接使用外部函数处理数据源的数据。系统会将外部函数下推到Connector连接的数据源执行。 例如SQL 语句:

  1. select mysqlfun.default.format(col1, 2) from double_table;

外部函数 mysqlfun.default.format会下推到数据源执行。下推语句为符合数据源SQL 语法的SQL语句,例如可能为:

  1. SELECT format(col1,2) FROM double_table