Create dynamic table

更新时间:
复制 MD 格式

Create a Dynamic Table that automatically refreshes query results from base tables using incremental or full refresh.

Important notes

  • Dynamic Table usage limitations: Dynamic Table support and limitations.

  • Hologres V3.1 and later requires the new syntax to create Dynamic Tables. You can still perform ALTER operations on tables created with the V3.0 syntax, but you cannot create new ones. For non-partitioned tables, you can use the syntax conversion command to convert the legacy syntax to the new syntax. For partitioned tables, recreate them manually.

  • Upgrading to Hologres V3.1 and later requires recreation of existing Incremental Dynamic Tables. You can use the syntax conversion command to do so.

  • In Hologres V3.1+, the engine adaptively optimizes the refresh process. Negative query IDs for refresh operations are expected.

Syntax

V3.1+ (new syntax)

Note

V3.1+ only supports the new syntax.

Create Dynamic Table syntax

Syntax for creating a Dynamic Table in V3.1+:

CREATE DYNAMIC TABLE [ IF NOT EXISTS ] [<schema_name>.]<table_name>
[ (<col_name> [, ...] ) ]
[LOGICAL PARTITION BY LIST(<partition_key>)]
WITH (
  -- Dynamic Table properties
  freshness = '<num> {minutes | hours}', -- Required
  [auto_refresh_enable = {true | false},] -- Optional
  [auto_refresh_mode = {'full' | 'incremental' | 'auto'},] -- Optional
  
  [base_table_cdc_format = {'stream' | 'binlog'},] -- Optional

  [auto_refresh_partition_active_time = '<num> {minutes | hours | days}',] -- Optional
  [partition_key_time_format = {'YYYYMMDDHH24' | 'YYYY-MM-DD-HH24' | 'YYYY-MM-DD_HH24' | 'YYYYMMDD' | 'YYYY-MM-DD' | 'YYYYMM' | 'YYYY-MM' | 'YYYY'},] --Optional
  
  [computing_resource = {'local' | 'serverless' | '<warehouse_name>'},] -- Optional. The warehouse_name value is supported only in Hologres V4.0.7 and later.
  [refresh_guc_hg_experimental_serverless_computing_required_cores=xxx,] --Optional. Specifies the required computing cores for Serverless.
  
  [refresh_guc_<guc_name> = '<guc_value>',] -- Optional

  -- General properties
  [orientation = {'column' | 'row' | 'row,column'},]
  [table_group = '<tableGroupName>',]
  [distribution_key = '<columnName>[,...]]',]
  [clustering_key = '<columnName>[:asc] [,...]',]
  [event_time_column = '<columnName> [,...]',]
  [bitmap_columns = '<columnName> [,...]',]
  [dictionary_encoding_columns = '<columnName> [,...]',]
  [time_to_live_in_seconds = '<non_negative_literal>',]
  [storage_mode = {'hot' | 'cold'},]
)
AS
<query>; -- Query definition.

Parameters

Refresh mode & resources

Parameter

Description

Required

Default

freshness

Target data freshness in minutes or hours. Minimum: 1 minute. The engine schedules refreshes based on the previous refresh time and this freshness value. Unlike a fixed interval, freshness adapts automatically to keep data as current as possible.

Yes

None

auto_refresh_mode

The refresh mode. Valid values:

  • auto: Automatic mode. The engine automatically uses incremental refresh if the query supports it; otherwise, it falls back to full refresh.

  • incremental: Incremental refresh. Only incremental data is refreshed each time. For more information, see Incremental refresh.

  • full: Full refresh. The entire table is refreshed each time. For more information, see Full refresh.

No

auto

auto_refresh_enable

Enables or disables automatic refresh. Valid values:

  • true: Enables automatic refresh.

  • false: Disables automatic refresh. All subsequent refresh jobs for the table stop.

No

true

base_table_cdc_format

How to consume base table data changes during incremental refresh.

  • stream (default): Reads file-level data changes. No extra storage overhead and higher performance than binlog. For more information, see Dynamic tables.

  • binlog: Consumes base table data changes via binlog. Requires manually enabling binlog on the base table (Subscribe to Hologres Binlog).

    begin;
    call set_table_property('<table_name>', 'binlog.level', 'replica');
    call set_table_property('<table_name>', 'binlog.ttl', '2592000');
    commit;
Note
  • From V3.1, all tables default to stream. Disable binlog if enabled to avoid unnecessary storage costs.

  • The stream method is not supported for row-oriented base tables; only the binlog method is.

  • This parameter cannot be modified after the table is created. To change it, recreate the table.

No

stream

computing_resource

Compute resource for refresh. Valid values:

  • serverless (default): Uses Serverless Computing resources, isolating refresh workloads from query traffic.

  • <warehouse_name>: Uses the specified computing warehouse for refresh.

    Note

    Only supported in Hologres V4.0.7 and later.

  • local: Uses local computing resources from the current instance for refresh.

Parameters.

No

serverless

refresh_guc_<guc_name>

Set GUC parameters for refresh. For supported GUCs, see GUC parameters.

No

None

Partitioned tables

Logical partitioned table

Parameter

Description

Required

Default

LOGICAL PARTITION BY LIST(<partition_key>)

Creates a logical partitioned Dynamic Table. Requires auto_refresh_partition_active_time and partition_key_time_format.

No

None

auto_refresh_partition_active_time

Refresh scope for partitions, in minutes, hours, or days. Hologres traces back from the current time and refreshes partitions within this window.

Active partitions are those whose elapsed time since start (derived from partition name) is less than the auto_refresh_partition_active_time value.

Note
  • The auto_refresh_partition_active_time parameter must specify a duration that is greater than one partition interval. For example, if data is partitioned daily, auto_refresh_partition_active_time must be set to a period longer than 24 hours.

  • This parameter is modifiable. Changes only affect future partitions.

  • Starting from Hologres V4.2, refreshing active partitions of a Dynamic Table uses partition-level locks instead of table-level locks. This means different partitions can be refreshed concurrently without waiting for each other.

Yes

Defaults to Partitioning interval + 1 hour.

This provides a 1-hour buffer to account for potential data delays from the base table. For example, with daily partitioning, the default becomes 25 hours (1 day + 1 hour).

