Skip to main content

Modifications non rétrocompatibles

Modifications des requêtes et de la syntaxe

  • Les window functions RANK et DENSE_RANK refusent désormais les arguments et lèvent NUMBER_OF_ARGUMENTS_DOESNT_MATCH, conformément à la norme SQL. Auparavant, des requêtes telles que RANK(x) OVER (ORDER BY id) étaient acceptées silencieusement et l’argument était ignoré, ce qui semait fréquemment la confusion chez les utilisateurs. Pour rétablir le comportement permissif précédent, définissez allow_rank_dense_rank_arguments = 1. #104324 (groeneai).

Modifications des types de données

  • icebergHash et icebergBucket rejettent désormais explicitement les arguments Int128, UInt128, Int256, UInt256 et Decimal256 avec une erreur. Auparavant, ils tronquaient silencieusement les valeurs de plus grande taille, ce qui produisait des hachages identiques. La spécification Iceberg ne définit le hachage que pour les entiers sur 32/64 bits et les décimaux d’une précision maximale de 38 ; effectuez une conversion vers Int64 ou Decimal128 pour conserver le comportement précédent pour les valeurs compatibles. #105866 (Algunenano).
  • toUUID, toUUIDOrNull, toUUIDOrZero, toUUIDOrDefault, le CAST vers UUID et Nullable(UUID), accurateCastOrNull vers UUID, ainsi que les formats d’entrée qui analysent un UUID à partir de texte (Avro, MsgPack, JSONExtract, …) rejettent désormais les chaînes ayant la bonne longueur mais contenant des caractères non hexadécimaux. Auparavant, de telles entrées étaient silencieusement transformées en un UUID fabriqué de toutes pièces, en dépassant la fin de la table de correspondance des chiffres hexadécimaux. Désormais, toUUID lève CANNOT_PARSE_UUID, et les variantes Or* renvoient NULL / l’UUID nul / la valeur par défaut fournie. #104370 (groeneai).
  • Les types Dynamic et Variant sont désormais validés dans la clause PARTITION BY d’une window ; cette vérification n’avait pas lieu auparavant lorsque allow_suspicious_types_in_group_by est désactivé. Les requêtes qui partitionnent une window sur une colonne Dynamic ou Variant lèvent désormais une erreur, sauf si allow_suspicious_types_in_group_by = 1. #105450 (Avogar).

Modifications du stockage et des index

  • Rejette les Dynamic/Variant imbriqués dans les agrégats min/max et les index minmax. Auparavant, seuls les Dynamic/Variant de premier niveau étaient vérifiés. #105468 (Avogar).
  • La valeur par défaut du paramètre serveur insert_deduplication_version passe de compatible_double_hashes à new_unified_hash. La déduplication des insertions s’applique désormais à l’ensemble du bloc inséré (par insertion) plutôt qu’à chaque part/partition : une nouvelle tentative de la même insertion est toujours dédupliquée, mais deux insertions distinctes produisant une part identique ne sont plus dédupliquées l’une par rapport à l’autre, et les insertions des mêmes lignes dans un ordre différent ne sont plus dédupliquées. Définissez insert_deduplication_version = compatible_double_hashes pour restaurer le comportement précédent. Avec new_unified_hash, la déduplication des insertions asynchrones est également régie par la fenêtre de synchronisation : son activation (replicated_deduplication_window) et sa durée de conservation (replicated_deduplication_window_seconds, 1 heure par défaut) suivent les paramètres de synchronisation. Par conséquent, *_for_async_inserts est legacy et ne s’applique qu’à old_separate_hashes / compatible_double_hashes. Les instances mises à niveau directement depuis une version dont la valeur par défaut était old_separate_hashes doivent d’abord fonctionner avec compatible_double_hashes jusqu’à l’expiration de la plus longue fenêtre de déduplication pertinente (y compris replicated_deduplication_window_for_async_inserts, une semaine par défaut, si des insertions asynchrones sont utilisées), avant de s’appuyer sur new_unified_hash. Les charges de travail asynchrones passant de compatible_double_hashes doivent d’abord augmenter replicated_deduplication_window[_seconds] jusqu’à la valeur de la fenêtre asynchrone (et attendre une fenêtre asynchrone complète), interrompre les insertions asynchrones ou rester sur compatible_double_hashes, car new_unified_hash ne vérifie plus les identifiants async_blocks conservés plus longtemps. #107886 (CheSema).
  • Corrige le fait que hasToken, lorsqu’il reçoit une aiguille contenant un séparateur, renvoie silencieusement des résultats via un index de texte au lieu de générer l’erreur BAD_ARGUMENTS. #108189 (Ergus).

Fonctionnalités supprimées

  • Il n’est plus possible d’utiliser le Parquet reader et le writer obsolètes basés sur Arrow. L’implémentation native est toujours utilisée à la place. Les paramètres qui sélectionnaient les anciennes implémentations ou les ajustaient sont désormais obsolètes et ignorés : input_format_parquet_use_native_reader_v3, output_format_parquet_use_custom_encoder, output_format_parquet_version, output_format_parquet_compliant_nested_types et output_format_parquet_unsupported_types_as_binary. Le Native writer écrit toujours du Parquet V2.6+ avec des types imbriqués conformes, et lève UNKNOWN_TYPE pour les types non pris en charge au lieu de les écrire en binaire brut. #100949 (alexey-milovidov).
  • Suppression du paramètre obsolète allow_experimental_query_deduplication et de son comportement expérimental non pris en charge de déduplication des requêtes. #99398 (devcrafter).
  • ALTER TABLE ... REPLACE PARTITION ... FROM ... ne supprime plus silencieusement les données de la partition de destination lorsque la table source ne contient aucune part dans la partition demandée. Auparavant, une telle requête supprimait la partition de destination sans rien écrire à sa place. Elle est désormais rejetée avec BAD_ARGUMENTS par défaut. Il s’agit d’un changement non rétrocompatible : un REPLACE PARTITION à partir d’une source vide qui réussissait auparavant (en vidant la destination) lèvera désormais une exception après la mise à niveau. Pour rétablir le précédent comportement de vidage silencieux, définissez le nouveau paramètre allow_replace_partition_from_empty_source = 1 (par requête ou dans le profil), ou définissez compatibility sur 26.5 ou une version antérieure. Pour supprimer explicitement les données de destination, utilisez ALTER TABLE ... DROP PARTITION .... #104939 (groeneai).
  • Suppression des fonctions KQL (Kusto) expérimentales array_sort_asc et array_sort_desc, ainsi que de leurs implémentations SQL kql_array_sort_asc et kql_array_sort_desc. Ces fonctions étaient expérimentales, de mauvaise qualité et à l’origine de bogues de correction et d’analyse syntaxique. Les requêtes utilisant ces noms renvoient désormais UNKNOWN_FUNCTION. #108101 (groeneai).

Nouveautés

Fonctions

  • Ajout de la prise en charge de la fonction PromQL histogram_quantile dans les fonctions de table prometheusQuery et prometheusQueryRange. Cette fonction permet de calculer des quantiles à partir des buckets d’histogrammes Prometheus classiques identifiés par le label le. #103477 (Yasumoto).
  • Ajout de la fonction h3PolygonToCellsWithContainment, qui prend en charge les modes de couverture par centre, entièrement contenue et par chevauchement. #104455 (yousefQadry).
  • Il est désormais possible de spécifier un argument facultatif de précision pour les fonctions formatReadableSize, formatReadableDecimalSize et formatReadableQuantity, afin de contrôler le nombre de chiffres après la virgule. La valeur par défaut est 2, ce qui conserve le comportement antérieur. #104648 (antoniofilipovic).
  • Ajout des alias d’agrégation min_by et max_by pour argMin et argMax. #105712 (itsjoeoui).

Fonctionnalités SQL et des requêtes

  • formatReadableTimeDelta accepte désormais en entrée une expression INTERVAL d’un type autre que Month et Year. #64315 (Beetelbrox).
  • Ajout de la prise en charge du format de sortie PNG, permettant de restituer directement les résultats de requêtes sous forme d’images PNG. #74691 (m7kss1).
  • Introduction d’une fonctionnalité de réservation de mémoire pour les charges de travail. Consultez la documentation sur la planification des charges de travail. #82414 (serxa).
  • Ajout des options IPV4_PREFIX_BITS et IPV6_PREFIX_BITS pour les quotas basés sur IP_ADDRESS ou FORWARDED_IP_ADDRESS, permettant de partager les limites de quota par sous-réseau IP plutôt que de les appliquer séparément à chaque adresse complète. #89270 (adityachopra29).
  • Implémentation de ADD ENUM VALUES dans les requêtes ALTER TABLE afin de simplifier l’ajout de nouvelles valeurs à un type Enum existant sans devoir spécifier à nouveau toutes les valeurs Enum actuelles. #93830 (ilejn).
  • Ajout du format d’entrée GeoJSON pour la lecture. #98124 (mneedham).
  • Ajout d’un postprocesseur à l’index de texte, qui transforme les jetons après la tokenisation. #98939 (Ergus).
  • Ajout d’une prise en charge facultative des nœuds TTL dans ClickHouse Keeper. Les nœuds TTL expirent automatiquement après leur durée de vie configurée et ne peuvent pas avoir d’enfants. #100397 (scanhex12).
  • Ajout du stockage des positions de jetons pour les index de texte afin de prendre en charge les recherches exactes avec hasPhrase. Activez l’argument d’index support_phrase_search et le paramètre MergeTree allow_experimental_text_index_phrase_search. #103172 (ahmadov).
  • Ajout des fonctions arrayTopK et arrayBottomK : - arrayTopK(k, array) renvoie les K plus grands éléments par ordre décroissant - arrayBottomK(k, array) renvoie les K plus petits éléments par ordre croissant. #104563 (vitlibar).
  • Ajout de la prise en charge de la sélection de colonnes par motif de nom avec * LIKE '<pattern>' et * ILIKE '<pattern>', y compris les formes qualifiées telles que table.* LIKE '<pattern>' et table.* ILIKE '<pattern>'. LIKE établit une correspondance avec les noms de colonnes en respectant la casse, tandis que ILIKE ne tient pas compte de la casse. #104569 (niyue).
  • Ajout de requêtes continues pour les tables MergeTree à l’aide d’une séquence de lectures d’instantanés. #105114 (Michicosun).
  • Ajout du format RowBinaryWithNamesAndTypesAndDefaults pour améliorer la prise en charge de l’évolution du schéma. #105736 (mzitnik).
  • Ajout de fonctions permettant de générer des Mapbox Vector Tiles directement depuis SQL : MVTEncodeGeom projette une géométrie dans l’espace de pixels d’une tuile slippy-map et l’écrête, MVTEncode agrège les géométries projetées d’un groupe dans les octets binaires d’une tuile à une seule couche, et MVTBoundingBox / MVTBoundingBoxMercator renvoient la boîte englobante d’une tuile afin de limiter les lignes à celle-ci. Les géométries de type point, ligne et polygone sont prises en charge. Également disponibles sous les alias PostGIS ST_AsMVTGeom et ST_AsMVT. #106107 (saarthak2002).
  • Ajout de LOCALTIME et LOCALTIMESTAMP (syntaxe SQL standard / PostgreSQL). LOCALTIMESTAMP est un alias de now() (renvoie DateTime) ; LOCALTIME renvoie l’heure actuelle sous la forme d’une valeur Time. #106139 (thomas-cabral).
  • Ajout de deux nouvelles stratégies load_balancing, hostname_longest_common_prefix et hostname_longest_common_suffix, qui privilégient la réplique dont le hostname partage le plus long préfixe commun (respectivement suffixe) avec celui de l’initiateur. Elles sont utiles lorsque le centre de données est encodé comme préfixe ou suffixe de hostnames dont les segments numériques sont de longueur variable, cas dans lequel les stratégies existantes nearest_hostname et hostname_levenshtein_distance sélectionnent la mauvaise réplique. #107360 (den-crane).
  • Nouvelles fonctions quantizeBFloat16ToInt8 et dequantizeInt8ToBFloat16 : un codec scalaire qui compresse les composants d’embedding sur 8 bits à l’aide d’un quantificateur gaussien Lloyd-Max à 256 niveaux, dont des codes Int4/Int2/binaires peuvent être extraits par troncature de bits. #108102 (alexey-milovidov).

Moteurs de table et stockage

  • Ajout de la prise en charge de l’écriture vers Azure Data Lake Storage Gen2. #105406 (scanhex12).

Paramètres et configuration

  • Ajout d’un paramètre output_format_always_write_decimal_point_in_float_and_decimal pour toujours afficher un point décimal pour les nombres à virgule flottante et Decimal dans les formats texte, même lorsque la valeur est un nombre entier. Par exemple, affiche 1. au lieu de 1. Désactivé par défaut. #62614 (qoega).
  • Ajout d’un nouveau paramètre immuable de MergeTree, allow_tuple_element_aggregation, désactivé par défaut. Lorsqu’il est activé, SummingMergeTree, AggregatingMergeTree et CoalescingMergeTree aplatissent récursivement les colonnes Tuple et agrègent chaque élément terminal indépendamment lors des fusions, comme s’il s’agissait d’une colonne de premier niveau : SummingMergeTree l’additionne, AggregatingMergeTree fusionne son état de fonction d’agrégation et CoalescingMergeTree conserve sa dernière valeur non-NULL. Le paramètre doit être spécifié lors de la création de la table et est ignoré silencieusement par les moteurs qui ne le prennent pas en charge. #98039 (JingYanchao).
  • Ajout du paramètre output_format_float_precision pour contrôler le nombre de chiffres décimaux dans la sortie texte des nombres à virgule flottante. #99721 (phulv94).
  • Ajout des paramètres de table MergeTree materialize_projections_on_insert et materialize_projections_on_merge. Lorsque materialize_projections_on_insert = 0, les INSERT ne créent pas de parts de projection, ce qui améliore le débit d’insertion pour les tables comportant de nombreuses projections. Lorsque materialize_projections_on_merge = 1, une fusion recrée une projection absente de toutes ses parts sources, ce qui permet de créer les projections lors des fusions plutôt qu’à l’insertion. Les fusions ne combinent toujours que des parts partageant le même ensemble de projections. #100993 (cwurm).
  • Ajout d’un nouveau paramètre S3Queue after_processing_move_preserve_path. Lorsqu’il est activé avec after_processing='move' et after_processing_move_prefix, les objets traités sont déplacés tout en préservant leur chemin source complet sous le préfixe de destination, au lieu d’être réduits au seul nom de fichier. #105354 (asya-ch).
  • Ajout des éléments de configuration du gestionnaire HTTP url_prefix et full_url_prefix pour faire correspondre tous les chemins commençant par un préfixe donné, ainsi que des éléments explicites url_regexp, full_url_regexp et headers_regexp. La forme héritée <url>regex:...</url> reste prise en charge. #107492 (vitlibar).

Authentification

  • Ajout d’un identifiant external_id facultatif pour l’accès à S3 basé sur les rôles. #106941 (eliangidoni).
  • Ajout à la table system.session_log des informations du certificat client TLS (sujets, numéro de série, émetteur et période de validité) afin d’améliorer l’observabilité de l’authentification par certificat. #107679 (alexey-milovidov).

Tables système

  • Ajout de la table system.iceberg_files, qui expose les métadonnées par fichier des tables Iceberg, avec une ligne par fichier de données ou de suppression dans le snapshot actuel de chaque table. #104415 (asya-ch).
  • Ajout d’index de saut de données hypothétiques. Utilisez CREATE HYPOTHETICAL INDEX ... ON t (expr) TYPE ... pour définir un index de saut de données virtuel limité à la session, puis EXPLAIN WHATIF SELECT ... pour estimer son taux d’exclusion et son coût sans le matérialiser. Les index définis sont visibles dans la nouvelle table system.hypothetical_indexes. #104608 (yariks5s).
  • Ajout de la table système system.constraints, qui fournit des informations sur toutes les contraintes CHECK et ASSUME de toutes les tables, y compris le nom, le type et l’expression de la contrainte. #105337 (PedroTadim).
  • Ajout d’une nouvelle table système system.documentation, qui regroupe dans une seule table la documentation de référence intégrée des composants uniformes du système (fonctions, moteurs de table, types de données, paramètres, formats et autres), avec une documentation rendue au format Markdown. #107463 (alexey-milovidov).

Fonctionnalités expérimentales

  • Ajout de l’algorithme expérimental de réordonnancement des jointures dphyp pour les jointures internes, en tant qu’option du paramètre query_plan_optimize_join_order_algorithm, ainsi que du paramètre query_plan_optimize_join_order_max_searched_plans, qui limite la recherche de l’ordre des jointures et bascule vers l’algorithme suivant de la chaîne lorsque cette limite est dépassée ; définissez-le sur 0 pour conserver le comportement précédent de recherche non limitée. #98798 (davenger).
  • Ajout du mode d’application différée des posting lists pour l’index de texte. Lorsqu’il est activé via SET allow_experimental_text_index_lazy_apply = 1 et SET text_index_posting_list_apply_mode = 'lazy', les posting lists sont décodées à la demande, à la granularité des blocs packed, à l’aide d’une approche basée sur un curseur, au lieu d’être entièrement matérialisées en bitmaps Roaring, ce qui réduit l’utilisation de la mémoire et le temps CPU pour les requêtes sélectives sur l’index de texte. #100035 (fastio).
  • Permet d’attacher des gestionnaires Prometheus au port HTTP principal avec un préfixe facultatif. #104975 (JTCunning).
  • Ajout d’un paramètre MergeTree expérimental, packed_skip_index_max_bytes, qui regroupe les petits substreams d’index de saut de données dans une seule archive skp_idx.packed par part, réduisant la pression sur les inodes lorsque de nombreux index de saut de données sont définis sur une table. La décision est prise pour chaque substream au moment de l’écriture : les substreams dont la taille sérialisée reste inférieure au seuil sont placés dans l’archive, tandis que les plus volumineux conservent la disposition autonome skp_idx_<name>.idx2 / .mrk2. Une même part peut combiner les deux dispositions. Les index de texte intégral ne sont pas pris en charge et sont toujours stockés dans des fichiers distincts. La valeur par défaut est 0 (packing désactivé). #105321 (Algunenano).
  • Prise en charge de la sérialisation Buffers pour les UDF WebAssembly utilisant ABI BUFFERED_V1, et ajout de webassembly_udf_enable_fuel comme paramètre persistant de fonction UDF WASM. #105574 (antonio2368).
  • Exécution de requêtes distribuées en plusieurs étapes : le planificateur divise le plan de requête en étapes reliées par des échanges scatter / broadcast / gather / shuffle et répartit les fragments de plan entre les nœuds workers. Les données entre les étapes sont transmises en streaming via TCP ou via des fichiers temporaires dans un stockage d’objets partagé. Cette fonctionnalité prend en charge les hash joins distribués de type shuffle et broadcast, l’agrégation shuffle et le tri distribué. Elle est expérimentale et désactivée par défaut. #106020 (davenger).
  • Le moteur expérimental de plan de requête distribué (make_distributed_plan) peut désormais utiliser, pour chaque worker, un port distinct pour la répartition des tâches et les échanges en streaming, configuré par réplique dans <remote_servers> avec stateless_worker_port et streaming_exchange_port. S’ils ne sont pas définis, les ports précédents au niveau du serveur (stateless_worker_client.port et distributed_query.streaming_exchange_port) sont utilisés. Cela permet d’exécuter plusieurs workers sur un même hôte. #107885 (davenger).

Améliorations des performances

Performances des JOIN

  • Application différée des index de sélecteur et de réplication lorsqu’un JOIN est suivi d’un LIMIT sélectif, d’un TopN ou d’un autre JOIN. Pour contrôler le nombre de colonnes de payload requis pour activer l’indexation différée des sélecteurs, utilisez le paramètre query_plan_min_columns_for_join_lazy_indexing (0 signifie que l’optimisation est désactivée). Pour définir la valeur de LIMIT à laquelle l’optimisation s’applique, utilisez le paramètre query_plan_max_limit_for_join_lazy_indexing. #98883 (m-selmi).
  • ASOF JOIN peut désormais utiliser l’algorithme de jointure parallel_hash, en parallélisant la phase de construction entre les différentes valeurs de clés d’égalité. Auparavant, ASOF était systématiquement exclu de parallel_hash. #105375 (gregakinman).
  • Partage de la FixedHashMap de la jointure par hachage comme filtre d’exécution de JOIN côté sondage. Lorsque la table de hachage côté construction est (ou peut être convertie en) une FixedHashMap, elle est publiée comme filtre d’exécution et remplace le Set/BloomFilter que BuildRuntimeFilterStep installerait autrement. Contrôlé par le nouveau paramètre enable_join_runtime_filter_shared_fixed_hash_table (activé par défaut : true). #105640 (wudidapaopao).
  • La réorganisation DP des JOIN est désormais autorisée avec des répliques parallèles. #105889 (nickitat).
  • Amélioration du plan de requête lorsque les JOIN utilisent des filtres d’exécution (enable_join_runtime_filters activé par défaut) : le modèle de coût de réorganisation des jointures traverse désormais WindowTransform (et les autres étapes du plan préservant les lignes) dans le sous-arbre de droite et utilise le nombre de lignes sous-jacent ainsi que le NDV par colonne, au lieu de considérer qu’aucune statistique n’est disponible. #107229 (UnamedRus).

Optimisation des requêtes

  • Amélioration des performances de l’analyse des index de texte pour les recherches portant sur plusieurs jetons grâce à une gestion optimisée des jetons rares. #98226 (CurtizJ).
  • Amélioration des performances des fonctions encrypt, decrypt et halfMD5 en évitant les recherches implicites du fournisseur OpenSSL pour chaque ligne dans OpenSSL 3.x. #99105 (thevar1able).
  • Regroupement des blocs sources avant projection.calculate() lors de MATERIALIZE PROJECTION afin de réduire le nombre de parties de projection temporaires et le surcoût des fusions. Accélération d’environ 3,4 fois sur une table de 50 millions de lignes. #100047 (amosbird).
  • Les utilisateurs bénéficient désormais de meilleures performances des filtres d’exécution approximatifs et des index de filtre de Bloom. #100201 (cv4g).
  • Accélération des requêtes ORDER BY ... LIMIT BY en exécutant LIMIT BY dans chaque flux trié en parallèle lors de Sort, lorsque les colonnes de LIMIT BY constituent un préfixe de celles de ORDER BY. Cela réduit le nombre de lignes passant par la fusion de tri finale et les étapes ultérieures du pipeline. Cette optimisation est contrôlée par le nouveau paramètre query_plan_push_limit_by_into_sort (activé par défaut). #104000 (nihalzp).
  • Réduction du surcoût par requête pour les requêtes SELECT simples (analyse syntaxique, analyse et planification). Par exemple, SELECT count() FROM hits exécutée depuis une seule connexion est environ 50 % plus rapide. #104513 (Algunenano).
  • Amélioration des performances de bitmapContains pour les états groupBitmap autres que UInt64 en évitant les appels répétés à rb_max lors des vérifications de plage. #105960 (niyue).
  • Amélioration des performances d’insertion pour les colonnes LowCardinality dotées d’index bloom_filter. #106410 (EmeraldShift).
  • Amélioration des performances des fonctions L2DistanceTransposed et cosineDistanceTransposed pour le type de données QBit. #106701 (rienath).
  • Amélioration des performances de l’analyse des requêtes sur des tables comportant de nombreuses colonnes : évite le calcul des hachages des nœuds de colonne (qui incluent l’expression complète de la table source) lorsqu’il n’est pas nécessaire. L’analyse de sous-requêtes SELECT * imbriquées sur une table d’environ 1 200 colonnes est désormais environ 50 fois plus rapide. #106957 (novikd).
  • Amélioration des performances des fonctions encrypt, decrypt, tryDecrypt, aes_encrypt_mysql et aes_decrypt_mysql jusqu’à un facteur dix, compensant les performances perdues lors de la migration de BoringSSL vers OpenSSL 3.x (24.4). #107339 (thevar1able).
  • Amélioration de l’exécution de arrayElement sur Array(LowCardinality(String)) et des fonctions LIKE sur les maps dont les clés ou les valeurs sont de type LowCardinality(String), en évitant la matérialisation inutile de chaînes. #107450 (EmeraldShift).
  • Réduction de l’utilisation du CPU et amélioration des performances d’évaluation des skip-index pour les requêtes filtrant des colonnes DateTime64. #107707 (shankar-iyer).
  • Amélioration des performances des recherches de sous-chaînes insensibles à la casse, notamment positionCaseInsensitiveUTF8, ILIKE et multiSearchAnyCaseInsensitiveUTF8. #107882 (Algunenano).
  • Correction d’une régression de débit d’environ 16 % du codec à virgule flottante FPC sur ARM, apparue lorsque ses tables de prédiction ont commencé à utiliser VectorWithMemoryTracking. #108182 (groeneai).
  • Correction d’une régression de performances où un seul DELETE léger désactivait le cache des conditions de requête pour l’ensemble de la table. Les requêtes sélectives répétées sur une table ayant déjà fait l’objet d’un DELETE léger ne permettaient plus d’élaguer les granules et entraînaient la lecture de chaque marque. #112947 (fm4v).
  • Limitation du coût de l’estimation de la sélectivité de col IN (...) à partir des statistiques de colonnes, qui pouvait ajouter plusieurs centaines de millisecondes à la planification d’une seule requête. L’estimateur n’exécute plus la sous-requête de col IN (subquery) pour remplir un ensemble dont il n’a besoin que pour obtenir une valeur de sélectivité : un ensemble non construit est ignoré. Pour un ensemble dont la taille dépasse le nouveau paramètre statistics_max_set_size_for_exact_selectivity_estimation (10000 par défaut), la sélectivité est désormais déduite de la taille de l’ensemble et de la plage qu’il couvre. #114389 (nickitat).

