v4.6.0 Release Notes

Release date: June, 2026

Version: v4.6.0

SynxDB v4.6.0 adds native Apache Iceberg table support, extends vectorized execution and GPORCA parallel query capabilities, and introduces type-specific column encodings for PAX tables.

  • Data federation and lakehouse integration: Manages Apache Iceberg tables as native tables with full INSERT, UPDATE, and DELETE support, works with the catalog and storage system you already use (Hive Metastore, Apache Polaris, Hadoop, S3, or a built-in catalog), and automatically compacts data in the background so query performance stays stable over time.

  • Query processing and optimization: Speeds up recurring multi-table analytical queries by reusing materialized views, accelerates common aggregations and top-N queries through vectorized execution improvements, and runs more join types in parallel for faster large-scale queries.

  • Storage: Introduces type-specific column encodings (deltadelta, gorilla, bool) for PAX tables to compress time-series data.

New features

Database

Category

Feature

User documents

Data federation and lakehouse integration

Manages Apache Iceberg tables as native relations through new FOREIGN CATALOG, FOREIGN VOLUME, and ICEBERG TABLE objects, with full INSERT, UPDATE, and DELETE support.

Create and Manage Apache Iceberg Tables

Data federation and lakehouse integration

Supports multiple Iceberg catalog backends (builtin, Hive Metastore, Apache Polaris, Hadoop, and S3) and S3-compatible or HDFS storage volumes for Iceberg tables.

Configure a foreign catalog, Configure a foreign volume

Data federation and lakehouse integration

Compacts Iceberg data files through VACUUM, with autovacuum enabled by default to reclaim position-delete accumulation automatically.

Compact tables with VACUUM

Query processing and optimization

Multi-table JOIN exact-match rewrite for AQUMV.

Multi-table join exact-match support

Query processing and optimization

Vectorized hash aggregation enhancements.

Vectorization query computing

Query processing and optimization

Vectorized scan and sort optimizations for top-N queries on PAX tables.

Vectorization query computing

Query processing and optimization

GPORCA parallel outer hash join and streaming hash aggregate enhancements.

Parallel hash join

Query processing and optimization

Parallel outer hash joins in the Postgres query optimizer.

Parallel execution with Postgres query optimizer

Storage

Type-specific column encodings for PAX tables.

Compress column data with encoding

New feature details

Data federation and lakehouse integration

  • Native Apache Iceberg tables: SynxDB manages Apache Iceberg tables as native relations instead of foreign tables, so CREATE, SELECT, INSERT, UPDATE, DELETE, and VACUUM run directly against Iceberg tables through the native executor. A FOREIGN CATALOG resolves Iceberg metadata, a FOREIGN VOLUME accesses the underlying storage, and an ICEBERG TABLE binds the two into a queryable relation. INSERT, UPDATE, and DELETE use Iceberg v2 merge-on-read semantics, producing position-delete records instead of rewriting data files. As a result, you can run ACID reads and writes against your Iceberg data lake directly from SynxDB, instead of treating it as read-only or routing every write through Spark or Trino.

    See Create and Manage Apache Iceberg Tables.

  • Multiple Iceberg catalog and storage backends: A FOREIGN CATALOG can resolve Iceberg metadata through a builtin catalog, a Hive Metastore, an Apache Polaris REST catalog, or a Hadoop or S3 catalog, and a FOREIGN VOLUME reads and writes data on S3-compatible storage or HDFS. Session-level defaults (iceberg_default_catalog, iceberg_default_volume) let CREATE ICEBERG TABLE omit these clauses. This lets you connect SynxDB to an Iceberg data lake you already share with Spark, Trino, or Flink, regardless of catalog or storage backend, without migrating metadata or data.

    See Create and Manage Apache Iceberg Tables - Configure a foreign catalog and Create and Manage Apache Iceberg Tables - Configure a foreign volume.

  • Iceberg VACUUM compaction and autovacuum: Running VACUUM on an Iceberg table compacts small data files and reduces the position-delete accumulation from merge-on-read updates and deletes. Compaction thresholds are tunable at the session level, and a background autovacuum worker, enabled by default, checks tables and triggers compaction automatically. This keeps query performance on frequently updated Iceberg tables from degrading, without requiring you to script and schedule compaction jobs yourself.

    See Create and Manage Apache Iceberg Tables - Compact tables with VACUUM.