partition_key_time_format

Partition name format. Valid values:

  • For TEXT/VARCHAR partition keys:

    YYYYMMDDHH24, YYYY-MM-DD-HH24, YYYY-MM-DD_HH24, YYYYMMDD, YYYY-MM-DD, YYYYMM, YYYY-MM, YYYY.

  • For INT partition keys:

    YYYYMMDDHH24, YYYYMMDD, YYYYMM, YYYY.

  • For DATE partition keys:

    YYYY-MM-DD

Yes

None

Physical partitioned tables

Parameter

Description

Required

Default

PARTITION BY LIST(<partition_key>)

Creates a physical partitioned Dynamic Table.

Physical partitioned Dynamic Tables lack dynamic partitioning and have usage limitations. Logical partitions are recommended. For differences, see CREATE LOGICAL PARTITION TABLE.

Important

Hologres V3.1+ do not support creating a Dynamic Table as a physical partitioned table.

No

None

Table properties

Parameter

Description

Required

Default value

Full refresh mode

Incremental refresh mode

col_name

Column names.

Specify names but not attributes or data types—the engine infers them.

Note

Specifying column attributes and data types can lead to incorrect engine inference.

No

Query column name

Query column name

orientation

Storage format. column indicates column-oriented storage.

No

column

column

table_group

Table Group. Defaults to the current database's default. For more information, see Manage table groups and shards.

No

Default Table Group name

Default Table Group name

distribution_key

Distribution key. For more information, see Distribution key.

No

(none)

(none)

clustering_key

Clustering key. For more information, see Clustering key.

No

Allowed, with a default inferred value.

Allowed, with a default inferred value.

event_time_column

See Event time column (segment key).

No

(none)

(none)

bitmap_columns

Bitmap columns. For more information, see Bitmap index.

No

TEXT type fields

TEXT type fields

dictionary_encoding_columns

See Dictionary encoding.

No

TEXT type fields

TEXT type fields

time_to_live_in_seconds

Data TTL.

No

No expiration

No expiration

storage_mode

Storage tier. Valid values:

  • hot: Hot storage.

  • cold: Cold storage.

Note

For details, see Tiered storage.

No

hot

hot

binlog_level

Enables binlog for the Dynamic Table. Subscribe to Hologres Binlog.

Note
  • This parameter requires V3.1.18 and later.

  • Avoid enabling binlog for Dynamic Tables that use full refresh.

No

none

none

binlog_ttl

The binlog TTL.

No

2592000

2592000

Query

Query that defines the Dynamic Table data. Supported queries and base tables vary by refresh mode. For more information, see Dynamic Table support and limitations.

V3.0 (legacy syntax)

Create Dynamic Table syntax

CREATE DYNAMIC TABLE [IF NOT EXISTS] <schema.tablename>(
[col_name],
[col_name]
  ) [PARTITION BY LIST (col_name)]
WITH (
    [refresh_mode='[full|incremental]',]
    [auto_refresh_enable='[true|false',]

  --Incremental refresh parameters:
    [incremental_auto_refresh_schd_start_time='[immediate|<timestamptz>]',]
    [incremental_auto_refresh_interval='[<num> {minute|minutes|hour|hours]',]  
    [incremental_guc_hg_computing_resource='[ local | serverless]',]
    [incremental_guc_hg_experimental_serverless_computing_required_cores='<num>',]

   --Full refresh parameters:
    [full_auto_refresh_schd_start_time='[immediate|<timestamptz>]',]
    [full_auto_refresh_interval='[<num> {minute|minutes|hour|hours]',] 
    [full_guc_hg_computing_resource='[ local | serverless]',]--hg_full_refresh_computing_resource defaults to serverless, can be set at the DB level, and is optional for users.
    [full_guc_hg_experimental_serverless_computing_required_cores='<num>',]
    
   --Shared parameters, GUCs are allowed:
   [refresh_guc_<guc>='xxx]',] 
   
  -- General Dynamic Table properties:
    [orientation = '[column]',]
    [table_group = '[tableGroupName]',]
    [distribution_key = 'columnName[,...]]',]
    [clustering_key = '[columnName{:asc]} [,...]]',]
    [event_time_column = '[columnName [,...]]',]
    [bitmap_columns = '[columnName [,...]]',]
    [dictionary_encoding_columns = '[columnName [,...]]',]
    [time_to_live_in_seconds = '<non_negative_literal>',]
    [storage_mode = '[hot | cold]']
    ) 
AS
<query> --Query definition

Parameters

Refresh mode and resources

Category

Parameter

Description

Required

Default

Shared refresh parameters

refresh_mode

Refresh mode. Valid values: full and incremental.

If it's not set, no refresh is performed.

No

(none)

auto_refresh_enable

Enable or disable automatic refresh. Valid values:

  • true

  • false

No

false

refresh_guc_<guc>

Set GUC parameters for refresh. For a list of supported GUCs, see GUC parameters.

Note

For example, to set the timezone GUC, use refresh_guc_timezone = 'GMT-8:00'.

No

(none)

Incremental refresh

incremental_auto_refresh_schd_start_time

The start time for incremental refresh. Valid values:

  • immediate: Default. Starts incremental refresh immediately after table creation.

  • <timestamptz>: A custom start time, e.g., '2024-08-24 1:00', to begin the refresh task at that time.

No

immediate

incremental_auto_refresh_interval

Incremental refresh interval, in minutes or hours.

  • Value range: [1min, 48hours].

  • If it's not set, the Dynamic Table is refreshed only once, at the start time.

No

(none)

incremental_guc_hg_computing_resource

Computing resources for incremental refresh. Valid values:

  • local: Use the instance's own resources.

  • serverless: Use Serverless Computing resources. To check if the instance meets Serverless Computing requirements, see Work with serverless computing.

Note

To set the computing resources at the DB level, run ALTER DATABASE xxx SET incremental_guc_hg_computing_resource=xx.

No

local

incremental_guc_hg_experimental_serverless_computing_required_cores

Serverless Computing cores for refresh.

Note

Serverless Computing resource quotas vary by instance specifications. For more information, see Manage serverless computing resources.

No

(none)

Full refresh

full_auto_refresh_schd_start_time