Performances des fonctions et des agrégations

  • Optimisation de l’analyse de l’index de clé primaire pour les clés primaires longues et à forte cardinalité. Pour une clé primaire longue, le temps d’exécution de l’analyse de l’index dépend désormais principalement de la complexité du filtre de la requête (les colonnes de clé qu’il utilise réellement), et non de la longueur de la clé primaire. Par conséquent, l’extension de la clé de tri n’entraîne qu’une surcharge négligeable pour l’analyse de l’index des requêtes qui ne filtrent que sur quelques-unes de ses colonnes. Pour une clé primaire à forte cardinalité, lorsque ClickHouse ne conserve en mémoire qu’un préfixe sélectif des colonnes de clé sans charger les suivantes, l’analyse de l’index ne porte désormais que sur ce préfixe en mémoire plutôt que sur l’ensemble de la clé. L’optimisation est activée par défaut et peut être désactivée avec le nouveau paramètre use_lightweight_primary_key_index_analysis. #91836 (nihalzp).
  • Réduction du pic d’utilisation de la mémoire lors de la fusion de résultats d’agrégation partiels à deux niveaux avec de grands états d’agrégation (par ex. groupArray), grâce à la libération progressive des états sources de chaque compartiment pendant la fusion, au lieu de tous les conserver jusqu’à sa fin. #102330 (yurifedoseev).
  • Nouvelle optimisation de GROUP BY pour les clés à forte cardinalité uniformément réparties, qui répartit les lignes entre les threads par hachage de la clé de regroupement, afin que chaque thread agrège un sous-ensemble distinct de clés sans phase de fusion. Définissez enable_sharding_aggregator = 1 pour l’activer. #104233 (nihalzp).
  • Accélération des requêtes LIMIT BY sur les tables MergeTree partitionnées en exécutant LIMIT BY en parallèle dans le flux de chaque partition, au lieu de fusionner tous les flux en un seul avant d’appliquer la limite. Cela s’applique lorsque l’expression de partition est une fonction déterministe des colonnes LIMIT BY, de sorte qu’aucun groupe LIMIT BY ne peut s’étendre sur deux partitions. Contrôlé par le nouveau paramètre allow_limit_by_partitions_independently (activé par défaut). #105126 (nihalzp).
  • Accélération des requêtes SELECT ... LIMIT N BY <cols> lorsque <cols> constitue un préfixe de la clé de tri de la table, ou le devient après que WHERE col = const a fixé les colonnes initiales. Lorsque cette option est activée, MergeTree lit les données dans l’ordre de la clé primaire et LIMIT BY les filtre d’abord en flux, avec une mémoire O(1) par flux trié, ce qui élimine la plupart des données, avant d’appliquer le LIMIT BY normal aux données réduites afin d’obtenir le résultat final. Contrôlé par le nouveau paramètre optimize_limit_by_in_order (activé par défaut). #105135 (nihalzp).
  • Accélération des requêtes LIMIT BY par suppression des expressions de clé redondantes : une clé qui est une fonction déterministe des autres clés est supprimée (par ex. LIMIT 5 BY x, f(x) devient LIMIT 5 BY x), et une fonction injective d’une clé est remplacée par son argument (par ex. LIMIT 5 BY toString(x) devient LIMIT 5 BY x). Cela permet d’évaluer moins d’expressions, et des expressions moins coûteuses, par ligne. Contrôlé par les nouveaux paramètres optimize_limit_by_function_keys et optimize_injective_functions_in_limit_by, tous deux activés par défaut. #106818 (nihalzp).
  • Accélération de l’analyse des requêtes comportant de nombreux appels de fonctions ou des appels de fonctions profondément imbriqués, grâce à la suppression d’un hachage redondant de l’arbre de requête du cache de résolution des fonctions. #107516 (novikd).
  • Parallélisation du traitement du résultat d’une CTE récursive : un GROUP BY ou toute autre opération sur un volumineux résultat de WITH RECURSIVE n’est plus limité à un seul thread. #107694 (alexey-milovidov).

Performances du stockage et des E/S

  • Les clients S3 utilisant le même point de terminaison et le même compartiment partagent un cache, ce qui évite la découverte redondante des régions. #96802 (zvonand).
  • Amélioration des performances de copie dans le stockage d’objets grâce à la copie parallèle des blobs. #105089 (asya-ch).
  • Évite de lire le contenu des fichiers lors de l’utilisation du format d’entrée One avec des fonctions de table de type fichier telles que file et s3. #105157 (niyue).
  • La clé primaire de MergeTree et les index de saut de données peuvent désormais élaguer des granules pour les filtres dans lesquels ifNull ou coalesce encapsule une condition, comme ifNull(key = 0, 0) ou coalesce(key = 0, 0). Ces prédicats — souvent générés par des générateurs de requêtes pour convertir une comparaison potentiellement NULL en valeur booléenne définie — étaient auparavant opaques pour l’analyse des index et ne permettaient pas d’ignorer des granules. Cette modification étend le paramètre existant allow_key_condition_coalesce_rewrite (activé par défaut). #106272 (andyzzhao).
  • Amélioration des performances de décodage des colonnes Parquet FLOAT et DOUBLE encodées avec BYTE_STREAM_SPLIT. #106376 (Algunenano).
  • Correction des blocages prolongés lors de la connexion et du démarrage des requêtes avec le stockage d’accès répliqué lorsque de nombreuses entités d’accès (politiques de lignes, rôles, quotas, profils de paramètres) changent simultanément. Chaque cache par entité est désormais recalculé une seule fois par lot de notifications, au lieu d’une fois par entité modifiée, éliminant ainsi un travail quadratique susceptible de maintenir le verrou d’accès pendant plusieurs minutes. #107672 (azat).
  • Correction d’une régression de performances : la lecture de nombreux petits fichiers depuis un stockage d’objets via s3 et d’autres fonctions de table ne préchargeait plus les données et basculait vers des lectures synchrones, ce qui ralentissait considérablement les lectures monothreadées ou à faible concurrence de nombreux petits fichiers. #108872 (fm4v).
  • Activation du préchargement initial des petits objets lorsque les lectures du stockage d’objets passent par le cache du système de fichiers (filesystem_cache_name). Auparavant, les lectures de nombreux petits fichiers, comme lors de l’ingestion S3Queue, restaient synchrones et limitées par la latence lorsque le cache du système de fichiers était activé. #109478 (fm4v).
  • Amélioration de l’optimisation PREWHERE pour les sous-colonnes Map en tenant compte de leur taille sur disque. #110623 (Avogar).
  • La matérialisation différée s’applique désormais aux requêtes avec FINAL, un filtre et un petit LIMIT, même sans ORDER BY (pour ReplacingMergeTree). #110722 (KochetovNicolai).
  • Réduction du temps CPU consacré à la déduplication lors des vidages d’insertions asynchrones couvrant de nombreuses partitions. #111150 (valerypetrov).
  • Correction d’une régression CPU pour les requêtes effectuant de nombreuses petites lectures indépendantes dans la même part MergeTree lorsque la table possède des colonnes LowCardinality. La vérification déterminant si une part possédait un unique dictionnaire partagé parcourait chaque marque de l’ensemble de la part à chaque tâche de lecture ; elle identifie désormais chaque séquence de marques identiques par recherche binaire. Les requêtes de ce type sur des tables avec une faible index_granularity pouvaient être plusieurs fois plus lentes depuis la version 26.6. #116134 (groeneai).

Optimisation de la mémoire

  • Réduction jusqu’à 10 fois de la mémoire utilisée par les métadonnées du type Enum pour les tables contenant des colonnes Enum. Les recherches de valeur à nom restent aussi rapides, voire plus rapides, tandis que les recherches de nom à valeur lors de l’analyse syntaxique et de la désérialisation peuvent être plus lentes. #95668 (qoega).
  • Réduction du pic d’utilisation de mémoire de BACKUP en évitant de copier la liste interne des informations de fichiers lors de l’écriture des entrées de sauvegarde (ce qui est particulièrement significatif pour les sauvegardes contenant des millions de fichiers). #111162 (jkartseva).

Améliorations

Requêtes et SQL

  • Identification des colonnes par position (plutôt que par nom) lors de la suppression des colonnes inutilisées du plan de requête. Cela permet de supprimer les colonnes inutilisées lorsque des noms de colonnes sont dupliqués. #100586 (antaljanosbenjamin).
  • Ajout de SESSION_USER comme alias non sensible à la casse de currentUser() pour assurer la compatibilité avec PostgreSQL et le standard SQL. #106081 (takumihara).
  • Réduction de la latence d’annulation des requêtes exécutées via le protocole filaire PostgreSQL : KILL QUERY interrompt désormais la sérialisation de la sortie au sein d’un seul fragment, au lieu d’attendre que l’intégralité du fragment soit envoyée au client. #106535 (rvasin).
  • Correction d’une erreur ILLEGAL_TYPE_OF_ARGUMENT pour les requêtes distribuées avec serialize_query_plan = 1 contenant une lambda avec un argument constant (par ex. arrayMap(t -> t.2, ...)). Les colonnes constantes des nœuds INPUT d’ActionsDAG sont désormais préservées lors de la sérialisation du plan de requête. #107124 (alexey-milovidov).
  • Réduction de la latence d’annulation des requêtes exécutées via le protocole filaire MySQL : KILL QUERY interrompt désormais la sérialisation de la sortie au sein d’un seul fragment, au lieu d’attendre que l’intégralité du fragment soit envoyée au client. #107228 (rvasin).

Fonctions

  • EXPLAIN SYNTAX formate désormais systématiquement les opérateurs sous forme d’appels de fonction dans la sortie d’explication (par exemple plus(1, 2) au lieu de 1 + 2). #94681 (1abdelhalim).
  • La syntaxe de type PostgreSQL expr OP SOME(array) / expr OP ALL(array) (avec un membre droit qui n’est pas une sous-requête) est désormais prise en charge et réécrite en has / NOT has pour =/<>, ou en lambdas arrayExists / arrayAll pour les autres opérateurs de comparaison. ANY n’est pas accepté dans la forme tableau, car any est également une fonction d’agrégation ; utilisez plutôt SOME. La forme sous-requête de ANY/SOME/ALL continue d’être convertie en IN / NOT IN. #105129 (alexey-milovidov).
  • Ajout de la prise en charge des fonctions multiSearchAny, multiSearchAnyUTF8 et multiMatchAny dans les index de texte. L’analyse des index de texte a également été améliorée pour la fonction match : les motifs comportant des groupes d’alternatives peuvent désormais ignorer davantage de granules. #106279 (CurtizJ).
  • La fonction h3PolygonToCells applique désormais la taille maximale de tableau à l’ensemble des polygones d’un MultiPolygon, valide les codes de retour de la bibliothèque H3 sous-jacente et rejette les arguments MultiLineString au lieu de renvoyer silencieusement un résultat vide. #106399 (Algunenano).
  • La désérialisation des états des fonctions d’agrégation contingency, cramersV, cramersVBiasCorrected et theilsU vérifie désormais que les comptes stockés forment une table de contingence cohérente et lève une exception CORRUPTED_DATA dans le cas contraire. #107185 (nihalzp).
  • Amélioration de l’estimation de cardinalité dans l’optimiseur de plans de requête : une colonne produite par une fonction déterministe à un seul argument (par ex. toYear(date)) hérite désormais du nombre de valeurs distinctes de son argument comme limite supérieure, au lieu de rester sans statistiques, ce qui permet un réordonnancement des jointures plus précis. #107757 (davenger).

Moteurs de table et stockage

  • Corrige les consommateurs du moteur de table Kafka qui continuaient à utiliser un intervalle de poll court après l’affectation des partitions, afin qu’ils reviennent au kafka_poll_timeout_ms configuré et évitent les polls à vide excessifs, les parts insérées de plus petite taille et la surcharge de fusion supplémentaire après les rééquilibrages. #100431 (sugaf1204).
  • Les moteurs de table de lac de données, notamment Iceberg et DeltaLake, peuvent désormais utiliser des disques S3 et Azure avec cache, ce qui permet aux lectures répétées d’utiliser le cache du système de fichiers. #102017 (RinChanNOWWW).
  • Permet de fusionner, lors d’un second passage de l’optimiseur, les filtres introduits après la sélection PREWHERE initiale (pushdown de prédicats, filtres d’exécution ou PREWHERE explicite associé à une clause WHERE définie par le planificateur) avec le PREWHERE existant, plutôt que de les conserver sous forme d’étape Filter distincte au-dessus de la lecture MergeTree. #105445 (yariks5s).
  • Ajout du paramètre wait_for_part_commit_in_dependent_materialized_views. Lorsqu’il est activé, une vue matérialisée en cascade qui effectue une jointure avec sa source peut voir la ligne en cours d’insertion. #105943 (ahmadov).
  • Prise en charge, compatible avec PostgreSQL, de EXTRACT(TIMEZONE_HOUR FROM dt) et EXTRACT(TIMEZONE_MINUTE FROM dt) pour extraire les composantes heure et minute d’un décalage de fuseau horaire, ainsi que de EXTRACT(<unit> FROM INTERVAL n <unit>) / date_part('<unit>', INTERVAL n <unit>) pour extraire la valeur d’un intervalle. #106227 (vinayakj592).
  • Implémentation de SYSTEM RESTART DISK <name> : cette commande recharge désormais les métadonnées d’un disque en mémoire et analyse de nouveau les parts de données des tables de répliques readonly qui s’y trouvent. Cela permet à une réplique readonly d’une table sur un stockage partagé plain_rewritable d’observer à la demande les données écrites par un autre serveur, sans attendre refresh_parts_interval ni redémarrer le serveur. #106645 (jrdi).
  • Évite les chargements inutiles de fichiers de marques pour les données partagées JSON avancées. #107051 (Avogar).
  • Ajout du paramètre materialized_postgresql_use_extended_date_and_time_types, défini à la création, pour le moteur de base de données MaterializedPostgreSQL. Par défaut (activé), les colonnes PostgreSQL date/timestamp sont inférées comme Date32/DateTime64 ; le définir sur 0 lors de CREATE DATABASE entraîne l’inférence des types plus restreints Date/DateTime. Ce paramètre ne s’applique pas au moteur de table MaterializedPostgreSQL. #107428 (alexey-milovidov).
  • MergeTree peut désormais lire un flux compressé dont les blocs utilisent différents codecs. Il s’agit du prérequis côté lecture pour la sélection adaptative de codec. #108592 (rienath).
  • Utilise l’index de saut de données bloom_filter pour les prédicats IN sur une colonne directement indexée lorsque transform_null_in = 1 et que l’ensemble IN ne contient aucune valeur NULL. Auparavant, l’index était ignoré pour ces requêtes, ce qui imposait un parcours complet. #111329 (groeneai).

S3 et stockage d’objets

  • Enregistre les privilèges dans system.query_log.used_privileges pour toutes les vérifications d’accès autorisées, y compris celles qui empruntent le chemin isGranted ne levant pas d’exception (checkAccessWithFilter). Auparavant, seuls les privilèges vérifiés via des points d’entrée levant des exceptions (checkAccess / checkGrantOption) étaient enregistrés, ce qui rendait READ ON FILE / READ ON S3 / READ ON AZURE / READ ON URL invisibles dans le journal d’audit pour les requêtes DESCRIBE, CREATE TABLE AS et similaires utilisant les fonctions de table file / s3 / azure / url. L’application des contrôles d’accès reste inchangée. #104693 (alexbakharew).
  • Effectue de manière asynchrone la requête finale de téléversement multipart vers S3 via le suivi des tâches, afin qu’elle puisse se chevaucher avec le téléversement de la dernière partie au lieu de s’exécuter en série lors de la finalisation. #105487 (asya-ch).
  • Augmente de une à six heures la valeur par défaut du paramètre persistent_processing_node_ttl_seconds pour S3Queue et AzureQueue, afin d’éviter qu’un traitement de longue durée ou redémarré ne perde trop tôt son verrou de bucket. #106838 (kssenii).
  • Prend en charge les valeurs REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, GLACIER_IR et EXPRESS_ONEZONE (en plus de STANDARD et INTELLIGENT_TIERING) pour le paramètre s3_storage_class_name. #107251 (adityaksolves).
  • Le chemin d’exemple de partitionnement Hive pour les tables de stockage d’objets (par exemple, S3) est résolu lors de la première utilisation de la table plutôt que lors de CREATE/ATTACH, de sorte qu’un endpoint non joignable ne bloque plus la création de tables ni le démarrage du serveur. #111842 (evillique).

Paramètres et configuration

  • La stratégie de partitionnement hive devient la valeur par défaut avec le paramètre de compatibilité file_like_engine_default_partition_strategy. #86746 (kssenii).
  • Ajout de quatre nouveaux paramètres de table MergeTree pour contrôler les paramètres par défaut des index de texte : text_index_dictionary_block_size, text_index_dictionary_block_frontcoding_compression, text_index_posting_list_block_size et text_index_posting_list_codec. Ces paramètres permettent d’ajuster le comportement des index de texte au niveau de la table sans spécifier de paramètres dans chaque définition d’index. Les arguments explicites définis pour chaque index restent prioritaires. #100626 (CurtizJ).
  • Ajout du paramètre output_format_pretty_use_nbsp_for_padding afin de restituer les espaces de remplissage des tableaux dans les formats Pretty sous forme d’espaces insécables U+00A0 lorsque output_format_pretty_grid_charset est défini sur UTF-8. Cela permet à la sortie Pretty copiée de conserver l’alignement des tableaux dans les outils qui réduisent les espaces ordinaires. Le paramètre est désactivé par défaut et la sortie avec le jeu de caractères ASCII conserve les espaces ordinaires. #103559 (ashrithb).
  • Prise en charge de la compatibilité avec l’ancien analyseur via le paramètre analyzer_compatibility_allow_non_aggregate_in_having. S’il est activé, les conjonctions non agrégées sont déplacées de HAVING vers WHERE. #104232 (novikd).
  • OPTIMIZE TABLE ... ON CLUSTER et les autres DDL ne restent plus bloqués lorsque la table cible a table_readonly = 1. Le paramètre génère désormais un nouveau code d’erreur dédié, TABLE_IS_PERMANENTLY_READ_ONLY, que DDLWorker traite comme non réessayable (à la différence de l’erreur transitoire TABLE_IS_READ_ONLY, qui survient lors de déconnexions temporaires de ZooKeeper pour ReplicatedMergeTree). Le paramètre table_readonly est également désormais explicitement refusé pour ReplicatedMergeTree, tant lors de la création que via ALTER MODIFY SETTING. #105109 (alexey-milovidov).
  • L’ordre de tri décroissant dans les clés de tri MergeTree (par exemple ORDER BY (time DESC, key)) est désormais toujours pris en charge et ne nécessite plus le paramètre expérimental allow_experimental_reverse_key, devenu obsolète. #106440 (nikitamikhaylov).
  • Prise en charge de keyed_by_normalized_query_hash pour les quotas définis dans la configuration statique du serveur (users.xml), conformément à la syntaxe DDL existante CREATE QUOTA ... KEYED BY normalized_query_hash. #107654 (alexey-milovidov).
  • Le paramètre de compatibilité n’applique plus les paramètres obsolètes ; il ne les marque donc plus comme modifiés et ne génère plus d’avertissements à leur sujet. #107737 (UberDever).
  • Ajout du paramètre analyzer_compatibility_multiple_joins_qualify_column_names (valeur par défaut : false). Lorsqu’il est activé et que la clause FROM d’une requête contient au moins deux JOIN, les noms des colonnes de résultat produits par l’analyseur reproduisent la réécriture des jointures multiples de l’ancien analyseur : les colonnes développées à partir de * sont nommées <alias-or-table>.<column>, et une référence à une colonne sans alias dans la liste SELECT conserve son nom exactement tel qu’il est écrit. Cela permet aux requêtes externes qui référencent de tels noms qualifiés, comme SELECT ll.Date FROM (SELECT * FROM t AS ll JOIN t1 ON ... JOIN t2 ON ...), de fonctionner comme avec l’ancien analyseur. Correction également d’un problème où l’analyseur perdait les noms qualifiés des colonnes de résultat développées à partir de * lorsque group_by_use_nulls était combiné avec ROLLUP, CUBE ou GROUPING SETS, ce qui produisait des noms de colonnes de résultat dupliqués et empêchait les références externes à ces colonnes. #110746 (novikd).
  • Ajout du paramètre analyzer_compatibility_apply_final_to_all_joined_tables, qui rétablit l’ancien comportement selon lequel le modificateur FINAL appliqué à la table située le plus à gauche d’un JOIN l’était également aux autres tables jointes. Ce paramètre est enregistré dans l’historique des modifications de paramètres, de sorte que compatibility avec des versions antérieures à 26.6 rétablit automatiquement l’ancienne sémantique. #111589 (fm4v).
  • Ajout d’un nouveau paramètre MergeTree text_index_version qui contrôle la version du format sur disque des index de texte : v0_initial, v1_with_codec ou v2_with_positions. Lors d’une mise à niveau progressive ou avant une rétrogradation, définissez-le sur une version antérieure afin que les serveurs plus récents continuent d’écrire les parties d’index de texte dans un format que les serveurs plus anciens peuvent encore lire ; le paramètre de compatibilité l’ajuste automatiquement. #111803 (CurtizJ).

Tables système et supervision

  • Renseigne used_storages dans system.query_log avec le nom du moteur de stockage lors de l’interrogation de tables via DataLakeCatalog. #100706 (melvynator).
  • Ajoute les colonnes current_projection, current_projection_progress, projections_completed et projections_remaining à system.merges afin d’exposer la progression des fusions de projections. #102611 (amosbird).
  • Les moteurs de table intègrent désormais de la documentation embarquée, consultable via les nouvelles colonnes description, syntax, examples, introduced_in et related de la table system.table_engines. #106177 (alexey-milovidov).
  • Les moteurs de base de données intègrent désormais de la documentation embarquée, consultable via les nouvelles colonnes description, syntax, examples, introduced_in et related de la table system.database_engines. #106178 (alexey-milovidov).
  • Les types de données intègrent désormais de la documentation embarquée, consultable via les nouvelles colonnes description, syntax, examples, introduced_in et related de la table system.data_type_families. #106180 (alexey-milovidov).
  • Les formats d’entrée/sortie intègrent désormais de la documentation embarquée, consultable via les nouvelles colonnes description, examples, introduced_in et related de la table system.formats. #106181 (alexey-milovidov).
  • Les combinateurs de fonctions d’agrégation intègrent désormais de la documentation embarquée, consultable via les nouvelles colonnes description, syntax, examples, introduced_in et related de la table system.aggregate_function_combinators. #106185 (alexey-milovidov).
  • Ajout d’une nouvelle table system.data_skipping_index_types qui répertorie les types d’index d’évitement de données disponibles, accompagnés de leur documentation embarquée (description, syntax, examples, introduced_in, related). #106186 (alexey-milovidov).
  • Ajout d’une nouvelle table system.disk_types qui répertorie les types de disques disponibles, accompagnés de leur documentation embarquée (description, syntax, examples, introduced_in, related). #106187 (alexey-milovidov).
  • Ajout des métriques asynchrones TotalUncompressedBytesOfMergeTreeTables et TotalUncompressedBytesOfMergeTreeTablesSystem, qui indiquent la taille totale non compressée des données stockées dans les tables de la famille MergeTree. #106364 (alexey-milovidov).
  • Ajoute l’événement de profil GlobalMemoryLimitExceeded afin que les opérateurs puissent surveiller les dépassements de la limite de mémoire globale du serveur. #106466 (sacheendra).
  • Ajout des métriques asynchrones ExecutableUserDefinedFunctionMemoryResidentBytes et ExecutableUserDefinedFunctionProcesses, qui indiquent la mémoire résidente (VmRSS) et le nombre de processus actifs des fonctions définies par l’utilisateur executable et executable_pool, y compris les processus descendants et les workers inactifs du pool. #107300 (HanziJiang).
  • Ajout de show_remote_databases_in_system_tables, activé par défaut, permettant aux utilisateurs de masquer les bases de données MySQL et PostgreSQL de system.tables, system.columns et system.completions. show_data_lake_catalogs_in_system_tables continue de contrôler uniquement la visibilité de DataLakeCatalog. #104416 (pamarcos). #109082 (pamarcos).