Query processing and optimization

  • Multi-table JOIN exact-match rewrite for AQUMV: Answer Query Using Materialized Views (AQUMV) now rewrites multi-table JOIN queries. When a query is structurally identical to a populated, up-to-date materialized view, the planner reads from the view instead of recomputing the join. This lets repeated multi-table analytical queries, such as a recurring dashboard query, reuse pre-computed results without requiring you to rewrite the query or maintain a custom rewrite rule.

    See Use automatic materialized views for query optimization.

  • Vectorized hash aggregation enhancements: The vectorized executor improves hash aggregation in the following areas:

    • Sonic and Normal hash aggregate engines: Hash aggregation now runs on a faster default engine (reported as Sonic in EXPLAIN VERBOSE) for common analytic aggregations, falling back to the legacy Normal engine otherwise. Both return identical results, so GROUP BY aggregations run faster with no query changes required. Check the Vec HashAgg Method: line in EXPLAIN VERBOSE to see which engine handled a query. See Hash aggregate execution engines.

    • date_trunc vectorization: date_trunc(unit, timestamp) now runs through the vectorized engine when the column is timestamp and unit is a constant string literal, falling back to row-based execution otherwise with identical results. Time-bucketed rollups, such as aggregating by day or month for a dashboard, pick up this speedup automatically. See Features supported by vectorization.

    • Limit+HashAgg early stop: When a GROUP BY feeds directly into LIMIT without an ORDER BY in between, the executor stops aggregating after the first N groups instead of building the full hash table, delivering roughly a 3x speedup on top-N-by-group workloads such as TPC-H Q18. Control the threshold with vector.limit_hashagg_max_total. See Speed up top-N group queries with Limit+HashAgg early stop.

    • Direct-send routing for redistribute Motion: For distributed queries that redistribute a hash aggregation’s result, the executor can forward output batches to the Motion operator without rehashing every row, reducing per-row overhead and latency on queries that span segments, such as a GROUP BY over a large fact table. Enable it with vector.sonic_motion_direct_send. See Reduce cross-segment latency with direct-send routing.

  • Vectorized scan and sort optimizations for top-N queries: The vectorized executor speeds up ORDER BY ... LIMIT N queries on PAX tables in the following areas:

    • TopK operator for ORDER BY ... LIMIT N: Instead of fully sorting the input, the executor maintains a bounded heap of the best N rows, so it never materializes a full sorted set. It applies when LIMIT + OFFSET is within vector.topk_bound_threshold (default 2000); larger values, or a query with OFFSET, fall back to a full sort. This speeds up common “top N rows” queries, such as the 10 most recent orders, without sorting the entire table. Look for Vec Sort Method: TopK in EXPLAIN to confirm. See Speed up ORDER BY … LIMIT N with TopK.

    • PAX row-group skipping for TopK queries: When vector.topk_runtime_filter is on (the default), the executor pushes the TopK heap’s current worst value down to the PAX scan as a threshold, so the scan skips any row group whose min/max statistics cannot improve the top N result. This reduces I/O for ORDER BY ... LIMIT N queries on large PAX tables. See Skip PAX row groups for TopK queries.

    • PAX fast filter with two-phase column read: For simple predicates on wide PAX tables, the vectorized scan reads only the filter columns first, evaluates the predicate natively, and reads remaining output columns only for rows that pass, skipping a group’s output columns entirely when no row passes. The savings grow with table width and predicate selectivity, so this has the biggest impact on selective queries against wide tables. Controlled by pax.enable_fast_filter (on by default). See Use fast filter for two-phase column read.

  • GPORCA parallel outer hash join and streaming hash aggregate enhancements: GPORCA improves parallel query plans in the following areas:

    • Parallel outer hash joins: GPORCA now generates parallel-aware hash plans for Right Outer and Full Outer joins, in addition to Inner and Left Outer joins, extending intra-segment parallelism to ORCA-planned outer-join workloads. For a LEFT JOIN, GPORCA can also flip the join into a Parallel Hash Right Join when the inner side is smaller, building the hash table on fewer rows. See Parallel hash join.

    • Streaming hash aggregate control: By default, GPORCA uses a streaming hash aggregate for local partial aggregation, avoiding disk spills; this helps queries that aggregate over large datasets or use GROUP BY with many distinct values. When the streaming plan doesn’t fit a workload, set optimizer_use_streaming_hashagg to off for a non-streaming aggregate that spills to disk and fully deduplicates. Applies only when optimizer is on; the Postgres optimizer uses gp_use_streaming_hashagg instead. See Parallel aggregation.

  • Parallel outer hash joins in the Postgres query optimizer: The Postgres query optimizer now parallelizes FULL JOIN and RIGHT JOIN using Parallel Hash Full Join and Parallel Hash Right Join nodes instead of falling back to serial execution. The join preserves the parallel locus, so aggregations and further joins built on top stay parallel instead of losing it partway through the plan. When the probe side is larger than the build side, the planner builds the hash table on the smaller table.

    See Parallel execution with Postgres query optimizer.