The start time for full refresh. Valid values:

  • immediate: Default. Starts full refresh immediately after table creation.

  • <timestamptz>: A custom start time, e.g., '2024-08-24 1:00', to begin the refresh task at that time.

No

immediate

full_auto_refresh_interval

Full refresh interval, in minutes or hours.

  • Value range: [1min, 48hours].

  • If it's not set, the Dynamic Table is refreshed only once, at the start time.

No

(none)

full_guc_hg_computing_resource

Computing resources for full refresh. Valid values:

  • local: The instance's own resources.

  • serverless: Use Serverless Computing resources. To check if the instance meets Serverless Computing requirements, see Work with serverless computing.

Note

To set the computing resources at the DB level, run ALTER DATABASE xxx SET full_guc_hg_computing_resource=xx.

No

local

full_guc_hg_experimental_serverless_computing_required_cores

Serverless Computing cores for refresh.

Note

Serverless Computing resource quotas vary by instance specifications. For more information, see Manage serverless computing resources.

No

(none)

Table properties

Parameter

Description

Required

Default

full

incremental

col_name

Column names.

Specify names but not attributes or data types—the engine infers them.

Note

Specifying column attributes and data types can lead to incorrect engine inference.

No

Query column name

Query column name

orientation

Storage format for the Dynamic Table. column indicates column-oriented storage.

No

column

column

table_group

Table Group. Defaults to the current database's default. For more information, see Manage table groups and shards.

No

Default Table Group name

Default Table Group name

distribution_key

Distribution key. For more information, see Distribution key.

No

(none)

(none)

clustering_key

Clustering key. For more information, see Clustering key.

No

Allowed, with a default inferred value.

Allowed, with a default inferred value.

event_time_column

Segment key. For more information, see Event time column (segment key).

No

(none)

(none)

bitmap_columns

Bitmap columns. For more information, see Bitmap index.

No

TEXT type fields

TEXT type fields

dictionary_encoding_columns

See Dictionary encoding.

No

TEXT type fields

TEXT type fields

time_to_live_in_seconds

Data TTL.

No

No expiration

No expiration

storage_mode

Storage tier. Valid values:

  • hot: Hot storage.

  • cold: Cold storage.

Note

See Tiered storage.

No

hot

hot

PARTITION BY LIST

Creates a partitioned Dynamic Table. Partitions can use different refresh modes for varying freshness needs.

No

Non-partitioned table

Non-partitioned table

Query

The query that generates Dynamic Table data. Supported queries and base table types vary by refresh mode. Dynamic Table support and limitations.

Incremental refresh

Incremental refresh detects base table changes and writes only the delta into the Dynamic Table, ideal for near-real-time (minute-level) queries.

  • Base table limitations:

    • V3.1 defaults to stream mode. If your base table had binlog enabled in V3.0, disable it to avoid extra storage costs.

    • In V3.0, you must enable binlog for the base table, except for a dimension table involved in a join. Enabling binlog for a base table incurs some storage overhead. Check the binlog storage usage by referring to View table storage details.

  • In incremental refresh mode, Hologres generates a state table in the background to record intermediate aggregation results (See Dynamic tables for details). The state table also consumes some space for state storage. To view storage usage, see View dynamic table schema and lineage.

  • Supported queries and operators for incremental refresh: Dynamic Table support and limitations.

Stream-stream joins

Stream-stream JOINs have the same semantics as OLAP queries, using HASH JOIN and supporting INNER JOIN, LEFT/RIGHT/FULL OUTER JOIN.

V3.1

Note

Starting from Hologres V3.1, the GUC for stream-stream JOIN is enabled by default.

Example:

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
);
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt WITH (
  auto_refresh_mode = 'incremental',
  freshness='10 minutes'
) 
AS 
SELECT order_id, orders.user_id, user_name 
FROM orders LEFT JOIN users ON orders.user_id = users.user_id;

-- After refresh, one joined record is visible
REFRESH TABLE dt;
SELECT * FROM dt;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- After refresh, two joined records are visible. Dimension table updates affect all data and can correct previously joined records.
REFRESH TABLE dt;
SELECT * FROM dt;

Result:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | dynamic table
        4 |       1 | dynamic table
(2 rows)

V3.0

Stream-stream JOINs are supported in V3.0.26. To enable this feature, upgrade your instance and enable the GUC:

-- Enable at session level
SET hg_experimental_incremental_dynamic_table_enable_hash_join TO ON;

-- Enable at DB level (takes effect for new connections)
ALTER database <db_name> SET hg_experimental_incremental_dynamic_table_enable_hash_join TO ON;

Example:

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
) WITH (binlog_level = 'replica');
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt WITH (refresh_mode = 'incremental') 
AS 
SELECT order_id, orders.user_id, user_name 
FROM orders LEFT JOIN users ON orders.user_id = users.user_id;

-- After refresh, one joined record is visible
REFRESH TABLE dt;
SELECT * FROM dt;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- After refresh, two joined records are visible. Dimension table updates affect all data and can correct previously joined records.
REFRESH TABLE dt;
SELECT * FROM dt;

Result:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | dynamic table
        4 |       1 | dynamic table
(2 rows)

Dimension table joins

Each stream record joins with the dimension table's latest snapshot at processing time. Changes to the dimension table after a JOIN do not affect already-processed data.

Note

Dimension table JOIN behavior is independent of table size; it is determined by the JOIN statement.

V3.1

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');

INSERT INTO orders VALUES(1, 1);
CREATE DYNAMIC TABLE dt_join_2 WITH (
    auto_refresh_mode = 'incremental',
    freshness='10 minutes') 
AS 
SELECT order_id, orders.user_id, user_name 
-- FOR SYSTEM_TIME AS OF PROCTIME() identifies 'users' as a dimension table
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;

-- After refresh, one joined record is visible
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;
 order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)


UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- After refresh, two joined records are visible. Dimension table updates only affect new data and cannot correct previously joined data.
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

Result:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | hologres
        4 |       1 | dynamic table
(2 rows)

V3.0

CREATE TABLE users (
  user_id INT,
  user_name TEXT,
  PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');

CREATE TABLE orders (
  order_id INT,
  user_id INT,
  PRIMARY KEY (order_id)
)  WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);