ClickHouse Keeper

  • Diverses modifications apportées à Keeper, le rendant globalement environ deux fois plus rapide (meilleur traitement par lots, acheminement en pipeline des messages vers le leader et ajout en pipeline au journal). #101757 (al13n321).
  • Ajout d’événements de profil Keeper supplémentaires (côté serveur et côté client) pour les watches. #105336 (scanhex12).
  • Ajout d’une table system.keeper_snapshots réservée à Keeper, contenant des informations sur les snapshots ClickHouse Keeper locaux. #105571 (mstetsyuk).
  • Ajout d’une table system.keeper_changelogs réservée à Keeper, contenant des informations sur les fichiers changelog (journal Raft) locaux de ClickHouse Keeper. #105617 (mstetsyuk).
  • Ajout d’une table system.keeper_cluster réservée à Keeper. Elle contient une ligne par membre du cluster Raft tel que vu par le Keeper actuel. #105646 (mstetsyuk).
  • Réduction de la consommation maximale de mémoire lors de l’application des snapshots reçus dans ClickHouse Keeper avec KeeperMemoryStorage. #105851 (antonio2368).
  • Ajout de paramètres coordination_settings à Keeper pour limiter l’admission des entrées de journal non validées de NuRaft et réguler les sondes inversées append-entries. #106108 (antonio2368).

Gestion de la mémoire

  • Correction des messages d’erreur de syntaxe susceptibles d’inclure des octets issus de zones mémoire adjacentes après que l’analyseur syntaxique est revenu en arrière au-delà de la fin d’une instruction. #105086 (groeneai).
  • Réduction de l’utilisation de la mémoire lors de l’ouverture d’une sauvegarde (pour RESTORE ou comme base d’un BACKUP incrémentiel). Les métadonnées .backup sont désormais analysées sous forme de flux au lieu d’être chargées dans une arborescence de documents XML en mémoire, ce qui évite, pour les sauvegardes volumineuses (en particulier incrémentielles), d’allouer une arborescence DOM de plusieurs gigaoctets. #109107 (jkartseva).
  • Réduction de l’utilisation maximale de la mémoire lors de la finalisation d’un BACKUP. L’écriture des métadonnées de sauvegarde ne copie plus les informations de tous les fichiers dans un vecteur temporaire (ce qui, pour les sauvegardes contenant des millions de fichiers, nécessitait temporairement plusieurs gigaoctets) ; elles sont désormais parcourues sur place. #109861 (jkartseva).

Formats de données

  • Les utilisateurs peuvent désormais insérer des champs Avro Fixed pour des variantes d’entiers de 8, 16, 32 ou 64 bits. #98139 (patrickpichler).
  • Le format AvroConfluent réessaie désormais le client HTTP de Confluent Schema Registry en cas d’échecs transitoires (dépassements de délai de transport, connexions refusées, erreurs DNS, erreurs HTTP 5xx/408/429) avec un backoff exponentiel, au lieu d’interrompre l’INSERT au premier incident réseau. Les nouveaux paramètres format_avro_schema_registry_max_retries (valeur par défaut : 5) et format_avro_schema_registry_retry_initial_backoff_ms (valeur par défaut : 100) contrôlent cette politique. Les erreurs de validation de schéma (HTTP 409, JSON Avro malformé) restent fatales. #106661 (groeneai).
  • Les codes d’erreur ClickHouse d’origine sont désormais préservés pour les erreurs renvoyées via Apache Arrow. #107267 (azat).

Collections nommées et dictionnaires

  • Ajout du paramètre enable_compression pour la fonction de table mysql, le moteur de table MySQL, le moteur de base de données MySQL, la source de dictionnaire SOURCE(MYSQL) et les collections nommées. Lorsqu’il est activé, ClickHouse négocie la compression au niveau du protocole MySQL pour toutes les données transférées via la connexion. #103229 (bernardlim).
  • Ajout d’une nouvelle table system.dictionary_layouts qui répertorie les layouts de dictionnaire disponibles ainsi que leur documentation intégrée (description, syntax, examples, introduced_in, related). #106182 (alexey-milovidov).
  • Ajout d’une nouvelle table system.dictionary_sources qui répertorie les sources de dictionnaire disponibles ainsi que leur documentation intégrée (description, syntax, examples, introduced_in, related). #106184 (alexey-milovidov).
  • Le type de stockage effectif des collections nommées est désormais disponible sous named_collections_storage.type dans system.server_settings et via getServerSetting('named_collections_storage_type'). #111806 (pamarcos).

Autres améliorations

  • Amélioration des suggestions de noms de tables dans les messages d’erreur : elles ne proposent plus exactement le même nom et incluent le nom de la base de données dans la suggestion (par ex., “Peut-être vouliez-vous dire other_db.my_table ?”). #95116 (matt-metivier).
  • Amélioration du message d’erreur pour les identifiants non résolus dans les requêtes sans clause FROM, afin de suggérer d’en ajouter une. #101769 (Onyx2406).
  • Correction d’un problème où PREWHERE avec une sous-requête IN sur des colonnes de clé primaire n’utilisait pas l’index de clé primaire pour l’élagage des granules, entraînant des parcours complets de la table au lieu de ne lire que les granules pertinents. #102570 (nikitamikhaylov).
  • Les vues matérialisées actualisables continuent désormais de s’actualiser après le remplacement de leur table cible avec EXCHANGE TABLES et la suppression de l’ancienne table. Auparavant, les actualisations pouvaient échouer avec une exception UNKNOWN_TABLE, car elles conservaient l’UUID de l’ancienne table. #102724 (seva-potapov).
  • Activation de enable_join_transitive_predicates par défaut. #103724 (davenger).
  • Les vues matérialisées actualisables prennent désormais en charge REFRESH DEPENDS ON afin de déclencher leur actualisation en fonction de l’actualisation d’une autre RMV, plutôt que selon une planification temporelle. (REFRESH EVERY ... DEPENDS ON existait déjà, mais ne pouvait pas être utilisé de manière fiable dans ce cas d’utilisation.) Consultez la documentation CREATE MATERIALIZED VIEW. #104440 (al13n321).
  • Ajout de l’option EXPLAIN PIPELINE pour compacter les chaînes de processeurs répétées. #104662 (niyue).
  • Ajout de REGEXP_SUBSTR comme alias insensible à la casse de regexpExtract pour assurer la compatibilité avec Oracle, MySQL et Snowflake. #105122 (alexey-milovidov).
  • Ajout de date_part('unit', expr) comme raccourci syntaxique pour EXTRACT(unit FROM expr). Les types d’intervalles standard et les extensions PostgreSQL (epoch, dow, doy, isodow, isoyear, century, decade, millennium) sont tous pris en charge. #105127 (alexey-milovidov).
  • Le QueryConditionCache enregistre désormais individuellement les granules exclues par le filtrage, même dans les lots de lecture qui passent partiellement PREWHERE, réduisant ainsi le nombre de marques relues par les requêtes ultérieures avec la même condition. #105335 (hanfei1991).
  • Ajout de la prise en charge de BFloat16 pour les fonctions de prédicat numérique. #105391 (mohhddhassan).
  • Prise en charge des statistiques de base, des statistiques compactes par colonne qui stockent les valeurs numériques minimales et maximales, la longueur moyenne des chaînes et le nombre de valeurs NULL, le cas échéant. #106048 (hanfei1991).
  • Prise en charge d’un modificateur NULL / NOT NULL final dans ALTER TABLE ... ADD/MODIFY COLUMN, à l’image de CREATE TABLE. #106150 (takumihara).
  • L’optimiseur PREWHERE regroupe désormais les conjonctions qui font référence au même ensemble de colonnes avant d’estimer la sélectivité, afin que des conditions telles que a > 2500 AND a < 2502 soient évaluées conjointement comme une plage combinée (sélectivité d’environ 0,02 %) plutôt que comme deux prédicats indépendants (environ 50 % chacun). Cela permet un ordonnancement plus précis des conditions PREWHERE lorsque des statistiques de colonnes sont disponibles. #106337 (hanfei1991).
  • Le préambule “Trace de pile (lors de la copie de ce message, incluez toujours les lignes ci-dessous) :” n’est plus affiché dans les messages d’exception lorsque la trace de pile est vide. #106524 (alexey-milovidov).
  • Correction de CREATE TABLE ... CLONE AS (and REPLACE / ATTACH PARTITION ... FROM) sur les disques chiffrés, qui copiait les données au lieu de créer des liens physiques. #106731 (nikitamikhaylov).
  • Correction de la lecture des données de table par les bases de données DataLakeCatalog avec catalog_type = 'onelake', qui utilisent désormais par défaut le point de terminaison Blob OneLake (.blob.fabric.microsoft.com). Définissez onelake_use_blob_endpoint = false pour conserver le comportement précédent utilisant le point de terminaison DFS (.dfs.fabric.microsoft.com). #106843 (scanhex12).
  • Réduction de la surcharge CPU de la journalisation asynchrone à des débits de journaux élevés, en notifiant le consommateur de journaux uniquement lors du passage d’une file vide à non vide, plutôt que pour chaque message. #107352 (nikitamikhaylov).
  • Correction de la lecture de la longueur de auth_response dans la négociation initiale MySQL, où un octet de longueur >= 128 était interprété comme une valeur de plusieurs gigaoctets, car lu comme un char signé. #107384 (uwezkhan).
  • MaterializedPostgreSQL associe désormais les colonnes PostgreSQL numeric(p, 0) dont la précision est supérieure à 76 (par ex. numeric(78, 0), utilisé pour les entiers 256 bits) à Int256 de ClickHouse, au lieu d’échouer avec “Precision too big”. Les valeurs qui ne tiennent pas dans Int256 sont rejetées avec une erreur explicite. #107431 (alexey-milovidov).
  • Nullable(Tuple(...)) est désormais en bêta. Désactivé par défaut ; définissez enable_nullable_tuple_type = 1 pour l’utiliser. #107754 (nihalzp).
  • Les insertions asynchrones ne journalisent plus la liste complète des query_id aux niveaux trace/debug, ce qui, depuis la version 26.2, pouvait saturer text_log sur les services traitant un volume important d’insertions asynchrones. Les lignes détaillées sont désormais au niveau test. #107852 (CheSema).
  • Réduction de l’utilisation des métadonnées du cache du système de fichiers grâce à la libération rapide des entrées de priorité invalidées. #107903 (kssenii).
  • Un index de saut bloom_filter sur une colonne Array est désormais utilisé pour arrayJoin(column) IN (set), arrayJoin(column) GLOBAL IN (set) et arrayJoin(column) = const, comme c’était déjà le cas pour hasAny(column, set) et has(column, const). Auparavant, ces formes arrayJoin ... recouraient à un parcours complet. #109536 (groeneai).
  • IS NOT DISTINCT FROM et IS TRUE utilisent désormais les index de clé primaire et minmax pour éliminer des granules, comme =. Auparavant, k IS NOT DISTINCT FROM 42 et (k = 42) IS TRUE parcouraient tous les granules. #110006 (groeneai).

Corrections de bogues

Correctifs JOIN

  • Correction de la fonction nested (utilisée en interne par ARRAY JOIN) qui supprimait LowCardinality des types de colonnes, entraînant la conversion de Array(LowCardinality(String)) en Array(String) dans la sortie. #98974 (Onyx2406).
  • Correction du réordonnancement des jointures qui supprimait silencieusement les lignes sans correspondance d’une jointure RIGHT/LEFT JOIN lorsqu’elle était jointe par virgule (cross join) à une autre table, par exemple t1 RIGHT JOIN t2 ON t1.c = t2.c, t3. La requête renvoyait auparavant le résultat d’une jointure interne au lieu de celui d’une jointure externe. #101684 (groeneai).
  • Correction d’une LOGICAL_ERROR (“Port is not connected”, code 49) susceptible de se produire lors de l’exécution de requêtes impliquant une VIEW avec agrégation dans une JOIN. #102574 (Ergus).
  • Correction de l’ignorance silencieuse de max_rows_to_transfer et max_bytes_to_transfer pour les requêtes GLOBAL IN et GLOBAL JOIN avec le nouvel analyseur. Ces paramètres déclenchent désormais SET_SIZE_LIMIT_EXCEEDED (ou interrompent l’exécution, selon transfer_overflow_mode) lorsque la table externe matérialisée dépasse la limite configurée, conformément au comportement de l’ancien analyseur. #104119 (groeneai).
  • Correction de résultats incorrects ou d’échecs de requêtes JOIN utilisant join_algorithm = 'direct' avec une table MergeTree à droite lorsque l’optimisation réordonnait les colonnes de recherche. #104174 (groeneai).
  • Correction d’un bug où les requêtes combinant arrayJoin avec ORDER BY ... LIMIT après une JOIN pouvaient renvoyer silencieusement zéro ligne. L’optimisation du plan de requête qui remonte l’évaluation des fonctions au-dessus de SortingStep ne s’applique plus lorsque l’expression remontée contient arrayJoin, car arrayJoin peut modifier le nombre de lignes. #104558 (groeneai).
  • Correction d’une erreur logique dans certains cas d’utilisation de LIMIT BY négatif avec ARRAY JOIN. #105403 (nihalzp).
  • Ajout d’un nouveau paramètre de compatibilité analyzer_compatibility_prefer_alias_over_subcolumn (désactivé par défaut). Lorsqu’il est activé, le nouvel analyseur privilégie l’interprétation comme préfixe d’alias plutôt que les correspondances avec des sous-colonnes Tuple ou des colonnes avec point pour les identifiants en plusieurs parties, rétablissant le comportement de l’interpréteur précédent. Cela évite les erreurs AMBIGUOUS_IDENTIFIER (et similaires) lorsqu’une requête joint une table dont le nom correspond à une table interne d’une CTE/sous-requête utilisant SELECT * sur une jointure, où les colonnes renommées par l’astérisque (par exemple b.id) feraient sinon fuiter les identifiants de la table interne dans la portée externe. #105491 (vdimir).
  • Correction de résultats potentiellement incorrects pour les requêtes combinant une jointure externe avec une jointure interne ultérieure référençant le côté de la jointure externe qui fournit les valeurs nulles. Le réordonnancement des jointures pouvait sélectionner un plan qui déplaçait les conditions de jointure interne dans la clause ON de la jointure externe. #105992 (vdimir).
  • Meilleure compatibilité avec l’ancien analyseur. Si la table comporte des colonnes telles que x.a Array, x.b Array, x String, les tableaux sont privilégiés pour ARRAY JOIN x. #106069 (KochetovNicolai).
  • Correction d’une exception pour les requêtes INNER JOIN avec une table MergeTree gauche vide lorsque enable_parallel_replicas, query_plan_use_new_logical_join_step et query_plan_optimize_join_order_algorithm = 'greedy' sont activés. #106338 (KochetovNicolai).
  • Correction d’une erreur logique (Left and right columns have same names) dans l’optimiseur de l’ordre des jointures, susceptible de se produire pour les jointures exécutées avec des répliques parallèles lorsque deux relations du graphe de jointures partagent des noms de colonnes. #106418 (alexey-milovidov).
  • Correction d’une LOGICAL_ERROR (Invalid number of rows in Chunk) dans JoiningTransform pour un LEFT JOIN avec des clés uniques à droite, une condition ON mixte et une faible valeur de max_joined_block_size_rows. #106928 (groeneai).
  • Correction d’une exception (LOGICAL_ERROR) dans le filtre d’exécution des JOIN lorsque la clé de jointure contient un type Variant ou Dynamic imbriqué dans un Tuple, Array ou Map, et que le côté droit de la jointure ne comporte qu’une seule valeur distincte. #106931 (groeneai).
  • Correction d’une LOGICAL_ERROR (Expected the argument N to have X rows, but it has Y) lors de l’exécution d’une fonction sur une colonne Dynamic construite par une JOIN sur Dynamic (par exemple, les lignes non jointes d’un RIGHT/FULL JOIN ou une sous-requête EXISTS corrélée et décorrélée en jointure). #107095 (groeneai).
  • Correction d’une exception d’erreur logique Bad cast from type DB::IColumn const* to DB::ColumnNullable const* lorsqu’un astérisque qualifié (t.*) appliqué à une clé JOIN ... USING est transmis à une fonction d’agrégation et que l’autre côté d’une jointure externe possède une clé Nullable (avec join_use_nulls = 0). #107129 (groeneai).
  • Correction d’une erreur logique (Unexpected return type from equals. Expected Nullable(UInt8). Got UInt8) lorsque l’optimisation de poussée des disjonctions (prédicats partiels) pousse une condition sur une clé USING dont le type est élargi par la JOIN. Correction également d’un plantage du serveur (erreur de segmentation) dans l’analyseur lors de la résolution d’identifiants dans des requêtes JOIN ... USING contenant des branches if/multiIf réductibles en constantes et référençant des identifiants inconnus. #107407 (groeneai).
  • Correction du filtre d’exécution des JOIN qui produisait des résultats incorrects pour les colonnes JSON. #107663 (Avogar).
  • Correction d’une exception d’erreur logique Bad cast from type DB::ColumnNullable to DB::ColumnVector<...> lorsqu’un astérisque qualifié (t.*) sélectionne une clé JOIN USING et que cette jointure est imbriquée sous une jointure PASTE/CROSS/par virgule ou une jointure externe ON, avec join_use_nulls = 0. #108043 (groeneai).
  • Correction d’un bogue dans le nouvel analyseur où FINAL sur une table d’une JOIN (par ex. FROM t1 FINAL JOIN t2) était également appliqué à tort aux autres tables jointes, ce qui pouvait ralentir ces requêtes. #108979 (vdimir).
  • Avec analyzer_compatibility_join_using_top_level_identifier = 1, un identifiant dans JOIN ... USING peut désormais être résolu à partir d’un alias défini sur une sous-expression de la liste SELECT (par exemple, SELECT uniqExact(lower(x) AS id) FROM t1 JOIN t2 USING (id)), conformément au comportement de l’ancien analyseur. Auparavant, seuls les alias de projection de niveau supérieur étaient pris en compte, et ces requêtes échouaient avec une exception UNKNOWN_IDENTIFIER même avec le paramètre activé. L’indication d’erreur suggérant ce paramètre est désormais également produite lorsque l’alias correspondant est imbriqué. #110739 (novikd).
  • Correction de l’erreur INCOMPATIBLE_TYPE_OF_JOIN pour une jointure ANY sur une table utilisant le moteur Join, lorsqu’un filtre WHERE sur une colonne du côté droit permettait au planificateur de requêtes de réécrire la jointure en SEMI ou ANTI. Une table du moteur Join possède une strictness déclarée fixe qui ne peut pas être modifiée ; la conversion est donc désormais refusée pour ces tables. #111362 (groeneai).
  • Correction de TYPE_MISMATCH (“Le type de clé pour une clé complexe … ne correspond pas”) lorsqu’une JOIN avec un dictionnaire utilise une clé de jointure Nullable, LowCardinality ou LowCardinality(Nullable), alors que la clé du dictionnaire n’est pas encapsulée. La recherche dans le dictionnaire pour les jointures directes normalise désormais la clé selon le type de clé déclaré du dictionnaire (comme le font déjà dictGet/dictHas), et une clé NULL ne correspond jamais. #111857 (groeneai).
  • Correction de AMBIGUOUS_COLUMN_NAME (Incompatibilité de structure de block dans (les colonnes portant le même nom doivent avoir une structure identique)) pour une requête qui répète une condition JOIN ON dans WHERE avec join_use_nulls = 1. Une telle requête renvoie désormais son résultat au lieu d’échouer. #112007 (groeneai).
  • Correction de résultats incorrects ou de l’arrêt du serveur pour des JOIN directs avec un dictionnaire dont la clé utilise une sérialisation creuse. #112327 (groeneai).
  • Correction de résultats incorrects lorsqu’une jointure par hash possède une seule clé LowCardinality d’un type dépassant 8 octets (UInt128, Int128, UInt256, Int256 et leurs variantes Nullable). Une telle jointure renvoyait silencieusement des lignes dont les valeurs de clé ne sont pas égales. #113230 (groeneai).
  • Correction de l’élagage des parts et des granules pour une condition JOIN ON impliquant des colonnes constantes de l’autre côté. #113484 (vdimir).
  • Correction d’une valeur erronée renvoyée pour une colonne virtuelle telle que _table ou _database, sélectionnée du côté droit d’une JOIN traitée par DirectKeyValueJoin (un stockage clé-valeur tel que EmbeddedRocksDB, KeeperMap, Redis ou un dictionnaire). La requête renvoyait à la place le contenu d’une colonne de données, ou échouait avec LOGICAL_ERROR. #113698 (groeneai).

