This topic describes how to create a Hologres external table, including how to specify a Hologres data source, grant access through a RAM role or service-linked role, map a target table, and configure JDBC driver settings in the CREATE TABLE statement.
Overview
Hologres is a real-time interactive analytical data warehouse that is compatible with the PostgreSQL protocol and seamlessly integrates with MaxCompute. You can create Hologres external tables in MaxCompute to query a Hologres data source using the PostgreSQL JDBC driver and Hologres RAM role authentication. This method eliminates redundant storage, requires no data imports or exports, and delivers fast query results.
Limitations
Data manipulation (DML)
MaxCompute does not support
UPDATEorDELETEoperations on Hologres external tables.Hologres external tables do not support the
INSERT OVERWRITEstatement.To overwrite data in a Hologres table with data from MaxCompute, run an
INSERT OVERWRITEstatement in Hologres. This statement reads data from an external table in Hologres that maps to a MaxCompute table. For more information, see INSERT OVERWRITE.
Data write risk
When you write large volumes of data to a Hologres external table, parallel write processes are used. In rare cases, one of these processes might rewrite data, which can cause data duplication.
Partitions
Partitioned tables in Hologres and MaxCompute do not map directly to each other. Hologres external tables do not support partitions. However, in direct-read mode, when you query a Hologres external table that maps to a Hologres partitioned parent table, partition pruning applies if the query filter includes a condition on the partition column of an underlying partitioned child table.
Hologres external tables do not support the
clusterattribute.Hologres external tables do not support mapping to a Hologres Dynamic Table.
See the list of Supported data types.
Create a Hologres external table
You can create a Hologres external table using either the RAM role authorization for Hologres or the service-linked role authorization mode.
Considerations
Guidelines for creating external tables
If your Hologres instance uses an IP whitelist for external access, upgrade it to a supported version:
For the RAM role authorization mode, upgrade to Hologres V3.2 or later.
For the service-linked role authorization mode, upgrade to Hologres V2.0.28 or later.
After the upgrade, Hologres automatically trusts MaxCompute node IPs based on the MaxCompute service identity or the service-linked role. You no longer need to add MaxCompute elastic node IP addresses to the IP whitelist of your Hologres instance.
You can map both parent tables and child tables in Hologres to an external table. However, you can only read from, not write to, an external table that maps to a parent table.
When you write data to a Hologres external table, the INSERT ON CONFLICT (UPSERT) mechanism is not supported. If the Hologres source table has a primary key, avoid writing data that causes primary key conflicts.
Table names and column names are case-insensitive. You cannot enforce case sensitivity when you create or query tables and columns.
Schema compatibility
If the Hologres source table schema does not match the external table schema, note the following points:
Mismatched column count: If the source table has fewer columns than the external table, reading data fails with an error such as
column "xxx" does not exist. If the source table has more columns than the external table, the extra columns are ignored.Mismatched column types: MaxCompute cannot map a
STRINGcolumn from a Hologres source table to anINTcolumn in the external table. Mapping anINTcolumn to aSTRINGcolumn is supported but not recommended.
Syntax
When creating an external table, specify the StorageHandler in the CREATE TABLE DDL statement, configure RAM role authorization or service-linked role authorization, and provide the JDBC connection URL to access the Hologres data source.
RAM role mode
For a complete code sample, see Create a Hologres external table (RAM role authorization mode).
CREATE EXTERNAL TABLE [IF NOT EXISTS] <table_name>(
<col1_name> <data_type>,
<col2_name> <data_type>,
......
)
stored BY 'com.aliyun.odps.jdbc.JdbcStorageHandler'
WITH serdeproperties (
'odps.properties.rolearn'='<role_arn>')
location 'jdbc:postgresql://<endpoint>:<port>/<database>?
ApplicationName=MaxCompute&[currentSchema=<schema>&]
[useSSL={true|false}&]table=<holo_table_name>/'
tblproperties (
'mcfed.mapreduce.jdbc.driver.class'='org.postgresql.Driver',
'odps.federation.jdbc.target.db.type'='holo',
-- When Hologres and MaxCompute column names differ, add the odps.federation.jdbc.colmapping parameter to map columns.
-- This parameter can be omitted if column names are identical.
['odps.federation.jdbc.colmapping'='<table_column1>:<source_column1>,
<table_column2>:<source_column2>,...']
);Service-linked role mode
For a complete code sample, see Create a Hologres external table (service-linked role authorization mode).
The service-linked role authorization mode allows the same RAM user to access authorized tables in both MaxCompute and Hologres without manual authorization. This mode also supports the Hologres IP whitelist feature.
-- Create an external table
CREATE EXTERNAL TABLE [IF NOT EXISTS] <table_name>(
<col1_name> <data_type>,
<col2_name> <data_type>,
......
)
STORED BY '<com.aliyun.odps.jdbc.JdbcStorageHandler>'
LOCATION 'jdbc:postgresql://<endpoint>:<port>/<database>?
ApplicationName=MaxCompute&[currentSchema=<schema>&]
[useSSL={true|false}&]table=<holo_table_name>/'
tblproperties (
'mcfed.mapreduce.jdbc.driver.class'='org.postgresql.Driver',
'odps.federation.jdbc.target.db.type'='holo',
-- When Hologres and MaxCompute column names differ, add the odps.federation.jdbc.colmapping parameter to map columns.
-- This parameter can be omitted if column names are identical.
['odps.federation.jdbc.colmapping'='<table_column1>:<source_column1>,
<table_column2>:<source_column2>,...']
);
Parameters
Examples
Step 1: Prepare Hologres data
You can skip this step if you have a Hologres database, table, and test data.
Create a Hologres database
Log on to the Hologres management console. In the upper-left corner, select a region.
In the navigation pane on the left, click Instances.
If you do not have an instance, you must first purchase a Hologres instance.
On the Instances page, click the name of the target instance.
On the instance details page, click Connect to Instance.
Click the Metadata Management tab.
Click Create Database, enter the Database Name in the dialog box that appears, and leave the other parameters at their default settings.
Create a Hologres table
On the instance details page, click Connect to Instance.
Click the SQL Editor tab.
Run the following statements to create a table and insert data:
CREATE TABLE IF NOT EXISTS holo ( id INT PRIMARY KEY, name TEXT ); INSERT INTO holo (id, name) VALUES (1, 'kate'), (2, 'mary'), (3, 'bob'), (4, 'tom'), (5, 'lulu'), (6, 'mark'), (7, 'haward'), (8, 'lilei'), (9, 'hanmeimei'), (10, 'lily'), (11, 'lucy'); SELECT * FROM holo ORDER BY id;
Step 2: Create a Hologres external table
RAM role
In this mode, the creator of the external table embeds a RAM role with Hologres data access permissions in the external table definition. Other MaxCompute users can then be granted permissions on this external table. When a user accesses the external table, the system uses the bound RAM role to access data in the mapped Hologres table.
Hologres does not support adding a cross-account RAM role to a database instance. Therefore, Hologres in RAM role mode supports only RAM roles from the same account. Similarly, when MaxCompute accesses Hologres using an external table or external schema, only RAM roles from the same account are supported.
Prerequisites
You have a target MaxCompute project where you want to create the Hologres external table.
For more information, see Create MaxCompute project.
You have created and authorized a RAM role. For more information, see Authorize a RAM Role for Hologres.
Create the external table in MaxCompute
Log on to the MaxCompute client and switch to your target MaxCompute project.
Run the following statement to create the Hologres external table.
The following example uses the data prepared in Step 1: Prepare Hologres data:
Hologres database name:
holo_external_test.Hologres database schema:
public.Hologres table name:
holo.Hologres classic network endpoint:
hgprecn-cn-oew210ut****-cn-hangzhou-internal.hologres.aliyuncs.com:80.
CREATE EXTERNAL TABLE IF NOT EXISTS my_table_holo_jdbc ( user_id bigint, user_name string ) stored BY 'com.aliyun.odps.jdbc.JdbcStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::139699392458****:role/<role name>') location 'jdbc:postgresql://hgprecn-cn-oew210ut****-cn-hangzhou-internal.hologres.aliyuncs.com:80/<holo database name>?ApplicationName=MaxCompute¤tSchema=public&table=<table name>/' tblproperties ( 'mcfed.mapreduce.jdbc.driver.class'='org.postgresql.Driver', 'odps.federation.jdbc.target.db.type'='holo', -- When the column names of the Hologres source table differ from those of the Hologres external table, -- add the odps.federation.jdbc.colmapping parameter for column mapping. -- This parameter can be omitted when the column names are identical. 'odps.federation.jdbc.colmapping'='user_id:id,user_name:name' );Run the following commands to query the Hologres source table by using the newly created external table.
-- The following properties are required to access Hologres external tables. SET odps.sql.split.hive.bridge=true; SET odps.sql.hive.compatible=true; SET odps.table.api.enable.holo.table=true; --Enable JDBC direct read access -- Query data from the Hologres external table. SELECT * FROM my_table_holo_jdbc limit 10; -- The command returns the following result. +------------+------------+ | user_id | user_name | +------------+------------+ | 9 | hanmeimei | | 4 | tom | | 7 | haward | | 2 | mary | | 5 | lulu | | 8 | lilei | | 10 | lily | | 1 | kate | | 6 | mark | | 11 | lucy | +------------+------------+Use the Hologres external table to exchange data with Hologres and perform federated analysis.
Write data processed in MaxCompute to Hologres using the external table for accelerated analytics and online services.
-- The following properties are required to access Hologres external tables. SET odps.sql.split.hive.bridge=true; SET odps.sql.hive.compatible=true; SET odps.table.api.enable.holo.table=true; --Enable JDBC direct read access -- Insert data into the Hologres external table. INSERT INTO my_table_holo_jdbc VALUES (12,'alice'); -- Query data from the Hologres external table. SELECT * FROM my_table_holo_jdbc; -- The command returns the following result. +------------+------------+ | user_id | user_name | +------------+------------+ | 9 | hanmeimei | | 4 | tom | | 7 | haward | | 2 | mary | | 5 | lulu | | 12 | alice | | 8 | lilei | | 10 | lily | | 1 | kate | | 11 | lucy | | 6 | mark | | 3 | bob | +------------+------------+Store frequently updated dimension tables in Hologres to support real-time updates. MaxCompute accesses the dimension table using an external table and joins it with a fact table in MaxCompute for federated analysis.
-- The following properties are required to access Hologres external tables. SET odps.sql.split.hive.bridge=true; SET odps.sql.hive.compatible=true; -- Create a MaxCompute internal table. CREATE TABLE holo_test AS SELECT * FROM my_table_holo_jdbc; -- Join the MaxCompute internal table with the Hologres external table for analysis. SELECT * FROM my_table_holo_jdbc t1 INNER JOIN holo_test t2 ON t1.id=t2.id; -- The command returns the following result. +------------+------------+------------+------------+ | user_id | user_name |user_id2 | user_name2 | +------------+------------+------------+------------+ | 9 | hanmeimei | 9 | hanmeimei | | 4 | tom | 4 | tom | | 7 | haward | 7 | haward | | 2 | mary | 2 | mary | | 5 | lulu | 5 | lulu | | 12 | alice | 12 | alice | | 8 | lilei | 8 | lilei | | 10 | lily | 10 | lily | | 1 | kate | 1 | kate | | 11 | lucy | 11 | lucy | | 6 | mark | 6 | mark | | 3 | bob | 3 | bob | +------------+------------+------------+------------+
Service-linked role
In this mode, you must create a service-linked role to access Hologres data. To prevent unauthorized access, this mode forwards the user's identity to Hologres for authentication, so the user must have permissions on both the external table and the underlying Hologres table.
Prerequisites
You have a target MaxCompute project where you want to create the Hologres external table.
For more information, see Create MaxCompute project.
An account with the same name as your MaxCompute account exists in Hologres, and this account has read and write permissions on the target table.
This service-linked role authorization mode is supported only in Hologres V1.3 and later. Currently, this mode supports only reading from, not writing to, Hologres external tables.
Create the external table in MaxCompute
Log on to the MaxCompute client and switch to your target MaxCompute project.
Run the following statement to create the Hologres external table.
The following example uses the data prepared in Step 1: Prepare Hologres data:
Hologres database name:
holo_external_test.Hologres database schema:
public.Hologres table name:
holo.Hologres classic network endpoint:
hgprecn-cn-oew210ut****-cn-hangzhou-internal.hologres.aliyuncs.com:80.
CREATE EXTERNAL TABLE IF NOT EXISTS holo_mc_external_dbl ( user_id int, user_name string ) STORED BY 'com.aliyun.odps.jdbc.JdbcStorageHandler' location 'jdbc:postgresql://hgpostcn-cn-****-cn-hangzhou-internal.hologres.aliyuncs.com:80/<holo database name>?ApplicationName=MaxCompute¤tSchema=public&table=<table name>/' TBLPROPERTIES ( 'mcfed.mapreduce.jdbc.driver.class'='org.postgresql.Driver', 'odps.federation.jdbc.target.db.type'='holo', -- When the column names of the Hologres source table differ from those of the Hologres external table, -- add the odps.federation.jdbc.colmapping parameter for column mapping. -- This parameter can be omitted when the column names are identical. 'odps.federation.jdbc.colmapping'='user_id:id,user_name:name' );Query the external table.
SELECT * FROM holo_mc_external_dbl; -- The command returns the following result. +------------+------------+ | user_id | user_name | +------------+------------+ | 9 | hanmeimei | | 4 | tom | | 7 | haward | | 2 | mary | | 5 | lulu | | 12 | alice | | 8 | lilei | | 10 | lily | | 1 | kate | | 11 | lucy | | 6 | mark | | 3 | bob | +------------+------------+
Enable direct read for Hologres external tables
By default, MaxCompute reads data from Hologres external tables through a JDBC connection. To improve performance, you can enable direct read mode, which allows MaxCompute to access the Hologres storage layer directly. This mode provides the following benefits:
Reduces read latency for faster query performance.
Minimizes the number of connections to the Hologres frontend. Most queries require only one connection.
Limitations
When you enable the direct read mode for Hologres, the following limitations apply. If these conditions are not met, the query falls back to JDBC mode.
Version requirements
Your Hologres instance must be V1.3.34 or later. The direct read feature is not supported in earlier versions.
Table type restrictions
Direct read mode is not supported for Hologres cold storage tables.
Direct read mode is not supported for Hologres row-oriented tables.
Data type mapping limitations
When you use the direct read mode, mapping a Timestamp With Time Zone type in Hologres to a TIMESTAMP type in MaxCompute can cause minor time discrepancies. The differences are as follows:
Time value discrepancy
For timestamps before
1900-12-31 15:54:15, the time returned by MaxCompute is ahead by 5 minutes and 44 seconds.For timestamps between
1900-12-31 15:54:16and1969-12-31 23:59:58, the time returned by MaxCompute is ahead by 1 second.For timestamps after
1969-12-31 23:59:59, the times in Hologres and MaxCompute are identical.
Time zone offset
For example, if the MaxCompute time zone is UTC+8 and a Timestamp With Time Zone column in Hologres is
2000-01-01 00:00:00, MaxCompute returns2000-01-01 08:00:00.For example, if the MaxCompute time zone is UTC+8 and a Timestamp With Time Zone column in Hologres is
1969-01-01 00:00:00, MaxCompute returns1969-01-01 08:00:01.
Same-region restriction
Due to network connectivity constraints, MaxCompute can access only Hologres instances in the same region. Cross-region access fails with the following error:
FAILED: ODPS-0010000:System internal error - fuxi job failed, caused by: Pangu request failed with error code 3.If your Hologres instance uses a primary/secondary architecture, you can specify only the primary instance in the connection URL, not a secondary instance.
Additional limitation for Foreign Server mode: You must enable the schema-level syntax switch for the MaxCompute project.
Enable direct read mode
To enable the direct read mode for your session, add the following command before your SQL query in MaxCompute:
SET odps.table.api.enable.holo.table=true;You can also enable or disable direct read mode at the project level.
-- You can enable direct read and disable JDBC fallback at the project level.
-- Enable direct read at the project level:
setproject odps.table.api.enable.holo.table=true; -- Set to true to enable, false to disable.
-- Disable the default fallback to JDBC:
setproject odps.table.api.allow.fallback.jdbc=false; -- Set to true to allow fallback, false to prevent it.Verify direct read mode
To verify that a query used the direct read mode, check the logs in Logview. For more information about how to use Logview, see Use Logview 2.0 to view job running information.
On the Summary tab in Logview, find the external holo tables field. The format is as follows:
<project_name>.<table_name>:<access mode>[<(fallback reason)>]Parameters:
Parameter | Description |
project_name | The name of the project. |
table_name | The name of the table. |
access mode | The access mode for the external table. Valid values:
|
fallback reason | If the access mode is
|
When a job using direct read mode encounters a limitation, it automatically reverts to JDBC mode. Under heavy workloads, this fallback can consume significant resources from the Hologres connection pool, and data transfer in JDBC mode is much less efficient than in direct read mode. Consequently, these resources may be released slowly, increasing the load on your Hologres instance.
In extreme cases, frequent fallbacks can impact other business-critical services that rely on the same Hologres instance. To prevent this, you can disable the automatic fallback mechanism by adding the set odps.table.api.allow.fallback.jdbc=false; parameter to your jobs. This causes jobs to fail instead of silently falling back, which prevents unexpected performance degradation.
Predicate pushdown for Hologres external tables
When accessing Hologres external tables, MaxCompute can push query filter conditions down to Hologres for execution (predicate pushdown). Data is filtered on the Hologres side in advance, which reduces data transfer and improves query performance. The following scenarios are supported:
Hologres Snapshot PPD: The filter expression is converted into a SQL WHERE clause and passed to the Hologres server through the filter parameter of
holo_create_table_snapshot().Hologres JDBC PPD: The WHERE condition is appended to the JDBC SQL statement, and Hologres filters data at the SQL layer.
ORC row group column-level filtering: File-level filtering on the MaxCompute side. For each ORC file, a SearchArgument is built and passed to the ORC reader, which uses column statistics (min/max/count) to skip row groups that do not match.
The following scenarios will be supported in the future:
Partition pruning: For Hologres physical partitioned tables, the filter expression is evaluated against each partition value before a snapshot is created. Partitions that do not match are skipped, and no snapshot is created for them.
Segment key filtering: After the snapshot is returned from Hologres, MaxCompute parses the min/max segment key in the metadata of each file and compares the range against the filter expression. If the segment key range of a file does not overlap with the filter at all, the file is skipped.
Distribution ID filtering: Supported only for Liquid Tables. Each file may contain rows with multiple distribution IDs. After a RecordBatch is read, rows are filtered by distribution ID range.
Usage
Scenario 1: Hologres Snatshot PPD
In Hologres direct-read scenarios, filter expressions are converted into SQL WHERE clauses for logical partition tables and sent to the Hologres server as the filter parameter of holo_create_table_snapshot(). This allows Hologres to filter out non-matching files on the server side during snapshot creation, reducing the number of files returned to MaxCompute and minimizing data transfer.
Scenario | PPD support in Hologres direct-read scenarios |
Core parameter | Valid values for the
Example syntax:
|
Supported types | INT、BIGINT、STRING、DATE、TIMESTAMP、BINARY |
Limitations | Predicate pushdown does not support the following:
|
Applicable scenarios | Hologres instances that support PPD, the instance version must meet one of the following requirements.
|
Scenario 2: Hologres JDBC PPD
When Hologres direct read is disabled (odps.table.api.enable.holo.table=false), queries are executed through the JDBC path. In this case, PPD works by appending the WHERE clause to the JDBC SQL sent to Hologres, and Hologres performs the filtering at the SQL level. This differs from PPD in Hologres direct-read scenarios:
Direct-read PPD: filters files at the snapshot level
JDBC PPD: filters rows at the SQL query level
Scenario | PPD support in Hologres JDBC read scenarios |
Core parameter | Values of the
Example of the parameter syntax:
|
Supported types | INT、BIGINT、DOUBLE、FLOAT、STRING、DATE、TIMESTAMP、TIMESTAMP_NTZ |
Limitations | Predicate pushdown does not support the following:
|
Applicable scenarios |
|
Scenario 3: ORC row group column-level filtering
File-level filtering on the MaxCompute side. For each ORC file, a SearchArgument is built and passed to the ORC reader. The ORC reader uses the column statistics (min/max/count) of each stripe/row group to determine whether the entire row group can be skipped.
File-level pruning is performed on the MaxCompute side
Depends on whether the PPD parameter is enabled on the Hologres side.
Non-partitioned tables, physical partitioned tables, and logical partitioned tables are all supported.
Scenario | ORC row group column-level filtering |
Core parameter |
|
Supported types | BOOLEAN、INT、BIGINT、FLOAT、DOUBLE、DECIMAL、STRING、DATE、TIMESTAMP |
Examples
Direct-read
Prepare the data. In your Hologres instance, create a test table and insert data.
CREATE TABLE test_multi_type_ppd ( c_id INT NOT NULL, c_boolean BOOLEAN, c_int INT, c_bigint BIGINT, c_double DOUBLE precision, c_float REAL, c_string TEXT, c_date DATE, c_timestamp_tz TIMESTAMPTZ, c_timestamp_ntz TIMESTAMP ) WITH (SEGMENT_KEY = 'c_id'); -- Insert 10 rows of data. INSERT INTO test_multi_type_ppd VALUES (1, true, 10, 1000, 1.25, 1.5, 'alpha', '2023-01-01', '2023-01-01 10:00:00+08', '2023-01-01 02:00:00'), (2, false, 20, 2000, -2.50, 2.5, 'beta', '2023-01-02', '2023-01-02 10:00:00+08', '2023-01-02 02:00:00'), (3, true, 30, 3000, 3.75, -3.5, 'gamma', '2023-01-03', '2023-01-03 10:00:00+08', '2023-01-03 02:00:00'), (4, false, 40, 4000, 4.00, 4.5, 'delta', '2023-01-04', '2023-01-04 10:00:00+08', '2023-01-04 02:00:00'), (5, true, 50, 5000, 5.50, 5.5, 'epsilon', '2023-01-05', '2023-01-05 10:00:00+08', '2023-01-05 02:00:00'), (6, false, 60, 6000, 6.60, 6.0, 'zeta', '2023-01-06', '2023-01-06 10:00:00+08', '2023-01-06 02:00:00'), (7, true, 70, 7000, 7.70, -7.0, 'eta', '2023-01-07', '2023-01-07 10:00:00+08', '2023-01-07 02:00:00'), (8, false, 80, 8000, 8.80, 8.0, 'theta', '2023-01-08', '2023-01-08 10:00:00+08', '2023-01-08 02:00:00'), (9, true, 90, 9000, -9.90, 9.0, 'iota', '2023-01-09', '2023-01-09 10:00:00+08', '2023-01-09 02:00:00'), (10, false, 100, 10000, 10.10, 10.0, 'kappa', '2023-01-10', '2023-01-10 10:00:00+08', '2023-01-10 02:00:00'); SELECT * FROM test_multi_type_ppd;Create a Hologres external table in MaxCompute.
CREATE EXTERNAL TABLE test_multi_type_ppd ( c_id int, c_boolean boolean, c_int int, c_bigint bigint, c_double double, c_float float, c_string string, c_date date, c_timestamp_tz timestamp, c_timestamp_ntz timestamp_ntz ) STORED BY 'com.aliyun.odps.jdbc.JdbcStorageHandler' WITH serdeproperties ('odps.properties.rolearn'='acs:ram::139****:role/<role name>') LOCATION 'jdbc:postgresql://<holo-endpoint>/<db>?currentSchema=public&table=test_multi_type_ppd' TBLPROPERTIES ( 'mcfed.mapreduce.jdbc.driver.class'='org.postgresql.Driver', 'odps.federation.jdbc.target.db.type'='holo' );Query the external table.
-- Enable Hologres direct read. SET odps.table.api.enable.holo.table=true; -- Set the PPD mode (off, on, or debug). SET odps.external.holo.read.table.rules="{predicate_pushdown_mode:on}"; -- Configure the type system. SET odps.sql.type.system.odps2=true; SET odps.sql.decimal.odps2=true; -- Allow expressions to be pushed down to TableScan. This is typically enabled by default. SET odps.use.builtin.function.input.range=true; -- set odps.mcqa.disable=true; SELECT * FROM test_multi_type_ppd WHERE c_id = 3; -- The query returns the following result. +------+-----------+-------+------------+------------+---------+----------+--------+----------------+-----------------+ | c_id | c_boolean | c_int | c_bigint | c_double | c_float | c_string | c_date | c_timestamp_tz | c_timestamp_ntz | +------+-----------+-------+------------+------------+---------+----------+--------+----------------+-----------------+ | 3 | true | 30 | 3000 | 3.75 | -3.5 | gamma | 2023-01-03 | 2023-01-03 10:00:00 | 2023-01-03 02:00:00 | +------+-----------+-------+------------+------------+---------+----------+--------+----------------+-----------------+ -- Check the Summary section in Logview. The following information is displayed: external holo tables: **.default.test_multi_type_ppd:Optimized Holo-side PPD enabled --> Filter pushdown applied successfully Snapshot Id: 56-1-100*** With-filter file count: 2 With-filter create snapshot duration: 19ms
JDBC
Prepare the data. In your Hologres instance, create a test table and insert data.
CREATE TABLE test_multi_type_ppd ( c_id INT NOT NULL, c_boolean BOOLEAN, c_int INT, c_bigint BIGINT, c_double DOUBLE precision, c_float REAL, c_string TEXT, c_date DATE, c_timestamp_tz TIMESTAMPTZ, c_timestamp_ntz TIMESTAMP ) WITH (SEGMENT_KEY = 'c_id'); -- Insert 10 rows of data. INSERT INTO test_multi_type_ppd VALUES (1, true, 10, 1000, 1.25, 1.5, 'alpha', '2023-01-01', '2023-01-01 10:00:00+08', '2023-01-01 02:00:00'), (2, false, 20, 2000, -2.50, 2.5, 'beta', '2023-01-02', '2023-01-02 10:00:00+08', '2023-01-02 02:00:00'), (3, true, 30, 3000, 3.75, -3.5, 'gamma', '2023-01-03', '2023-01-03 10:00:00+08', '2023-01-03 02:00:00'), (4, false, 40, 4000, 4.00, 4.5, 'delta', '2023-01-04', '2023-01-04 10:00:00+08', '2023-01-04 02:00:00'), (5, true, 50, 5000, 5.50, 5.5, 'epsilon', '2023-01-05', '2023-01-05 10:00:00+08', '2023-01-05 02:00:00'), (6, false, 60, 6000, 6.60, 6.0, 'zeta', '2023-01-06', '2023-01-06 10:00:00+08', '2023-01-06 02:00:00'), (7, true, 70, 7000, 7.70, -7.0, 'eta', '2023-01-07', '2023-01-07 10:00:00+08', '2023-01-07 02:00:00'), (8, false, 80, 8000, 8.80, 8.0, 'theta', '2023-01-08', '2023-01-08 10:00:00+08', '2023-01-08 02:00:00'), (9, true, 90, 9000, -9.90, 9.0, 'iota', '2023-01-09', '2023-01-09 10:00:00+08', '2023-01-09 02:00:00'), (10, false, 100, 10000, 10.10, 10.0, 'kappa', '2023-01-10', '2023-01-10 10:00:00+08', '2023-01-10 02:00:00'); SELECT * FROM test_multi_type_ppd;Create a Hologres external table in MaxCompute.
CREATE EXTERNAL TABLE test_multi_type_ppd ( c_id int, c_boolean boolean, c_int int, c_bigint bigint, c_double double, c_float float, c_string string, c_date date, c_timestamp_tz timestamp, c_timestamp_ntz timestamp_ntz ) STORED BY 'com.aliyun.odps.jdbc.JdbcStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::122**79014:role/<role name>') LOCATION 'jdbc:postgresql://hgprecn-cn-oew210ut****-cn-hangzhou-internal.hologres.aliyuncs.com:80/<holo database name>?ApplicationName=MaxCompute¤tSchema=public&useSSL=true&table=<table name>/' TBLPROPERTIES ( 'mcfed.mapreduce.jdbc.driver.class'='org.postgresql.Driver', 'odps.federation.jdbc.target.db.type'='holo' );Query the external table.
-- Disable Hologres direct read and use the JDBC path. SET odps.table.api.enable.holo.table=false; SET odps.table.api.enable.holo.table.auto.fallback=false; -- Enable JDBC PPD. SET odps.external.hive.scan.ppd.enabled=true; -- Allow expressions to be pushed down to TableScan. -- This is enabled by default in most cases. SET odps.use.builtin.function.input.range=true; -- Enable common table. SET odps.sql.common.table.planner.ext.hive.bridge=true; SET odps.sql.common.table.planner.ext.hive.bridge.v2=true; -- After PPD is enabled, TableScan reads only one record. SELECT * FROM test_multi_type_ppd WHERE c_id = 3; -- The query result is as follows: +------+-----------+-------+------------+------------+---------+----------+--------+----------------+-----------------+ | c_id | c_boolean | c_int | c_bigint | c_double | c_float | c_string | c_date | c_timestamp_tz | c_timestamp_ntz | +------+-----------+-------+------------+------------+---------+----------+--------+----------------+-----------------+ | 3 | true | 30 | 3000 | 3.75 | -3.5 | gamma | 2023-01-03 | 2023-01-03 10:00:00 | 2023-01-03 02:00:00 | +------+-----------+-------+------------+------------+---------+----------+--------+----------------+-----------------+ -- Check the stdout details of the instance in Logview. The following messages are displayed: [2026-07-22 10:02:41] Volcano instance executor [MainThreadID: 222960] Jdbc HoloRecordReader query conditions: (c_id = 3) JDBC HoloRecordReader: Query predicate pushdown succeeded. JdbcShardRecordReader getSelectQuery: SELECT c_id, c_boolean, c_int, c_bigint, c_double, c_float, c_string, c_date, c_timestamp_tz, c_timestamp_ntz FROM test_multi_type_ppd0721 AS test_multi_type_ppd0721 WHERE ( hg_shard_id = 9) AND ((c_id = 3))
ORC row group column-level filtering
This method applies to scenarios with large data volumes. Each row group in ORC contains 10,000 rows, so the filtering effect is not obvious when the data volume is too small
Prepare data. Create a test table in the Hologres instance.
DROP TABLE IF EXISTS test_2m_data; BEGIN; CREATE TABLE test_2m_data ( id INT NOT NULL, name TEXT NOT NULL ); -- Set a distribution key to avoid data skew and improve batch write performance. CALL set_table_property('test_2m_data', 'distribution_key', 'id'); COMMIT; INSERT INTO test_2m_data (id, name) SELECT g AS id, 'user_' || g AS name FROM generate_series(1, 2000000) AS g; SELECT COUNT(*) FROM test_2m_data;Create a Hologres external table in MaxCompute.
CREATE EXTERNAL TABLE ext_holo_test_2m_data ( id INT , name STRING ) STORED BY 'com.aliyun.odps.jdbc.JdbcStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::*****:role/<role_name>') LOCATION 'jdbc:postgresql://hgpostcn-cn-2bj4lnv16008-cn-<region>-internal.hologres.aliyuncs.com:80/<holo_database>?currentSchema=public&table=test_2m_data' TBLPROPERTIES ( 'mcfed.mapreduce.jdbc.driver.class'='org.postgresql.Driver', 'odps.federation.jdbc.target.db.type'='holo' );Query external table data
-- Enable Hologres direct read SET odps.table.api.enable.holo.table=true; -- Enable PPD SET odps.external.holo.use.predicate.pushdown=true; -- Set the PPD mode SET odps.external.holo.read.table.rules="{predicate_pushdown_mode:on}"; SELECT * FROM ext_holo_test_2m_data where id>100 and id<100000;Check the stdout details of the instance in LogView. Filtering succeeds if the following occurs:
IOCount and IOLatencyPercentiles appear in TableScan1.
ReadRowCount is smaller than RequestedRowCount in TableScan1.
Hologres data import and export
Supported data types
Decimal type limitations
For Hologres external tables created in MaxCompute, the
DECIMALdata type is fixed atdecimal(38,18)and cannot be modified. If the source table has fewer decimal places, you can define the column as theSTRINGtype in the MaxCompute external table and then use theCASTfunction to explicitly cast the data when you use it.Complex type limitations
Hologres external tables created in MaxCompute do not support complex data types such as
Array,Map, orStruct.Other incompatible types
Data types in Hologres, such as
MONEY, are not supported because there are no corresponding data types in MaxCompute.
The following table lists the data type mappings between Hologres and MaxCompute.
Hologres type | MaxCompute type | JDBC read | JDBC write | Direct read (odps.table.api.enable.holo.table=true) | Description |
INTEGER (alias: INT or INT4) | INT | A 32-bit signed integer. | |||
TEXT | STRING, VARCHAR | A string type with a length limit of 8 MB. | |||
SMALLINT | SMALLINT | A 16-bit signed integer. | |||
INT2 | SMALLINT | A 16-bit signed integer. | |||
BIGINT (alias: INT8) | BIGINT | A 64-bit signed integer. | |||
BYTEA | BINARY | The binary data type currently has a length limit of 8 MB. The Hologres | |||
REAL (alias: FLOAT4) | FLOAT | A 32-bit binary floating-point number. | |||
DOUBLE PRECISION (alias: FLOAT8) | DOUBLE | A 64-bit binary floating-point number. | |||
BOOLEAN (alias: BOOL) | BOOLEAN | A BOOLEAN type. | |||
TIMESTAMP | TIMESTAMP_NTZ | The Hologres It maps to MaxCompute's | |||
TIMESTAMP WITH TIME ZONE (alias: TIMESTAMPTZ) | TIMESTAMP | The timestamp data type is accurate to the nanosecond and uses the format The underlying precision conversion is handled automatically. | |||
DECIMAL (alias: NUMERIC) | DECIMAL(precision,scale) | A base-10 exact numeric type.
In MaxCompute, the | |||
CHAR(n) | CHAR(n) | In MaxCompute, The maximum size of the | |||
VARCHAR(n) | VARCHAR(n) | The In Hologres, the maximum size for | |||
DATE | DATE | The data type is date in the | |||
INT4[] | ARRAY<INT> | Hologres arrays are mapped to the corresponding MaxCompute | |||
INT8[] | ARRAY<BIGINT> | ||||
FLOAT4[] | ARRAY<FLOAT> | ||||
FLOAT8[] | ARRAY<DOUBLE> | ||||
BOOLEAN[] | ARRAY<BOOLEAN> | ||||
TEXT[] | ARRAY<STRING> | ||||
JSONB | JSON | Hologres | |||
JSON | STRING | When using JDBC, the Hologres | |||
SERIAL (auto-increment) | INT | MaxCompute reads Hologres | |||
RoaringBitmap | Not supported | No corresponding type exists in MaxCompute. | |||
RoaringBitmap64 | Not supported | No corresponding type exists in MaxCompute. | |||
BIT(n) | Not supported | No corresponding type exists in MaxCompute. | |||
VARBIT(n) | Not supported | No corresponding type exists in MaxCompute. | |||
INTERVAL | Not supported | No corresponding type exists in MaxCompute. | |||
TIMETZ | Not supported | No corresponding type exists in MaxCompute. | |||
TIME | Not supported | No corresponding type exists in MaxCompute. | |||
INET | Not supported | No corresponding type exists in MaxCompute. | |||
MONEY | Not supported | No corresponding type exists in MaxCompute. | |||
OID | Not supported | No corresponding type exists in MaxCompute. | |||
UUID | Not supported | No corresponding type exists in MaxCompute. |
FAQ
ODPS-0130071 error when directly reading Hologres data
Problem
When you read data from Hologres in direct read mode, the job fails with an error similar to
ODPS-0130071 Failed to split to equal size...max count: 7777. For example:ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: storage/table/src/input_splits_builder.cpp(195): StorageException: Failed to split to equal size, total size: 2143570729934, min size: 268435456, max size: 272629760, max count: 7777, split size: 275629513, split count: 7777Cause
When MaxCompute reads data from Hologres, its default data splitting strategy can cause the number of mapper instances to exceed the 7,777 concurrency limit.
NoteThis limit prevents jobs with an excessive number of mappers from running, which protects the stability of Hologres files and network connections.
Solution
You can resolve this error by setting the following parameters.
SET odps.external.holo.mapper.instances=10000; -- Increase the concurrency limit. The maximum value is 10,000. SET odps.sql.mapper.split.size=512; -- Adjust the job concurrency. The maximum value is 512 MB.
Slow SQL jobs on Hologres external tables
Problem
Performance is slow when you use the SDK to search for data in a MaxCompute external table.
Solution
External tables perform slowly because they only support full table scans. For better performance, use a MaxCompute internal table instead.
Error when a column name is a keyword
Problem
If a column name in your Hologres table is a keyword, queries may fail with the following errors without special configuration:
ODPS-0123131:User defined function exception - SQLException in nextKeyValueCaused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near ","Solution
Add the
odps.federation.jdbc.colmappingparameter to map the columns of the Hologres source table to the columns of the Hologres external table.For example, if the Hologres source table contains the keyword
"offset"as a column name, add the'odps.federation.jdbc.colmapping'='offset:"offset"'parameter when you create the Hologres external table.
The password authentication failed for user "mcslr$STS.******" error in service-linked role mode
Problem
When a RAM user or RAM role reads a Hologres external table by using the service-linked role authorization mode the job may fail with the
password authentication failed for user "mcslr$STS.******"error. The following provides an error message example:Caused by: java.lang.RuntimeException: java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: pooler: c0a981a2413b5: password authentication failed for user "*******$V2#****#TMP.3KvMuCpXhuMbeZsbpaE****m738WfEw73rze ohJUeXxhsKza1khCxdKSJQAU5CFac*****qDCA#STS.NZFkZ3TbJNmAjS2TKLdUHHdiW#**.*.*.***" at org.apache.hadoop.mapreduce.lib.db.DBInputFormat.setConf(DBInputFormat.java:171) at com.aliyun.odps.jdbc.wrapper.InputFormatWrapper.checkAndInitDbInputFormat(InputFormatWrapper.java:48) ... 45 more Caused by: java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: pooler: c0a981a2413b5: password authentication failed for user "*******$V2#****#TMP.3KvMuCpXhuMbeZsbpaE****m738WfEw73rzeohJUeXxhsKza1khCxdKSJQAU 5CFac*****qDCA#STS.NZFkZ3TbJNmAjS2TKLdUHHdiW#**.*.*.***" at org.apache.hadoop.mapreduce.lib.db.DBInputFormat.createConnection(DBInputFormat.java:205) at com.aliyun.odps.jdbc.impl.JdbcDBInputFormat.superCreateConnection(JdbcDBInputFormat.java:69) at com.aliyun.odps.jdbc.impl.JdbcDBInputFormat.createConnection(JdbcDBInputFormat.java:56) at org.apache.hadoop.mapreduce.lib.db.DBInputFormat.setConf(DBInputFormat.java:164)Cause
The service-linked role authorization mode failed.
Solution
Add the
set odps.external.holo.enable.slr = force;parameter before the SQL statement to forcibly enable the service-linked role authorization mode.
The Holo-side PPD disabled --> The Holo snapshot PPD mode is enabled, but FAILED to push down the filter into Holo error in direct read mode
Error message
Holo-side PPD disabled --> The Holo snapshot PPD mode is enabled, but FAILED to push down the filter into Holo, errorMsg[storage/table/src/holo/snapshot.cpp(319): StorageException: Create/Get snapshot failed for table: test_multi_type_ppd partition: Query:select holo_create_table_snapshot('public.test_multi_type_ppd', 259200, filter=>$$c_id = 3$$) with error ERROR: internal error: Failed to build fragment dag desc: node type 65 is not supportedSolution
Ensure that your Hologres internal table meets the requirements in Usage notes.
References
For more information about common issues with Hologres foreign tables, see Lakehouse and Foreign Table FAQ.