CREATE DYNAMIC TABLE dt_join_2 WITH (refresh_mode = 'incremental') 
AS 
SELECT order_id, orders.user_id, user_name 
-- FOR SYSTEM_TIME AS OF PROCTIME() identifies 'users' as a dimension table
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;

-- After refresh, one joined record is visible
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

order_id | user_id | user_name 
----------+---------+-----------
        1 |       1 | hologres
(1 row)
 
UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);

-- After refresh, two joined records are visible. Dimension table updates only affect new data and cannot correct previously joined data.
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;

Result:

order_id | user_id |   user_name   
----------+---------+---------------
        1 |       1 | hologres
        4 |       1 | dynamic table
(2 rows)

Incremental consumption of Paimon lake tables

  • Incremental refresh supports consuming Paimon tables for lakehouse scenarios.

  • External Dynamic Tables support incremental reads and write-back, reducing processing cost and query latency. External Dynamic Table introduction.

Hybrid consumption

Incremental Dynamic Tables support a hybrid model: an initial full load of all existing base table data, followed by continuous incremental processing.

V3.1

V3.1 enables the hybrid refresh model by default. Example:

--Prepare the base table and insert data
CREATE TABLE base_sales(
  day TEXT NOT NULL,
  hour INT,
  user_id BIGINT,
  ts TIMESTAMPTZ,
  amount FLOAT,
  pk text NOT NULL PRIMARY KEY
);

-- Import data into the base table
INSERT INTO base_sales values ('2024-08-29',1,222222,'2024-08-29 16:41:19.141528+08',5,'ddd');


-- Import more data
INSERT INTO base_sales VALUES ('2024-08-29',2,3333,'2024-08-29 17:44:19.141528+08',100,'aaaaa');


-- Create an incremental Dynamic Table
CREATE DYNAMIC TABLE sales_incremental
  WITH (
    auto_refresh_mode='incremental',
    freshness='10 minutes'
  ) 
AS 
  SELECT day, hour, SUM(amount), COUNT(1) 
    FROM base_sales 
  GROUP BY day, hour;

Check data consistency:

  • Query the base table

    SELECT day, hour, SUM(amount), COUNT(1) 
        FROM base_sales 
      GROUP BY day, hour;

    Result:

    day	    hour	sum	count
    2024-08-29	2	100	1
    2024-08-29	1	5	1
  • Query the Dynamic Table

    SELECT * FROM sales_incremental;

    Result:

    day	    hour	sum	count
    2024-08-29	1	5	1
    2024-08-29	2	100	1

V3.0

In V3.0, to use hybrid consumption, manually enable the GUC incremental_guc_hg_experimental_enable_hybrid_incremental_mode. Example:

--Prepare the base table, enable Binlog, and insert data
CREATE TABLE base_sales(
  day TEXT NOT NULL,
  hour INT,
  user_id BIGINT,
  ts TIMESTAMPTZ,
  amount FLOAT,
  pk text NOT NULL PRIMARY KEY
);

-- Import data into the base table
INSERT INTO base_sales values ('2024-08-29',1,222222,'2024-08-29 16:41:19.141528+08',5,'ddd');

-- Enable Binlog for the base table
ALTER TABLE base_sales SET (binlog_level = replica);

-- Import incremental data into the base table
INSERT INTO base_sales VALUES ('2024-08-29',2,3333,'2024-08-29 17:44:19.141528+08',100,'aaaaa');


-- Create an auto-refreshing incremental Dynamic Table and enable the GUC for hybrid consumption
CREATE DYNAMIC TABLE sales_incremental
  WITH (
    refresh_mode='incremental',
    incremental_auto_refresh_schd_start_time = 'immediate',
    incremental_auto_refresh_interval = '3 minutes',
    incremental_guc_hg_experimental_enable_hybrid_incremental_mode= 'true'
  ) 
AS 
  SELECT day, hour, SUM(amount), COUNT(1) 
    FROM base_sales 
  GROUP BY day, hour;

Check data consistency:

  • Query the base table

    SELECT day, hour, SUM(amount), COUNT(1) 
        FROM base_sales 
      GROUP BY day, hour;

    Result:

    day	    hour	sum	count
    2024-08-29	2	100	1
    2024-08-29	1	5	1
  • Query the Dynamic Table

    SELECT * FROM sales_incremental;

    Result:

    day	    hour	sum	count
    2024-08-29	1	5	1
    2024-08-29	2	100	1

Full refresh

Full refresh rewrites the entire dataset from the query. Compared to incremental refresh:

  • Supports more base table types.

  • Supports a richer set of query types and operators.

Full refresh uses more resources. Best for periodic reporting and data backfills.

Note

For more information, see Full refresh.

Examples

V3.1

Example 1: Create a regular Incremental Dynamic Table

Before proceeding, import the tpch_10g public dataset into Hologres by following the guide at Import public datasets with a few clicks.

Note

Before creating an Incremental Dynamic Table, enable Binlog for the base table (not required for dimension tables).

-- Create an Incremental Dynamic Table that refreshes every 3 minutes.
CREATE DYNAMIC TABLE public.tpch_q1_incremental 
WITH (
auto_refresh_mode='incremental',
freshness='3 minutes'
) AS SELECT
        l_returnflag,
        l_linestatus,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus;

Example 2: Create an Incremental Dynamic Table from stream-stream joins

Before proceeding, import the tpch_10g public dataset into Hologres by following the guide at Import public datasets with a few clicks.

Note

Before creating an Incremental Dynamic Table, enable binlog for the base table (not required for the dimension table).

-- Create an Incremental Dynamic Table from stream-stream joins.
CREATE DYNAMIC TABLE dt_join
  WITH (
    auto_refresh_mode='incremental',
    freshness='30 minutes'
  ) 
AS 
SELECT
        l_shipmode,
        SUM(CASE
                WHEN o_orderpriority = '1-URGENT'
                        OR o_orderpriority = '2-HIGH'
                        THEN 1
                ELSE 0
        END) AS high_line_count,
        SUM(CASE
                WHEN o_orderpriority <> '1-URGENT'
                        AND o_orderpriority <> '2-HIGH'
                        THEN 1
                ELSE 0
        END) AS low_line_count
FROM
        hologres_dataset_tpch_10g.orders,
        hologres_dataset_tpch_10g.lineitem