Correctifs apportés aux requêtes et à l’analyseur

  • Corrige un bogue où splitMultipartQuery levait une erreur “Requête vide” pour les requêtes se terminant par un commentaire après un point-virgule. #85491 (yariks5s).
  • Corrige le cas où un alias placé après une sous-requête dans DESCRIBE TABLE n’était pas accepté par l’analyseur syntaxique, ce qui entraînait une erreur de syntaxe. #100205 (yariks5s).
  • Corrige le fait que la clause FORMAT était consommée par INSERT au lieu de s’appliquer à la sortie de EXPLAIN dans EXPLAIN INSERT INTO ... SELECT ... FORMAT .... #101772 (Onyx2406).
  • Corrige le ralentissement important des requêtes SELECT lors de l’exécution d’INSERT concurrents. Auparavant, un pipeline INSERT réservait des créneaux CPU jusqu’à max_threads au démarrage de la requête, même si la plupart n’étaient jamais utilisés, privant ainsi les SELECT concurrents de ressources. L’allocation des créneaux CPU est désormais à la demande : le pipeline ne demande des créneaux qu’à mesure qu’il soumet du travail parallélisable. Cela s’applique tant au contrôle de concurrence qu’à l’ordonnanceur CPU préemptif des charges de travail. Le nouveau paramètre serveur concurrent_threads_lazy_allocation (valeur par défaut : true) permet de revenir au comportement précédent. #102928 (seva-potapov).
  • Corrige un bogue où ALTER TABLE ... MODIFY SETTING sur une table EmbeddedRocksDB pouvait enregistrer une valeur de paramètre non valide dans le fichier de métadonnées de la table, même lorsque le serveur rejetait la requête. Au redémarrage suivant du serveur, la table ne pouvait pas être attachée en raison de CANNOT_PARSE_BOOL (ou d’une erreur d’analyse similaire) et, dans les bases de données où les échecs de chargement sont fatals, le serveur refusait de démarrer. Les valeurs de paramètre non valides sont désormais rejetées avant toute écriture de métadonnées. #103417 (groeneai).
  • Corrige les INSERT en continu avec input_format_max_block_wait_ms pour l’interface HTTP et INSERT SELECT FROM input, afin que les blocs d’entrée partiels soient vidés avant la fin de la requête. #104534 (alexey-milovidov).
  • Corrige l’expression CASE, qui renvoyait la branche ELSE au lieu de la branche THEN correspondante lorsque l’expression et une valeur WHEN étaient toutes deux NULL. #105556 (Algunenano).
  • Corrige la prise en charge des UDF SQL WASM dans les définitions de MATERIALIZED VIEW. #106161 (niyue).
  • Corrige INTERPOLATE (), qui levait INVALID_WITH_FILL_EXPRESSION lorsque des colonnes ORDER BY recevaient des alias dans la liste SELECT avec l’ancien analyseur. #106252 (yakov-olkhovskiy).
  • Les fonctions base58Encode, base58Decode et tryBase58Decode respectent désormais max_execution_time et l’annulation des requêtes pour les entrées volumineuses, et rejettent les entrées de plus de 10 KB au lieu de s’exécuter pendant très longtemps. La limite est configurable via le nouveau paramètre function_base58_max_input_size (0 la désactive). #106428 (alexey-milovidov).
  • Corrige un bogue produisant des résultats incorrects : WHERE c0 = const ne renvoyait aucune ligne pour les tables avec ORDER BY f(c0) lorsque f(const) s’évalue à NaN, par exemple ORDER BY sqrt(c0) avec une constante négative. L’analyse de la clé primaire écartait incorrectement chaque granule et corrompait le cache des conditions de requête pour les requêtes suivantes. #106507 (groeneai).
  • Correction de résultats incorrects pour SELECT c, count() FROM t WHERE c GROUP BY c sur des tables utilisant la projection implicite _minmax_count_projection, une projection d’agrégat explicite ou une projection standard : tous les groupes étaient auparavant fusionnés en une seule ligne avec une clé constante et le nombre total de lignes. #106590 (groeneai).
  • FORMAT s’applique désormais aussi à la sortie de EXPLAIN dans EXPLAIN ... INSERT ... SELECT ... FORMAT ..., y compris lorsque SETTINGS précède FORMAT ou que le format de sortie est Values. #106686 (alexey-milovidov).
  • Correction d’une rare erreur parasite RESOURCE_ACCESS_DENIED (“Scheduler queue with resource request is about to be destructed”) pour une requête qui avait effectivement obtenu l’accès à une ressource de charge de travail, causée par la réutilisation d’un objet de requête local au thread qui conservait l’échec d’une requête précédente. #106690 (alexey-milovidov).
  • Correction de match, extract, extractAll et countMatches, qui renvoyaient des résultats incorrects pour des expressions régulières contenant des séquences d’échappement hexadécimales ou octales. #106709 (ofeliacode).
  • Correction d’un sous-dépassement d’entier dans l’analyseur du protocole filaire PostgreSQL : un message dont le champ de longueur était inférieur à 4 provoquait un dépassement par retour à zéro de size - 4 et un resize/ignore surdimensionné. #107485 (uwezkhan).
  • Avec enable_analyzer = 1 (valeur par défaut), l’interrogation d’une table par son nom non qualifié, lorsqu’elle n’existe que dans une autre base de données, suggère désormais la bonne table. Par exemple, SELECT * FROM functions renvoie Maybe you meant system.functions?. Auparavant, le nouvel analyseur renvoyait l’erreur Unknown table expression identifier sans suggestion, tandis que l’ancien analyseur proposait déjà cette suggestion utile. #107550 (groeneai).
  • Correction d’un arrêt du serveur (std::terminate, signal 6) lors de l’arrêt d’une requête utilisant un plan distribué (make_distributed_plan = 1), lorsqu’une vérification de l’état d’un worker ne parvenait pas à planifier la vérification suivante (par exemple CANNOT_SCHEDULE_TASK lors de l’arrêt ou MEMORY_LIMIT_EXCEEDED). La requête échoue désormais proprement et le serveur continue de fonctionner. #107575 (groeneai).
  • Correction de résultats incorrects dans des requêtes distribuées sélectionnant des colonnes ALIAS partageant une sous-expression commune : les colonnes pouvaient être mal alignées et les valeurs renvoyées sous la mauvaise colonne. #107675 (vdimir).
  • Correction d’une erreur logique Inconsistent AST formatting pour une fonction fenêtre sans argument dans une déclaration de CODEC ou de moteur (par ex. CODEC(cume_dist() OVER (...))) ; cette fonction conserve désormais ses parenthèses afin que la requête résiste à un aller-retour de formatage/analyse. #107806 (alexey-milovidov).
  • getClientHTTPHeader est désormais correctement traité comme non déterministe, de sorte que son résultat n’est plus réutilisé à tort par le cache de résultats de requête. #108029 (alexey-milovidov).
  • Correction de résultats incorrects lors de l’utilisation de SELECT [...] SAMPLE [...] avec le cache de conditions de requête (paramètre use_query_condition_cache = 1, qui est aussi la valeur par défaut). #108488 (groeneai).
  • Correction de NOT_FOUND_COLUMN_IN_BLOCK lorsqu’un prédicat composé reçoit un alias dans GROUP BY puis est de nouveau référencé, avec enable_identifier_resolve_cache activé (valeur par défaut). L’optimisation optimize_and_compare_chain n’était pas idempotente, et un nœud résolu partagé accumulait un conjonctif transitif en double. #108553 (groeneai).
  • Correction de l’erreur NUMBER_OF_COLUMNS_DOESNT_MATCH lorsqu’une sous-requête sur une table Distributed lit au moins deux colonnes ALIAS qui se développent en la même expression (par exemple a1 String ALIAS toString(x), a2 String ALIAS toString(x)) et alimente une requête externe, par ex. SELECT count() FROM (SELECT a1, a2 FROM dist GROUP BY a1, a2). #108725 (groeneai).
  • Correction de l’erreur UNKNOWN_IDENTIFIER avec ALTER TABLE ... DROP COLUMN lorsqu’une autre colonne possède une expression DEFAULT ou MATERIALIZED qui définit et référence un alias intégré. #109374 (alexey-milovidov).
  • Correction de system.tables, qui ignorait silencieusement des bases de données pour les utilisateurs disposant d’autorisations par base de données lorsque la requête ne lisait que les colonnes name/database. Introduit dans la version 26.2. #109723 (samay-sharma).
  • Correction de l’erreur UNKNOWN_IDENTIFIER pour les colonnes qualifiées par le nom d’une CTE (cte_name.column) dans les requêtes stockées dans des vues lorsque l’analyseur est activé. #111386 (novikd).
  • Correction de NOT_FOUND_COLUMN_IN_BLOCK lorsqu’une requête FINAL filtre sur une colonne de la clé de tri absente de la liste SELECT et que le filtre est déplacé vers PREWHERE (par exemple SELECT s FROM t FINAL WHERE k GROUP BY s avec optimize_move_to_prewhere_if_final = 1). #111721 (groeneai).
  • Correction de l’échec du démarrage du serveur et de ATTACH avec WITH RECURSIVE is not supported with the old analyzer pour une vue contenant une CTE récursive lorsque enable_analyzer = 0 est la valeur par défaut du serveur. #112784 (evillique).
  • Correction de la propagation des paramètres de requête et de la gestion des valeurs NULL dans accurateCastOrDefault. #114912 (alexey-milovidov).
  • Correction de read_rows, read_bytes, written_rows et written_bytes dans system.query_thread_log, qui rapportaient un total cumulé sur la durée de vie d’un thread au lieu des valeurs de la requête enregistrée. Les lignes des threads regroupés à longue durée de vie, en particulier le thread HTTPHandler ayant initié la requête, étaient affectées. #115596 (groeneai).

Correctifs liés à MergeTree et au stockage

  • Les parties détachées portant le suffixe tryN peuvent désormais être supprimées. #58957 (antaljanosbenjamin).
  • Correction d’une exception MULTIPLE_EXPRESSIONS_FOR_ALIAS pour les requêtes comportant des alias de projections en double (par exemple SELECT *, day + 365 AS day) dans des sous-requêtes imbriquées exécutées avec des répliques parallèles. #80310 (alexey-milovidov).
  • Correction d’une sélection incorrecte du codec de compression pour les parties MergeTree lorsque le paramètre de table default_compression_codec était explicitement configuré. Les parties écrites lors des insertions, des fusions et pour les projections utilisaient le codec par défaut du serveur au lieu du paramètre de table (cela couvre désormais également la partie vide produite par une mutation supprimant toutes les données). #101784 (Onyx2406).
  • Correction des erreurs MULTIPLE_EXPRESSIONS_FOR_ALIAS levées par des répliques distantes lors de l’exécution, avec des répliques parallèles et parallel_replicas_local_plan = 0, de requêtes référençant des alias de projections dans PREWHERE / WHERE / HAVING / QUALIFY (par ex. SELECT x AS a, y AS b, (a AND b) AS c FROM t PREWHERE c) ou de requêtes SELECT * sur des auto-jointures comportant des noms de colonnes en commun. #103806 (groeneai).
  • Correction d’une partie de correctif corrompue après ALTER TABLE ... DROP PARTITION ID 'patch-...', suivi de DETACH/ATTACH TABLE. Auparavant, la partie de couverture vide était écrite sans partition.dat ni source_parts.dat, ce qui entraînait l’apparition d’une entrée broken-on-start_patch-... dans system.detached_parts après l’attachement suivant ou le redémarrage du serveur. #104353 (groeneai).
  • Correction du remplacement silencieux de données par des valeurs par défaut lorsque ALTER TABLE ... RENAME COLUMN s’exécutait simultanément avec OPTIMIZE TABLE ... FINAL ou une autre fusion en arrière-plan. #104822 (groeneai).
  • Correction de deux cas de LOGICAL_ERROR: Reading from materialized CTE 'X' before it has been materialized levés par des requêtes avec enable_materialized_cte : (1) une CTE matérialisée réutilisée et filtrée par IN (subquery) sur une autre CTE matérialisée, et (2) une CTE matérialisée référencée à la fois directement et dans un filtre WHERE ... IN (...) qui accède à une clé primaire MergeTree via une sous-requête IN imbriquée. EXPLAIN sur ces mêmes requêtes était également affecté, car les bogues se déclenchaient lors de l’optimisation du plan. #105041 (novikd).
  • Avec skip_cache_on_disk_failure = 1, les requêtes se poursuivent désormais lorsque FileCache ne parvient pas à créer un répertoire de cache sur disque. L’échec est journalisé au lieu de faire échouer la requête. #105250 (Diskein).
  • Correction de l’exception d’erreur logique Mutation of Memory table produced incomplete output levée par ALTER TABLE <memory_table> APPLY PATCHES et ALTER TABLE <memory_table> APPLY DELETED MASK. Les tables Memory ne possèdent pas de parties de correctif ni de masques de suppression ; les deux commandes sont donc désormais correctement traitées comme des opérations sans effet. #105286 (groeneai).
  • Correction de CANNOT_CONVERT_TYPE pour Merge sur Merge sur Distributed avec distributed_group_by_no_merge=1. #105330 (azat).
  • Correction de singleValueOrNullMerge, qui renvoyait une valeur concrète au lieu de NULL lors de la fusion d’un état ayant déjà observé plusieurs valeurs distinctes. #105734 (fallintoplace).
  • Corrige un plantage dans la fonction de table mongodb, le stockage MongoDB et la source de dictionnaire MongoDB lorsque le nom de la collection est vide ou contient des octets NUL. #105776 (Algunenano).
  • Corrige le rejet de ALTER TABLE ... CLEAR COLUMN pour les colonnes columns_to_sum explicitement définies de SummingMergeTree et CoalescingMergeTree. #105785 (antonio2368).
  • Corrige les erreurs UNKNOWN_DATABASE lors de la création d’une vue paramétrée dont le nom de la base de données est fourni par un paramètre de requête. #105799 (groeneai).
  • Rétablit l’optimisation de lecture dans l’ordre pour les tables Merge lors de l’utilisation de l’analyseur. #105867 (KochetovNicolai).
  • Corrige les mutations UPDATE et DELETE sur les tables Iceberg accessibles via un catalogue, y compris les mises à jour et suppressions répétées qui ne correspondent à aucune ligne. #106111 (scanhex12).
  • Corrige le fait que optimize_skip_unused_shards ne s’appliquait pas (et que force_optimize_skip_unused_shards échouait à tort) lorsqu’une table Distributed est interrogée via une table Merge ou la fonction de table merge, avec le prédicat appliqué au niveau supérieur. #106250 (KochetovNicolai).
  • Corrige une erreur logique Column identifier ... is already registered lorsqu’un prédicat de mutation (DELETE/UPDATE) contient une sous-requête IN/EXISTS qui lit une expression de table par défaut imbriquée dans une autre sous-requête. #106414 (alexey-milovidov).
  • Corrige des résultats parfois incorrects pour les requêtes ORDER BY ... DESC lors de la lecture en ordre inverse de parties larges avec read_in_order_use_virtual_row_per_block = 1 et une faible valeur de max_block_size. #106429 (vdimir).
  • Corrige une exception Bad cast exception pour les dictionnaires Redis utilisant STORAGE_TYPE 'simple' avec une disposition cache/direct et une clé complexe constituée d’une seule chaîne ; ces dictionnaires fonctionnent désormais, et les clés composites avec le stockage simple signalent une erreur explicite. #106501 (vdimir).
  • Corrige l’exception Mutation of Memory table produced incomplete output levée par les commandes ALTER TABLE <memory_table> n’ayant aucun effet sur les données ligne par ligne d’un moteur Memory, notamment APPLY PATCHES, APPLY DELETED MASK, MATERIALIZE STATISTICS, MATERIALIZE INDEX, MATERIALIZE PROJECTION et REWRITE PARTS. Les tables Memory ne possèdent pas ces structures ; ces commandes sont donc désormais traitées comme des opérations sans effet. #106621 (groeneai).
  • Corrige l’échec du démarrage du serveur avec Too many marks in file ...skp_idx_idx.cmrk4, marks expected 0 (bytes size 0) lorsqu’une table MergeTree comporte une partie d’index de saut avec zéro granule et un fichier de marques non vide sur le disque. #106675 (groeneai).
  • Corrige le cas où les répliques parallèles n’étaient pas appliquées à une vue avec UNION en raison d’une table vide dans l’UNION. #106900 (devcrafter).
  • Corrige une exception d’erreur logique conflicted_part_name.has_value() pouvant survenir lors d’un insert synchrone dans une table ReplicatedMergeTree lorsque le bloc inséré était entièrement dédupliqué et que le nœud de déduplication de la part en conflit avait déjà été supprimé (par exemple par un DROP PARTITION concurrent). #107026 (groeneai).
  • Corrige la rare LOGICAL_ERROR “Tentative de libérer un contexte de requête inexistant” et le crash du serveur associé lors de la lecture de tables MergeTree via un disque de cache du système de fichiers créé avec enable_filesystem_query_cache_limit = 1. #107028 (groeneai).
  • Corrige un crash du serveur lors du déplacement d’une part vide vers un disque plain_rewritable (par exemple avec ALTER TABLE ... MOVE PARTITION ... TO DISK pour une part vide conservée avec remove_empty_parts = 0). #107040 (groeneai).
  • Corrige une exception Logical error: Too large size passed to allocator lors d’un INSERT dans une table MergeTree lorsque adaptive_write_buffer_initial_size est défini sur une valeur extrêmement élevée. La taille initiale du tampon d’écriture adaptatif est désormais plafonnée à la taille maximale du tampon. #107104 (groeneai).
  • Corrige les lots ALTER TABLE ... ON CLUSTER mélangeant MODIFY SETTING/RESET SETTING et une modification de commentaire (par exemple MODIFY COMMENT 'x', MODIFY SETTING old_parts_lifetime = 123), qui n’étaient appliqués que sur la réplique leader, laissant les autres répliques désynchronisées. Corrige également un MODIFY COLUMN ... COMMENT positionnel ou avec SETTINGS par colonne, qui était à tort considéré comme une modification locale des métadonnées limitée au commentaire, excluant ainsi le réordonnancement des colonnes des métadonnées répliquées et pouvant provoquer INCOMPATIBLE_COLUMNS au redémarrage d’une réplique. #107142 (groeneai).
  • Corrige l’erreur Argument ... of GROUPING function is not a part of GROUP BY clause pour les requêtes utilisant la fonction grouping avec le paramètre group_by_use_nulls activé. #107206 (KochetovNicolai).
  • Corrige les requêtes UPDATE légères avec les anciennes répliques parallèles activées sur des tables MergeTree non répliquées. #107246 (groeneai).
  • Corrige une possible exception d’erreur logique dans SYSTEM SYNC DATABASE REPLICA … STRICT et garantit que le modificateur STRICT prend réellement effet pour les répliques de base de données. #107344 (PedroTadim).
  • Corrige Logical error: 'Duplicate announcement received for replica number N', qui pouvait survenir avec des répliques parallèles lorsqu’une sous-requête scalaire contenait des sous-requêtes imbriquées lisant la même table. #107381 (groeneai).
  • Corrige une perte silencieuse de données sur MergeTree simple (non répliqué) lorsque REPLACE PARTITION, MOVE PARTITION, DETACH PARTITION ou DETACH PART est exécuté sur une partition comportant encore des correctifs UPDATE légers non appliqués. Ces opérations rejettent désormais la commande (comme le fait déjà ReplicatedMergeTree) et indiquent d’utiliser ALTER TABLE ... APPLY PATCHES, au lieu d’annuler silencieusement la mise à jour validée. #107386 (groeneai).
  • Corrige l’arrêt silencieux de la réplication des modifications par MaterializedPostgreSQL lorsque le nom de la base de données ou de la table PostgreSQL contient des lettres majuscules (le consommateur pgoutput demandait un nom de publication non entre guillemets et en minuscules, qui ne correspondait pas à la publication préservant la casse). #107423 (alexey-milovidov).
  • Corrige l’erreur THERE_IS_NO_COLUMN lorsque optimize_if_transform_strings_to_enum = 1 et que l’expression optimisée if/transform appliquée à des littéraux de chaînes est une clé de GROUP BY ou ORDER BY sur une table Distributed ou des répliques parallèles. #107455 (groeneai).
  • Corrige le fait que SELECT ... FINAL et OPTIMIZE TABLE ... FINAL renvoyaient des lignes dupliquées après l’adoption, par CREATE TABLE ... CLONE AS, ATTACH PARTITION ... FROM ou MOVE PARTITION ... TO TABLE, de parts issues d’une MergeTree simple dans une ReplacingMergeTree, SummingMergeTree ou AggregatingMergeTree. Le niveau de fusion de la part adoptée est désormais réinitialisé à 0 lorsque les moteurs source et de destination diffèrent, afin qu’elle soit dédupliquée lors de la fusion suivante. #107481 (groeneai).
  • Le suivi de l’annulation des requêtes est désormais amélioré lors de l’attente du quorum dans ReplicatedMergeTree. #107513 (nickitat).
  • Prend désormais en compte, dans le memory tracker, la mémoire utilisée par la bibliothèque rapidjson (dans prettyPrintJSON, JSONMergePatch et l’analyseur JSON de rapidjson), afin que les entrées pathologiques soient rejetées avec MEMORY_LIMIT_EXCEEDED au lieu d’entraîner des allocations sans limite. #107555 (Algunenano).
  • Corrige une Logical error: Stream ... variant_discr ... is not found pouvant se produire lors de la fusion ou de la lecture d’une part MergeTree produite par la mutation d’une table comportant une colonne Dynamic. #107562 (alexey-milovidov).
  • Corrige une LOGICAL_ERROR (updateFormatPrewhereInfo called more than once) levée lors de l’interrogation d’une source file(), url() ou de stockage d’objets avec un PREWHERE explicite et un WHERE, lorsque optimize_prewhere_after_pushdown était activé. #107568 (groeneai).
  • Corrige une exception du serveur (erreur logique Digest does not match) pouvant survenir avec RENAME TABLE, RENAME DATABASE ou CREATE OR REPLACE TABLE impliquant une table TimeSeries dans une base de données Replicated. Le renommage d’une table TimeSeries est désormais pris en charge. #107583 (groeneai).
  • Corrige DROP TABLE sur une table TimeSeries dans une base de données Replicated, qui laissait auparavant les tables internes et faisait réessayer indéfiniment la tâche de suppression en arrière-plan (DROP TABLE ... SYNC se bloquait). #107604 (groeneai).
  • Corrige deux vulnérabilités de traversée de répertoires dans le protocole de récupération des parts répliquées, qui pouvaient permettre à une réplique malveillante d’écrire des fichiers en dehors du répertoire de la part. #107606 (antonio2368).
  • Corrige ALTER TABLE ... REPLACE PARTITION sur une table MergeTree simple, qui faisait réapparaître les parts remplacées après un redémarrage du serveur, entraînant le renvoi par la table à la fois des lignes de remplacement et des anciennes lignes remplacées. #107623 (groeneai).
  • Corrige une LOGICAL_ERROR (“Block structure mismatch … between ConvertingTransform and RemovingReplicatedColumnsTransform”) lors de l’insertion dans une vue matérialisée dont la table cible TO déclare une colonne avec un Enum plus large que celui produit par le SELECT de la vue. L’élargissement valide de l’Enum est désormais appliqué lors de l’insertion dans la vue matérialisée, comme pour un INSERT ... SELECT direct. #107648 (groeneai).
  • Correction de l’erreur NUMBER_OF_COLUMNS_DOESNT_MATCH lors de l’interrogation d’une table Distributed (ou de l’utilisation de répliques parallèles) comportant plusieurs colonnes ALIAS qui se développent en une même expression et sont référencées avec ORDER BY/GROUP BY/HAVING. #107913 (yakov-olkhovskiy).
  • Une erreur transitoire lors de l’actualisation des parties de données d’une table en lecture seule n’interrompt plus définitivement la tâche d’actualisation en arrière-plan. #108034 (alexey-milovidov).
  • index_granularity_bytes est désormais respecté pour les colonnes contenant des états AggregateFunction. Auparavant, la limite de taille des granules en octets était ignorée pour ces colonnes (par exemple, les états uniqExact dans les tables AggregatingMergeTree et les projections d’agrégation), ce qui produisait des granules bien plus grands que la limite configurée et augmentait l’amplification des lectures ainsi que la mémoire utilisée lors des requêtes. #108297 (groeneai).
  • Correction de insert_quorum = 'auto', qui ne rejetait pas immédiatement les insertions lorsque moins de la majorité des répliques étaient actives. Ces insertions échouent désormais immédiatement avec TOO_FEW_LIVE_REPLICAS au lieu d’écrire une partie locale, puis d’expirer avec UNKNOWN_STATUS_OF_INSERT. #108800 (gagandhakrey).
  • Correction d’un plantage du serveur lors d’une insertion asynchrone avec déduplication lorsque optimize_on_insert vide le bloc inséré (par exemple, des lignes dont la somme est nulle dans SummingMergeTree). #109229 (Diskein).
  • Correction de la perte de données d’une colonne sans expression par défaut lorsqu’une fusion s’exécute simultanément avec ALTER TABLE ... RENAME COLUMN, ou lorsque les seules valeurs de la colonne proviennent d’un UPDATE léger. La colonne pouvait être supprimée de la partie fusionnée, de sorte que toutes ses valeurs étaient lues comme NULL. #109356 (groeneai).
  • Correction d’un arrêt rare du serveur lors de la fusion en parallèle d’états d’agrégat uniqExact avec GROUPING SETS, ROLLUP ou CUBE. #109389 (groeneai).
  • Correction des fusions de rollup qui étaient replanifiées indéfiniment. #109410 (Michicosun).
  • Correction des mutations GROUP BY pour les tables dotées de colonnes virtuelles matérialisées ou persistantes. #109532 (Michicosun).
  • Correction de l’erreur UNKNOWN_IDENTIFIER: Missing columns: '_block_offset' lors de l’exécution de ALTER TABLE ... MATERIALIZE INDEX sur l’index minmax implicite créé par add_minmax_index_for_block_number_column/add_minmax_index_for_block_offset_column pour une table comportant des parties fraîchement insérées (niveau 0). L’index est désormais créé pour ces parties au lieu de provoquer un échec. #110236 (groeneai).
  • Correction d’une réplique de stockage d’objets en lecture seule (un disque configuré avec read_only = true) qui ne détectait pas les nouvelles parties via refresh_parts_interval, ainsi que de table_disk = true, qui était rejeté sur un tel disque avec “table_disk is not supported for non-ObjectStorage disks”. #110460 (jkartseva).
  • Correction d’une LOGICAL_ERROR (“No set is registered for key”) dans les mutations ALTER TABLE … DROP COLUMN, ALTER TABLE … DELETE/UPDATE et DELETE léger, sur les tables comportant une colonne ALIAS dont l’expression utilise l’opérateur IN, y compris via une autre colonne ALIAS. #111039 (PedroTadim).
  • Corrige les cas où une politique de lignes n’était pas appliquée aux projections MergeTree lors de l’exécution des requêtes. #112329 (yariks5s).
  • Corrige l’erreur logique ReadBufferFromEncryptedFile: Wrong file position lors de la lecture d’une partie Compact depuis un disque encrypted avec des E/S directes, qui bloquait les fusions dans system.replication_queue. #112943 (alexey-milovidov).
  • Corrige la lecture de la base de données interne _temporary_and_external_tables via la fonction de table merge et le moteur de table Merge, qui permettait à une session de lire les tables temporaires d’autres sessions et d’autres utilisateurs, et provoquait une exception lors de l’utilisation de l’ancien analyseur. Une expression régulière de base de données exclut désormais cette base, et la nommer explicitement est refusé, tout comme l’accès direct à celle-ci. #113224 (alexey-milovidov).
  • Corrige le fait qu’une politique de lignes contenant une sous-requête scalaire n’était évaluée qu’une seule fois, puis réutilisée indéfiniment après lecture de la table via une table Merge. La condition de politique analysée est mise en cache et partagée par toutes les requêtes, et sa lecture via Merge réécrivait l’expression en cache sur place, ce qui provoquait également une course de données entre des requêtes concurrentes utilisant la même politique. #113563 (alexey-milovidov).
  • Corrige les erreurs CANNOT_CONVERT_TYPE lors de la lecture d’une table Merge contenant une table Distributed avec des répliques parallèles utilisant une clé personnalisée. #113742 (alexey-milovidov).
  • Corrige l’erreur Logical error: No set is registered for key ... lors de la lecture via une table Merge dont une table enfant déclare une colonne ALIAS contenant IN et dont les tables enfants n’ont pas la même valeur par défaut pour cette colonne. #113757 (groeneai).
  • Corrige un contournement de politique de lignes où la fonction de table mergeTreeIndex exposait les valeurs de la clé primaire et de l’index minmax des lignes masquées par une politique de lignes SELECT sur la table source ; la lecture de mergeTreeIndex pour une table dotée d’une politique de lignes est désormais refusée. #115304 (yariks5s).