Storage

  • Type-specific column encodings for PAX tables: PAX columns can now use encodings tuned to their data type: deltadelta for integer, date, and timestamp columns, gorilla for floats, and bool for booleans, compressing time-series data far more than general compression does. deltadelta suits timestamps and monotonic counters, gorilla suits slowly changing metrics such as CPU usage or sensor readings, and bool suits flag columns. Apply per column with the ENCODING clause; writing data in sorted order improves the compression ratio.

    See Compress column data with encoding.

Product change information

GUC configuration parameters

Newly added GUCs

The following configuration parameters are added:

  • iceberg_default_catalog: default '' (empty string). Sets the default foreign catalog used by CREATE ICEBERG TABLE when the statement omits the CATALOG clause. See Configuration parameters.

  • iceberg_default_volume: default '' (empty string). Sets the default foreign volume used by CREATE ICEBERG TABLE when the statement omits the VOLUME clause. See Configuration parameters.

  • datalake.iceberg_autovacuum: default on. Enables the background autovacuum worker for Iceberg tables. See Configuration parameters.

  • datalake.iceberg_autovacuum_naptime: default 600 (s). Sets the interval at which the Iceberg autovacuum worker checks tables. See Configuration parameters.

  • datalake.iceberg_vacuum_compact_min_input_files: default 5. Sets the minimum number of small data files required before VACUUM compacts them into a larger file. See Configuration parameters.

  • datalake.iceberg_vacuum_rewrite_target_file_size_mb: default 512 (MB). Sets the target file size produced by Iceberg VACUUM compaction. See Configuration parameters.

  • datalake.iceberg_postion_deletes_threshold: default 100000, range [100000, 10000000]. Sets the maximum number of position-delete records accumulated per Iceberg data file before compaction is triggered. See Configuration parameters.

  • datalake.iceberg_max_compactions_per_vacuum: default 100. Sets the maximum number of compaction operations performed within a single VACUUM on an Iceberg table. See Configuration parameters.

  • datalake.iceberg_max_file_removals_per_vacuum: default 100000. Sets the maximum number of orphan or expired files the background deletion queue removes per VACUUM invocation. See Configuration parameters.

  • datalake.iceberg_max_snapshot_age: default 432000 (s, 5 days). Sets the maximum retention age for Iceberg snapshots before they become eligible for cleanup by the background deletion queue. See Configuration parameters.

  • datalake.iceberg_log_autovacuum_min_duration: default 600000 (ms). Logs autovacuum runs that exceed this duration; -1 disables logging and 0 logs every run. See Configuration parameters.

  • datalake.enable_iceberg_fragment_cache: default on. Controls whether Iceberg scan fragments (data file split metadata) are cached across queries to reduce metadata lookup overhead. See Configuration parameters.

  • datalake.disable_filter_pushdown: default off. When on, disables predicate pushdown for datalake_fdw external tables and Iceberg tables, applying filters in upper plan nodes instead. See Configuration parameters.

  • vector.limit_hashagg_max_total: default 1000. Controls the Limit+HashAgg early-stop optimization for vectorized top-N group queries. See Vectorization query computing.

  • vector.sonic_motion_direct_send: default off. Enables direct-send routing between a vectorized hash aggregate and a redistribute Motion. See Vectorization query computing.

  • vector.topk_bound_threshold: default 2000. Controls the bounded-heap TopK optimization for vectorized ORDER BY ... LIMIT N queries. See Vectorization query computing.

  • vector.topk_runtime_filter: default on. Controls PAX row-group skipping driven by the TopK threshold. See Vectorization query computing.

  • pax.enable_fast_filter: default on. Controls the PAX fast filter with two-phase column read for simple predicates. See Use fast filter for two-phase column read.

  • optimizer_use_streaming_hashagg: default on. Controls whether GPORCA uses a streaming hash aggregate for local partial aggregation. See Parallel aggregation.