WHERE
        o_orderkey = l_orderkey
        AND l_shipmode IN ('FOB', 'AIR')
        AND l_commitdate < l_receiptdate
        AND l_shipdate < l_commitdate
        AND l_receiptdate >= DATE '1997-01-01'
        AND l_receiptdate < DATE '1997-01-01' + INTERVAL '1' YEAR
GROUP BY
        l_shipmode;

Example 3: Create an Auto-refresh Dynamic Table

Set the refresh mode to auto. The engine prioritizes incremental refresh and falls back to full refresh if unsupported.

Before proceeding, import the tpch_10g public dataset into Hologres by following the guide at Import public datasets with a few clicks.

-- Create an Auto-refresh Dynamic Table that intelligent decides the refresh mode. In this example, incremental refresh is the result.
CREATE DYNAMIC TABLE thch_q6_auto
  WITH (
    auto_refresh_mode='auto',
    freshness='1 hours'
       ) 
AS
SELECT
        SUM(l_extendedprice * l_discount) AS revenue
FROM
        hologres_dataset_tpch_100g.lineitem
WHERE
        l_shipdate >= DATE '1996-01-01'
        AND l_shipdate < DATE '1996-01-01' + INTERVAL '1' YEAR
        AND l_discount BETWEEN 0.02 - 0.01 AND 0.02 + 0.01
        AND l_quantity < 24;

Example 4: Create a logical partitioned Dynamic Table

For a real-time transaction dashboard, there's often a need for both near-real-time viewing of current data and correction of historical data, which requires an integrated real-time and offline analysis solution (Business and data cognition). We typically use `Dynamic Table` logical partitions for this scenario. The approach is as follows:

  • The base table is partitioned by day. The latest partition is written to by Flink in real-time/near-real-time, while historical partitions are written from MaxCompute.

  • The Dynamic Table is created as a logical partitioned table. The latest two partitions are active and refreshed incrementally for near-real-time data analytics.

  • Historical partitions are inactive and use full refresh. If the base table's historical partitions have been corrected or backfilled, they can be refreshed using a full refresh.

This example uses a public dataset from GitHub.

  1. Prepare the base table.

    Use Flink to write the latest data to the base table. For detailed steps, see Unified batch and real-time analytics on GitHub events.

    DROP TABLE IF EXISTS gh_realtime_data;
    
    BEGIN;
    CREATE TABLE gh_realtime_data (
        id BIGINT,
        actor_id BIGINT,
        actor_login TEXT,
        repo_id BIGINT,
        repo_name TEXT,
        org_id BIGINT,
        org_login TEXT,
        type TEXT,
        created_at timestamp with time zone NOT NULL,
        action TEXT,
        iss_or_pr_id BIGINT,
        number BIGINT,
        comment_id BIGINT,
        commit_id TEXT,
        member_id BIGINT,
        rev_or_push_or_rel_id BIGINT,
        ref TEXT,
        ref_type TEXT,
        state TEXT,
        author_association TEXT,
        language TEXT,
        merged BOOLEAN,
        merged_at TIMESTAMP WITH TIME ZONE,
        additions BIGINT,
        deletions BIGINT,
        changed_files BIGINT,
        push_size BIGINT,
        push_distinct_size BIGINT,
        hr TEXT,
        month TEXT,
        year TEXT,
        ds TEXT,
        PRIMARY KEY (id,ds)
    )
    PARTITION BY LIST (ds);
    CALL set_table_property('public.gh_realtime_data', 'distribution_key', 'id');
    CALL set_table_property('public.gh_realtime_data', 'event_time_column', 'created_at');
    CALL set_table_property('public.gh_realtime_data', 'clustering_key', 'created_at');
    
    COMMENT ON COLUMN public.gh_realtime_data.id IS 'Event ID';
    COMMENT ON COLUMN public.gh_realtime_data.actor_id IS 'Event actor ID';
    COMMENT ON COLUMN public.gh_realtime_data.actor_login IS 'Event actor login name';
    COMMENT ON COLUMN public.gh_realtime_data.repo_id IS 'Repo ID';
    COMMENT ON COLUMN public.gh_realtime_data.repo_name IS 'Repo name';
    COMMENT ON COLUMN public.gh_realtime_data.org_id IS 'Repo organization ID';
    COMMENT ON COLUMN public.gh_realtime_data.org_login IS 'Repo organization name';
    COMMENT ON COLUMN public.gh_realtime_data.type IS 'Event type';
    COMMENT ON COLUMN public.gh_realtime_data.created_at IS 'Event time';
    COMMENT ON COLUMN public.gh_realtime_data.action IS 'Event action';
    COMMENT ON COLUMN public.gh_realtime_data.iss_or_pr_id IS 'Issue/pull_request ID';
    COMMENT ON COLUMN public.gh_realtime_data.number IS 'Issue/pull_request number';
    COMMENT ON COLUMN public.gh_realtime_data.comment_id IS 'Comment ID';
    COMMENT ON COLUMN public.gh_realtime_data.commit_id IS 'Commit ID';
    COMMENT ON COLUMN public.gh_realtime_data.member_id IS 'Member ID';
    COMMENT ON COLUMN public.gh_realtime_data.rev_or_push_or_rel_id IS 'Review/push/release ID';
    COMMENT ON COLUMN public.gh_realtime_data.ref IS 'Name of created/deleted resource';
    COMMENT ON COLUMN public.gh_realtime_data.ref_type IS 'Type of created/deleted resource';
    COMMENT ON COLUMN public.gh_realtime_data.state IS 'State of issue/pull_request/pull_request_review';
    COMMENT ON COLUMN public.gh_realtime_data.author_association IS 'Relationship between actor and repo';
    COMMENT ON COLUMN public.gh_realtime_data.language IS 'Programming language';
    COMMENT ON COLUMN public.gh_realtime_data.merged IS 'Whether merged';
    COMMENT ON COLUMN public.gh_realtime_data.merged_at IS 'Merge time';
    COMMENT ON COLUMN public.gh_realtime_data.additions IS 'Number of added lines';
    COMMENT ON COLUMN public.gh_realtime_data.deletions IS 'Number of deleted lines';
    COMMENT ON COLUMN public.gh_realtime_data.changed_files IS 'Number of changed files in pull request';
    COMMENT ON COLUMN public.gh_realtime_data.push_size IS 'Number of pushes';
    COMMENT ON COLUMN public.gh_realtime_data.push_distinct_size IS 'Number of distinct pushes';
    COMMENT ON COLUMN public.gh_realtime_data.hr IS 'Hour of event, e.g., 00 for 00:23';
    COMMENT ON COLUMN public.gh_realtime_data.month IS 'Month of event, e.g., 2015-10 for Oct 2015';
    COMMENT ON COLUMN public.gh_realtime_data.year IS 'Year of event, e.g., 2015';
    COMMENT ON COLUMN public.gh_realtime_data.ds IS 'Date of event, ds=yyyy-mm-dd';
    
    COMMIT;
  2. Create a logical partitioned Dynamic Table.

    CREATE  DYNAMIC TABLE ads_dt_github_event
    LOGICAL PARTITION BY LIST(ds)
    WITH (
      -- Dynamic table properties
      freshness = '5 minutes', 
      auto_refresh_mode = 'auto', 
      auto_refresh_partition_active_time = '2 days' ,
      partition_key_time_format = 'YYYY-MM-DD'
    )
    AS
    SELECT
        repo_name,
        COUNT(*) AS events,
        ds
    FROM
        gh_realtime_data
    GROUP BY repo_name,ds
  3. Query the Dynamic Table.

    SELECT * FROM ads_dt_github_event ;
  4. Backfill a historical partition.

    If historical data in the base table changes (e.g., data for '2025-04-01'), and the Dynamic Table needs to be updated, set the historical partition to full refresh mode and trigger a refresh, preferably with Serverless Computing resources.

    REFRESH OVERWRITE DYNAMIC TABLE ads_dt_github_event
    PARTITION (ds = '2025-04-01') 
    WITH (
      refresh_mode = 'full'
    );