Correctifs liés aux types de données et à la sérialisation

  • Correction d’une exception dans ARRAY JOIN lors de l’utilisation de types numériques LowCardinality. #91784 (Ergus).
  • Correction de la création silencieuse de colonnes NOT NULL en tant que Nullable lorsque data_type_default_nullable = 1 et que la table est créée dans une base de données Replicated ou via ON CLUSTER. #97572 (xiaohuanlin).
  • Correction d’un nombre de lignes incorrect renvoyé par une requête sur une MaterializedView avec query_plan_enable_optimizations = 0 lorsque la vue associe une colonne integer à une colonne Bool. #100692 (Maximus5).
  • Correction de métadonnées de parties incohérentes après des mutations de colonnes utilisant des sérialisations non par défaut. #102817 (korowa).
  • Correction de la propagation de NULL lors de la lecture de sous-colonnes extraites de colonnes Nullable(Tuple(...)). Par exemple, pour tup Nullable(Tuple(s Nullable(String))), SELECT tup.s renvoie désormais correctement NULL dans les lignes où le tuple externe est NULL, au lieu de valeurs indésirables. Cela couvre tous les types d’éléments pouvant représenter NULL : Nullable, Dynamic, Variant et LowCardinality(Nullable(...)). #102942 (nihalzp).
  • Correction de recursiveRemoveLowCardinality, qui supprimait les noms personnalisés de types géométriques (par ex. LineString au lieu de Ring, MultiLineString au lieu de Polygon), entraînant une mauvaise interprétation du type géométrique. #103041 (jh0x).
  • Correction de dictGetOrNull, qui écrasait silencieusement d’autres colonnes de la projection SELECT par NULL lorsqu’il était appelé avec une colonne clé Nullable dont les valeurs sont absentes du dictionnaire. La fonction modifiait sur place une map de valeurs nulles aliasée en entrée ; elle effectue désormais une copie profonde de la colonne de résultat avant de la modifier. #104327 (groeneai).
  • Correction d’une exception pour des requêtes distribuées contenant un tuple IN vide sur la clé de partitionnement lorsque optimize_skip_unused_shards_rewrite_in est activé. #104966 (alexey-milovidov).
  • Correction de l’estimation de la sélectivité PREWHERE des statistiques count-min pour les colonnes Float32, y compris lors de comparaisons avec des littéraux Float64. #105047 (hanfei1991).
  • Correction de ILLEGAL_TYPE_OF_ARGUMENT lors de la fusion des états d’agrégat quantileExactWeightedInterpolated, quantileDD ou quantilePrometheusHistogram avec leurs équivalents au pluriel quantilesXxxMerge (et inversement). Les variantes au singulier et au pluriel de ces trois familles de quantiles partagent le même état d’agrégat interne, mais n’étaient pas répertoriées dans la table interne de mappage des noms ; la fusion d’états entre fonctions — ainsi que l’optimisation de fusion de fonctions pour ces familles — était donc rejetée. #105189 (groeneai).
  • Correction des résultats incorrects de toStartOfWeek, toLastDayOfWeek, toMonday, toStartOfMonth, toLastDayOfMonth, toStartOfQuarter et toStartOfYear pour les arguments Date32 et DateTime64 dont le résultat se situe hors de la plage Date : au lieu de déborder sur des dates arbitraires, les résultats antérieurs au 1970-01-01 sont désormais bornés à 1970-01-01 et ceux postérieurs au 2149-06-06 à 2149-06-06. Corrige également les résultats de requête erronés (parties et granules incorrectement élagués) lorsque ces fonctions étaient utilisées dans WHERE sur une clé Date32 ou DateTime64 contenant des valeurs hors plage. #105244 (yariks5s).
  • Correction d’une erreur logique dans arrayRemove lorsque le premier argument est un tableau de Variant dont toutes les alternatives sont incompatibles avec le type du second argument et que variant_throw_on_type_mismatch est désactivé. La fonction considère désormais la comparaison comme “jamais égale” et renvoie le tableau inchangé au lieu de provoquer un échec de assertTypeEquality côté serveur. #105248 (groeneai).
  • Correction de toFloat64/toUInt32/toString/etc. sur Dynamic, qui ignoraient cast_keep_nullable. #105467 (Avogar).
  • Correction d’un segfault du serveur dans uniqStateOrNull / uniqStateOrDefault / uniqOrNullState (et des chaînes de combinators similaires sur uniq) lorsqu’ils sont utilisés avec GROUP BY ... WITH ROLLUP, WITH CUBE ou WITH TOTALS et un argument Nullable. #105470 (groeneai).
  • Correction de toStartOfMillisecond et toStartOfMicrosecond, qui renvoyaient un résultat décalé de presque une seconde pour des valeurs DateTime64 négatives (antérieures à l’époque Unix), ainsi que d’un dépassement d’entier signé détecté par UndefinedBehaviorSanitizer dans toStartOfSecond, toStartOfMillisecond et toStartOfMicrosecond pour des entrées DateTime64 proches de INT64_MIN. #105482 (groeneai).
  • Correction d’un arrêt du serveur lors de la désérialisation d’états singleValueOrNull pour JSON. #105535 (Avogar).
  • Correction de la prise en compte de input_format_try_infer_datetimes lors de l’insertion dans des données partagées en JSON. #105544 (Avogar).
  • Correction du bouclage de DateTime pour les valeurs hors plage dans JSONExtract et lors des désérialisations de texte. #105551 (Avogar).
  • Correction d’un plantage lors de l’insertion de tuples de tailles différentes, dans la même clause VALUES, dans une colonne String. #105582 (Avogar).
  • Correction de l’erreur NOT_IMPLEMENTED dans toString à partir d’un DateTime avec un fuseau horaire contenant une valeur NULL. #105587 (yariks5s).
  • Ajout d’une validation des colonnes Dynamic aplaties mal formées en entrée Native. #105666 (Avogar).
  • Correction d’une LOGICAL_ERROR (Unexpected return type from if) levée lors de la planification d’une requête pour les expressions if dont le type de résultat est Variant et dont la deuxième ou la troisième branche est un if à condition constante appliqué à un littéral UInt64 pouvant tenir dans Int64. #105680 (groeneai).
  • Correction de l’erreur Bad get: has Decimal32, requested Decimal128 avec sumMap et sumMapWithOverflow sur une colonne Nested(... Nullable(Decimal(P, S))) lorsque l’état d’agrégation est sérialisé (p. ex. répliques parallèles, sumMapState via un formateur d’état binaire, agrégation externe). #105816 (groeneai).
  • Correction des erreurs Expected ColumnLowCardinality, got String / Bad cast from type DB::ColumnString to DB::ColumnLowCardinality lorsque apply_mutations_on_fly = 1 est utilisé sur une table comportant des mutations UPDATE/DELETE à la volée en attente, mises en file avant une mutation ALTER MODIFY COLUMN ... LowCardinality(...). #105847 (Algunenano).
  • Correction de l’erreur Cannot find column pour les requêtes distribuées avec un filtre IN Array(...) dans le nouvel analyseur. #105894 (KochetovNicolai).
  • Correction d’un arrêt du serveur lorsqu’une colonne avec STATISTICS était modifiée en Nullable alors qu’un autre ALTER la supprimait simultanément. #105917 (groeneai).
  • Rejet des octets IntervalKind hors plage lors du décodage des types RowBinaryWithNamesAndTypes (input_format_binary_decode_types_in_binary_format = 1) avec une erreur INCORRECT_DATA explicite, au lieu de construire un DataTypeInterval avec un type invalide susceptible d’entraîner ultérieurement un comportement indéfini dans les chemins de hachage. #106261 (groeneai).
  • Lecture de la sous-colonne ‘null’ comme chemin JSON dans Nullable(JSON), au lieu du null-map. #106295 (Avogar).
  • Correction d’une lecture hors limites dans sipHash64Keyed, sipHash128Keyed et sipHash128ReferenceKeyed lors du hachage d’une colonne dont tous les tableaux sont vides et dont la clé n’est pas constante. #106355 (Algunenano).
  • Correction d’un bogue empêchant l’utilisation de sous-requêtes scalaires dans le premier argument de IN lorsque le second argument est un tuple non constant. #106610 (yariks5s).
  • Correction de l’ignorance de session_timezone lors de la sérialisation de colonnes LowCardinality(DateTime) dans des formats textuels (CSV, TSV, JSONEachRow, etc.). Auparavant, après la première écriture d’une colonne LowCardinality(DateTime) sur un serveur, chaque requête ultérieure écrivant une telle colonne affichait la chaîne correspondant à l’heure locale dans le premier fuseau horaire rencontré, indépendamment de session_timezone. #106634 (groeneai).
  • Correction d’un arrêt du serveur dans if et multiIf lorsque la condition est une valeur constante Nullable(Nothing). #106678 (groeneai).
  • Annulation d’un changement qui faisait rejeter par sumMap / le combinateur -Map les types numériques de valeurs portant un nom personnalisé (tels que SimpleAggregateFunction(sum, T) et Bool) avec ILLEGAL_TYPE_OF_ARGUMENT: Values for -Map cannot be summed, ce qui empêchait des agrégations auparavant fonctionnelles. #106729 (fm4v).
  • Correction d’une exception Bad cast lors de l’élagage de parties à l’aide des statistiques MinMax lorsqu’une colonne clé est LowCardinality et que la constante du prédicat est LowCardinality(Nullable(...)). #106793 (groeneai).
  • Corrige une erreur logique dans parseDateTime avec des octets d’entrée non ASCII. #106856 (Avogar).
  • Corrige l’exception THERE_IS_NO_COLUMN pour les requêtes distribuées impliquant l’optimisation optimize_rewrite_aggregate_function_with_if lorsque l’argument de la fonction d’agrégation nécessite une conversion vers le type Nullable. #106908 (yakov-olkhovskiy).
  • Corrige un dépassement d’entier signé (comportement indéfini) dans arrayLevenshteinDistanceWeighted et arraySimilarity lorsque les tableaux de poids contiennent de grandes valeurs entières. La distance pondérée est désormais accumulée dans un entier de plus grande taille pour les poids entiers, afin que les grandes valeurs de poids ne provoquent plus de dépassement et restent exactes. #106934 (groeneai).
  • Corrige un plantage (Source column is not Map / SIGSEGV) lors de la fusion de blocs triés contenant une colonne Variant avec une variante Map dont l’ordre de stockage local diffère de l’ordre global. #107011 (groeneai).
  • Corrige l’erreur TYPE_MISMATCH (“Cannot convert string … to type …”) pour les requêtes ORDER BY <numeric column> ... LIMIT n lorsque la matérialisation paresseuse plaçait une autre colonne avant la colonne de tri. Le seuil top-K est désormais lu dans la bonne colonne de tri. #107060 (groeneai).
  • Corrige une instruction composée ALTER TABLE ... RENAME COLUMN a TO b, RENAME COLUMN c TO a qui réutilise un nom de colonne libéré (un “échange”) entre des colonnes de types différents. La partie matérialisée enregistrait le mauvais type de colonne, de sorte qu’un SELECT ultérieur échouait avec Conversion between numeric types and IPv6 is not supported (ou s’arrêtait lors du chargement de la partie dans les builds de débogage). #107064 (groeneai).
  • Corrige les résultats non déterministes de la fonction roundDown lorsque le tableau de limites contient NaN. Une même valeur d’entrée pouvait renvoyer une limite finie ou NaN selon les lignes environnantes d’un lot. Les limites NaN sont désormais ignorées, de sorte que le résultat ne dépend que des limites finies. #107065 (groeneai).
  • Corrige le fait que quantileTDigest et quantileTDigestWeighted lèvent DECIMAL_OVERFLOW pour des arguments Date et DateTime lorsque le quantile interpolé est fractionnaire mais reste dans la plage (par exemple, quantileTDigestWeighted(date, weight) sur des valeurs toutes représentables par le type). Le résultat fractionnaire est désormais tronqué au type de résultat, comme dans quantilesTDigestWeighted ; les valeurs réellement hors plage lèvent toujours une erreur. #107066 (groeneai).
  • Corrige la troncature silencieuse de valeurs entières hors plage dans les définitions de type Enum8/Enum16. Enum8('a' = 200) lève désormais ARGUMENT_OUT_OF_BOUND au lieu de créer silencieusement Enum8('a' = -56). #107081 (groeneai).
  • Corrige un ordre de lignes incorrect (ainsi qu’une LOGICAL_ERROR “Rows are not sorted with permutation” dans les builds de débogage) pour les requêtes ORDER BY ... LIMIT à plusieurs colonnes qui trient selon des colonnes Nullable lorsque plusieurs lignes sont ex æquo sur les premières colonnes. #107094 (groeneai).
  • Correction de Logical error: 'Bad cast from type DB::ColumnVector<...> to DB::ColumnTuple' lors de la lecture d’une colonne Array(Tuple(...)) dont la valeur est définie sur les valeurs par défaut, par exemple après ALTER TABLE ... ADD COLUMN ou après une mutation ALTER TABLE ... CLEAR COLUMN inachevée appliquée à la volée. #107232 (groeneai).
  • Rejet, lors de l’exécution de CREATE TABLE, des utilisations non prises en charge de colonnes AggregateFunction dans les expressions TTL (par exemple TTL toDateTime(state)), au lieu d’échouer ultérieurement, pendant l’exécution de la TTL, avec ILLEGAL_TYPE_OF_ARGUMENT. Cela couvre également les états contenus dans des alternatives Variant et des valeurs Dynamic. Les consommateurs valides tenant compte des états, tels que finalizeAggregation, restent acceptés. #107366 (Ria-K912).
  • Correction de arrayResize avec un argument de taille Decimal : la taille est désormais interprétée selon sa valeur réelle (par exemple, arrayResize([1, 2, 3], 1.5::Decimal(2, 1)) renvoie un élément) plutôt que selon sa représentation brute non mise à l’échelle. #107389 (alexey-milovidov).
  • Correction de LOGICAL_ERROR: Unexpected return type from materialize (et d’erreurs similaires d’incompatibilité de types) lorsque apply_mutations_on_fly = 1 est utilisé sur une table avec un UPDATE à la volée en attente, dont la colonne cible est également lue comme entrée de fonction par un UPDATE à la volée antérieur, avant une mutation ALTER MODIFY COLUMN ... LowCardinality(...). #107475 (groeneai).
  • Correction de la conversion silencieuse de valeurs NULL en chaînes vides lors de l’insertion de données Arrow/ORC dans une colonne LowCardinality(Nullable(…)). Il s’agissait d’une régression introduite dans la version 26.5. #107532 (Ergus).
  • Correction d’une LOGICAL_ERROR (“Input nodes size mismatch in dag”) lorsqu’une requête avec make_distributed_plan = 1 effectue une jointure sur une clé encapsulée dans une fonction, dont les deux côtés n’ont pas de type commun (par exemple ON intDiv(-1, t1.key) = t2.key avec une clé de droite UInt64). #107701 (groeneai).
  • Correction de la déduplication des insertions, qui calculait des hachages incorrects pour les colonnes String et Array avec le paramètre serveur insert_deduplication_version = new_unified_hash : des insertions identiques pouvaient ne pas être dédupliquées, car le hachage de déduplication dépendait de la position de la ligne dans le bloc inséré. #107915 (CheSema).
  • Correction d’un arrêt du serveur dans has lors d’une recherche dans un Map avec des clés Dynamic à l’aide d’un argument LowCardinality. #107956 (groeneai).
  • Correction d’une régression de performances pour les sous-colonnes Map utilisées avec PREWHERE. #107988 (Avogar).
  • Correction d’une erreur logique lors de la conversion d’une colonne Dynamic ou Variant imbriquée dans un Tuple vers un type d’élément non Nullable avec accurateCastOrNull ou accurateCastOrDefault. #108061 (alexey-milovidov).
  • Correction d’une exception d’erreur logique Bad cast from type DB::ColumnSparse to DB::ColumnVector<char8_t> lorsqu’une requête LIKE lit un index text via le chemin de repli de lecture directe sur une colonne stockée de manière sparse. #108068 (groeneai).
  • Corrige une LOGICAL_ERROR (“Unexpected return type from if”) lors de la lecture d’une colonne avec apply_mutations_on_fly = 1, après un ALTER UPDATE col = ... WHERE <cond> dont la condition est non constante ou fausse, suivi d’un ALTER MODIFY COLUMN col <new type>. #108128 (groeneai).
  • Corrige un signed integer overflow (comportement indéfini) dans dateDiff avec les unités hour et minute pour des valeurs DateTime64 extrêmes proches des limites de la plage Int64. #108229 (groeneai).
  • Corrige une exception du serveur (Logical error dans IColumn::insertFrom) lors de la conversion d’un Array(Dynamic) ou d’un Array(Variant) en QBit avec accurateCastOrNull, par exemple accurateCastOrNull(CAST(range(114), 'Array(Dynamic)'), 'QBit(Float32, 114)'). #108288 (groeneai).
  • Corrige parseDateTimeBestEffort avec un fuseau horaire, qui levait CANNOT_PARSE_DATETIME pour les lignes NULL de toString(Nullable(DateTime64)). #108310 (yariks5s).
  • Corrige un plantage du serveur (dépassement de pile) provoqué par des expressions profondément imbriquées telles que [[[ ... ]]] ou array(array( ... )) lorsque max_parser_depth est défini sur une valeur élevée. #108493 (Algunenano).
  • Corrige une projection SELECT * qui renvoyait la valeur par défaut du type d’une colonne (par ex. 0) au lieu de sa valeur DEFAULT (par ex. -1) lors de la lecture d’une colonne ajoutée avec ALTER TABLE ... ADD COLUMN ... DEFAULT après la création de la projection. Les lectures depuis la table de base étaient déjà correctes ; seules celles servies par la projection étaient affectées, jusqu’à sa reconstruction. #108569 (tiandiwonder).
  • Corrige la désactivation silencieuse de l’élagage des partitions et des clés primaires lorsqu’une colonne de clé LowCardinality(FixedString) (ou LowCardinality(Nullable(FixedString))) était encapsulée dans une fonction de clé, par exemple PARTITION BY sipHash64(k) % N avec WHERE k = 'literal'. Ces requêtes analysaient toutes les partitions au lieu de les élaguer. #108777 (groeneai).
  • Préserve l’ordre d’origine des clés dans la sérialisation Map par compartiments afin de corriger les opérations de comparaison qui en dépendent. #109178 (Avogar).
  • Corrige l’inférence de schéma pour les formats Arrow, ArrowStream, Avro et les lecteurs hérités ORC et Parquet, qui renvoyait Nullable(Tuple) pour les colonnes struct nullables alors que le type Nullable(Tuple) n’est pas autorisé (allow_experimental_nullable_tuple_type est désactivé). DESCRIBE renvoyait un type refusé par CREATE TABLE, de sorte que la création d’une table ou l’insertion de données à l’aide du schéma inféré échouait avec l’erreur Nullable Tuple type is not allowed. #109185 (nihalzp).
  • Corrige un bug où les valeurs DEFAULT des colonnes n’étaient pas appliquées pour INSERT INTO TABLE FUNCTION (par exemple remote(...) ou file(...)) avec des données VALUES intégrées lorsque le serveur analysait lui-même ces données (send_table_structure_on_insert_with_inline_data = 0). Un NULL explicite inséré dans une colonne non-Nullable avec un DEFAULT devenait 0 au lieu de la valeur par défaut déclarée. Le comportement est désormais identique à celui d’un INSERT dans une table classique et du protocole HTTP. #109258 (groeneai).
  • Correction d’un segfault dans groupArrayLastMerge. La désérialisation de l’état d’une fonction d’agrégation est désormais validée. Un état corrompu ne peut donc plus entraîner d’accès hors limites. #109485 (mstetsyuk).
  • Correction d’un segfault dans la fonction d’agrégation largestTriangleThreeBuckets en rejetant les états de fonction d’agrégation corrompus lors de la désérialisation. #109492 (mstetsyuk).
  • Correction de la lecture d’une colonne Parquet avec un Tuple non nullable lorsque le type ClickHouse demandé l’encapsule dans Nullable (p. ex. Nullable(Tuple(...))), ce qui échouait auparavant avec TYPE_MISMATCH. #109615 (groeneai).
  • Le lecteur natif Parquet v3 peut désormais lire une colonne struct physiquement nullable (un groupe Parquet OPTIONAL) comme Nullable(Tuple(...)). Auparavant, cela levait TYPE_MISMATCH. #109898 (groeneai).
  • Correction d’un crash du serveur (dépassement de pile natif) lors de la copie ou de la destruction d’un littéral Array/Tuple/Map/Object fortement imbriqué, par exemple dans une requête contenant un littéral très profondément imbriqué avec une valeur élevée de max_parser_depth. #110393 (Algunenano).
  • Correction de résultats erronés pour IS NULL / IS NOT NULL / count() avec optimize_functions_to_subcolumns sur une colonne rendue Nullable par un ALTER MODIFY COLUMN T limité aux métadonnées vers Nullable(T). Pour les parties écrites avant la conversion, la sous-colonne .null était renseignée avec la valeur par défaut du type de stockage (NULL), au lieu d’être dérivée de la colonne parente physiquement présente ; les lignes existantes non nulles étaient donc à tort signalées comme NULL. #110584 (groeneai).
  • Correction d’une LOGICAL_ERROR (“Bad cast from ColumnString to ColumnLowCardinality”) lors de l’analyse de l’index de clé primaire lorsqu’une colonne clé LowCardinality est encapsulée dans une chaîne de CAST imbriqués qui réintroduit LowCardinality, p. ex. WHERE CAST(CAST(s, 'LowCardinality(String)'), 'String') < '5'. Dans les builds de débogage et avec sanitizer, cela provoquait l’arrêt du serveur ; dans les builds de production, la requête échouait. #111050 (groeneai).
  • Correction de la lecture de données Arrow et ArrowStream contenant des colonnes Array ou Map imbriquées vides produites par Apache Arrow Java avant la version 19.0.0 (fourni avec Apache Spark), qui étaient auparavant rejetées avec une erreur INCORRECT_DATA indiquant que le tampon des offsets était trop petit. #111101 (Algunenano).
  • Correction d’une erreur logique Block structure mismatch (dans les builds de débogage et avec sanitizer) et d’une erreur Illegal types of arguments pour les opérations ensemblistes sur des colonnes d’états d’agrégation compatibles (p. ex. quantileState et quantilesState(0.9)) imbriquées dans des colonnes conteneurs telles que Tuple, Array, Map, Nullable ou Variant. #111191 (alexey-milovidov).
  • Ajout d’une validation des données d’index répliqué corrompues reçues via le protocole natif. #112331 (Avogar).
  • Correction d’une lecture hors limites lors de la déduplication des insertions lorsqu’un INSERT passe par une vue matérialisée qui modifie le nombre de lignes avant l’écriture dans une table cible partitionnée. #112649 (CheSema).
  • Correction d’une écriture hors limites lors de la lecture d’une colonne DECIMAL Parquet dont le type physique est plus large que celui correspondant à sa précision déclarée, par exemple DECIMAL(9, 2) stocké avec le type physique INT64. Ces fichiers Parquet sont valides et peuvent être produits par d’autres outils d’écriture, mais le lecteur dimensionnait la colonne de destination à partir de la précision déclarée tandis que le décodeur écrivait sur la largeur physique, ce qui corrompait la mémoire. La lecture d’un tel fichier déclenche désormais aussi DECIMAL_OVERFLOW lorsqu’une valeur ne tient pas dans la précision déclarée, au lieu de renvoyer des données corrompues, et s’effectue sans perte avec une indication de type au moins aussi large que le type physique. #113046 (groeneai).
  • Correction de l’échec de ATTACH PARTITION FROM, REPLACE PARTITION, MOVE PARTITION TO TABLE et de l’ajout d’une réplique ReplicatedMergeTree, qui pouvaient échouer avec Tables have different ..., METADATA_MISMATCH ou INCOMPATIBLE_COLUMNS pour les tables dont les définitions comportaient des parenthèses redondantes, telles que PARTITION BY (a), ORDER BY (b), INDEX ix (b * c) TYPE minmax, PROJECTION p (SELECT (b) ...), CONSTRAINT c CHECK (a > 0), TTL (d + INTERVAL 10 YEAR) ou DEFAULT (a + 1). #114188 (alexey-milovidov).
  • Correction d’un bogue où une entité d’accès contenant un paramètre de type Map, tel qu’un profil de paramètres avec http_response_headers ou additional_table_filters, était stockée dans un format que ClickHouse ne pouvait pas relire, laissant l’entité définitivement impossible à charger après un redémarrage. #114620 (groeneai).
  • Correction de has, indexOf, countEqual, mapContainsKey, mapContainsValue et de l’accès par indice à Map, qui renvoyaient “not found” pour une valeur recherchée constante LowCardinality égale à la valeur par défaut du type d’élément, telle qu’une String vide ou zéro. #114624 (groeneai).
  • Correction des résultats incorrects de l’optimisation triviale GROUP BY ... LIMIT (paramètre optimize_trivial_group_by_limit_query) pour les requêtes avec DISTINCT, QUALIFY, des fonctions fenêtre ou arrayJoin dans la projection : ces éléments consomment ou filtrent les groupes après l’agrégation, de sorte que limiter l’agrégation à LIMIT + OFFSET clés pouvait renvoyer trop peu de lignes ou des valeurs incorrectes. L’optimisation ne s’applique plus à ces requêtes. #114695 (alexey-milovidov).
  • Correction des résultats incorrects pour SELECT count(arrayJoin(arr)) avec la valeur par défaut optimize_trivial_count_query = 1. Le nombre de lignes stocké était renvoyé à la place du nombre d’éléments du tableau, et avec file() et url(), la requête renvoyait 0. #115227 (groeneai).
  • Correction de uniq, uniqExact, uniqHLL12 et uniqTheta, qui renvoyaient un résultat incorrect pour un argument encapsulé dans une fonction injective masquant la nullabilité, tel que uniqExact(tuple(x)) sur une colonne Nullable. L’optimisation optimize_injective_functions_inside_uniq supprimait la fonction encapsulante, après quoi les lignes NULL étaient ignorées au lieu d’être comptées. #115466 (vdimir).
  • Les lecteurs KeeperMap acceptent désormais des métadonnées partagées lorsque des clés primaires équivalentes ne diffèrent que par des parenthèses externes redondantes. #115642 (skuznetsov-clickhouse).