Changed GUCs

The following configuration parameters are changed:

  • vector.winagg_spill_work_mem is renamed to vector.winagg_spill_memory_mb, with the unit changed from kB to MB, the default changed from 0 to 512, and 0 now disabling spill-to-disk instead of falling back to work_mem. See Set window aggregate spill memory budget.

Bug fixes and improvements

Data federation and lakehouse integration

  • Bumped CATALOG_VERSION_NO for laketable catalogs so upgraded clusters reject catalog files written by a previous version instead of silently reading a mismatched layout, preventing data corruption after upgrade.

  • Fixed data loss when concurrent INSERT statements into an Iceberg table both retried a metadata commit, which could drop one writer’s files from the resulting snapshot.

  • Stopped sharing the IcebergMetadataFetcher across concurrent requests in datalake_agent, eliminating metadata corruption and intermittent failures under concurrent Iceberg queries.

  • Fixed a double-free in datalake_fdw Iceberg End hooks triggered when an error occurred during cleanup, eliminating a class of crashes on the Iceberg query error path.

  • Fixed a backend crash at INSERT plan time when CREATE FOREIGN TABLE omitted required Iceberg options, replacing it with a clear error naming the missing option.

  • Fixed the dlproxy write request to set Content-Type: application/json, restoring compatibility with catalog servers that strictly validate the header.

  • Rejected all ALTER TABLE subcommands on Iceberg tables and fixed a crash that could leave the relation in a half-applied state, including a related fix so ALTER TABLE DROP COLUMN on the source heap no longer breaks the Parquet writer.

  • Fixed external-catalog Iceberg tables storing the metadata file URI as the table location, which broke later scans.

  • Fixed an orphaned pg_depend row left behind after dropping an Iceberg table under datalake_fdw.

  • Fixed a failure when an Iceberg table on an S3 catalog received two UPDATE statements in the same transaction.

  • Fixed Iceberg bytea values being silently truncated at the first NUL byte during write.

  • Fixed an incorrect type-mapping warning for CHAR(N) columns in Iceberg tables.

  • Fixed INSERT failures on Iceberg tables containing TIMESTAMPTZ columns.

  • Fixed Iceberg merge-on-read UPDATE writing empty position-delete entries that broke downstream readers such as Spark and Trino.

  • Fixed silent data corruption for Iceberg columns declared numeric(p,s) with scale 37 or 38.

  • Fixed Iceberg SeqScan rewrites dropping Sequence node children from the plan tree.

  • Fixed UPDATE and DELETE statements on Iceberg tables that reference cross-table subqueries.

  • Fixed a C++ handle leak in datalake_fdw Iceberg catalog End hooks that slowly leaked resources on long-lived sessions.

  • Fixed a null catalogHandle in fdwContext after the context is deleted, closing a use-after-free in the datalake_fdw error-recovery path.

  • Required the datalake_fdw extension for CREATE TABLE ... USING iceberg and CREATE ICEBERG TABLE, returning a clear error instead of leaving an unreadable, undroppable relation when the extension is missing.

  • Routed Iceberg commits through commitAppend for non-builtin catalogs so the external catalog pointer advances atomically on each commit, ensuring external readers see the new snapshot.

  • Extended the external-catalog commit path in datalake_agent to cover UPDATE, DELETE, and rewrite operations, matching the coverage already available on the builtin catalog.

  • Added NULL guards and clearer missing-option errors in the shared Iceberg/Hudi option builder.