Example 5: Calculate UVs with Incremental Dynamic Table

Starting from Hologres V3.1, an Incremental Dynamic Table supports the RB_BUILD_AGG function for calculations like the number of UVs. Compared to pre-aggregation, this offers:

  • Faster performance: Computes only incremental data.

  • Lower cost: Reduced data volume and resource usage, enabling calculations over longer periods.

Example:

  1. Prepare a user detail table.

    BEGIN;
    CREATE TABLE IF NOT EXISTS ods_app_detail (
         uid INT,
         country TEXT,
         prov TEXT,
         city TEXT,
         channel TEXT,
         operator TEXT,
         brand TEXT,
         ip TEXT,
         click_time TEXT,
         year TEXT,
         month TEXT,
         day TEXT,
         ymd TEXT NOT NULL
    );
    CALL set_table_property('ods_app_detail', 'orientation', 'column');
    CALL set_table_property('ods_app_detail', 'bitmap_columns', 'country,prov,city,channel,operator,brand,ip,click_time, year, month, day, ymd');
    -- Set distribution_key based on query needs for optimal sharding effect.
    CALL set_table_property('ods_app_detail', 'distribution_key', 'uid');
    -- For a field with full date-time used in WHERE filters, setting it as clustering_key and event_time_column is recommended.
    CALL set_table_property('ods_app_detail', 'clustering_key', 'ymd');
    CALL set_table_property('ods_app_detail', 'event_time_column', 'ymd');
    COMMIT;
  2. Calculate UV using an Incremental Dynamic Table.

    CREATE DYNAMIC TABLE ads_uv_dt
      WITH (
        freshness = '5 minutes', 
        auto_refresh_mode = 'incremental') 
      AS 
    SELECT  
     RB_BUILD_AGG(uid),
     country,
     prov,
     city,
     ymd,
    COUNT(1)
    FROM    ods_app_detail
    WHERE ymd >= '20231201' AND ymd <='20240502'
    GROUP BY country,prov,city,ymd;
  3. Query UV for a specific day.

    SELECT  
    RB_CARDINALITY(RB_OR_AGG(rb_uid)) AS uv,
      country,
      prov,
      city,
      SUM(pv) AS pv
    FROM    ads_uv_dt
    WHERE   ymd = '20240329'
    GROUP BY country,prov,city;

V3.0

Example 1: Create an auto-starting full-refresh dynamic table

Before proceeding, import the tpch_10g public dataset into Hologres by following the guide at Import public datasets with a few clicks.

--Create "test" Schema
CREATE SCHEMA test;

--Create a single-table full refresh dynamic table, starting immediately and refreshing every hour.
CREATE DYNAMIC TABLE test.thch_q1_full
  WITH (
    refresh_mode='full',
    auto_refresh_enable='true',
    full_auto_refresh_interval='1 hours',
    full_guc_hg_computing_resource='serverless',
    full_guc_hg_experimental_serverless_computing_required_cores='32'
       ) 
AS
  SELECT
        l_returnflag,
        l_linestatus,
        SUM(l_quantity) AS sum_qty,
        SUM(l_extendedprice) AS sum_base_price,
        SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
        SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
        AVG(l_quantity) AS avg_qty,
        AVG(l_extendedprice) AS avg_price,
        AVG(l_discount) AS avg_disc,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus;

Example 2: Create an incremental dynamic table with a start time

Before proceeding, import the tpch_10g public dataset into Hologres by following the guide at Import public datasets with a few clicks.

Example:

Note

Before creating an incremental `Dynamic Table`, you must enable Binlog for the base table (not required for dimension tables).

--Enable binlog for the base table:
BEGIN;
CALL set_table_property('hologres_dataset_tpch_10g.lineitem', 'binlog.level', 'replica');
COMMIT;

--Create a single-table incremental refresh dynamic table, specifying a start time and a 3-minute refresh interval.
CREATE DYNAMIC TABLE public.tpch_q1_incremental 
WITH (
refresh_mode='incremental',
auto_refresh_enable='true',
incremental_auto_refresh_schd_start_time='2024-09-15 23:50:0',
incremental_auto_refresh_interval='3 minutes',
incremental_guc_hg_computing_resource='serverless',
incremental_guc_hg_experimental_serverless_computing_required_cores='30'
) AS SELECT
        l_returnflag,
        l_linestatus,
        COUNT(*) AS count_order
