Hologres V3.1 and later supports remote calls to user-defined functions (UDFs) running in Alibaba Cloud Function Compute (FC). Use remote functions to run complex business logic or advanced analytics directly within Hologres queries—without moving data out of Hologres.
How it works
When a query references a remote function, Hologres batches the input rows and sends them to FC via an HTTP POST request. FC processes the batch and returns results in a structured JSON response. Hologres then incorporates the results into the query output.
Hologres query → batch rows as JSON → FC function → JSON results → Hologres outputUse cases
Real-time data processing: Call FC during queries to clean data, convert formats, or run complex calculations.
Third-party service integration: Interact with other Alibaba Cloud services or external APIs using Hologres data.
Advanced analytics: Run machine learning inference or other analytics algorithms in FC and write results back to Hologres.
Prerequisites
Before you begin, ensure that you have:
A Hologres instance V3.1 or later. For details, see Purchase a Hologres instance.
Function Compute (FC) activated, with FC version V3.0. Log on to the Function Compute console to activate the service.
The
AliyunServiceRoleForHologresRemoteUDFservice-linked role granted:
Log on to the Hologres console. In the left navigation pane, click Create a Service-linked Role.
Select
AliyunServiceRoleForHologresRemoteUDFand click Authorize Now.
The FC function developed and deployed before calling it from Hologres. For details, see Code development.
The Hologres instance and the FC service must be in the same region.
Limitations
Supported function types: scalar UDFs and user-defined table-valued functions (UDTFs). User-defined aggregate functions (UDAFs) are not supported.
Supported data types:
BOOLEAN,INTEGER,BIGINT,REAL,DOUBLE PRECISION, andTEXT, plus their corresponding array types.Constants are not supported as input parameters.
This feature incurs fees in FC. No extra fees apply in Hologres. For FC billing details, see Billing.
Manage remote functions
Create an extension
Run the following command once per database before using remote functions:
CREATE EXTENSION [ IF NOT EXISTS ] function_compute;Create a function
Parameters
Required parameters
| Parameter | Description |
|---|---|
function_name | The function name. Must be unique within the same schema. Functions with the same name can coexist if their parameter types differ (overloading), for example, rf_add(int) and rf_add(float). Add the rf_ prefix to all remote functions to avoid naming conflicts with built-in functions. When using CREATE OR REPLACE FUNCTION, you cannot change the function name, parameter types, or return type—delete and recreate the function instead. |
argtype | The data type of each parameter. |
LANGUAGE function_compute | A fixed value that declares the use of FC. |
fc_endpoint | The internal network endpoint of FC. For endpoint formats, see Service endpoints. |
func_name | The name of the FC function to call. Create this function in the FC console before referencing it here. |
Optional parameters
| Parameter | Description | Default |
|---|---|---|
argmode | The parameter mode: IN, OUT, or INOUT. Avoid INOUT to prevent ambiguity. A function can have at most one OUT or INOUT parameter. | IN |
argname | The parameter name. For input parameters, the name is for documentation only. For output parameters, the name determines the column name in the result set. | System-generated |
default_expr | The default value for an input parameter. If a parameter has a default, all subsequent parameters must also have defaults. | None |
rettype | The return value type. Can be omitted when OUT or INOUT parameters are present; if specified, it must match the output parameter types. | — |
column_name | The output column name when using RETURNS TABLE. Using RETURNS TABLE implies RETURNS SETOF. | System-generated |
column_type | The data type of an output column in RETURNS TABLE. | — |
CALLED ON NULL INPUT | Calls the function even when some arguments are null. The function must handle null values. | Default behavior |
RETURNS NULL ON NULL INPUT / STRICT | Returns null automatically if any argument is null. STRICT is an alias for RETURNS NULL ON NULL INPUT. | — |
qualifier | The FC function version or alias to invoke. | LATEST |
compression | The compression algorithm for request and response payloads. Valid values: None (disabled) or GZIP. | None |
max_batch_size | The maximum number of rows sent to FC per request batch. Set this only when the FC function has memory limits or other constraints. If omitted, Hologres calculates the optimal batch size automatically. | Auto |
Examples
Create a scalar UDF:
CREATE OR REPLACE FUNCTION rf_add (
a INTEGER,
b INTEGER DEFAULT 1
)
RETURNS BIGINT
LANGUAGE function_compute
AS 'xxxxxxxxxxxxx.cn-shanghai-internal.fc.aliyuncs.com/add'
;Create a user-defined table-valued function (UDTF):
-- Form 1: RETURNS TABLE
CREATE OR REPLACE FUNCTION rf_unnest(TEXT [])
RETURNS TABLE (item TEXT)
LANGUAGE function_compute
AS 'xxxxxxxxxxxxxx.cn-hangzhou-internal.fc.aliyuncs.com/unnest'
STRICT
SET function_compute.max_batch_size TO 1024;
-- Form 2: RETURNS SETOF
CREATE OR REPLACE FUNCTION rf_unnest(TEXT [])
RETURNS SETOF TEXT
LANGUAGE function_compute
AS 'xxxxxxxxxxxxxx.cn-hangzhou-internal.fc.aliyuncs.com/unnest'
STRICT
SET function_compute.max_batch_size TO 1024;View functions
List all remote functions in the current database:
SELECT
CASE
WHEN p.proretset = 'f' THEN 'scalar UDF'
WHEN p.proretset = 't' THEN 'UDTF'
END AS function_type,
n.nspname AS schema_name,
p.proname AS function_name,
pg_get_function_arguments(p.oid) AS arguments,
pg_get_function_result(p.oid) AS return_type,
p.proisstrict AS is_strict,
p.proconfig AS config,
pg_get_functiondef(p.oid) AS definition
FROM
pg_proc p
JOIN pg_language l ON p.prolang = l.oid
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE
l.lanname = 'function_compute'
AND p.prokind != 'p'
ORDER BY
function_type,
schema_name,
function_name;Delete a function
Parameters
| Parameter | Required | Description |
|---|---|---|
function_name | Yes | The name of the function to delete. |
argtype | Yes | The data type of the parameter. |
argmode | No | The parameter mode: IN, OUT, or INOUT. Defaults to IN. |
argname | No | The parameter name. For input parameters, the name is for documentation only. For output parameters, the name determines the column name in the result set. |
Example
DROP FUNCTION rf_add(INTEGER, INTEGER);Data interaction format
Hologres and FC exchange data as JSON. The following examples use a remote function with the signature rf_demo(TEXT, INTEGER, BOOLEAN).
Request: Hologres to FC
Hologres calls the FC InvokeFunction API with an HTTP POST request. The request body contains a data key holding a two-dimensional array. Each element in the array represents one row of input data for the function call.
Serialization rules:
| SQL type | JSON type |
|---|---|
BOOLEAN | boolean |
INTEGER, BIGINT | number |
REAL, DOUBLE PRECISION | number |
TEXT | string |
NULL | null |
Request example:
{
"data": [
["foo", 100, true],
[null, null, false],
["bar", 200, false]
]
}FC handler skeleton (Python):
Parse the data field and return a results array. The following skeleton covers the complete request-to-response cycle for a scalar UDF:
import json
def handler(event, context):
evt = json.loads(event)
data = evt.get('data', [])
results = []
for row in data:
# row is a list of argument values, e.g. ["foo", 100, True]
output = process(row) # replace with your logic
results.append([output]) # each result must be wrapped in a list
return json.dumps({'results': results})For a UDTF that produces multiple output rows per input row, see the response format section below.
Response: FC to Hologres
FC returns results as a JSON object with a results field.
Scalar UDFs
Each element in results corresponds to one input row, in the same order. Each element must be an array.
{
"results": [
["Beijing"],
["Shanghai"],
["Shenzhen"],
["Guangzhou"]
]
}UDTFs
A UDTF can produce multiple output rows from a single input row. Each element in results is a two-element array: [row_num, result].
row_num: The 0-based index of the corresponding input row. Values must be in ascending order.result: The output value for that row.
{
"results": [
[0, "Beijing"],
[1, "Shanghai"],
[3, "Shenzhen"],
[3, "Guangzhou"]
]
}In this example, input row 2 produced no output, and input row 3 produced two output rows.
End-to-end example
This example creates an unnest function that expands an integer array into individual rows.
Step 1: Create an FC event-triggered function
Log on to the Function Compute console. In the left navigation pane, click Functions and switch to the region where your Hologres instance resides.
On the Functions page, click Create Function.
Select Event Function and configure the following parameters. Keep the defaults for all other settings. For details, see Create an event-triggered function.
Parameter Value Function Name unnestRuntime Built-in Runtimes > Python > Python 3.10 Code Upload Method Upload Code via ZIP Package Code Package Save the following code as unnest.py, compress it intounnest.zip, and upload the file.Handler unnest.unnestimport json def unnest(event, context): evt = json.loads(event) data = evt.get('data', None) if data is None: raise ValueError('no "data" key in event.') if not isinstance(data, list): raise ValueError('data is not a list.') res = list() for i in range(len(data)): if len(data[i]) != 1 or not isinstance(data[i], list): raise ValueError('the item in data is not a list.') for item in data[i][0]: res.append([i, item]) return json.dumps({'results': res})
Step 2: Create the Hologres remote function
Run these statements in HoloWeb or any PostgreSQL-compatible client connected to Hologres. For details, see Connect to HoloWeb.
CREATE EXTENSION IF NOT EXISTS function_compute;
CREATE OR REPLACE FUNCTION rf_unnest(INTEGER [])
RETURNS SETOF INTEGER
STRICT
LANGUAGE function_compute
AS 'xxxxxxxxxxxxxxxxx.cn-shanghai-internal.fc.aliyuncs.com/unnest';Step 3: Prepare test data
CREATE TABLE test_array (
numbers INTEGER[]
);
INSERT INTO test_array (numbers) VALUES
(ARRAY[1, 3]),
(ARRAY[2, 4]),
('{}'),
(ARRAY[]::INTEGER[]),
(NULL);Step 4: Call the remote function
SELECT numbers, rf_unnest(numbers) FROM test_array;Expected output:
numbers | rf_unnest
---------+-----------
{2,4} | 2
{2,4} | 4
{1,3} | 1
{1,3} | 3
(4 rows)Rows with empty arrays or NULL produce no output, because the function is defined with STRICT.
What's next
Trial quotas — Claim a free FC resource plan to get started without cost.
FC billing — Understand how FC charges apply when Hologres calls remote functions.
Service endpoints — Find the internal network endpoint for your FC region.