Query optimizer and executor

  • Fixed ORDER BY being lost after the AQUMV join rewrite.

  • Added C.utf8 and C.UTF-8 to the vectorized sort collation whitelist.

  • Fixed an attnum-index mismatch in column-specific ANALYZE that produced incorrect per-segment NDV statistics.

  • Fixed a hang in vectorized execution when ShareInputScan crosses slice boundaries.

  • Fixed CREATE TABLE ... LIKE ... INCLUDING INDEXES producing duplicated distribution keys on the new table.

  • Made ORCA fall back to the PostgreSQL planner for queries with KNN ORDER BY, because ORCA lacks support for the operator.

  • Fixed ORCA incorrectly decorrelating GROUP BY () HAVING <outer_ref> queries, which produced wrong results.

  • Initialized previously uninitialized PlannedStmt fields in ORCA.

  • Fixed ORCA misdetecting mixed storage in partitioned tables whose partitions include foreign tables.

  • Set the FRAMEOPTION_BETWEEN flag on ORCA-generated window frames so downstream consumers interpret them correctly.

  • Fixed a use-after-free in flatten_join_alias_var_optimizer that could crash ORCA under specific query shapes.

  • Fixed ORCA picking the wrong column type for CREATE TABLE AS SELECT plans that contain UNION ALL.

  • Kept the numeric output path for sum(bigint), fixing a crash in vectorized SUM aggregates over BIGINT columns.

  • Fixed vectorized Motion hashing on TIMESTAMP, TIMESTAMPTZ, and TIME columns, which previously produced inconsistent hashes between segments.

  • Fixed incorrect row counts on queries whose GROUP BY target list contains only constant expressions.

  • Eliminated redundant derived GROUP BY expressions before execution, speeding up affected grouping queries.

Storage and access methods

  • Fixed aoco_relation_size() reading pg_aocsseg with the wrong snapshot, which could return stale or inconsistent sizes.

  • Fixed concurrent palloc/pfree calls in the PAX TopK runtime filter that could crash under parallel scan.

  • Fixed a SIGSEGV in fsm_extend when vacuuming a table stored in a non-default tablespace.

  • Fixed a SIGSEGV on segments when creating an in-place tablespace.

  • Fixed typos and added MPP support for the allow_inplace_tablespace GUC.

Processes and concurrency

  • Fixed a session lock leak in ALTER DATABASE ... SET TABLESPACE when run in utility mode.

  • Fixed a SIGSEGV in getCdbComponentInfo() when the standby coordinator is deployed on a dedicated host rather than co-located with a primary.

Security

  • Backported the upstream libpq fix to bail out immediately on SSL/GSS negotiation errors instead of retrying with a downgraded protocol, closing a downgrade-attack vector during connection negotiation.

Tools and utilities

  • Fixed duplicate counting of num_executed in gp_toolkit.gp_resgroup_status.

  • Fixed a SyntaxWarning under Python 3.12 in orphaned_toast_tables_check.py.

  • Fixed stale errno handling in initdb’s setup_cdb_schema().

  • Fixed pg_dump/restore failures when expression indexes reference nested SQL functions.

  • Advanced old-cluster checkpoint counters to new-cluster values during pg_upgrade so post-upgrade WAL replay starts from a consistent point.

  • Forward-ported upstream pg_upgrade xid fixes to segments for more reliable upgrades on clusters with high xid usage.

  • Froze coordinator data after relfilenode transfer during pg_upgrade to prevent xid-wraparound issues post-upgrade.

  • Invalidated BRIN indexes on AO/CO tables after pg_upgrade so they are rebuilt instead of returning stale summaries.

  • Preserved gp_fastsequence values across pg_upgrade, preventing duplicate-row or sequence-skip issues on AO/CO tables after upgrade.

  • Fixed a syntax error in a packaged bash script that handles LD_LIBRARY_PATH.

  • Fixed COPY FROM double-counting encoding errors and enabled single-row error handling for transcoding errors.

  • Improved psql SQL tab-completion for resource group commands.

Observability

  • Fixed places that displayed Oids incorrectly in log and error messages.

  • Widened MotionLayerState stat counters from uint32 to uint64 to prevent overflow on long-running queries with high motion volume.