Corrections apportées aux index de texte et aux index d’exclusion

  • Corrige l’arrêt du serveur lorsqu’une requête utilise des comparaisons coalesce/ifNull imbriquées (par ex. WHERE coalesce(a, b, coalesce(c, d), e) = const) sur une table MergeTree dotée de plusieurs index de saut minmax et de use_skip_indexes_for_disjunctions = 1. La réécriture d’index de saut de <op>(coalesce(...), const) est désormais appliquée récursivement aux arguments internes de coalesce, afin que la RPN KeyCondition de chaque index corresponde à la RPN du modèle, comme le suppose déjà le code de suivi des disjonctions. #103929 (groeneai).
  • Corrige l’erreur NOT_FOUND_COLUMN_IN_BLOCK levée par ALTER TABLE ... MATERIALIZE INDEX sur des parties créées en version 25.8 et contenant un index de saut sur une colonne ajoutée via un ALTER TABLE ... ADD COLUMN distinct. Lors du recalcul forcé, la mutation lit désormais correctement toutes les colonnes requises par chaque index de saut et projection préexistants dans la partie. #105039 (groeneai).
  • Corrige une sous-estimation silencieuse dans les requêtes SELECT lorsque use_query_condition_cache = 1 (valeur par défaut). Une requête de la forme PREWHERE pk_prefix = X WHERE non_pk IN (...) sur une colonne dotée d’un index de saut par filtre de Bloom empoisonnait le QueryConditionCache pour le prédicat pk_prefix = X, si bien qu’une requête SELECT count() ... WHERE pk_prefix = X ultérieure et valide renvoyait un résultat incorrect, sous-estimé. Toutes les versions 26.x étaient affectées. #105686 (groeneai).
  • Corrige une exception lorsqu’une requête de recherche vectorielle utilise un index vectoriel ainsi qu’un autre index de saut tel que minmax, avec use_skip_indexes_on_data_read = 1. #106473 (shankar-iyer).
  • Corrige l’erreur « Too many marks » pour un index de texte sur une partie fusionnée vide. #106867 (azat).
  • Corrige des résultats erronés lors de l’interrogation d’une table ReplacingMergeTree avec FINAL et un filtre sur un index de texte lorsque query_plan_optimize_lazy_final était activé. L’optimisation FINAL différée générait des étapes de lecture qui ne reproduisaient pas la lecture directe depuis l’index de texte, de sorte que le filtre supprimait toutes les lignes correspondantes. #106894 (Ergus).
  • Corrige LOGICAL ERROR (Bad cast from type DB::ColumnString to DB::ColumnLowCardinality) lorsqu’une constante Variant contenant un membre LowCardinality est comparée à une colonne clé dont l’expression de clé est une fonction déterministe non monotone (par exemple, un index de saut minmax sur sipHash64(col)). #107111 (groeneai).
  • Corrige des résultats erronés, souvent vides, avec ORDER BY <col> LIMIT n lorsque l’optimisation use_skip_indexes_for_top_k est active et qu’une partie dotée d’un index de saut minmax sur la colonne de tri contient des lignes supprimées par un DELETE léger. L’optimisation ne classe plus le minmax obsolète des parties affectées par des suppressions légères avant les parties contenant les premières lignes encore actives. #107320 (groeneai).
  • Corrige l’index de saut set, qui n’élaguait pas les granules des colonnes LowCardinality. #107868 (thevar1able).
  • Le paramètre use_skip_indexes_on_data_read peut désormais être rétabli à sa valeur par défaut antérieure à la version 26.1 (false) via le paramètre compatibility, offrant une solution de repli en cas de régression de performances où le chemin de lecture des données empêche l’élagage des plages de marques par les index de saut minmax/set/bloom_filter. #108330 (egor-click).
  • Correction de la lecture directe à partir de plusieurs index de texte partiellement matérialisés. #108607 (CurtizJ).
  • Correction d’un index de texte défini sur mapValues(map) ou mapKeys(map) qui n’était pas utilisé silencieusement lorsqu’une table était interrogée via une table du moteur Distributed avec l’analyseur. L’index était utilisé pour la table locale et via cluster()/remote(), mais une requête passant par une table du moteur Distributed l’ignorait (et échouait avec INDEX_NOT_USED sous force_data_skipping_indices). #109188 (groeneai).
  • Correction d’un plantage du serveur avec CREATE HYPOTHETICAL INDEX ... TYPE set (ainsi que ngrambf_v1/tokenbf_v1) lorsque l’argument d’index requis est omis. Ces instructions sont désormais rejetées avec un message d’erreur explicite. #109294 (groeneai).
  • Correction de résultats incorrects pour les fonctions has, mapContainsKey et mapContainsValue avec un motif vide lorsqu’un index de texte est présent. #110246 (rschu1ze).
  • Correction de l’erreur ATTEMPT_TO_READ_AFTER_EOF lors de la fusion de parties dotées d’un index de texte si l’une des parties fusionnées était vide, par exemple après une mutation ayant supprimé toutes ses lignes. #112490 (CurtizJ).
  • Correction d’un blocage de l’optimisation du plan de requête lorsqu’une clause WHERE contient une longue constante de chaîne comportant de nombreux points et que la table possède un index de saut bloom_filter, tokenbf_v1, ngrambf_v1 ou text. La comparaison d’un nom de colonne de filtre avec les colonnes d’index JSONAllPaths(...) énumérait toutes les divisions du nom sur les points, ce qui rendait quadratique, par rapport à la longueur de la constante, la construction des conditions d’index de saut. #113289 (groeneai).
  • Correction de ORDER BY ... LIMIT, qui renvoyait moins de lignes que demandé, voire aucune, lorsqu’une politique de lignes était le seul filtre de la requête et que la colonne de tri possédait un index de saut minmax. L’optimisation top-K ramenait la lecture avant l’application de la politique de lignes. #114073 (alexey-milovidov).