FROM
        hologres_dataset_tpch_10g.lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus
;

Example 3: Create a multi-join full-refresh dynamic table

--Create a dynamic table with a multi-table join query, using full refresh mode every 3 hours.
CREATE DYNAMIC TABLE dt_q_full
  WITH (
    refresh_mode='full',
    auto_refresh_enable='true',
    full_auto_refresh_schd_start_time='immediate',
    full_auto_refresh_interval='3 hours',
    full_guc_hg_computing_resource='serverless',
    full_guc_hg_experimental_serverless_computing_required_cores='64'
  ) 
AS 
SELECT
        o_orderpriority,
        COUNT(*) AS order_count
FROM
        hologres_dataset_tpch_10g.orders
WHERE
        o_orderdate >= DATE '1996-07-01'
        AND o_orderdate < DATE '1996-07-01' + INTERVAL '3' MONTH
        AND EXISTS (
                SELECT
                        *
                FROM
                        hologres_dataset_tpch_10g.lineitem
                WHERE
                        l_orderkey = o_orderkey
                        AND l_commitdate < l_receiptdate
        )
GROUP BY
        o_orderpriority;

Example 4: Create a dimension-join incremental dynamic table

Example:

Note

Before creating an incremental `Dynamic Table`, you must enable Binlog for the base table (not required for dimension tables).

The semantics of a dimension table JOIN are that each record is joined only with the latest version of the dimension table data at that time, i.e., the JOIN occurs at processing time. If the dimension table data changes (add, update, or delete) after the JOIN, the already joined data is not updated. SQL example:

--Detail table
BEGIN;
CREATE TABLE public.sale_detail(
        app_id TEXT,
        uid TEXT,
        product TEXT,
        gmv BIGINT,
        order_time TIMESTAMPTZ
);
--Enable binlog for the base table; dimension tables do not require it.
CALL set_table_property('public.sale_detail', 'binlog.level', 'replica');
COMMIT;

--Property table
CREATE TABLE public.user_info(
        uid TEXT,
        province TEXT,
        city TEXT
);

CREATE DYNAMIC TABLE public.dt_sales_incremental
  WITH (
    refresh_mode='incremental',
    auto_refresh_enable='true',
    incremental_auto_refresh_schd_start_time='2024-09-15 00:00:00',
    incremental_auto_refresh_interval='5 minutes',
    incremental_guc_hg_computing_resource='serverless',
    incremental_guc_hg_experimental_serverless_computing_required_cores='128') 
AS 
SELECT 
    sale_detail.app_id,
    sale_detail.uid,
    product,
    SUM(sale_detail.gmv) AS sum_gmv,
    sale_detail.order_time,
    user_info.province,
    user_info.city 
FROM public.sale_detail 
INNER JOIN public.user_info  FOR SYSTEM_TIME AS OF PROCTIME()
ON sale_detail.uid =user_info.uid
GROUP BY sale_detail.app_id,sale_detail.uid,sale_detail.product,sale_detail.order_time,user_info.province,user_info.city;

Example 5: Create a partitioned dynamic table

For a real-time transaction dashboard, there's often a need for both near-real-time viewing of current data and correction of historical data. This can be achieved using a combination of `Dynamic Table` incremental and full refresh. The approach is as follows:

  1. Create a partitioned base table where the latest partition is written in real-time/near-real-time, and historical partitions are occasionally corrected.

  2. Create a `Dynamic Table` as a partitioned parent table. Use incremental refresh for the latest partition to meet near-real-time analysis needs.

  3. Switch historical partitions to full refresh mode. If the source table's historical partitions have been corrected, the `Dynamic Table`'s partitions can also be backfilled using full refresh, preferably with Serverless to speed it up.

Example:

  1. Prepare the base table and data.

    The base table is a partitioned table, with the latest partition receiving real-time data.

    -- Create a partitioned source table
    CREATE TABLE base_sales(
      uid INT,
      opreate_time TIMESTAMPTZ,
      amount FLOAT,
      tt TEXT NOT NULL,
      ds TEXT,
      PRIMARY KEY(ds)
    ) PARTITION BY LIST (ds) ;
    
    --Historical partition
    CREATE TABLE base_sales_20240615 PARTITION OF base_sales FOR VALUES IN ('20240615');
    INSERT INTO base_sales_20240615 VALUES (2,'2024-06-15 16:18:25.387466+08','111','2','20240615');
    
    --Latest partition, typically for real-time writes
    CREATE TABLE base_sales_20240616 PARTITION OF base_sales FOR VALUES IN ('20240616');
    INSERT INTO base_sales_20240616 VALUES (1,'2024-06-16 16:08:25.387466+08','2','1','20240616');

  2. Create a partitioned `Dynamic Table` parent table, defining only the query without a refresh mode.

    --Create extension
    CREATE EXTENSION roaringbitmap;
    
    CREATE DYNAMIC TABLE partition_dt_base_sales
    PARTITION BY LIST (ds)
    as
    SELECT  
     public.RB_BUILD_AGG(uid),
     opreate_time,
     amount,
     tt,
     ds,
    COUNT(1)
    FROM    base_sales
    GROUP BY opreate_time ,amount,tt,ds;

  3. Create sub-tables and set their refresh modes.

    You can create `Dynamic Table` sub-partitions manually or dynamically using DataWorks. Set the latest partition to incremental refresh and historical partitions to full refresh.

    -- Enable Binlog for the base table
    ALTER TABLE base_sales SET (binlog_level = replica);
    
    -- Assume the historical Dynamic Table sub-partition is as follows:
    CREATE DYNAMIC TABLE partition_dt_base_sales_20240615 PARTITION OF partition_dt_base_sales FOR VALUES IN ('20240615')
      WITH (
        refresh_mode='incremental',
        auto_refresh_enable='true',
        incremental_auto_refresh_schd_start_time='immediate',
        incremental_auto_refresh_interval='30 minutes'
           );
    
    -- Create a new Dynamic Table sub-partition, set its refresh mode to incremental, start immediately, refresh every 30 minutes, and use instance resources.
    CREATE DYNAMIC TABLE partition_dt_base_sales_20240616 PARTITION OF partition_dt_base_sales FOR VALUES IN ('20240616')
      WITH (
        refresh_mode='incremental',
        auto_refresh_enable='true',
        incremental_auto_refresh_schd_start_time='immediate',
        incremental_auto_refresh_interval='30 minutes'
           );
    
    --Switch the historical partition to full refresh mode
    ALTER DYNAMIC TABLE partition_dt_base_sales_20240615 SET (refresh_mode = 'full');
    --If historical partition data needs correction, execute a refresh, preferably with serverless.
    SET hg_computing_resource = 'serverless';
    REFRESH DYNAMIC TABLE partition_dt_base_sales_20240615;

