Fixed inconsistent query formatting caused by incorrect alias substitution. Note: when the analyzer is disabled, certain CREATE VIEW queries that use IN with an alias reference may no longer be processed. To avoid this, ensure the analyzer is enabled (it has been enabled by default since 24.3). #82838 (Alexey Milovidov).
An empty column list in JOIN USING () is now a syntax error. Previously, this was reported as INVALID_JOIN_ON_EXPRESSION at query execution time, and in some cases (such as joining with Join storage) could cause a LOGICAL_ERROR. #92371 (Vladimir Cherkasov).
Subqueries are no longer allowed in ORDER BY and other table key expressions. #96847 (Alexey Milovidov).
Added support for Nullable(Tuple). To enable it, set allow_experimental_nullable_tuple_type = 1. #89643 (Nihal Z. Miaji).
Advanced shared data for the JSON type is now enabled by default. Downgrading to versions earlier than 25.8 will not be possible, as older versions cannot read data parts written with the new JSON format. For safe upgrades, set the compatibility setting to the previous version, or set MergeTree settings dynamic_serialization_version='v2' and object_serialization_version='v2'. #92511 (Pavel Kruglov).
SKIP REGEXP in the JSON type now uses partial matching by default. #92847 (Pavel Kruglov).
Fixed a logical error that occurred on Variant type mismatch. #95811 (Bharat Nallan).
DATE columns from PostgreSQL are now inferred as Date32 in ClickHouse (previously they were inferred as Date, which could overflow for values outside its narrow range). Inserting Date32 values back to PostgreSQL is also now supported. #95999 (Alexey Milovidov).
Improved the storage layout of the inverted text index for more efficient reads from object storage, along with better merge performance for tables with inverted text indexes. If you used the experimental text index before version 25.12, you must drop the index before upgrading and rebuild it on the new version. #91518 (Anton Popov).
The storage format for statistics has changed — all statistics are now stored in a single file. #93414 (Anton Popov).
Index filenames are now escaped to prevent broken parts. ClickHouse will fail to load indices with non-ASCII characters in their name that were created by previous versions. To handle this, use the MergeTree setting escape_index_filenames. #94079 (Raúl Marín).
The DEFLATE_QPL and ZSTD_QAT codecs have been removed. Convert any existing data compressed with these codecs to another codec before upgrading. Note that using these codecs previously required enabling enable_deflate_qpl_codec or enable_zstd_qat_codec. #92150 (Robert Schulze).
INSERT into simple ALIAS columns is no longer supported (reverts #84154). This feature did not work with custom formats and was not guarded by a setting. #92849 (Azat Khuzhin).
The Lazy database engine has been removed and is no longer available. #93627 (Alexey Milovidov).
The transposed_with_wide_view mode of metric_log has been removed due to a bug that made it unusable. It is no longer possible to define system.metric_log with this mode. #93867 (Alexey Milovidov).
A new setting now throws an error if a data lake catalog does not have access to object storage. #93606 (Konstantin Vedernikov).
CPU scheduling for workloads is now preemptive by default. See the cpu_slot_preemption server setting. #94060 (Sergei Trifonov).
The settings exact_rows_before_limit, rows_before_aggregation, cross_to_inner_join_rewrite, regexp_dict_allow_hyperscan, regexp_dict_flag_case_insensitive, regexp_dict_flag_dotall, and dictionary_use_async_executor have been reclassified from format settings to regular settings. This is mostly an internal change with no user-visible side effects, unless you specified any of these in an Iceberg, DeltaLake, Kafka, S3, S3Queue, Azure, Hive, RabbitMQ, Set, FileLog, or NATS table engine definition — in which case, such definitions will now throw an error instead of silently ignoring them. #94106 (Robert Schulze).
The semantics of do_not_merge_across_partitions_select_final have been simplified. Previously, the feature could be automatically enabled even when not explicitly set, which caused confusion and production issues. Now: setting it to 1 enables the functionality unconditionally, and setting it to 0 defers to the new setting enable_automatic_decision_for_merging_across_partitions_for_final (default 1). #96110 (Nikita Taranov).
The apply_row_policy_after_final setting is now enabled by default, ensuring that ROW POLICY respects FINAL as it did originally. If you previously relied on optimize_move_to_prewhere_if_final=1 to apply row policies before FINAL, use apply_row_policy_after_final=0 instead. #97279 (Nikolai Kochetov).
joinGet/joinGetOrNull now enforce SELECT privileges on the underlying Join table. Executing joinGet('db.table', 'column', key) requires SELECT privilege on both the key columns and the attribute column being retrieved. Queries without these privileges will fail with ACCESS_DENIED. To migrate, grant permissions using GRANT SELECT ON db.join_table TO user for full table access, or GRANT SELECT(key_col, attr_col) ON db.join_table TO user for column-level access. #94307 (Vladimir Cherkasov).
CREATE TABLE ... AS ... queries now require SHOW COLUMNS privilege instead of SHOW TABLES, which was previously checked incorrectly. #94556 (pufit).
Deduplication is now enabled by default for all inserts. Previously it was off for async inserts and materialized views, but on for sync inserts. To preserve the old behavior, explicitly set deduplicate_insert='backward_compatible_choice' (and similarly for deduplicate_blocks_in_dependent_materialized_views). #95970 (Sema Checherinda).
S3Queue and AzureQueue in-memory metadata is now limited. The system tables have been renamed: system.s3queue is now system.s3queue_metadata_cache, and system.azure_queue is now system.azure_queue_metadata_cache. #95809 (Kseniia Sumarokova).
Added lazy_load_tables database setting. When enabled, tables are not loaded during database startup — a lightweight StorageTableProxy is created instead and the real table engine is materialized on first access. #96283 (xiaohuanlin).
Added support for auxiliary ZooKeeper for DatabaseReplicated. #91683 (RinChanNOW).
Data and system files in cache can now be split into separate segments. #87834 (MikhailBurdukov).
Added a new SLRU cache for Parquet metadata to improve read performance by avoiding redundant file downloads. The cache can be dropped with SYSTEM DROP PARQUET METADATA CACHE. #89750 (Grant Holly).
Data lake tables now support PREWHERE and multistage PREWHERE in the Parquet reader v3. #93542 (Konstantin Vedernikov).
Added distributed index analysis across multiple replicas, beneficial for shared storage and large data volumes. #86786 (Azat Khuzhin).
Async insert deduplication now works with dependent materialized views. When a block_id collision occurs, the original block is filtered to remove rows associated with the colliding block_id, and the remaining rows are transformed through all relevant materialized view queries. #89140 (Sema Checherinda).
Async inserts now support parallel quorum — inserted data is replicated to the quorum, and if duplicates are found, the query waits until previously inserted data is replicated as well. #93356 (Sema Checherinda).
Added insert_deduplication_version server setting to enable migration to a unified deduplication hash. #95409 (Sema Checherinda).
Added SYSTEM CLEAR [...] CACHE syntax as a clearer alternative to the existing SYSTEM DROP [...] CACHE. The old syntax remains available. #93727 (Pranav Tiwari).
Added OPTIMIZE <table> DRY RUN PARTS <part names> query to simulate merges without committing the result part. Useful for verifying merge correctness, reproducing merge-related bugs, and benchmarking merge performance. #96122 (Anton Popov).
DDL queries with ON CLUSTER can now be executed for Replicated databases when the ignore_on_cluster_for_replicated_database setting is enabled. The cluster name will be ignored. #92872 (Kirill).
Introduced a new syntax and framework to simplify and extend the projection index feature. #91844 (Amos Bird).
Added max_insert_block_size_bytes setting for finer control over the formation of inserted blocks. #92833 (Kirill Kopnev).
Added use_primary_key setting. Set it to false to disable granule pruning based on the primary key. #93319 (Nihal Z. Miaji).
Added default_dictionary_database setting, which lets ClickHouse resolve external dictionaries referenced without a database qualifier in a specified default database. This simplifies migration from XML-defined global dictionaries to SQL-defined per-database dictionaries. #91412 (Dmitrii Plotnikov).
Added check_named_collection_dependencies setting (enabled by default) to prevent dropping named collections that are used by tables. #96181 (Pablo Marcos).
Added a max-min fair scheduler for concurrency control, providing better fairness under high oversubscription where many queries compete for limited CPU slots. The concurrent_threads_scheduler server setting now defaults to max_min_fair instead of fair_round_robin, so short-running queries are no longer penalized by long-running ones. #94732#95300 (Sergei Trifonov).
Added logger.startup_console_level and logger.shutdown_console_level configuration options to override the console log level during ClickHouse startup and shutdown respectively. #95919 (Garrett Thomas).
Added a ClickHouse_Info metric to the Prometheus /metrics endpoint containing version information, making it possible to build charts tracking detailed version information over time. #91125 (Christoph Wurm).
Vector search can now distribute the load across replicas in a cluster, enabling support for large vector indexes that exceed the memory capacity of a single VM. #95876 (Shankar Iyer).
Added a server-side AST fuzzer controlled by the ast_fuzzer_runs and ast_fuzzer_any_query settings. When enabled, the server runs randomized mutations of each query after its normal execution, discarding the results. #97568 (Alexey Milovidov).
Correlated subqueries now support more table engines and data source kinds. #90175 (Dmitry Novik).
Non-constant IN is now supported for scalars (e.g. val1 NOT IN if(cond, val2, val3)). #93495 (Yarik Briukhovetskyi).
Added support for extended table aliases for JOINs (e.g. SELECT * FROM (SELECT 1) AS t(a) JOIN (SELECT 1) AS u(b) ON a = b). #95331 (Yarik Briukhovetskyi).
EXPLAIN indices = 1 is now supported as an alias for EXPLAIN indexes = 1. #92774 (Pranav Tiwari).
Improved filter pushdown for numbers and primes table functions — ClickHouse can now derive conservative value bounds from WHERE conditions to restrict sequence generation, avoiding unbounded scans. #96115 (Nihal Z. Miaji).
Equivalent sets optimization now works across multiple consecutive INNER JOIN operations, so filters applied to any table in the chain are automatically pushed down to all related tables. #96596 (Vladimir Cherkasov).
Automatic cluster table functions are now used for single subqueries in FROM. #96332 (phulv94).
The primary key index is now used when filtering with startsWithUTF8 if the prefix contains only ASCII characters. #97055 (vkcku).
assumeNotNull, coalesce, and ifNull now enable primary key and skip index pruning for range predicates when key columns are wrapped in these functions. #94754 (Nihal Z. Miaji).
Unused columns are now also removed from the reading step when reading from MergeTree, which is especially useful when a filter is pushed down into PREWHERE. #89982 (János Benjamin Antal).
The use_join_disjunctions_push_down optimization is now enabled by default. #89313 (Alexey Milovidov).
The enable_join_runtime_filters optimization is now enabled by default. #89314 (Alexey Milovidov).
JOIN runtime filter overhead is now reduced by automatically disabling filters when too many bits are set in the bloom filter or too few rows are filtered out. #91578 (Alexander Gololobov).
Added use_hash_table_stats_for_join_reordering setting (enabled by default) to control whether runtime hash table size statistics are used for join reordering. #93912 (Vladimir Cherkasov).
Index analysis is now performed only once regardless of whether the query executes locally or with parallel replicas. #94854 (Nikita Taranov).
If a skip index in a FINAL query is on a column that is part of the primary key, the additional primary key intersection check in other parts is now skipped. #93899 (Shankar Iyer).
DROP DATABASE now drops tables in reverse dependency order, improving crash-safety when the database contains tables with loading dependencies. #97057 (Alexey Milovidov).
Synchronous waiting for mutations now respects query cancellation and time limits. #96756 (Alexey Milovidov).
Prevented resurrection of dropped data if ADD COLUMN is run quickly after a DROP COLUMN mutation. #96713 (Alexey Milovidov).
Conflicting ALTER expressions with UPDATE and RENAME COLUMN now throw a proper exception instead of a logical error. #96022 (Alexey Milovidov).
Estimated total row count and NDV (number of distinct values) statistics are now collected for aggregation key columns. #92812 (Alexander Gololobov).
All replicas can now steal orphaned ranges in parallel replicas reading, improving load balancing and reducing long-tail latency. #91374 (zoomxi).
Improved estimation accuracy for automatic parallel replicas with highly selective PREWHERE filters. #97231 (Nikita Taranov).
StorageEmbeddedRocksDB now supports multiple columns as a primary key. #33917 (usurai).
Added ALTER TABLE <table> ATTACH PART <part_name> FROM <directory_name> syntax, allowing attachment of parts from arbitrary subdirectories of detached/ (e.g. parts with broken-on-start or unexpected prefixes) without manual filesystem renaming. #74816 (Anton Popov).
min_free_disk_bytes_to_perform_insert now works correctly with JBOD volumes. #90878 (Aleksandr Musorin).
max_parts_to_merge_at_once is now respected during TTL drop-part merges. #95315 (Kseniia Sumarokova).
Background operations (mutate, merge) can now be configured independently via a background profile, rather than sharing settings with regular queries via the default profile. #93905 (Arsen Muk).
Improved subcolumn reading with correct size calculation, reducing memory usage and improving speed. #96251 (Pavel Kruglov).
Limited the number of pipeline streams generated with split_intersecting_parts_ranges_into_layers to avoid excessive memory consumption. #96478 (Nikita Taranov).
When saving table schema with enable_positional_arguments_for_projections, expressions are now substituted instead of positional arguments, allowing server restart with the setting disabled. #96372 (Alexey Milovidov).
In Replicated databases, the cached cluster is no longer updated for every dummy query. #96897 (Tuan Pham Anh).
Added SYSTEM RESET DDL WORKER [ON CLUSTER] query to reset the DDLWorker state, useful for refreshing replica activity when host IDs are updated. #93780 (Tuan Pham Anh).
Refactored S3Queue ordered mode processing with buckets, reducing the number of Keeper requests and improving performance. #92889 (Kseniia Sumarokova).
Added more generic partitioning support for S3Queue ordered mode. #94321 (Bharat Nallan).
Added bucketing based on partition key for S3Queue in ordered mode. #94698 (Bharat Nallan).
S3Queue auxiliary ZooKeeper support via the keeper_path setting. #95203 (Diego Nieto).
S3(Azure)Queue ordered mode now cleans up failed nodes by tracking limits. #94412 (Kseniia Sumarokova).
S3 x-amz-server-side-encryption headers are no longer propagated to HeadObject, UploadPart, and CompleteMultipartUpload requests. #64577 (Francisco J. Jurado Moreno).
storage_class_name can now be specified in named collections for the S3 table engine and s3 table function. #91926 (János Benjamin Antal).
Fixed EC2 metadata endpoint throttling when running many concurrent S3 queries with instance profile credentials — the credentials provider is now cached and shared across all queries. #92891 (Sav).
Added MinIO compatibility support to the AWS S3 C++ SDK with error code mapping for MinIO-specific errors, improving reliability for self-hosted MinIO clusters. #93082 (XiaoBinMu).
Improved S3 authentication error messages with hints to check credentials. #95648 (Gerald Latkovic).
Azure Blob Storage now falls back to read-write copy when native copy fails with any error (previously only on Unauthorized). #92888 (Smita Kulkarni).
Removed the 64-token limit for hasAnyTokens and hasAllTokens functions. #95152 (Elmi Ahmadov).
Added distanceCosine as an alias for cosineDistance, consistent with other distance functions. #96065 (Raufs Dunamalijevs).
Added iif function to ClickHouse KQL. #94790 (happyso).
use_variant_as_common_type is now enabled by default, allowing incompatible types inside Array, UNION queries, and if/multiIf/case branches. #90677 (Alexey Milovidov).
use_skip_indexes_on_data_read is now enabled by default. #93407 (Shankar Iyer).
Added add_minmax_index_for_time_columns setting — when enabled, automatically creates minmax indexes for all Date, Date32, Time, Time64, DateTime, and DateTime64 columns. #93355 (Michael Jarrett).
Added materialize_statistics_on_merge setting (default enabled) to control whether statistics are materialized during merges. #93379 (Han Fei).
Added input_format_binary_max_type_complexity setting to limit the total number of type nodes that can be decoded in binary format, preventing malicious payloads. #92519 (Raufs Dunamalijevs).
Added trace_profile_events_list setting to limit tracing with trace_profile_event to specific event names. #92298 (Alexey Milovidov).
Added type_json_allow_duplicated_key_with_literal_and_nested_object setting to allow duplicated paths in JSON where one is a literal and another is a nested object, for backward compatibility with data created before path deduplication was enforced. #93604 (Pavel Kruglov).
Added merge_max_dynamic_subcolumns_in_compact_part MergeTree setting and max_dynamic_subcolumns_in_json_type_parsing query-level setting to limit dynamic subcolumns in JSON columns during merge and parsing. #94184 (Pavel Kruglov).
Added use_statistics as an alias for allow_statistics_optimize, consistent with use_primary_key and use_skip_indexes. #94366 (Robert Schulze).
Enabled input_format_numbers_enum_on_conversion_error for Numbers-to-Enum conversion to check element existence. #94384 (Elmi Ahmadov).
Added a setting to throw an exception when a table has row policies but none apply to the current user, catching potential misconfigurations. #95014 (Vitaly Baranov).
enable_max_bytes_limit_for_min_age_to_force_merge is now enabled by default for compatibility version 26.2 and higher. #95917 (Christoph Wurm).
core_dump.size_limit is now hot-reloadable without server restart. #96524 (Miсhael Stetsyuk).
Command-line overrides are now respected when reloading configuration. #80295 (Alexey Milovidov).
Added composite rotation strategy (size + time) for server logs. #87620 (Jianmei Zhang).
Distributed index analysis can now be enabled based on part count (distributed_index_analysis_min_parts_to_activate) and index size (distributed_index_analysis_min_indexes_size_to_activate). #95216 (Azat Khuzhin).
Statistics cache is now enabled by default with a 300-second update period. #95841 (Han Fei).
The path configuration parameter is now resolved relative to the working directory at startup, preventing data directories from being placed in unusual locations. #96305 (Alexey Milovidov).
Added parts_postpone_reasons column to system.mutations for improved diagnostics. #92206 (Shaohua Wang).
Added creation (implicit/explicit) column to system.data_skipping_indices. #92378 (Raúl Marín).
Running tasks are now reflected in system.background_schedule_pool and the corresponding log table. #92587 (Azat Khuzhin).
Added QueryNonInternal metric to track the number of executing non-internal queries, helping monitor concurrency against the max_concurrent_queries limit. #94284 (Ashwath Singh).
Added an asynchronous metric for the longest running merge elapsed time. #94825 (Raúl Marín).
Added connection_address and connection_port to query_log to reflect the physical connection (useful when connected through a proxy). #95471 (Yakov Olkhovskiy).
Added system.tokenizers table showing all available tokenizers. #96753 (Robert Schulze).
Added system.jemalloc_stats table and /jemalloc.html HTTP endpoint for interactive visualization of jemalloc memory allocator statistics. #97077 (Antonio Andelic).
Added system.jemalloc_profile_text table for reading and analyzing jemalloc heap profiles, with support for raw, symbolized, and collapsed output formats. #97218 (Antonio Andelic).
Added mutation_ids to system.part_log for MUTATE_PART and MUTATE_PART_START events. #93811 (Shaohua Wang).
Nested global server settings (e.g. logger.level) are now partially visible in system.server_settings. #94001 (Hechem Selmi).
view_duration_ms now shows the time a group was active, rather than the sum of thread durations. #94966 (Sema Checherinda).
system.blob_storage_log is now available for Azure Blob Storage, Local, and HDFS. Added error_code column. #93105 (Alexey Milovidov).
Background tasks slower than average are now logged with a configurable threshold (background_schedule_pool_log.duration_threshold_milliseconds, default 30ms). #92965 (Azat Khuzhin).
Added new Keeper metrics: KeeperChangelogWrittenBytes, KeeperChangelogFileSyncMicroseconds, KeeperSnapshotWrittenBytes, KeeperSnapshotFileSyncMicroseconds, KeeperBatchSizeElements, and KeeperBatchSizeBytes. #92149 (Miсhael Stetsyuk).
CHECK_STAT and TRY_REMOVE Keeper extensions are now enabled by default. #93886 (Mikhail Artemenko).
Keeper now throws an exception instead of aborting when it detects a broken snapshot or inconsistent changelogs, requiring manual intervention for safer recovery. #94168 (Antonio Andelic).
Added with_data and with_stat extensions to getChildren Keeper requests, allowing fetching children along with their data and stats in a single operation. #94826 (Nikolay Degterinsky).
Added a check for Keeper misconfiguration that could lead to cluster assembly failures. #94682 (Konstantin Bogdanov).
Added with_data Keeper extension support to improve table fetching in Database Replicated. #96090 (Nikolay Degterinsky).
Auxiliary ZooKeeper can now be inserted into via system.zookeeper. #92092 (RinChanNOW).
Optimized filesystem cache space reservation — eviction candidates are now collected without holding a unique lock. #82764 (Kseniia Sumarokova).
Enabled parallelized reads in the filesystem cache read buffer for remote table engines/functions. #71781 (Kseniia Sumarokova).
Reduced memory usage on non-Linux systems by enabling immediate purging of jemalloc dirty pages. #93360 (Eduard Karacharov).
jemalloc dirty page purging now runs in a separate thread from the main MemoryWorker thread. Added memory_worker_purge_total_memory_threshold_ratio config for purging based on total memory usage ratio. #94902 (Antonio Andelic).
jemalloc dirty page decay is now dynamically disabled when ClickHouse is under sustained memory pressure. #95145 (Antonio Andelic).
Added an explicit memory consumption check before reading data from MergeTree, with lowered thread pool queue sizes based on production experience. #94692 (Nikita Mikhaylov).
Total memory limit is now checked before user authentication, throwing memory limit exceeded if the limit is breached. #95003 (Nikolai Kochetov).
Fixed incorrect memory accounting for the query conditions cache. #95478 (Nikita Mikhaylov).
Made query memory usage detection for spilling to disk during aggregation/sorting more robust. #92500 (Azat Khuzhin).
The scheduler now prioritizes the MemoryWorker thread under CPU starvation to protect the process. #94864 (Nikita Mikhaylov).
Fixed ClickHouse not respecting memory limits in some cases when reading from a table. #93715 (Nikita Mikhaylov).
The Date type is now serialized as Arrow's native date32 type in Arrow/ArrowStream formats (previously uint16). The old behavior can be restored with the output_format_arrow_date_as_uint16 setting. #96860 (Alexey Milovidov).
Simple types in Pretty JSON format are no longer printed on separate lines. #93836 (Pavel Kruglov).
Schema inference now respects allow_experimental_nullable_tuple_type — when enabled, missing nested objects can become NULL instead of a tuple of NULL elements. #95525 (Nihal Z. Miaji).
The SQL formatter now outputs COMMENT before AS SELECT instead of wrapping SELECT in parentheses. #96293 (Alexey Milovidov).
Optimized postings list compression with simdcomp. #92871 (Peng Jian).
Added backup_data_from_refreshable_materialized_view_targets backup setting to control whether to back up data of refreshable materialized views. Targets of RMVs with APPEND refresh strategy are always backed up. #93658 (Julia Kartseva).
Added support for SQL-defined named collections in BACKUP/RESTORE for S3 and Azure Blob Storage. #94605 (Pablo Marcos).
Improved the UX of SYSTEM INSTRUMENT ADD/REMOVE: string literals are now used for function names, all matching functions are patched, and function_name is supported in REMOVE. #93345 (Pablo Marcos).
Added SYSTEM NOTIFY FAILPOINT for pausable failpoints and SYSTEM WAIT FAILPOINT for PAUSE/RESUME. #92368 (Shaohua Wang).
C++ function names in system.trace_log, system.symbols, and the demangle function are now displayed correctly. #93075 (Alexey Milovidov).
jemalloc profiles are now written with symbols, eliminating the need for a binary during heap profile generation. #93099 (Azat Khuzhin).
Fixed crash when attaching a table to a MaterializedPostgreSQL database if dropReplicationSlot throws during stack unwinding. #96871 (Alexey Milovidov).
Fixed leaving possible leftovers when CREATE TABLE fails. #94174 (Azat Khuzhin).
Fixed uninitialized memory access when a password-protected TLS key is used. #94182 (Konstantin Bogdanov).
When alter table ... modify setting ... times out while acquiring a lock, it now returns a timeout error instead of a logical error. #93856 (Han Fei).
Improved CPU and real-time profiler interoperability with socket timeouts. #96601 (Sergei Trifonov).
Enabled fast libcxx hardening for release builds (primarily out-of-bounds checks) with no noticeable performance impact. #94757 (Miсhael Stetsyuk).
Extended filter push-down from JOIN ON conditions for ANY, SEMI, and ANTI joins when the filter uses inputs from only one side. #92584 (Dmitry Novik).
Equivalent sets can now be used to push down filters for SEMI JOIN. #92837 (Dmitry Novik).
Parallelized processing of non-joined rows in ParallelHashJoin for complex predicates, controlled by the parallel_non_joined_rows_processing setting (enabled by default). #92068 (Yarik Briukhovetskyi).
Hash join now skips reading the left side entirely when the right side is empty, avoiding unnecessary work from heavy filtering or aggregation. #94062 (Alexander Gololobov).
JOIN runtime filters are now supported for RIGHT OUTER JOINs. #96183 (Hechem Selmi).
PREWHERE optimization is now postponed until after JOIN runtime filter optimization, allowing runtime filters to also be pushed to PREWHERE. #95838 (Alexander Gololobov).
Disabled sort order optimization for window functions when the partition key matches or is a prefix of the sorting key, improving parallel execution performance. #87299 (Nikita Taranov).
Outer filters are now pushed down into views, allowing PREWHERE to be applied on both local and remote nodes. #88316 (Igor Nikonov).
Optimized performance and memory usage for fractional LIMIT and OFFSET. #91167 (Ahmed Gouda).
Constant filters on virtual columns are no longer evaluated redundantly. #91588 (c-end).
Any deterministic expression in the primary key (e.g. ORDER BY cityHash64(user_id)) can now be used for data skipping. ClickHouse applies the expression to query constants and uses the result for primary key index lookups with =, IN, and has. For injective expressions, negated forms (!=, NOT IN, NOT has) are also supported. #92952 (Nihal Z. Miaji).
The read-in-order optimization now recognizes when ORDER BY columns are constant due to WHERE conditions, enabling efficient reverse-order reads. This benefits multi-tenant queries like WHERE tenant='42' ORDER BY tenant, event_time DESC. #94103 (matanper).
For FINAL queries using a primary key condition followed by skip indexes, the PrimaryKeyExpand step now only checks the initially shortlisted primary key ranges. #94903 (Shankar Iyer).
Lazy materialization optimization is now applied to all branches of a UNION ALL query, not just the first one, reducing I/O for queries that combine multiple sorted and limited reads from different MergeTree tables. #96832 (Federico Ginosa).
Reduced INSERT and merge memory usage for very wide tables with Wide parts by enabling adaptive write buffers. Also added adaptive write buffer support for encrypted disks. #92250 (Azat Khuzhin).
Improved full text search performance with the text index and sparseGrams tokenizer by reducing the number of tokens searched. #93078 (Anton Popov).
Sped up T64 codec compression using dynamic dispatch on x86. #95881 (Raúl Marín).
Sped up LZ4 decompression of 32-byte blocks on x86. #96778 (Raúl Marín).
Text index direct read optimization now works partially — parts with a materialized text index will use it, while parts without fall back to the original filter expression. #96411 (Anton Popov).
Optimized minmax skip index computation during INSERT by removing an unnecessary data copy and enabling vectorized min/max calculation for numeric columns. #97392 (Raúl Marín).
Added minmax secondary indexes on time columns and bloom_filter indexes on query_id/initial_query_id columns to system log tables for faster filtering. #96712 (Alexey Milovidov).
Avoided memory usage regression on INSERT when deduplication is not enabled. #96503 (Alexey Milovidov).
Reduced memory footprint of ASTLiteral by removing unused fields when highlighting and VALUES parsing are not active. #93974 (Ilya Yatsishin).
Introduced a specialized Enum AST class that stores value parameters as string/integer pairs instead of generic ASTLiteral children, reducing memory consumption. #94178 (Ilya Yatsishin).
Optimized memory consumption of named tuple AST objects by storing column names as strings directly instead of in generic AST literal nodes. #94704 (Ilya Yatsishin).
Reduced the size of the CachedOnDiskReadBufferFromFile structure by approximately 50x. #96098 (Azat Khuzhin).
HashTable::resize no longer copies old data when the table is empty. #96180 (Raúl Marín).
Adopted the "fastrange" (Daniel Lemire) method for partitioning data inside the query pipeline, improving parallel sorting and JOINs. #93080 (Alexey Milovidov).
Improved devirtualization with additional linker options. #94737 (Nikita Taranov).
Improved clone replica performance for ReplicatedMergeTree tables with many parts by batching ZooKeeper requests. #94847 (c-end).
Reduced ZooKeeper receive thread CPU consumption from observeOperations by over 20% by switching to faster hashing and lock-free counters. #95962 (Miсhael Stetsyuk).
Fixed a possible crash with join_on_disk_max_files_to_merge setting. #92335 (Bharat Nallan).
Fixed LOGICAL_ERROR caused by unwanted modification of query plan when converting outer join to inner join. Also relaxed optimization requirements to apply when injective functions are used on aggregating keys during joins. #92503 (János Benjamin Antal).
Fixed logical error with multiple joins on constant condition and join_use_nulls. #92892 (Vladimir Cherkasov).
Fixed NULL != NULL case for full_sorting_join on LowCardinality(Nullable(T)) column. #92924 (Vladimir Cherkasov).
Fixed join results when the right-side join key was a sparse column. #93038 (Amos Bird).
Fixed runtime filters working incorrectly when LEFT ANTI JOIN had an extra post-condition. #91824 (Alexander Gololobov).
Fixed logical error when runtime filters were used in a query with totals for right-side table. #93330 (Alexander Gololobov).
Fixed logical error in some cases triggered when join runtime filters were added to query plan due to incorrectly returned duplicated const columns. #93144 (Alexander Gololobov).
Fixed __applyFilter function used by join runtime filters returning ILLEGAL_TYPE_OF_ARGUMENT in some valid cases. #93187 (Alexander Gololobov).
Fixed runtime filters not being added when joining with an already-filled right table. #93211 (Alexander Gololobov).
Fixed NOT_FOUND_COLUMN_IN_BLOCK error when runtime filter was enabled and joined tables returned the same column multiple times. #93526 (Alexander Gololobov).
Fixed FilterStep not properly added when join runtime filter was applied over Merge table. #94021 (Alexander Gololobov).
Fixed type conversion to super type during join operation of Join storage with USING clause. #94000 (Dmitry Novik).
Fixed queries with parallel replicas and JOIN with non-MergeTree table. #93902 (Igor Nikonov).
Fixed race condition for Nullable join column in runtime filters. #95775 (Hechem Selmi).
Fixed empty string becoming NULL in Join table with Nullable(String) key. #96002 (Alexey Milovidov).
Fixed NOT_SUPPORTED error when using direct join algorithm with an empty MergeTree table. #95935 (Vladimir Cherkasov).
Fixed incorrect results from queries involving outer joins combined with multiple INNER JOINs due to illegal join reordering when an outer join's ON condition referenced columns from multiple previously joined tables. #96193 (Vladimir Cherkasov).
Fixed runtime filter exception for Tuple columns with Nullable subfields. #96509 (Alexey Milovidov).
Fixed queries with CROSS JOINs and enabled parallel replicas returning incorrect results. #96848 (Igor Nikonov).
Fixed arrayJoin producing duplicate rows when used with INNER JOIN and WHERE clause, caused by partial predicate push-down incorrectly pushing filters containing arrayJoin below a JOIN. #96989 (Alexey Milovidov).
Fixed LOGICAL_ERROR when arrayJoin in WHERE clause referenced columns from both sides of a JOIN. #97239 (Alexey Milovidov).
Fixed logical error when using a matcher (*) inside a lambda function within a VALUES clause in a JOIN with USING. #95661 (Vladimir Cherkasov).
Fixed possible logical error with matcher (*, table.*) and analyzer_compatibility_join_using_top_level_identifier when USING column had different types. #95808 (Vladimir Cherkasov).
Fixed logical error with analyzer_compatibility_join_using_top_level_identifier and ALIAS columns. #97297 (Vladimir Cherkasov).
Fixed crash in old analyzer when using JOIN with duplicated aliases. #96405 (Ilya Golshtein).
Fixed Merge table engine query planning throwing ILLEGAL_COLUMN for hostName() when merging local and remote/Distributed tables. #93286 (Jinlin).
Fixed NO_SUCH_COLUMN_IN_TABLE error in Merge engine over tables with aliases. #92910 (Pavel Kruglov).
Fixed SELECT query with predicate on multiple columns with bloom filter skip indexes and both OR and NOT conditions returning inconsistent results. #94026 (Shankar Iyer).
Fixed applying projection when filter contained subcolumns. #93141 (Pavel Kruglov).
Fixed _part_offset corruption when projections were rebuilt during merges, and optimized projection processing by avoiding unnecessary reads. #93827 (Amos Bird).
Prevented different interpolated columns from collapsing into the same column in a block when they were effectively aliases of the same column. #93197 (Yakov Olkhovskiy).
Removed unused columns when the projection was rebuilt during merge, reducing memory usage and creating fewer temporary parts. #93233 (Nikolai Kochetov).
Fixed a logical error in some cases when negative LIMIT/OFFSET was used in distributed queries. #95357 (Nihal Z. Miaji).
Fixed a logical error in some cases when fractional LIMIT/OFFSET was used in distributed queries. #96475 (Nihal Z. Miaji).
Fixed IN function returning incorrect results with NULL values when transform_null_in was enabled. #95674 (Nihal Z. Miaji).
Fixed IN (col) with a single column reference failing with UNSUPPORTED_METHOD error. #97646 (Alexey Milovidov).
Fixed optimize_syntax_fuse_functions rewriting sum/count/avg into sumCount() when the aggregate argument was LowCardinality(Nullable). #96239 (Nihal Z. Miaji).
Fixed incorrect partition pruning for not IN and not has functions. #96241 (Nihal Z. Miaji).
Fixed prewhere filter error caused by lambda expressions in prewhere. #95395 (Xiaozhe Yu).
Fixed LOGICAL_ERROR in query analyzer when a lambda expression was passed where a concrete value was expected. #96892 (Alexey Milovidov).
Fixed null pointer dereference in certain expressions with lambda functions. #96479 (Alexey Milovidov).
Fixed per-subquery SETTINGS not being applied to table functions like file in CTEs and subqueries. #96882 (Alexey Milovidov).
Fixed query condition cache hash collision for CTE folded constants, which could lead to wrong query results. #96172 (Alexey Milovidov).
Fixed BAD_ARGUMENTS error when querying tables with lambda expressions inside ALIAS columns through the merge() table function with the analyzer enabled. #97551 (Alexey Milovidov).
Fixed EXCEPT ALL and INTERSECT ALL ignoring row multiplicities and behaving like their DISTINCT counterparts. #96876 (Alexey Milovidov).
Fixed assertion failure in WindowTransform with a large PRECEDING offset. #96026 (Alexey Milovidov).
Fixed exception when using window functions with group_by_use_nulls = 1 and CUBE/ROLLUP/GROUPING SETS. #96878 (Alexey Milovidov).
Fixed interaction of GROUPING SETS, group_by_use_nulls, and Tuple with LowCardinality producing unexpected block structure. #96358 (Alexey Milovidov).
Fixed logical error during GROUP BY ... WITH ROLLUP/CUBE when keys included LowCardinality(Nullable(...)) inside Nullable(Tuple(...)). #97647 (Alexey Milovidov).
Fixed assertion failure in IfTransformStringsToEnumPass when if or transform returned Nullable(String). #97002 (Alexey Milovidov).
Fixed ACCESS_DENIED for users without CREATE TEMPORARY TABLE permission when optimize_inverse_dictionary_lookup rewrote dictGet(...) predicates. #97484 (Nihal Z. Miaji).
Fixed if function type mismatch between UInt64 and Int32 in an unusual case of distributed queries with PREWHERE and type inference. #96012 (Alexey Milovidov).
Fixed incorrect results when JIT-compiled expressions converted DateTime to DateTime64 (e.g. in CASE/if/multiIf with mixed DateTime types). #96879 (Alexey Milovidov).
Fixed use-of-uninitialized-value in formatDateTime with non-fixed-width formatters. #96133 (Alexey Milovidov).
Fixed std::terminate in indexOfAssumeSorted when called with incompatible types. #96877 (Alexey Milovidov).
Geometry functions now accept individual geometry subtypes in addition to the Geometry variant type. #97571 (Alexey Milovidov).
Fixed cases where indexes affected results for queries with row policy/PREWHERE and FINAL. #97076 (Yarik Briukhovetskyi).
Fixed LOGICAL_ERROR when using text-indexed columns with QUALIFY clause. #97313 (Alexey Milovidov).
Fixed a possible crash when the WHERE clause had more than 32 expressions with AND/OR. #97698 (Shankar Iyer).
Fixed block structure mismatch in removeUnusedColumns optimization when using indexHint with star expansion on tables with FINAL. #97622 (Alexey Milovidov).
Always replaced file names with hashes in MergeTree if the filesystem is case insensitive. Previously on macOS it could lead to data corruption when column/subcolumn names differed only in case. #86559 (Pavel Kruglov).
Materialized views now use the database where they were created as execution context, allowing omission of explicit database qualification in the view's select query. #88193 (Dmitry Kovalev).
Added full permissions check on the create stage for the underlying query inside a materialized view. #89180 (pufit).
Fixed logical error when mutation without transaction mutated parts in an active transaction that was rolled back. #90469 (Shaohua Wang).
Fixed system.warnings not updating correctly after an ordinary database was converted to an atomic database. #90473 (sdk2).
Fixed LOGICAL_ERROR: Storage does not support transaction during ATTACH AS REPLICATED. #91772 (Shaohua Wang).
Fixed possible FILE_DOESNT_EXIST error after mutation of a sparse column with ratio_of_defaults_for_sparse_serialization=0.0. #92860 (Pavel Kruglov).
Fixed possible FILE_DOESNT_EXIST error after sparse column mutation when ratio_of_defaults_for_sparse_serialization was changed to 1.0 via alter. #93016 (Pavel Kruglov).
Fixed possible usage of outdated parts due to TOCTOU race for shared parts. #93022 (Azat Khuzhin).
Inherited source part serialization info settings during mutation in MergeTree, fixing possible incorrect query results over mutated parts after data type serialization changes. #92419 (Pavel Kruglov).
Fixed possible conflict between column and subcolumn with the same name leading to wrong serialization and query failures. #92453 (Pavel Kruglov).
Fixed NOT_FOUND_COLUMN_IN_BLOCK during insert into a table with subcolumn in partition expression. #92905 (Pavel Kruglov).
Fixed possible missing subcolumn in MV during alter of source table. #93276 (Pavel Kruglov).
Fixed LOGICAL_ERROR when restoring ReplicatedMergeTree with deduplication race. #93612 (Pablo Marcos).
Fixed using sparse column for TTL update during direct deserialization, preventing Unexpected type of result TTL column error. #93619 (Pavel Kruglov).
Restored LowCardinality wrappers on SET expression results if needed during TTL aggregation. #92971 (Seva Potapov).
Fixed Cannot add action to empty ExpressionActionsChain for ALTER TABLE REWRITE PARTS. #92754 (Azat Khuzhin).
Fixed query parameter substitution in CREATE USER authentication methods when using ON CLUSTER. #92777 (xiaohuanlin).
No longer attempts to delete temporary directories at startup if a MergeTree table is on a read-only disk. #92748 (Alexey Milovidov).
Fixed materialization of skip indexes created on top of subcolumns. #93708 (Anton Popov).
Fixed attaching Replicated databases when the interserver host changed after restarting. #93779 (Tuan Pham Anh).
Fixed logical error with CREATE TABLE ... AS urlCluster() and Replicated database engine. #92418 (Kseniia Sumarokova).
Fixed race condition between REPLACE PARTITION and background mutations that could result in both old and new data being visible. #96955 (Alexey Milovidov).
Fixed remaining race condition between REPLACE PARTITION and background mutations that could cause old data to reappear. #97105 (Alexey Milovidov).
Fixed stuck mutations when PartCheckThread re-enqueued a GET_PART for an already-mutated part. #97162 (Alexey Milovidov).
Fixed ALTER TABLE DROP COLUMN failing after a lightweight update was previously performed on the same column. #96861 (Anton Popov).
Fixed null pointer dereference when applying patch parts during lightweight updates. #97583 (Alexey Milovidov).
Parts with unknown projections are no longer marked as lost forever. #95952 (Mikhail Artemenko).
Fixed CREATE TABLE ... CLONE AS ... ignoring the full qualifier of the source table. #96415 (Hasyimi Bahrudin).
Fixed implicit index regeneration in replicated tables during metadata changes. #96600 (Raúl Marín).
Fixed implicit indices with alias columns and added full validation before creating them. #97115 (Raúl Marín).
Fixed min(timestamp) returning epoch (1970-01-01) via _minmax_count_projection after TTL merge when all rows were filtered out. #96703 (Raquel Barbadillo).
Fixed combination of use_const_adaptive_granularity and index_granularity_bytes (non-adaptive granularity) leading to miscalculation. #96143 (Alexey Milovidov).
Fixed Number of rows in lazy chunk does not match number of offsets exception when reading from tables with non-adaptive index granularity using ORDER BY ... LIMIT. #97270 (Alexey Milovidov).
Fixed regression in zero-copy replication where shared parts could be deleted before other replicas finished fetching them. #95597 (filimonov).
Fixed SYSTEM RESTART REPLICA losing table from database when table re-creation failed with a non-ZooKeeper exception, causing metadata digest mismatches in DatabaseReplicated. #97276 (Alexey Milovidov).
Fixed assert_cast exception when building column statistics after ALTER TABLE MODIFY COLUMN changed the column type. #97027 (Alexey Milovidov).
When a table has no statistics defined, ClickHouse no longer tries to load them, avoiding unnecessary overhead. #96233 (Han Fei).
Fixed There was an error: Cannot obtain error message logical error when waiting for a distributed DDL and dropping the Replicated database concurrently. #95664 (Alexander Tokmakov).
Fixed logical error in KeyCondition when a table had a nullable primary key and the query used coalesce with a constant first argument. #96340 (Alexey Milovidov).
Fixed possible error during reading of size subcolumn from Dynamic/JSON types. #95573 (Pavel Kruglov).
Fixed crash during tupleElement applied to arrays of JSON. #95647 (Pavel Kruglov).
Fixed executing tupleElement on JSON with nested paths returning wrong results. #95907 (Pavel Kruglov).
Fixed tupleElement throwing an exception with JSON for paths with type hints. #97728 (Pavel Kruglov).
Fixed skipping paths in JSON data type — previously JSON(SKIP path) would skip all keys with prefix path (even keys like pathpath), which could lead to data loss. Now only the exact key is skipped. #95948 (Pavel Kruglov).
Fixed applying type_json_allow_duplicated_key_with_literal_and_nested_object to typed paths in JSON. #97422 (Pavel Kruglov).
Fixed dynamic subcolumns resolution in column aliases in analyzer. #92583 (Pavel Kruglov).
Fixed Nested columns sizes are inconsistent with local_discriminators error due to wrong in-place filtering optimization for Variant columns. #96410 (Alexey Milovidov).
Fixed crash in ifNull with Variant argument used in GROUP BY. #96790 (Alexey Milovidov).
Fixed logical error in FunctionVariantAdaptor with functions requiring const arguments like arrayROCAUC. #97116 (Bharat Nallan).
Fixed LOGICAL_ERROR in FunctionVariantAdaptor when a function returned Nothing type. #97213 (Alexey Milovidov).
Fixed logical exception when comparing NULL with a Variant column containing LowCardinality types. #97379 (Alexey Milovidov).
Fixed LOGICAL_ERROR in concat when an argument contained a Variant type with LowCardinality inside. #97654 (Alexey Milovidov).
Fixed incorrect results when LowCardinality columns were converted to Nullable. #96483 (Nihal Z. Miaji).
Correctly handled LowCardinality Nullable types in CAST when cast_keep_nullable was enabled. #95747 (Alexey Milovidov).
Fixed ColumnNullable is not compatible with original exception when casting complex nested types. #96924 (Alexey Milovidov).
Fixed LOGICAL_ERROR when using isNull/isNotNull on subcolumns of Nullable(Tuple(... Nullable(T) ...)) types. #97582 (Alexey Milovidov).
Creating and materializing text indexes on tables with parts over 4,294,967,295 rows is temporarily disabled to prevent incorrect query results. #92644 (Anton Popov).
Fixed several crashes during merges of text indexes in MergeTree tables. #92925 (Anton Popov).
Fixed merges of text indexes built on complex expressions (such as concat(col1, col2)). #93073 (Anton Popov).
Fixed text index analysis on array columns when the index contained no tokens. #93457 (Anton Popov).
Fixed rebuilding of text indexes created on top of subcolumns. #93326 (Anton Popov).
Fixed direct reading from text index with duplicate search queries. #93516 (Anton Popov).
Fixed inconsistencies in text index analysis for has, mapContainsKey, and mapContainsValue functions that could return different results depending on whether a text index was used. #93578 (Anton Popov).
Fixed calculation of uncompressed sizes of text indexes in system.parts. #92832 (Anton Popov).
Fixed ngrambf_v1 indexes with ngram length > 8 throwing an exception. #92672 (Robert Schulze).
Fixed ngram_bf index on non-UTF-8 data leading to uninitialized memory read. #93663 (Alexey Milovidov).
Fixed possible failures of DiskObjectStorage cleanup thread when many errors occurred. #94048 (Kseniia Sumarokova).
Fixed data race in copyS3File for multipart_tags. #97227 (Azat Khuzhin).
Running an invalid ALTER UPDATE mutation on object storage file-like tables (S3, Azure) no longer caused a nullptr dereference. #96162 (Alexey Milovidov).
Fixed incorrect logic in access grant checks for wildcard grants that was too restrictive. #92725 (pufit).
Prevented users from getting the list of columns from a table without SHOW COLUMNS permission using the merge table engine. #93695 (János Benjamin Antal).
Fixed integer overflow vulnerability in groupConcat state deserialization that could cause memory safety issues. #93426 (Raufs Dunamalijevs).
Validated decompressed buffer size is as expected. #93690 (Raúl Marín).
Fixed TraceSender buffer size not being updated, causing interleaved flushes from different threads. #93966 (Miсhael Stetsyuk).
Stored storage shared pointers in QueryPipeline to ensure IStorage objects are not destroyed while PipelineExecutor is alive. #93746 (Miсhael Stetsyuk).
Fixed possible crash for distributed queries in case of cancellation. #95466 (Aleksandr Musorin).
Fixed crash on DROP WORKLOAD while running concurrently with queries. #95856 (Alexey Milovidov).
Fixed data race on shutdown_called in DatabaseMaterializedPostgreSQL. #97554 (Alexey Milovidov).
Fixed race condition in sharded HASHED dictionary parallel loading that could cause some rows to not be loaded. #96953 (Alexey Milovidov).
Fixed deadlock in dictionaries when one dictionary referenced a Merge table that referenced it recursively. #96120 (Alexey Milovidov).
Fixed BaseSettings::readBinary out-of-bounds access when a newer server sent an unknown setting during query plan deserialization. #97585 (Michael Stetsyuk).
Fixed crash when attaching a table to a MaterializedPostgreSQL database if dropReplicationSlot threw during stack unwinding. #96871 (Alexey Milovidov).
Released request stream in insert select to prevent closing HTTP connection. #92175 (Sema Checherinda).
Fixed deadlock for SHOW CREATE DATABASE for Backup database. #92541 (Azat Khuzhin).