Correctifs relatifs au lac de données

  • Correction d’une exception d’erreur logique lors de la lecture de tables Iceberg dont la version du format avait été mise à niveau par un outil externe (p. ex. Spark). #100407 (alexey-milovidov).
  • Correction d’une exception (LOGICAL_ERROR: 'PREWHERE passed to format that doesn't support it') lors de la lecture de tables Iceberg contenant des fichiers de données ORC avec l’optimisation PREWHERE activée. #101206 (groeneai).
  • Correction des exceptions LOGICAL_ERROR lors de la lecture de tables de lac de données Iceberg ou DeltaLake via des chemins susceptibles d’atteindre le pipeline de lecture sans datalake_table_state fixé, notamment lors de mises à jour concurrentes des métadonnées Iceberg ou de lectures merge sur des tables DeltaLake. #102033 (groeneai).
  • Correction de l’erreur sporadique Logical error: 'Database <name> not found' émise par DataLakeConfiguration::getCatalog lorsqu’une table utilisant le moteur Iceberg est chargée dans une base de données classique pendant le chargement asynchrone des métadonnées. #103775 (groeneai).
  • Correction des lectures excessives de métadonnées de catalogue et S3 lorsqu’une instruction INSERT ou DDL référence une table inexistante dans une base de données de catalogue DataLake avec show_data_lake_catalogs_in_system_tables activé. Le mécanisme de suggestion en cas de faute de frappe chargeait les métadonnées Iceberg complètes de chaque table de l’ensemble du catalogue, ce qui pouvait épuiser la mémoire sur les catalogues volumineux. #104124 (il9ue).
  • Correction de read_bytes surestimé (ainsi que des octets/s dérivés affichés dans system.query_log, la barre de progression, etc.) lors de la lecture de fichiers Parquet. L’implémentation précédente signalait la taille compressée totale du groupe de lignes à chaque fragment, de sorte que la lecture de K colonnes sur N entraînait une surestimation d’un facteur N / K. Cette valeur n’est désormais additionnée que pour les colonnes sélectionnées. Corrige également le suivi de la progression au niveau des fichiers pour les tables Iceberg, qui ne signalait auparavant jamais la taille du fichier de données. #105413 (groeneai).
  • Correction de résultats erronés lors de la lecture d’une table Iceberg avec iceberg_use_version_hint = 1 après qu’un autre écrivain (tel que la fonction de table icebergLocal/icebergS3) sans ce paramètre a fait évoluer la table. version-hint.text est désormais maintenu synchronisé par chaque écrivain dès que le fichier existe, afin que les lecteurs ultérieurs utilisant l’indication voient le dernier instantané. #105682 (groeneai).
  • Les écritures Iceberg préservent désormais les valeurs NULL dans les colonnes de partition Nullable(T). Auparavant, un NULL écrit par ClickHouse apparaissait comme la valeur par défaut du type interne (0 pour int) lors de sa relecture par Spark ou d’autres lecteurs Iceberg. #105862 (groeneai).
  • Correction des suppressions par position merge-on-read d’Iceberg v2 qui renvoyaient des lignes erronées lorsqu’un même fichier de suppression référençait plusieurs fichiers de données et que plusieurs fichiers de suppression s’appliquaient au même fichier de données. Les entrées de suppression sont désormais filtrées selon le chemin du fichier auquel elles font référence. #105888 (groeneai).
  • Correction du moteur de table IcebergLocal qui passait en lecture seule après un cycle DETACH + ATTACH ou un redémarrage du serveur, entraînant l’échec de chaque INSERT ultérieur avec Local object storage Local is readonly. (READONLY). #106016 (groeneai).
  • Correction du cache du système de fichiers, qui était silencieusement désactivé pour Azure Blob Storage (p. ex. les tables Delta Lake sur Azure), car les métadonnées d’objet n’incluaient pas l’ETag du blob. #106091 (thewisenerd).
  • Ajout d’une validation des chemins pour les tables Delta Lake afin d’empêcher les métadonnées d’accéder à des objets situés en dehors de l’emplacement de stockage configuré. #106115 (scanhex12).
  • L’élagage des partitions Iceberg gère désormais correctement les filtres WHERE partition_col = (SELECT ... FROM ...), lorsque l’analyseur encapsule le résultat de la sous-requête scalaire dans un _CAST(Const, 'TargetType') interne dont les types source et cible correspondent. Auparavant, ces filtres désactivaient l’élagage des partitions et entraînaient un parcours complet de la table. #106204 (groeneai).
  • Correction d’un problème où des catalogues REST Iceberg contenant des tables étaient signalés à tort comme vides. #106301 (LefterisXefteris).
  • Correction d’une exception NOT_FOUND_COLUMN_IN_BLOCK lors de l’interrogation d’une table Iceberg ou S3 avec une clause WHERE composée contenant IS NOT NULL sur une colonne absente de la liste SELECT, avec le lecteur natif Parquet V3. #106443 (tiandiwonder).
  • Correction d’un rapport de progression surestimé lors de la lecture de tables Iceberg avec des filtres _file ou _path. Auparavant, la progression total_bytes_to_read incluait tous les fichiers du manifeste, indépendamment du filtrage. #106491 (PedroTadim).
  • Correction d’une exception du serveur (erreur logique std::out_of_range) lors de l’insertion dans une table Iceberg dont les noms de colonnes du bloc d’écriture ne correspondent pas aux ID de champ du schéma le plus récent (par exemple, après qu’un rédacteur concurrent a renommé une colonne pendant la fenêtre iceberg_metadata_staleness_ms). L’insertion échoue désormais avec une erreur de requête claire au lieu d’arrêter le serveur. #107279 (groeneai).
  • Correction d’un possible débordement de pile du serveur (crash) lors de la lecture d’un schéma ou d’une valeur profondément imbriqués dans les formats MsgPack, BSON, ORC, Parquet, JSON, DeltaLake, Iceberg et Paimon. Ces entrées profondément imbriquées sont désormais rejetées avec une exception. #107341 (Algunenano).
  • Correction d’un crash (LOGICAL_ERROR dans les builds de débogage) et d’un bogue produisant silencieusement des résultats incorrects (dans les builds de production) lors de la lecture d’une table Iceberg dont les métadonnées réassocient un schema-id existant à un schéma différent entre les versions de métadonnées. Ces métadonnées sont désormais rejetées avec ICEBERG_SPECIFICATION_VIOLATION. #107370 (groeneai).
  • Correction de la lecture des tables Iceberg v3 dont les fichiers de données Parquet contiennent des colonnes réservées de traçabilité des lignes (telles que _row_id) ; le lecteur Parquet natif ne génère plus ICEBERG_SPECIFICATION_VIOLATION pour les ID de champ réservés qui ne font pas partie du schéma de la table. #107377 (gregakinman).
  • Correction d’une exception parasite filesystem error: in last_write_time: No such file or directory lors du listage d’un répertoire de stockage d’objets sur disque local (par exemple, une table Iceberg sur un disque local) alors que des fichiers sont remplacés simultanément. Une entrée supprimée entre-temps est désormais omise du listage au lieu d’interrompre celui-ci. #107432 (groeneai).
  • Correction de l’erreur ‘Account must be specified error’ lors de la lecture d’une table Delta Lake sur Azure. #107620 (SmitaRKulkarni).
  • Correction d’un crash lors de la lecture de tables Iceberg avec des fichiers de suppression par égalité. Si une colonne est nullable dans le fichier de suppression par égalité, mais non nullable dans le schéma de la table (ou inversement), les valeurs lues dans le fichier de suppression étaient insérées dans une colonne d’un type différent via un cast non vérifié (une confusion de types de colonnes), ce qui corrompait la colonne et faisait planter le serveur. #109551 (mstetsyuk).
  • Correction d’une fausse erreur ICEBERG_SPECIFICATION_VIOLATION lors de la lecture d’une table Iceberg dont le type decimal (ou un autre type primitif paramétré) est sérialisé avec des espaces différents selon les fichiers de métadonnées, par exemple decimal(20,0) dans les métadonnées de la table et decimal(20, 0) dans le manifeste. Ces chaînes de types équivalentes selon la spécification sont désormais comparées sans tenir compte des espaces. #109676 (groeneai).
  • Correction de la lecture des tables Iceberg dont l’ordre de tri par défaut référence une colonne nécessitant d’être entourée de guillemets (par exemple @timestamp). Ces tables étaient illisibles, car la clause ORDER BY de stockage générée était construite à partir du nom brut de la colonne et ne pouvait pas être analysée, entraînant l’erreur SYNTAX_ERROR. #110233 (groeneai).
  • Correction de la lecture des tables Paimon contenant une colonne ARRAY ou MAP nullable. Ces tables ne pouvaient pas être lues, car le mappeur de schéma encapsulait le type composite dans Nullable, ce que ClickHouse interdit. Ainsi, DESC et SELECT échouaient avec Nested type Array(Nullable(Int32)) cannot be inside Nullable type. Une colonne composite nullable est désormais mappée vers un type composite non-Nullable, et une valeur NULL est lue comme une valeur vide. #113450 (groeneai).
  • Enregistrement de l’espace de noms Iceberg dans le catalogue avant l’écriture des fichiers de table (nécessaire pour SeaweedFS) #114285 (azat).

Correctifs S3/Azure/de stockage d’objets

  • Correction de l’exception « Distributed task iterator is not initialized » lors de l’utilisation des fonctions de table url, s3 ou similaires dans des requêtes avec des répliques parallèles activées. #100146 (alexey-milovidov).
  • Correction d’un possible segfault du serveur dans les fonctions de table de cluster (s3Cluster, urlCluster, fileCluster, …) lorsque le planificateur génère un SELECT avec l’indicateur recursive_with défini, mais sans expression WITH. #105433 (groeneai).
  • Correction du pushdown de filtre Parquet et ORC pour les prédicats IN (subquery), permettant l’élagage des groupes de lignes, pages et filtres de Bloom lors des lectures depuis file, url, s3 et le stockage d’objets. #105863 (arsenmuk).
  • Correction de l’exception LOGICAL_ERROR lors du pré-téléchargement dans le cache lorsqu’un objet S3 distant est remplacé par un contenu plus court entre son listage et sa lecture. #106375 (fm4v).
  • Correction du fait que la fonction de table s3 ignorait silencieusement une partition_strategy positionnelle en minuscules (par ex. hive). #107297 (jkartseva).
  • Correction d’une régression où le paramètre compatibility = '26.6' (qui active implicitement la stratégie de partitionnement hive) acceptait silencieusement {_partition_id} dans les chemins de table S3 et de stockage d’objets au lieu de générer BAD_ARGUMENTS. #107437 (LefterisXefteris).
  • Correction du fait que s3 et d’autres fonctions de table de stockage d’objets généraient LOGICAL_ERROR au lieu de BAD_ARGUMENTS lorsqu’un argument clé-valeur était dupliqué, par ex. s3('http://...', format = 'CSV', format = 'TSV'). #107670 (groeneai).
  • Correction d’une exception serveur (Logical error: 'index >= result.start') lors du formatage d’une requête malformée mélangeant les formes positionnelle et nommée de l’argument secret des fonctions de table s3/gcs, par ex. s3('url', 'a', 'b', secret_access_key = 'c'). #107818 (groeneai).
  • Correction de la priorité des paramètres S3 afin qu’un bloc d’endpoint <s3> associé à une URL ait préséance sur les valeurs par défaut <s3> de niveau supérieur. #109251 (bharatnc).
  • Correction des erreurs 411 Length Required renvoyées par les services Azure : le transport HTTP Azure basé sur Poco définit désormais Content-Length à partir du corps de la requête pour les clients SDK qui ne définissent pas eux-mêmes l’en-tête (par ex. Azure Key Vault). #110299 (thevar1able).

Correctifs de S3Queue

  • Corrige un plantage du serveur (accès hors limites) dans S3Queue/AzureQueue avec enable_hash_ring_filtering = 1 lorsqu’un lot contenait un fichier impossible à traiter et que la requête Keeper visant à marquer le lot comme en cours de traitement échouait simultanément. #108977 (groeneai).
  • Corrige les fuites d’identifiants dans SHOW CREATE, system.query_log, les journaux du serveur et la sortie de EXPLAIN. Toutes les formes de localisateurs S3 masquent désormais session_token et les secrets Google ADC, les valeurs de extra_credentials/headers, quelle que soit la position de l’argument, les clés secrètes dupliquées ou construites par une expression, les formes positionnelles non valides (échec sécurisé) et les identifiants intégrés aux URL S3 ; cela couvre les fonctions de table s3/s3Cluster avec URL explicite et collection nommée, les moteurs de table basés sur S3 (S3, GCS, les moteurs de lac de données, S3Queue), le moteur de base de données S3, BACKUP ... TO S3 et le moteur de base de données Backup. De plus, les arguments secrets de encrypt/decrypt/HMAC construits par une expression (y compris ceux intégrés depuis une UDF SQL) sont désormais masqués dans les noms de projection, EXPLAIN QUERY TREE et EXPLAIN actions. #109768 (Algunenano).
  • Corrige le mode ordonné de S3Queue/AzureQueue avec des nœuds de traitement persistants : les verrous de bucket sont désormais renouvelés pendant le streaming afin que le nettoyage TTL (persistent_processing_node_ttl_seconds) ne supprime pas les verrous d’un processeur actif. Si la propriété d’un verrou est néanmoins perdue, cela est détecté et signalé (une erreur logique et l’événement de profil ObjectStorageQueueBucketLockLostOwnership), et le streaming reprend avec un nouvel itérateur de fichiers. #110292 (kssenii).

Correctifs de sécurité et de contrôle d’accès

  • Correction d’un crash du serveur (SIGSEGV) accessible à tout utilisateur disposant du droit CREATE TABLE lors de l’envoi, via HTTP ou le protocole natif, de CREATE TABLE ... TO INNER UUID '...' sans clause ENGINE. Le même bogue faisait également planter le client. L’analyseur renvoie désormais une erreur BAD_ARGUMENTS appropriée au lieu de déréférencer un pointeur nul. #105579 (groeneai).
  • Correction d’un crash du serveur lors de l’interrogation de tables DeltaLake avec allow_experimental_delta_kernel_rs activé et des informations d’identification ou une option contenant des octets non valides (la FFI Rust paniquait au-delà de la frontière extern "C"). #106109 (Algunenano).
  • Correction de plusieurs lectures hors limites du tas dans le lecteur du format Arrow IPC (ArrowColumnToCHColumn). Un fichier Arrow malformé pouvait déclarer davantage de lignes que n’en contiennent ses buffers, déclarer des longueurs d’enfants de type liste/struct/map incohérentes avec leur parent, fournir des offsets de liste non monotones ou tronquer un bitmap de validité enfant, entraînant des lectures au-delà de la fin des allocations du tas. Cette vulnérabilité est exploitable par tout utilisateur disposant du privilège SELECT via file(), format(), les fonctions de table ou des entrées ArrowFlight. Tous les buffers de données, d’offsets, de view-struct et de bitmap de validité sont désormais validés avant tout accès à des pointeurs bruts, et la cohérence des formes et des offsets des listes/struct/maps est vérifiée. #106395 (Algunenano).
  • Correction d’un bogue où les colonnes used_privileges et missing_privileges de system.query_log pouvaient contenir des chaînes de privilèges provenant de requêtes antérieures non liées, exécutées par un autre utilisateur, sur une autre base de données ou dans une autre session. #106425 (alexey-milovidov).
  • Correction d’un dépassement de buffer du tas (crash du serveur) dans decodeHTMLComponent lors du décodage de chaînes contenant les entités HTML à expansion &nGt; ou &nLt;, exploitable par tout utilisateur avec un seul SELECT. #106741 (Algunenano).
  • Correction de résultats de requête incorrects causés par le cache de conditions de requête lorsque des mutations à la volée (apply_mutations_on_fly) ou des patch parts filtraient des lignes avant PREWHERE. Une requête lue avec apply_mutations_on_fly = 1 pouvait empoisonner le cache, de sorte qu’une requête ultérieure avec apply_mutations_on_fly = 0 et le même prédicat ignorait des marques qu’elle aurait dû lire et renvoyait trop peu de lignes. Le même correctif couvre également les politiques de sécurité au niveau des lignes, ajoutées comme filtre avant PREWHERE : une requête exécutée avec une politique de ligne restrictive pouvait empoisonner le cache pour une requête ultérieure utilisant le même prédicat sans cette politique. #107145 (groeneai).
  • Correction d’un dépassement de buffer du tas (crash du serveur) dans windowFunnel lors de la finalisation d’un état de fonction d’agrégation spécialement conçu avec un type d’événement hors plage, exploitable par tout utilisateur avec un seul SELECT. #107412 (uwezkhan).
  • Correction d’un problème où currentUser(), user(), SESSION_USER et authenticatedUser() renvoyaient une chaîne vide lors du vidage des insertions asynchrones (avec async_insert = 1). Cela affectait les expressions de colonne DEFAULT/MATERIALIZED et les vues matérialisées qui référencent ces fonctions, lesquelles stockaient silencieusement une chaîne vide au lieu de l’utilisateur effectuant l’insertion. #107541 (groeneai).
  • Lorsque plusieurs quotas sont attribués au même utilisateur ou rôle, ils sont désormais tous appliqués conjointement (une requête est rejetée si l’un d’eux est dépassé), au lieu qu’un seul quota soit appliqué et choisi de façon non déterministe. SHOW QUOTA et system.quota_usage affichent désormais tous les quotas appliqués pour l’utilisateur courant. #107664 (alexey-milovidov).
  • SYSTEM RESET DDL WORKER nécessite désormais le nouveau privilège SYSTEM RESET DDL WORKER. Auparavant, tout utilisateur authentifié (y compris les utilisateurs en readonly) pouvait l’exécuter et réinitialiser à plusieurs reprises l’état du worker DDL, bloquant les DDL ON CLUSTER. #108460 (groeneai).
  • Correction de l’identification des utilisateurs par ssl_certificate afin qu’un unique caractère générique * corresponde exactement à un composant de nom (RFC 6125 6.4.3). Auparavant, un caractère générique dans un sujet SAN CN ou DNS: (par exemple *.corp.example.com) correspondait également à des noms comportant plusieurs libellés, tels que evil.deep.corp.example.com, permettant au détenteur d’un certificat pour un sous-domaine plus profond de s’authentifier en tant qu’utilisateur générique. La correspondance des SAN URI: reste inchangée. #108472 (groeneai).
  • Les commandes du protocole MySQL COM_FIELD_LIST (mysql_list_fields) et COM_INIT_DB (USE database) appliquent désormais le même contrôle d’accès que leurs équivalents SQL (SHOW COLUMNS/DESCRIBE et USE). Auparavant, elles pouvaient divulguer les noms de colonnes de tables pour lesquelles l’utilisateur ne disposait que de privilèges partiels sur les colonnes, et changer la base de données courante sans le privilège SHOW DATABASES. #108508 (groeneai).
  • http_forbid_headers est désormais mis en correspondance sans distinction entre majuscules et minuscules. Les noms d’en-têtes HTTP ne distinguent pas les majuscules des minuscules. Ainsi, interdire Authorization bloque désormais aussi authorization, AUTHORIZATION et les autres variantes de casse. Les modèles header_regexp configurés sont désormais mis en correspondance sans distinction entre majuscules et minuscules, sans nécessiter d’indicateur (?i) explicite. #108509 (groeneai).
  • Correction d’une divulgation de métadonnées : DESCRIBE loop('db', 'table') et DESCRIBE loop(<inner table function>) contournaient la vérification de l’accès SHOW COLUMNS / de l’accès à la source, permettant à un utilisateur non privilégié de lire le schéma des colonnes d’une table. #108624 (groeneai).
  • Correction d’un échec de démarrage : une base de données DataLakeCatalog créée par une version antérieure (25.12 ou précédente) avec un auth_header mal formé ne pouvait pas être attachée après une mise à niveau vers la version 26.2 ou ultérieure, ce qui empêchait le démarrage du serveur. Le auth_header n’est désormais validé que lors de CREATE et, lors de ATTACH, le catalogue est construit de manière différée, à sa première utilisation plutôt qu’au démarrage. Ainsi, une seule base de données de catalogue mal configurée ou non joignable ne bloque plus le démarrage du serveur. #108674 (groeneai).
  • Renforcement des connexions RabbitMQ contre les trames AMQP malveillantes excessivement volumineuses et application systématique des vérifications remote_url_allow_hosts à rabbitmq_address. #112479 (kssenii).
  • Correction d’un cas où CREATE TABLE ... ENGINE = Distributed(...) sans liste de colonnes pouvait révéler la structure d’une table locale que l’utilisateur à l’origine de la création n’est pas autorisé à consulter. Lors d’un CREATE exécuté par le serveur local lui-même, la structure est désormais déduite dans le contexte de l’utilisateur, de sorte que le privilège SHOW COLUMNS sur la table cible est requis, comme c’est déjà le cas pour le moteur Remote. Un CREATE rejoué depuis la DDL queue (ON CLUSTER ou au sein d’une base de données Replicated) n’est pas couvert. #113220 (groeneai).
  • Correction d’un cas où CREATE TABLE ... ENGINE = Buffer(...) sans liste de colonnes pouvait révéler la structure d’une table de destination que l’utilisateur à l’origine de la création n’est pas autorisé à consulter. Lorsqu’un CREATE est exécuté par le serveur local lui-même, la structure est désormais inférée dans le contexte de l’utilisateur. La permission d’exécuter SHOW COLUMNS sur la destination est donc requise, comme c’est déjà le cas pour Merge et Remote. Un CREATE rejoué depuis la file d’attente DDL (ON CLUSTER ou au sein d’une base de données Replicated) n’est pas concerné. #113372 (groeneai).
  • Limitation de la taille du message de démarrage du protocole PostgreSQL, lu avant l’authentification. #115708 (alexey-milovidov).

Correctifs de sauvegarde et de restauration

  • Corrige un arrêt du serveur lors de la commande RESTORE de sauvegardes contenant des tables aux dépendances cycliques. #103824 (thevar1able).
  • Corrige la non-prise en compte de la classe de stockage S3 (s3_storage_class / s3_storage_class_name) pour les objets écrits via un téléversement multipartite sur les disques S3 et le stockage d’objets, ce qui entraînait la création de gros objets avec la classe STANDARD par défaut. Le nom de l’option est désormais accepté sous les formes s3_storage_class et s3_storage_class_name pour les disques, le stockage d’objets et les sauvegardes. #106214 (alexey-milovidov).
  • Corrige le fait que SYSTEM RELOAD CONFIG ignorait les paramètres Azure Blob Storage spécifiques aux endpoints (tels que use_native_copy), ce qui empêchait la prise en compte des paramètres configurés d’un disque pour BACKUP/RESTORE jusqu’au redémarrage du serveur. #106357 (jkartseva).
  • Corrige l’échec des sauvegardes avec FILE_DOESNT_EXIST lorsqu’une cible REPLACE d’une vue matérialisée actualisable est collectée sur une base de données Replicated ou Shared dont la vue matérialisée n’est pas encore instanciée sur la réplique qui initie la sauvegarde. #106411 (jkartseva).
  • Corrige le fait qu’Azure BACKUP/RESTORE ignorait les paramètres d’endpoint pour les disques azure_blob_storage au format hérité. #106784 (jkartseva).
  • Corrige BACKUP vers AzureBlobStorage : la copie d’un fichier de données au sein d’une sauvegarde écrivait l’objet de destination hors du répertoire de sauvegarde. Les vérifications de l’existence d’objets de sauvegarde sur les destinations S3 utilisent désormais des requêtes HeadObject exactes au lieu d’un listage par préfixe, évitant les correspondances erronées avec des clés ayant des préfixes similaires. #107153 (pamarcos).
  • Les sauvegardes incrémentielles ne stockent plus les identifiants S3 dans le localisateur <base_backup> du fichier de métadonnées .backup. Les sauvegardes créées avec use_same_s3_credentials_for_base_backup = 1, ou avec des identifiants explicites de sauvegarde de base correspondant à ce localisateur, stockent un marqueur non secret et sont restaurées sans paramètres supplémentaires lors de la restauration ; pour les sauvegardes créées avec des identifiants explicites de sauvegarde de base différents ou des arguments d’authentification supplémentaires pour la sauvegarde de base, transmettez-les à RESTORE avec le paramètre base_backup. Les sauvegardes créées par des versions antérieures avec des identifiants intégrés restent restaurables. #107357 (pamarcos).
  • Corrige RESTORE pour les tables ReplicatedMergeTree afin que les parties au contenu dupliqué d’une sauvegarde soient conservées au lieu d’être dédupliquées silencieusement. #107652 (pamarcos).
  • Un espace réservé {_partition_id} dans le chemin d’un moteur de type fichier (S3, AzureBlobStorage, URL, etc.) sans partition_strategy explicite implique de nouveau la stratégie wildcard, indépendamment de file_like_engine_default_partition_strategy. Cela rétablit la rétrocompatibilité des DDL antérieurs à la version 26.6 qui commençaient à échouer avec BAD_ARGUMENTS (“Partition strategy hive can not be used with a ‘_partition_id’ wildcard in the path”). #111279 (fm4v).

Correctifs de ClickHouse Keeper

  • Corrige le nettoyage des snapshots de Keeper après des écritures échouées, afin que les snapshots partiels soient supprimés en toute sécurité et que les écritures puissent être réessayées sans faire progresser latest_snapshot_meta. #105779 (antonio2368).
  • Corrige les défaillances de Keeper lors du rattrapage d’un follower, lorsque la nouvelle file de réponses du répartiteur de requêtes pouvait se remplir avant le démarrage du thread de réponse. #106049 (antonio2368).
  • Corrige un blocage occasionnel de Keeper au démarrage lorsque le paramètre nuraft_max_log_gap_in_stream est défini sur une valeur autre que celle par défaut (0, c’est-à-dire que le pipeline des requêtes append_entries est désactivé). #106220 (al13n321).
  • Le TLS Raft interne de Keeper respecte désormais le paramètre openSSL.client.verificationMode. Auparavant, la vérification des certificats des pairs était toujours activée pour les communications Raft entre instances Keeper, indépendamment de ce paramètre, de sorte que none était ignoré silencieusement. Désormais, none désactive explicitement la vérification des certificats des pairs Raft, tandis que l’absence de paramètre conserve le comportement précédent, sécurisé par défaut. Après la mise à niveau, les configurations qui définissent explicitement none ne vérifieront plus les certificats des pairs Raft, conformément à la configuration définie. #106726 (antonio2368).
  • Corrige la recréation intempestive de sessions ZooKeeper lors du rechargement de la configuration. #107096 (azat).
  • Corrige un bogue dans ClickHouse Keeper où les métadonnées de snapshot signalées via last_snapshot (et zk_latest_snapshot_size dans mntr) pouvaient régresser après l’installation d’un snapshot obsolète ou dupliqué. Cela pouvait également permettre à un snapshot local ayant le même index d’écraser un fichier de snapshot enregistré alors qu’il était encore transmis en flux à un pair ou téléversé vers S3. #107321 (antonio2368).
  • Corrige le blocage d’une vue matérialisée actualisable si la connexion à ZooKeeper est perdue au mauvais moment. #108234 (al13n321).
  • Corrige les mutations utilisant un paramètre de requête comme partition (ALTER TABLE ... UPDATE/DELETE ... IN PARTITION {param:Type}) : la valeur de partition substituée était sérialisée dans l’entrée de mutation sous une forme qui ne pouvait pas être analysée de nouveau, ce qui empêchait le chargement de la table (pour les tables répliquées, sur chaque réplique). Les commandes de mutation sont désormais également vérifiées pour s’assurer qu’elles peuvent être analysées de nouveau avant d’être écrites dans ZooKeeper ou sur disque, afin qu’une incompatibilité similaire fasse échouer la requête ALTER plutôt que de rendre la table inutilisable. #111518 (al13n321).
  • Corrige un dépassement numérique lors de l’analyse des données pour system.zookeeper_info. #111629 (kssenii).

Correctifs de plantages et de stabilité

  • Corrige l’exception NOT_FOUND_COLUMN_IN_BLOCK lors de l’utilisation de LIMIT BY avec des colonnes constantes, ainsi que de DISTINCT et ORDER BY avec le nouvel analyseur. #93195 (ashrithb).
  • Améliore la stabilité de la connexion HiveCatalog en ajoutant un mécanisme de tentatives automatiques et une logique de reconnexion pour gérer les erreurs TTransportException lors des communications avec Hive Metastore. #98471 (otselnik).
  • Corrige le repliement de constantes lors de l’analyse pour les fonctions à court-circuit (if, multiIf, and, or, etc.), afin que les branches statiquement inaccessibles ne lèvent plus d’exceptions lors de l’analyse. Par exemple, WITH 0 AS n SELECT multiIf(n = 0, 0, intDiv(100, n)) renvoie désormais correctement 0 au lieu d’échouer avec une erreur de division par zéro. #103157 (fastio).
  • Corrige un arrêt du serveur lorsque runningAccumulate était appelée sur une fonction d’agrégation renvoyant son propre état. #105085 (antaljanosbenjamin).
  • Corrige getServerSetting afin qu’il renvoie la valeur effective actuelle des paramètres serveur modifiables à l’exécution (tels que max_server_memory_usage, mark_cache_size, max_concurrent_queries, les tailles des pools de threads, etc.), conformément à ce que renvoie system.server_settings. #105172 (alexey-milovidov).
  • Corrige l’exception NOT_FOUND_COLUMN_IN_BLOCK lors de la combinaison de ORDER BY ... WITH FILL INTERPOLATE et LIMIT N BY avec l’analyseur activé. #105481 (yakov-olkhovskiy).
  • Corrige une exception du serveur (erreur logique Trying to execute PLACEHOLDER action) lorsqu’une CTE MATERIALIZED dont le corps est une sous-requête corrélée est utilisée comme opérande droit de IN. Une telle CTE est désormais rejetée lors de l’analyse, comme c’est déjà le cas lorsque le même modèle est référencé directement dans FROM. #105518 (groeneai).
  • Corrige le fait que variant_throw_on_type_mismatch/dynamic_throw_on_type_mismatch=false ne capture pas les exceptions lors de l’exécution des fonctions. #105543 (Avogar).
  • Corrige l’exception NOT_FOUND_COLUMN_IN_BLOCK lorsqu’une expression TTL référence une sous-colonne. #105578 (Avogar).
  • Corrige un crash du serveur pouvant survenir lorsqu’une requête lisant des données depuis PostgreSQL — via la fonction de table postgresql, le moteur de table PostgreSQL ou un dictionnaire utilisant une source PostgreSQL — était annulée (par exemple avec KILL QUERY) et que l’annulation de la requête PostgreSQL distante échouait. #105949 (rorylshanks).
  • Corrige un éventuel crash dû à un littéral de chaîne trop volumineux envoyé dans la requête. #105996 (nickitat).
  • Corrige l’exception INVALID_WITH_FILL_EXPRESSION lors de l’utilisation de INTERPOLATE () (vide) avec un préfixe de tri dans ORDER BY et use_with_fill_by_sorting_prefix activé. Les colonnes du préfixe de tri sont désormais correctement exclues de l’ensemble d’interpolation implicite, conformément au comportement de INTERPOLATE (col) lorsque les colonnes sont explicitement nommées. #106001 (yakov-olkhovskiy).
  • Les états AggregateFunction(uniqTheta, ...) mal formés provenant d’une entrée RowBinary ou de paramètres de requête sont désormais rejetés avec CORRUPTED_DATA au lieu d’entraîner l’arrêt du serveur. #106260 (groeneai).
  • Corrige un crash et une possible erreur NOT_FOUND_COLUMN_IN_BLOCK lorsque l’optimisation basée sur les contraintes (optimize_using_constraints) est utilisée avec des sous-requêtes corrélées. #106349 (Algunenano).
  • Corrige l’exception NUMBER_OF_COLUMNS_DOESNT_MATCH lors de l’interrogation d’une table Distributed comportant au moins deux colonnes ALIAS qui se développent en la même expression (par ex. toutes deux définies comme toString(x)), ou lorsque la même expression est écrite à la fois comme référence à une colonne ALIAS et directement dans la liste SELECT, avec une clause ORDER BY. #106404 (yakov-olkhovskiy).
  • Corrige l’erreur LOGICAL_ERROR “Trying to get name of not a column: ExpressionList” générée par des requêtes qui transmettent un astérisque dans multiIf comme argument d’une fonction de table, par ex. numbers(multiIf(*, ...), 2). La requête rejette désormais ce sélecteur impossible à résoudre avec UNSUPPORTED_METHOD. #106647 (groeneai).
  • Rejette les motifs glob pathologiques de file qui entraîneraient une récursion non bornée lors de l’énumération de répertoires. Une profondeur de récursion maximale de 1000 est désormais appliquée ; les requêtes qui la dépassent génèrent TOO_DEEP_RECURSION au lieu d’interrompre le serveur par dépassement de pile. #106676 (groeneai).
  • Corrige l’exception 'Trying to read from input() twice.' générée lorsque la fonction de table input est encapsulée dans une CTE non-MATERIALIZED référencée à plusieurs endroits dans la requête. La requête est désormais rejetée avec l’erreur explicite INVALID_USAGE_OF_INPUT lors de la planification. input est un flux client à usage unique et ne peut être consommé que par une seule source dans le plan de requête. #106682 (groeneai).
  • Corrige les colonnes incohérentes (qui entraînent ultérieurement une erreur LOGICAL_ERROR) en cas d’exception (par ex. MEMORY_LIMIT_EXCEEDED) durant l’analyse syntaxique. #106802 (azat).
  • Corrige un crash du serveur (SIGSEGV) lors de la lecture de données Protobuf tronquées avec input_format_allow_errors_num > 0. #106905 (atsarevskiy).
  • Corrige un crash du serveur (déréférencement d’un pointeur nul) lors de l’exécution de TRUNCATE ou DROP sur une table EmbeddedRocksDB dont le handle RocksDB a été libéré, par exemple une table read_only dont le répertoire de données a été vidé par un TRUNCATE antérieur. #106940 (groeneai).
  • Corrige une exception (std::length_error signalée comme une LOGICAL_ERROR) lors de la lecture à partir d’une fonction de table *Cluster, telle que urlCluster, avec un paramètre max_streams_for_files_processing_in_cluster_functions très élevé. Le nombre de flux est désormais limité à une valeur raisonnable. #106946 (groeneai).
  • Corrige l’arrêt du serveur lorsqu’une requête distribuée était annulée immédiatement avant son envoi à un shard. #106950 (groeneai).
  • Correction d’une exception du serveur (erreur logique this->visited_views == right->visited_views) lors d’un INSERT lorsque deux vues matérialisées sur la même table source écrivent dans la même table cible et qu’une vue dépendante lit cette dernière, avec materialized_views_squash_parallel_inserts activé. #107027 (groeneai).
  • Correction d’une exception LOGICAL_ERROR lors de l’insertion dans une table DeltaLake dont les colonnes ne correspondent pas à son schéma d’écriture (par exemple, une colonne Nested qui est aplatie en sous-colonnes, ou une fonction de table avec un sous-ensemble explicite de colonnes). Ces insertions échouent désormais avec une erreur INCOMPATIBLE_COLUMNS signalée à l’utilisateur. #107058 (groeneai).
  • Correction d’une LOGICAL_ERROR (“Table expression … data must be initialized”) déclenchée lorsqu’un sélecteur astérisque qualifié (par exemple x.*) référençait une CTE récursive par son nom dans son propre terme récursif. Ces sélecteurs développent désormais les colonnes de la table récursive, comme le font déjà à cet emplacement une colonne qualifiée (x.a) ou un sélecteur non qualifié (*). #107144 (groeneai).
  • Correction d’une LOGICAL_ERROR (“Unexpected exception in refresh scheduling”) qui pouvait entraîner le serveur dans une boucle de plantages au redémarrage lorsqu’une vue matérialisée actualisable possède une dépendance REFRESH ... DEPENDS ON <name> dont le nom non qualifié correspond à une table temporaire ou à un nom de CTE. #107156 (groeneai).
  • Correction d’une LOGICAL_ERROR (Variant N (T) has size X, but expected Y) lorsqu’une fonction telle que toString ou concat est appliquée à une colonne Variant ou Dynamic contenant un seul variant non vide ainsi que des valeurs NULL, et que la fonction renvoie sa colonne d’entrée inchangée. #107374 (groeneai).
  • Correction d’une LOGICAL_ERROR (block.rows() == getRows()) déclenchée lors d’un INSERT asynchrone dans une table Alias lorsque use_strict_insert_block_limits était activé. #107400 (groeneai).
  • Correction d’une exception du serveur (Logical error: Not-ready Set is passed as the second argument for function 'in') lorsqu’une expression de clé (ORDER BY, PRIMARY KEY, PARTITION BY ou un INDEX de saut) contenait un opérateur IN avec une table à droite, par exemple ORDER BY (x IN some_table). Ces expressions de clé sont désormais rejetées lors de la création de la table. #107424 (groeneai).
  • Correction d’un plantage rare du serveur lors du traitement de DISTINCT, qui pouvait se produire lorsqu’une allocation échouait (par exemple, lorsqu’une limite de mémoire était atteinte) pendant l’initialisation de l’ensemble de clés distinctes. #107467 (groeneai).
  • Correction des échecs d’opérations DeltaLake après l’expiration d’informations d’identification S3 temporaires, grâce à l’actualisation des informations d’identification mises en cache avant l’opération suivante. Les informations d’identification STS assume-role sont également actualisées après des échecs d’authentification. #107480 (ahmadov).
  • Correction d’une Not-ready Set is passed as the second argument for function 'in' (LOGICAL_ERROR) lors de l’interrogation d’une table avec une clé PARTITION BY et une sous-requête IN/NOT IN intégrée à une expression plus large, par exemple WHERE (c0 IN (SELECT ...)) != 0. #107515 (groeneai).
  • Corrige un crash (déréférencement de pointeur nul) pouvant survenir lors de l’exécution locale d’un plan de requête distribué (make_distributed_plan + distributed_plan_execute_locally) avec log_formatted_queries = 1. #107570 (groeneai).
  • Corrige un crash du serveur lors de la lecture d’une vue matérialisée dont la cible est une table Distributed, lorsque la requête s’exécute avec enable_analyzer = 0. #107653 (groeneai).
  • Corrige un crash du serveur (SIGSEGV) lors de la lecture de données Protobuf avec input_format_allow_errors_num > 0, lorsqu’un message valide précède un message incorrect (pouvant être ignoré) dans le même bloc. #107739 (atsarevskiy).
  • Corrige le blocage pendant plusieurs minutes des fonctions de table odbc et jdbc, qui ignoraient l’annulation des requêtes (KILL QUERY, max_execution_time) lorsque le pont ne répondait plus pendant l’inférence de la structure de la table distante. #107809 (alexey-milovidov).
  • Corrige un possible crash (déréférencement de pointeur nul) lorsque la surcharge database/db d’une collection nommée passée à remote()/remoteSecure() n’est pas un nom de base de données constant, par exemple remote(nc, database = (SELECT 1)). La requête échoue désormais avec une erreur explicite au lieu de provoquer un crash. #108271 (groeneai).
  • Les requêtes de recherche vectorielle qui sélectionnent la colonne _distance renvoient désormais une erreur appropriée au lieu d’échouer avec une LOGICAL_ERROR. #108423 (rschu1ze).
  • Corrige un possible crash (dépassement de tampon sur le tas) lorsqu’une colonne d’état de fonction d’agrégation de la famille quantileTDigest était utilisée comme clé GROUP BY et sérialisée simultanément par plusieurs threads. #110263 (groeneai).
  • Corrige un élagage incorrect lors de l’analyse de l’index de clé primaire sur les tables dotées d’une clé de tri inverse (décroissante) (ORDER BY (g, r DESC)). Un granule couvrant un changement dans une colonne de clé principale, suivi d’une colonne de clé décroissante, pouvait être élagué à tort, supprimant ainsi des lignes correspondantes. #111059 (nihalzp).
  • Corrige une erreur logique block.rows() == getRows() (une lecture hors limites et une déduplication d’insertion défectueuse dans les builds de production) lorsqu’un INSERT passe par une vue matérialisée dépendante dont la cible est un Alias et dont la requête interne modifie le nombre de lignes, avec une table assurant la déduplication accessible derrière l’alias. #111103 (alexey-milovidov).
  • Corrige une erreur de segmentation due à un accès mémoire hors limites lors de la désérialisation d’un état de fonction d’agrégation malformé contenant une valeur String. Ces états sont désormais validés et rejetés au lieu d’entraîner des erreurs de segmentation. #111606 (mstetsyuk).
  • Corrige un crash lors de la lecture d’un fichier Parquet avec des métadonnées de filtre de Bloom incohérentes. Ces fichiers pouvaient également renvoyer silencieusement moins de lignes que prévu. #112498 (tiandiwonder).
  • Corrige un segfault et une corruption silencieuse des données lorsqu’un INSERT dans le moteur File ou la fonction de table file ajoute des données à un fichier non vide dans un format qui ne prend pas en charge l’ajout, tel que Avro. L’écriture via un descripteur de fichier ou un chemin partitionné contournait la vérification existante : le préfixe de format était alors omis et un second en-tête était écrit après les octets existants, rendant le fichier illisible. Un tel INSERT est désormais rejeté avec CANNOT_APPEND_TO_FILE, comme c’était déjà le cas pour un chemin simple. #112839 (groeneai).
  • Corrige le blocage de DROP TABLE et de SYSTEM STOP VIEW lorsqu’une vue matérialisée actualisable est bloquée pendant la planification de sa requête d’actualisation. #113188 (evillique).
  • Corrige un arrêt rare du serveur lorsque des entrées de la file d’insertions asynchrones avaient des échéances identiques. #113363 (mstetsyuk).
  • Corrige une corruption de la mémoire du tas lors de la lecture de Parquet via un format d’entrée qui possède son propre tampon de lecture, par exemple un dictionnaire avec SOURCE(FILE(... format 'Parquet')). Les tâches d’extraction anticipée et de décodage en arrière-plan pouvaient encore lire et écrire dans le tampon après que le pipeline l’avait libéré, ce qui pouvait arrêter le serveur. #114668 (groeneai).
  • Corrige un blocage lors de la suppression d’une table TimeSeries dont le nom est classé lexicographiquement avant ceux de ses tables internes, par exemple une table nommée -ts, ou lors de la suppression d’une vue matérialisée déclarée avec ENGINE = TimeSeries. La suppression entraînait un auto-interblocage sur le verrou DDL et ne pouvait pas être annulée avec KILL QUERY. #114953 (groeneai).

Autres corrections de bogues

  • Les fonctions like, ilike, notLike, notILike et match prennent désormais en charge une chaîne de recherche constante avec un motif non constant (p. ex. 'foo' LIKE pattern_column), ce qui provoquait auparavant ILLEGAL_COLUMN. #100479 (Onyx2406).
  • Correction de l’erreur NOT_FOUND_COLUMN_IN_BLOCK lors d’une sélection depuis une VIEW sur une table comportant une projection standard. #101218 (amosbird).
  • Rejet des valeurs Float64 négatives (p. ex. -100.5) dans les paramètres de charge tels que max_bytes_per_second, max_cpus, etc. Auparavant, seuls les entiers négatifs étaient validés, ce qui permettait aux flottants négatifs de créer silencieusement des nœuds de planificateur défectueux. #101842 (groeneai).
  • Les lectures depuis le stockage d’objets réagissent désormais rapidement à l’annulation des requêtes. #103016 (SmitaRKulkarni).
  • Correction du problème où input_format_max_block_size_bytes était silencieusement ignoré lors de l’analyse d’INSERT lorsque max_insert_block_size_bytes vaut 0 (valeur par défaut). Ce paramètre limite désormais correctement la taille des blocs produits par les formats d’entrée orientés lignes. #103068 (Fgrtue).
  • Correction d’un problème où ClickHouse produisait occasionnellement des jetons GSSAPI non valides en raison d’une suppression incorrecte des octets nuls de fin. #103114 (EmeraldShift).
  • EXPLAIN SYNTAX développe les vues paramétrées. #103263 (jrdi).
  • Correction de la corruption de données lors de l’écriture de fichiers Parquet (et d’autres formats avec pied de page, tels que ORC et Arrow) dans HDFS via INSERT INTO FUNCTION hdfs(...). Depuis la version 26.1, WriteBufferFromHDFS ne vidait pas son tampon de travail lors de finalize(), si bien que les derniers DBMS_DEFAULT_BUFFER_SIZE octets de chaque fichier pouvaient être silencieusement perdus, y compris le pied de page Parquet PAR1. La lecture de tels fichiers renvoyait Not a Parquet file (wrong magic bytes at the end of file). #103268 (groeneai).
  • Correction de résultats erronés et d’une possible erreur logique pour les sous-requêtes corrélées lorsqu’une limite de taille de jointure (max_rows_in_join / max_bytes_in_join) est définie avec join_overflow_mode = 'break'. La jointure créée en interne pour évaluer une sous-requête corrélée ignore désormais ces limites définies par l’utilisateur, et ne peut donc plus s’arrêter prématurément ni omettre des lignes. #103322 (groeneai).
  • Correction de résultats erronés ou d’une projection non utilisée lorsqu’une projection agrégée contient plusieurs agrégats sumIf avec différentes conditions IN (...). #104765 (Ergus).
  • Correction de deltaSumTimestamp, qui renvoyait des résultats erronés pour les types entiers signés passant par zéro. #104830 (thevar1able).
  • Correction de l’erreur Logical error: 'Metadata is not initialized' déclenchée par DELETE FROM sur une table Iceberg, DeltaLake ou Hudi nouvellement attachée, dont le fichier de métadonnées est corrompu ou ne peut pas être chargé. Une exception standard destinée à l’utilisateur est désormais renvoyée et le serveur continue de fonctionner. #104917 (groeneai).
  • Les requêtes ATTACH TABLE name <clauses>; qui fournissent des clauses de stockage (ORDER BY, PARTITION BY, PRIMARY KEY, SAMPLE BY, TTL, UNIQUE KEY ou des SETTINGS de moteur) sans ENGINE génèrent désormais l’erreur BAD_ARGUMENTS, au lieu de rattacher silencieusement la table à partir de sa définition stockée tout en ignorant les clauses fournies par l’utilisateur. Les SETTINGS de session au niveau de la requête (tels que log_comment) sont toujours appliqués. Utilisez ATTACH TABLE t; pour rattacher la table avec ses métadonnées stockées, ou ALTER TABLE t MODIFY SETTING ... après ATTACH pour modifier les paramètres. #105068 (groeneai).
  • Correction d’un dépassement de tampon sur le tas lors de la lecture de fichiers Arrow ou ArrowStream contenant des décalages intermédiaires corrompus dans une colonne binaire ou de chaînes, ainsi que d’un déréférencement de pointeur nul lors de la lecture de colonnes Arrow géoballisées. #105449 (Algunenano).
  • Correction d’un arrêt du serveur lors de la lecture de sous-colonnes Dynamic depuis une table Memory compressée après un ALTER. #105464 (Avogar).
  • Ajout de skip_first_lines à la clé du cache de schéma pour les formats WithNames. #105469 (Avogar).
  • Correction de histogram, qui produisait des résultats erronés pour de petites entrées non triées. #105548 (Avogar).
  • Correction de l’utilisation de la table d’insertion dans les fonctions de table lorsque optimize_trivial_insert_select est activé. #105555 (Avogar).
  • Correction de la fonction de fenêtre estimateCompressionRatio, qui perdait les données accumulées entre les lignes. #105581 (Avogar).
  • L’extraction des valeurs de partition Hive respecte désormais le paramètre cast_string_to_date_time_mode et accepte par défaut les timestamps ISO 8601 avec des suffixes de fuseau horaire (par ex. +0000, +00:00, Z) dans les clés de partition. #105584 (alexey-milovidov).
  • Correction de la récupération après erreur du format d’entrée Template à la suite de lignes mal formées. #105735 (niyue).
  • Correction du formatage de SYSTEM INSTRUMENT ADD afin que les arguments du gestionnaire soient séparés par une seule espace, et rejet des listes d’arguments d’instrumentation SLEEP non valides contenant plus de deux valeurs ou une plage dont le minimum est supérieur au maximum. #105984 (pamarcos).
  • Correction de l’échec silencieux des opérations de partition ALTER TABLE pour les clés de partition Bool. #106004 (Avogar).
  • Correction de JSONExtractRaw et JSONHas pour les chemins JSON typés avec des valeurs par défaut. #106005 (Avogar).
  • Correction d’un préfixe / incorrect pour les chemins de base vides dans les configurations de lac de données. #106013 (thewisenerd).
  • Correction de system.dictionaries, qui renvoyait 0 ligne lorsqu’une révocation partielle de SHOW DICTIONARIES était appliquée. #106105 (Avogar).
  • Correction de résultats incorrects pour les requêtes sur des tables dont ORDER BY contient une fonction monotone décroissante telle que (c0 / -42) ou intDiv(c0, -42). Les prédicats sur la colonne sous-jacente (par exemple, c0 < 0) pouvaient à tort exclure des granules contenant des lignes correspondantes, entraînant l’absence de certains résultats. #106136 (nihalzp).
  • Ajout d’une validation des états d’agrégat DDSketch malformés lors de l’insertion. #106236 (yariks5s).
  • Correction de la cohérence du cache du système de fichiers après l’échec de rétrogradations SLRU, empêchant les entrées de rester bloquées dans un état d’éviction. Correction également du redimensionnement du cache segmenté System/Data et du nettoyage de l’espace libre, afin que les limites soient mises à jour atomiquement et que l’espace puisse être récupéré dans les deux segments du cache. #106286 (kssenii).
  • Correction d’une conversion incorrecte de valeurs Float16 subnormales en Float32 (par exemple lors de leur lecture depuis des fichiers .npy Numpy), causée par un décalage de mantisse d’une unité. #106343 (jh0x).
  • Correction de regexpExtract(haystack, pattern) afin que les motifs sans groupe de capture renvoient la correspondance complète au lieu de lever INDEX_OF_POSITIONAL_ARGUMENT_IS_OUT_OF_RANGE. #106374 (groeneai).
  • Correction d’une erreur logique lors de la création d’un dictionnaire de polygones à partir de données source contenant des coordonnées de points NaN ou infinies. Ces coordonnées sont désormais rejetées avec un message d’erreur explicite. #106423 (alexey-milovidov).
  • Les dictionnaires HTTP peuvent désormais spécifier des en-têtes de requête via des collections nommées. #106459 (ZelvaMan).
  • Les valeurs d’énumération Avro malformées sont désormais validées et rejetées avec une exception au lieu de provoquer un accès mémoire hors limites et l’arrêt du serveur. #106476 (mstetsyuk).
  • Correction de LIMIT WITH TIES et de LIMIT WITH TIES fractionnaire, qui ne respectaient pas la collation de ORDER BY ... COLLATE lors de la détermination des ex æquo. Les lignes égales selon la collation (par exemple '1' et '01' avec une collation numérique) étaient comparées octet par octet, de sorte que certaines lignes ex æquo étaient à tort exclues du résultat. #106539 (nihalzp).
  • Correction des optimisations DISTINCT in order et LIMIT BY in order (y compris LIMIT BY négatif), qui renvoyaient des résultats incorrects lorsque l’entrée était triée avec une collation (ORDER BY ... COLLATE). Les lignes égales selon la collation (par exemple 'a' et 'A' avec une collation insensible à la casse) sont ordonnées par clé de collation et ne sont pas adjacentes en termes de valeur ; l’optimisation in order est donc désormais ignorée lorsqu’un collateur est utilisé. #106564 (nihalzp).
  • Correction d’une condition de concurrence lors de l’arrêt d’un consumer NATS qui pouvait entraîner l’arrêt du serveur. #106692 (mstetsyuk).
  • Correction de plusieurs problèmes de sûreté mémoire et d’épuisement des ressources dans des lecteurs de formats accessibles via des entrées non fiables : une lecture hors limites du tas dans le traitement, par le lecteur Parquet natif, des longueurs des niveaux de définition et de répétition de DataPageV2, un débordement de pile avec des fichiers Parquet dont les schémas sont profondément imbriqués, et des allocations ignorant max_memory_usage lors de l’analyse de géométries WKB/WKT GeoParquet et de chaînes/octet Avro. #106739 (Algunenano).
  • Correction de keeper_server.http_control.secure_port, qui envoyait des réponses HTTP en clair aux clients HTTPS. Le port sécurisé répond désormais correctement en HTTPS. #106822 (linjiayu1025-collab).
  • Correction de SHOW CREATE ROW POLICY, qui produisait restrictive/permissive en minuscules au lieu de majuscules, contrairement aux autres mots-clés. #106865 (valerypetrov).
  • Correction du marquage de parties comme corrompues et de leur détachement lors de tout rechargement de partie (redémarrage du serveur, DETACH ou ATTACH) pour les tables dont la clé de partition contient une colonne LowCardinality(Nullable(...)). Depuis la version 26.5, le fichier d’index minmax par partie n’était pas écrit lorsque le minimum et le maximum d’une telle colonne étaient NULL, alors que la vérification de cohérence des parties exigeait toujours ce fichier. Les parties écrites par les versions concernées ne disposent pas du fichier d’index minmax et doivent encore être rattachées manuellement. #106945 (PedroTadim).
  • Correction de elapsed_us, qui était toujours égal à zéro, et du sous-comptage de read_rows/read_bytes dans system.processors_profile_log et system.query_log pour les requêtes de vidage d’insertions asynchrones (AsyncInsertFlush). #106982 (cwurm).
  • Correction d’une erreur logique Block structure mismatch in UnionStep stream (arrêt du serveur sur les builds de débogage/avec sanitizer, Code: 49 sur les builds de production) qui se produisait lorsqu’une branche d’un UNION/INTERSECT/EXCEPT lisait une colonne sérialisée Sparse, tandis que l’autre branche lisait la même colonne en entier (par exemple lors d’une insertion dans une vue matérialisée). #107041 (groeneai).
  • Correction d’un ordre de lignes incorrect dans les requêtes ORDER BY sur UNION ALL avec optimize_read_in_order et read_in_order_use_virtual_row activés. #107053 (vdimir).
  • Correction d’une erreur de syntaxe lorsqu’une clause FORMAT, SETTINGS ou INTO OUTFILE suit SHOW ROW POLICIES ou SHOW MASKING POLICIES (par ex. SHOW ROW POLICIES FORMAT TabSeparated). #107061 (groeneai).
  • Correction de trimLeft, trimRight et trimBoth (ainsi que des alias ltrim, rtrim, trim) qui généraient TOO_LARGE_STRING_SIZE lorsque le jeu de caractères de suppression personnalisé dépassait 16 caractères. Les jeux de caractères de suppression, quelle que soit leur longueur, sont de nouveau pris en charge. #107071 (fm4v).
  • Correction d’un dépassement d’entier signé dans quantileExactExclusive, quantilesExactExclusive, quantileExactInclusive et quantilesExactInclusive, qui pouvait produire un résultat incorrect pour des entrées Int64 couvrant une vaste plage de valeurs. #107154 (groeneai).
  • Les rechargements de configuration ne relancent plus les scripts de démarrage, empêchant ainsi l’exécution répétée d’actions de démarrage ponctuelles. #107187 (mstetsyuk).
  • Correction d’un ordre de résultat incorrect pour ORDER BY sur UNION ALL avec optimize_read_in_order activé lorsque le pipeline d’union était réduit en raison du paramètre max_streams_for_union_step ; cette réduction est désormais ignorée lorsque le plan dépend de flux de sortie UNION triés. #107208 (vdimir).
  • Correction d’un possible déréférencement de pointeur nul lors de la résolution de la configuration du proxy pendant la phase finale d’arrêt du serveur. #107231 (PedroTadim).
  • Correction de ORDER BY ... WITH FILL, qui produisait des lignes supplémentaires lorsqu’une colonne ORDER BY précédant la colonne de remplissage utilisait une collation COLLATE. Les lignes sont désormais regroupées par préfixe de tri à l’aide de cette collation, conformément à l’ordre de tri. #107365 (groeneai).
  • Correction d’un comportement indéfini lorsqu’une valeur à virgule flottante non finie (telle que nan ou inf) est transmise comme argument d’horodatage/de durée aux fonctions de table prometheusQuery / prometheusQueryRange. Un tel argument déclenche désormais BAD_ARGUMENTS au lieu de produire un horodatage erroné. #107417 (groeneai).
  • Correction de résultats incorrects dus à l’optimisation optimize_rewrite_aggregate_function_with_if pour les fonctions d’agrégation qui préservent les valeurs utiles NULL (famille *_respect_nulls : anyRespectNulls, first_value_respect_nulls, anyLast_respect_nulls, last_value_respect_nulls). L’optimisation ne réécrit plus f(if(cond, x, NULL)) sous la forme -If pour ces fonctions. #107430 (groeneai).
  • Ajout d’une validation des limites mal formées dans les entrées ORC. #107580 (al13n321).
  • Correction d’un déni de service non authentifié par épuisement de la mémoire sur le port du protocole MySQL. #107599 (tiandiwonder).
  • Correction d’un problème rendant l’interface MySQL inutilisable avec MySQL Connector/J 8.2.0 et versions ultérieures (y compris 9.x). Le champ info du paquet OK est désormais encodé avec une longueur, comme sur le serveur MySQL, afin que le pilote JDBC puisse se connecter. #107693 (alexey-milovidov).
  • Correction d’une erreur logique Block structure mismatch in UnionStep stream (arrêt du serveur dans les builds de débogage/avec sanitizer, Code: 49 dans les builds de publication) qui survenait lorsque des branches sœurs d’un UNION/INTERSECT/EXCEPT ne différaient que par leur prédicat WHERE et que le prédicat de l’une d’elles était replié en constante dans une colonne Const. #107719 (groeneai).
  • La lecture de données Arrow et ArrowStream comportant des colonnes String ou Binary vides, produites par Apache Arrow Java avant la version 19.0.0 (y compris Apache Spark), ne déclenche plus INCORRECT_DATA. #107764 (Algunenano).
  • Les blocs Native mal formés dont le discriminateur Variant référence une variante inexistante sont désormais rejetés de façon sûre. #107991 (uwezkhan).
  • Correction d’une régression des performances lors de la lecture de colonnes Dynamic avec plusieurs threads. #107997 (Avogar).
  • Le paramètre de data lake obsolète storage_catalog_url est désormais correctement rejeté par la protection du catalogue (auparavant, seuls storage_catalog_type et storage_aws_access_key_id étaient vérifiés), et le message d’erreur répertorie tous les paramètres obsolètes. #108040 (alexey-milovidov).
  • Correction d’un problème où la fonction/moteur de table ArrowFlight rejetait une collection nommée omettant la clé facultative dataset, avec l’erreur No such key 'dataset'. #108041 (alexey-milovidov).
  • Les secrets et les informations d’identification sont désormais masqués dans system.query_views_log.view_query au lieu d’apparaître dans le SQL journalisé des vues. #108214 (Fidelaggio).
  • Correction de type_json_allow_duplicated_key_with_literal_and_nested_object, qui ne fonctionnait pas avec les chemins typés dans JSON. #108218 (Avogar).
  • Correction d’un comportement indéfini (pointeur nul passé à memcpy) dans les fonctions detectCharset et detectLanguageUnknown lorsque la chaîne d’entrée dépasse 32 768 octets et qu’aucun jeu de caractères ne peut être détecté. #108250 (groeneai).
  • Correction de l’erreur NOT_FOUND_COLUMN_IN_BLOCK pour les requêtes utilisant les colonnes virtuelles _part_starting_offset/_part_offset dans WHERE avec la matérialisation paresseuse. #108287 (vdimir).
  • Masquage des arguments secrets de fonctions telles que encrypt, decrypt et HMAC dans les sorties de EXPLAIN actions, EXPLAIN header et EXPLAIN PIPELINE lorsque format_display_secrets_in_show_and_select est désactivé (paramètre par défaut). #108386 (Algunenano).
  • CREATE OR REPLACE réussit désormais pour une vue matérialisée actualisable lorsque sa cible TO appartient déjà à cette même vue. Les cibles appartenant à une autre vue restent refusées. #108392 (evillique).
  • Le chemin du modèle utilisé par catboostEvaluate est désormais limité au répertoire user_files, comme pour file() et les sources de dictionnaires. Auparavant, la fonction acceptait un chemin de système de fichiers arbitraire sans vérification de confinement, ce qui permettait de vérifier l’existence de fichiers hors de user_files et d’en déclencher la lecture. Les modèles doivent désormais se trouver dans user_files. #108463 (groeneai).
  • Correction de CREATE OR REPLACE MATERIALIZED VIEW ... POPULATE, qui laissait la nouvelle vue non abonnée à sa table source, entraînant la perte silencieuse de chaque ligne insérée après le remplacement. #108728 (alexey-milovidov).
  • Correction d’une erreur de segmentation lors de la fusion d’états d’agrégat uniqExact avec GROUPING SETS, ROLLUP ou CUBE et max_threads > 1. #108928 (Algunenano).
  • Correction d’une possible erreur logique “Unexpected substream … for column …” lors de la mise à jour du paramètre de compatibilité. #109496 (Avogar).
  • La fonction getClientHTTPHeader traite désormais les noms d’en-têtes sans distinction entre majuscules et minuscules, conformément à la RFC 9110 ; en particulier, l’en-tête authorization est désormais filtré quelle que soit sa casse. #109791 (Felixoid).
  • Correction d’une perte silencieuse de données avec les insertions asynchrones et la déduplication (async_insert=1, async_insert_deduplicate=1). Lorsque plusieurs entrées async-insert avec des valeurs insert_deduplication_token distinctes étaient regroupées dans un seul flush écrivant dans des partitions disjointes, chaque jeton était enregistré dans le journal de déduplication de chaque partition concernée par le flush, et non seulement dans la partition où ses propres lignes avaient été écrites. Une insertion ultérieure réutilisant l’un de ces jetons dans une partition où il n’avait jamais écrit était alors silencieusement dédupliquée. Les jetons sont désormais enregistrés uniquement pour la partition où leurs lignes ont réellement été écrites. #111049 (groeneai).
  • Correction des insertions asynchrones au format Native afin qu’une entrée mise en mémoire tampon, devenue incompatible après ALTER ... MODIFY COLUMN, n’entraîne plus l’échec de l’ensemble du lot. #111108 (Felixoid).
  • Correction de CREATE OR REPLACE d’un dictionnaire par un objet d’un autre type : l’opération échouait avec CANNOT_DETACH_DICTIONARY_AS_TABLE alors que le remplacement avait déjà été validé, laissant une table _tmp_replace_* orpheline. #111142 (evillique).
  • Correction d’une fuite de mémoire liée au certificat pair lors des handshakes TLS avec vérification des certificats activée. #111425 (thevar1able).
  • Correction d’une erreur logique Block structure mismatch in IntersectOrExceptStep stream: different number of columns susceptible de se produire lorsque l’optimisation de fractionnement des filtres (query_plan_split_filter) s’exécutait sur une clause WHERE dont le nom de la colonne de filtre était également celui d’une colonne d’entrée. L’optimisation laissait une colonne interne __split_filter dans l’en-tête de sortie de la branche, qui différait alors de celui de la branche sœur d’une opération ensembliste telle que INTERSECT ou UNION. #111930 (groeneai).
  • Correction de résultats incorrects pour les filtres ou les expressions ORDER BY utilisant toString avec des valeurs Time, Time64 ou DateTime dans des fuseaux horaires appliquant l’heure d’été. Restauration également de l’optimisation de lecture dans l’ordre pour ORDER BY sur un préfixe de la clé de tri de la table et pour les conversions de String vers Nullable(String). #113291 (vdimir).
  • Correction de ATTACH d’une table Kafka lorsque kafka_num_consumers dépasse la limite dérivée du nombre de cœurs CPU. #113390 (evillique).
  • Désactivation de l’analyse distribuée des index lorsque des projections sont utilisées afin d’éviter des résultats de requête incorrects. #115132 (azat).
  • Correction d’un bug dans la fonction formatRowNoNewline susceptible de produire des résultats incorrects ou une erreur logique lorsqu’une ligne est formatée en résultat vide. #115669 (alexey-milovidov).
  • Ne renvoie plus de mémoire non initialisée dans le résultat d’un littéral de chaîne binaire dont la longueur n’est pas un multiple de huit, ni depuis le décompresseur LZ4 lorsqu’un bloc compressé n’a pas de corps. #115704 (alexey-milovidov).
  • Inclusion des chemins d’objet dans les hachages de déduplication afin d’empêcher la déduplication incorrecte de valeurs d’objet distinctes. #115866 (Felixoid).
Dernière modification le 26 septembre 2026