Convert legacy to new syntax

Hologres V3.1 changed the Dynamic Table creation syntax. After upgrading from V3.0, recreate Dynamic Tables with the new syntax. A conversion tool simplifies this process.

Scenarios

  • Incremental Dynamic Tables must be recreated with new syntax.

  • Syntax incompatibilities found during the upgrade check. Refer to your upgrade check report for details.

Note

Except for the scenarios above, Dynamic Tables from V3.0 do not require recreation in Hologres V3.1. However, only ALTER DYNAMIC TABLE can be performed on them. CREATE DYNAMIC TABLE (old syntax) is not supported in V3.1+.

Limitations

The syntax conversion command is restricted to non-partitioned tables (both Incremental and Full-refresh). For partitioned Dynamic Tables from V3.0, recreate them manually.

View Dynamic Tables requiring syntax conversion

Find tables in your instance that need conversion after an upgrade:

Non-partitioned tables

SELECT DISTINCT 
    p.dynamic_table_namespace as table_namespace, 
    p.dynamic_table_name as table_name
FROM hologres.hg_dynamic_table_properties p
JOIN pg_class c ON c.relname = p.dynamic_table_name
JOIN pg_namespace n ON n.oid = c.relnamespace AND n.nspname = p.dynamic_table_namespace
WHERE p.property_key = 'refresh_mode' 
    AND p.property_value = 'incremental'
    AND c.relispartition = false 
    AND c.relkind != 'p';

Partitioned tables

SELECT DISTINCT 
    pn.nspname as parent_schema,
    pc.relname as parent_name
FROM hologres.hg_dynamic_table_properties p
JOIN pg_class c ON c.relname = p.dynamic_table_name
JOIN pg_namespace n ON n.oid = c.relnamespace AND n.nspname = p.dynamic_table_namespace
JOIN pg_inherits i ON c.oid = i.inhrelid
JOIN pg_class pc ON pc.oid = i.inhparent
JOIN pg_namespace pn ON pn.oid = pc.relnamespace
WHERE p.property_key = 'refresh_mode' 
    AND p.property_value = 'incremental'
    AND c.relispartition = true 
    AND c.relkind != 'p';

Perform syntax conversion

Notes:

  • Version requirement: V3.1.11 and later.

  • Role requirement: Superuser.

  • Post-conversion behavior changes:

    • Automatic refresh starts immediately if the refresh mode is auto. Ensure the operation occurs during off-peak hours to avoid resource contention. For better isolation, use Serverless Computing resources.

    • Resource usage changes for virtual warehouse instances:

      • V3.1/V3.2 (new syntax): Refreshing Dynamic Tables use resources from the primary virtual warehouses of base and dynamic tables' Table Groups.

      • V3.0 (legacy syntax) and V4.1 (new syntax): Refreshing Dynamic Tables use resources from the primary virtual warehouse of the Dynamic Table's Table Group.

    • New syntax adds one connection per Dynamic Table for scheduling. If your instance has high connection usage, clear idle connections first.

Commands:

-- Only for non-partitioned tables (full and incremental).
-- Convert a single Dynamic Table
call hg_dynamic_table_config_upgrade('<table_name>');

-- Convert all Dynamic Tables. Use with caution.
call hg_upgrade_all_normal_dynamic_tables();
Note

These commands convert Dynamic Tables (old syntax) in the current database to the new syntax.

Syntax parameter mappings

The command maps V3.0 and V3.1 parameters and values as follows:

Legacy syntax (V3.0)

New syntax (V3.1+)

Description

refresh_mode

auto_refresh_mode

The parameter value is preserved after conversion. For example, refresh_mode='incremental' becomes auto_refresh_mode='incremental'.

auto_refresh_enable

auto_refresh_enable

The parameter value is preserved after conversion.

{refresh_mode}_auto_refresh_schd_start_time

freshness

The auto_refresh_interval value becomes the freshness value.

E.g., full_auto_refresh_interval='30 minutes' becomes freshness='30 minutes'.

{refresh_mode}_auto_refresh_interval

{refresh_mode}_guc_hg_computing_resource

computing_resource

The parameter value is preserved after conversion. E.g., full_guc_hg_computing_resource='serverless' becomes computing_resource='serverless'.

{refresh_mode}guc_hg_experimental_serverless_computing_required_cores

refresh_guc_hg_experimental_serverless_computing_required_cores

The parameter value is preserved after conversion.

{refresh_mode}guc<guc>

refresh_guc<guc_name>

The parameter value is preserved after conversion. For example, incremental_guc_hg_experimental_max_consumed_rows_per_refresh='1000000' becomes refresh_guc_hg_experimental_max_consumed_rows_per_refresh='1000000'.

Table properties (e.g., orientation)

Table properties (e.g., orientation)

Basic table properties remain unchanged.

References

FAQ

  • Q: How do I fix the error with a null segment or clustering key? Example:

    ERROR: commit ddl phase1 failed: the index partition key "xxx" should not be nullable
  • Cause: A Dynamic Table's segment or clustering key is non-nullable. For rules on setting these keys, see Event time column (segment key).

  • Solution:

    1. Clustering key error: For Hologres earlier than V3.1.26, V3.2.9, V4.0.0, upgrade your instance and modify the following GUC to allow a nullable clustering key:

      -- For V3.1 and later
      ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET
      (refresh_guc_hg_experimental_enable_nullable_segment_key=true);
    2. Segment key error: Run the following command to allow a nullable segment key. Starting from Hologres V4.1, segment keys are nullable allowed by default, so we recommend upgrading your instance to fix the error.

      --For V3.1 and later, allows a nullable clustering key
      ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET
      (refresh_guc_hg_experimental_enable_nullable_clustering_key=true);