後方互換性を持たない変更
クエリ、関数、構文の変更
- 本体が単一の
Distributedテーブルに対する単純なSELECTであるビューについて、外側のクエリ全体が分片にプッシュダウンされるようになりました (新しい設定optimize_trivial_view_pushdown_to_distributed、デフォルトで有効) 。これにより、このようなビューで観測される動作が変わります。ビュー参照に記述されたFINALおよびSAMPLEは、無視されずに分片ローカルのテーブルへ伝播されるようになり、単一分片のクラスターではextremesが報告されなくなります。以前の動作に戻すには、optimize_trivial_view_pushdown_to_distributed = 0を設定してください。#101791 (simonmichal)。 - 軽量
UPDATEのパッチパートは、(sorting_key..., _block_number, _block_offset) でソートされた新しい v2 オンディスクフォーマットを使用し、新しいマージアルゴリズムで適用されるようになりました。ピークメモリ使用量の上限は、パッチ全体ではなく、ソートキーが等しい最大の連続範囲によって決まります。また、マージ境界をまたぐ更新が、メモリ上での Join による適用にフォールバックすることもなくなりました。旧フォーマットのパッチパートも引き続き読み取れます。26.8 より前のバージョンからローリングアップグレードを行う場合は、すべてのレプリカのアップグレードが完了するまでpatch_parts_version = 'v1'のままにするか、compatibility設定を使用してください。#103182 (CurtizJ)。 AggregatingMergeTreeは、ソートキーの一部でも集約状態のメジャー (AggregateFunction/SimpleAggregateFunction) でもないカラムを含むスキーマを、テーブル作成時に拒否するようになりました。このようなカラムはバックグラウンドマージ中に任意の値へと暗黙的に集約されてしまうため、そのカラムでGROUP BYやフィルタリングを行うクエリが誤った結果を返します。以前の動作に戻すには、allow_dimensions_outside_sorting_key = 1を設定してください。#108087 (alexey-milovidov)。- ClickHouse は、同期挿入と非同期挿入のいずれでも、常に統一された挿入の重複排除ハッシュを使用するようになり、挿入ごとのレガシーな重複排除の動作は削除されました。サーバー設定
insert_deduplication_versionは移行時の安全策として残されており、レガシーな値 (old_separate_hashesまたはcompatible_double_hashes) が設定されている場合、サーバーは起動しません。レガシーな値を使用していたバージョンからアップグレードするには、まずcompatible_double_hashes(レガシーと統一の両方のハッシュを書き込む) をサポートするリリースで運用してください。レプリケートテーブルの場合は、少なくともreplicated_deduplication_window_seconds(デフォルトは 1 時間。デフォルトのウィンドウでは、その期間内のすべての挿入の統一ハッシュが保持され、挿入のリトライループには十分とみなされます) の間運用してください。non_replicated_deduplication_window> 0 の非レプリケートテーブルの場合、そのウィンドウは時間ベースではなく件数ベースであるため、少なくともその件数の挿入が行われるまでcompatible_double_hashesで運用してください。その後、このバージョンにアップグレードする前に、設定を削除する (またはnew_unified_hashに設定する) 必要があります。#108361 (CheSema)。 - 設定
use_legacy_to_timeのデフォルトが0になったため、toTimeは日時を固定日付の値に変換するのではなく、値をTimeデータ型に変換するようになりました。レガシーな動作は、toTimeWithFixedDate関数を使用するか、use_legacy_to_time = 1を設定することで引き続き利用できます。#108729 (alexey-milovidov)。 - Naive Bayes モデル (
naiveBayesClassifierで使用) は、従来のサーバー側の設定 (シリアル化された.binモデルファイルを参照する XML 設定ファイル) ではなく、NAIVE_BAYESレイアウトを持つ Dictionary として設定するようになりました。この Dictionary は、クラスごとに事前集計された n-gram 出現回数のテーブルから、ロード時に構築されます。従来の方式はサポートされなくなったため、既存のモデルは Dictionary として再作成する必要があります。また、naiveBayesClassifierに加えて 3 つの新しい関数が追加されました。naiveBayesClassifierWithProbは予測されたクラスとその確率を返し、naiveBayesClassifierWithAllProbsはすべてのクラスとそれぞれの確率を返します。naiveBayesNgramsは Dictionary と同じ方法でテキストを n-gram にトークン化する関数で、ラベル付きの生テキストから学習データを構築する際に使用します。さらに、複数のパフォーマンス最適化も行われました。9.7 MiB のコードポイント trigram 言語モデルでは、メモリ使用量が約 49 分の 1 (1.84 GiB から 38 MiB) に削減され、ロードと分類はいずれも約 11 倍高速になっています。#108773 (nihalzp)。 max_insert_threads設定のデフォルト値が1(並列化なし) からautoに変更されました。autoは、サーバーで利用可能な CPU コア数に解決されます (メモリ逼迫時にはmax_insert_threads_min_free_memory_per_threadに基づいて減らされます) 。これにより、INSERT SELECTはデフォルトで並列実行されます。また、挿入先の書き込みパスを安全に分岐できる場合は、条件を満たす通常のINSERTでも書き込み側が並列化されることがあります。この変更により、作成されるパーツの数や挿入される行の順序が変わる可能性があります。以前の動作に戻すには、max_insert_threadsを1に設定するか、compatibilityを26.8より前のバージョンに設定してください。#109000 (alexey-milovidov)。#109006 (alexey-milovidov)。- CSV で単体の
Tupleを読み込む際、すべての位置で要素ごとに 1 つのフィールドを読み取るようになりました。そのため、トップレベル要素のフィールドにある\Nはその要素の値として扱われ、input_format_null_as_defaultもその要素に適用されます。以前は、先頭の\Nがカラム全体の null とみなされていたため、その行はカラムのデフォルト値に置き換えられ、残りの要素のセルはパースに失敗していました。この変更は、単体のTuple全体に対して 1 つのフィールドしか指定していない行については後方互換性がありません。そのような行は残りの要素分のフィールドが不足するため拒否されます。また、要素が 1 つのTupleではどちらの場合もフィールド数が変わらないため、カラムのDEFAULTではなく要素のデフォルト値が警告なしに返されます。このようなフィールドを従来どおりカラム全体として読み込むには、input_format_csv_deserialize_separate_columns_into_tuple = 0を設定してください。#109744 (groeneai)。 CREATE USERおよびALTER USERに、VALID UNTILの省略形としてVALID FOR <interval>句が追加されました。有効期限のデッドラインは、クエリ実行時点の現在時刻に指定したインターバルを加えて算出され、VALID UNTILの形式で保存されます。2106 年以降のデッドラインも正確に表現できるよう、system.usersテーブルのvalid_untilカラムの型はArray(DateTime)からArray(DateTime64(0))に変更されました。このカラムを読み取るツールは、新しい型に対応する必要があります。#110171 (alexey-milovidov)。EXPLAIN SYNTAXは、1 行ごとに 1 レコードを返す代わりに、整形済みのクエリを (改行を含む) 単一のStringレコードとして返すようになりました。これにより、出力は元のクエリを復元可能な単一の行となり、そのまま利用できます (たとえば、SELECT count() FROM (EXPLAIN SYNTAX ...)は1を返します) 。この動作は新しいsingle_recordオプションで制御され、デフォルトは1です。従来の 1 行 1 レコードの出力に戻すには、single_record = 0を設定してください。その他の種類のEXPLAIN(PLAN/PIPELINE/AST) は、引き続き行ごとのツリー形式で出力します。#110479 (alexey-milovidov)。hasColumnInTable関数は、任意のリモートサーバー上のカラムを確認するためのオプション引数hostname、username、passwordを受け付けなくなりました。今後はhasColumnInTable(database, table, column)の形式のみ使用できます。削除されたリモートモードにはセキュリティ上の問題がありました。任意のユーザーが任意のホストへの外向き接続を発生させることができ、認証情報がクエリログに漏洩するうえ、いかなる権限による制限も受けていなかったためです。#110881 (alexey-milovidov).PostgreSQLおよびMaterializedPostgreSQLデータベースエンジンは、PostgreSQLテーブルエンジン、postgresqlテーブル関数、DDL で作成されたディクショナリと同様に、サーバーのremote_url_allow_hosts設定に従うようになりました。このポリシーはCREATE DATABASEおよびユーザーが発行するATTACH DATABASEに適用されます。サーバーでremote_url_allow_hostsが設定されている場合、ホワイトリスト外のホストを指すPostgreSQLまたはMaterializedPostgreSQLデータベースを作成またはアタッチしようとすると、UNACCEPTABLE_URLエラーで拒否されます。既存のデータベースはサーバー起動時に引き続き読み込まれるため、アップグレードによってサーバーが起動できなくなることはありません。#111135 (alexey-milovidov).ArrowおよびArrowStreamフォーマット向けの、Apache Arrow ライブラリベースのリーダーとライターを削除しました。今後は、26.7 以降デフォルトとなっていた ClickHouse のネイティブ実装のみが使用されます。設定input_format_arrow_use_native_readerおよびoutput_format_arrow_use_native_writerは廃止されました。これらの設定は引き続き指定できますが効果はなく、Apache Arrow 実装を強制するために0に設定していたクエリでも、ネイティブ実装が使用されます。#111996 (alexey-milovidov).- MySQL ソースの TLS 認証情報 (
ssl_ca、ssl_cert、ssl_key) は、SQL からファイルパスとして指定できなくなりました。対象は、CREATE NAMED COLLECTIONで作成した名前付きコレクション、クエリ引数、CREATE DICTIONARYクエリです。これは、サーバーがこれらのファイルを自身の権限で開いてしまうためです。サーバー設定ファイルでは引き続きパスを指定できます。それ以外の場所では、証明書または秘密鍵の内容を新しいパラメータssl_ca_pem、ssl_cert_pem、ssl_key_pemで渡してください。これらのパラメータは、パスワードと同様にログおよびSHOWクエリでマスクされます。#112070 (alexey-milovidov). disable_insertion_and_mutationは、外部ストレージへの直接書き込みは許可したまま、Kafka、RabbitMQ、NATSテーブルによるバックグラウンドでのメッセージ消費を停止するようになりました。制限対象のKafka2、NATS、RabbitMQテーブルは、直接のSELECTに対してコンシューマーを初期化しません。また、最近導入されたmessage_queue_disable_insertion設定の変更にはサーバーの再起動が必要になりました。#113660 (cwurm).AggregateFunctionカラムに対するウィンドウのPARTITION BYまたはORDER BYは、トップレベルのORDER BYと同様に、ILLEGAL_COLUMNエラーで拒否されるようになりました。以前は、少なくとも一方のアナライザーでこのようなクエリが受け付けられており、ウィンドウのPARTITION BYによるパーティション分割の結果がmax_threadsによって異なっていました。この制限は、Array、Tuple、Map、Variant、SimpleAggregateFunctionにネストされたステートにも適用されます。通常の型に対するSimpleAggregateFunction、QBit、およびステートに対するGROUP BYとDISTINCTは影響を受けません。#113878 (groeneai).SYSTEM ... CACHE ON CLUSTERコマンドのアクセスチェックを修正しました。これらのコマンドは個々のコマンドに対応する権限ではなくSYSTEM DROP CACHE権限グループを要求していました。そのため、個別のキャッシュ権限のみを持つユーザーは実行を拒否される一方、グループ権限を持つユーザーはSYSTEM SYNC FILESYSTEM CACHE権限がなくてもSYSTEM SYNC FILESYSTEM CACHE ON CLUSTERを実行できていました。#114042 (groeneai).NATSテーブルエンジンは、新しいnats_credentials設定で認証情報をインラインで指定できるようになりました (ペイロードは.credsファイルと同じです) 。また、SQL からnats_credential_fileを指定することはできなくなりました。このパスはサーバーのファイルシステム上のファイルを参照し、サーバーが自身の権限でそのファイルを開くため、サーバー設定ファイルで定義された名前付きコレクション内、またはサーバー設定自体のnats.credential_fileでのみ指定できます。このように設定されたパスは、クエリ側でインラインのnats_credentialsに置き換えることができます。ただし、管理者が<nats_credential_file overridable="false">で固定している場合は置き換えられません。この制限が導入される前に作成されたテーブルは、アップグレード後も引き続き動作します。#114644 (alexey-milovidov).
データ型とフォーマットの変更
- オブジェクトストレージ上に保存されるバックアップ (
S3(...)/AzureBlobStorage(...)を直接指定する宛先、および S3 または Azure をバックエンドとするDisk(...)の宛先) では、BACKUPとRESTOREのいずれにおいてもzip/zipxバックアップアーカイブフォーマットを拒否するようにしました。Zip はセントラルディレクトリの読み取りにシークを必要とするため、オブジェクトストレージ上では非常に低速になります。代わりにtar.gzなどの tar ベースのフォーマットを使用してください。#101770 (Onyx2406). DateTime64のサポート範囲を[1900-01-01, 2299-12-31]から[0000-01-01, 9999-12-31]に拡張しました。従来の範囲外の値は、境界値に丸め込まれることなく (cctz により) 正しく計算されるようになりました。精度が 8 または 9 の場合は、ティックがInt64として保存されるため、範囲は引き続き狭くなります (ナノ秒精度での最大値は従来どおり2262-04-11です)。後方互換性: これまで範囲外の日時を使用し、旧範囲内での非常に特殊な飽和ルールに依存していた場合は、結果がより正確な値に変わる点に注意してください。#107907 (alexey-milovidov).JSONEachRowなどのフォーマットで、DateTime64/DateTimeカラムに対する引用符なしの JSON 数値は、Valuesフォーマット、CAST、toDateTime64と同様に、Unixタイムスタンプ (エポックからの秒数、サブ秒精度も指定可能) として解釈されるようになりました。これまでは、小数部を含む数値 (例:1703363853.035) はCANNOT_PARSE_INPUT_ASSERTION_FAILEDで拒否され、小数部のない整数 (例:1703363853) はDateTime64のスケーリング済みの生の値として読み込まれるため、1970-...のタイムスタンプになっていました。これはDateTime64カラムに引用符なしの整数を入力する場合における後方互換性を持たない変更です。引用符付きの文字列や、ClickHouse 自身が出力する (常に引用符付きの) JSON には影響しません。#108091 (alexey-milovidov).- 実験的な
ALPコーデックで、Float32のスケーリング演算をFloat64で実行するようになりました。これにより、小数データで発生していた例外が解消され、圧縮率も大幅に向上します。#111627 (rienath). - Int64 のマイクロ秒に換算するとオーバーフローする時間間隔設定 (ミリ秒/秒) の値を拒否するようにしました #112757 (azat).
- 非同期メトリクスで
Mapデータ型を使用できるようになり、CPU コアごとおよびデバイスごとのメトリクスは単一のキー・バリューのメトリクスに統合されました。たとえばOSUserTimeCPU0、OSUserTimeCPU1、… は、CPU コア番号と値の Map を持つ単一のOSUserTimeCPUメトリクスになりました (他のOS*TimeCPU*メトリクス、CPUFrequencyMHz_*、Temperature*、EDAC*、Block*_*、Network(Receive|Send)*_*、Disk*_*、*BlobsQueueEstimate、AsyncLogging*QueueSizeも同様です)。これに伴い、system.asynchronous_metricsには新たにkey_values Map(LowCardinality(String), Float64)カラムが追加され (該当するメトリクスではvalueカラムはNaNになります)、system.asynchronous_metric_logは新しいkeyカラムを用いてキーごとに 1 行ずつ記録し、Prometheus エンドポイントはラベル付きでエクスポートし (例:ClickHouseAsyncMetrics_BlockReadBytes{device="sda"})、Graphite のMetricsTransmitterは<prefix>.<Metric>.<key>として送信します。監視で旧メトリクス名を参照している場合は、asynchronous_metrics_key_values_modeをlegacy_namesに設定して旧名を維持するか、移行期間中はbothに設定してください。このサーバー設定は、再起動せずにSYSTEM RELOAD CONFIGで反映できます。#115333 (alexey-milovidov). #116791 (alexey-milovidov). - オブジェクトストレージディスクがデフォルトでネイティブのメタデータストレージトランザクションを使用するようになり、メタデータ更新の整合性が向上しました。#89658 (Michicosun)。
設定および構成の変更
- 長らく非推奨となっていた関数
snowflakeToDateTime、snowflakeToDateTime64、dateTimeToSnowflake、dateTime64ToSnowflakeを削除しました。これらは v24.6 の時点で非推奨となっており、代わりにsnowflakeIDToDateTime、snowflakeIDToDateTime64、dateTimeToSnowflakeID、dateTime64ToSnowflakeIDを使用してください。これらの関数を再び有効化するための設定allow_deprecated_snowflake_conversion_functionsは廃止され、指定しても効果はありません。#108711 (alexey-milovidov). Date32のサポート範囲を[1900-01-01, 2299-12-31]から[0000-01-01, 9999-12-31]に拡張し、DateTime64と揃えました。パースおよび変換では、従来の境界値に暗黙的に丸め込むことなく、拡張後の範囲を受け付けるようになりました。後方互換性に関する注記: 数値変換toDate32(N)では、[120530, 2932896]の範囲の値が、1970年初頭のUnixタイムスタンプではなく日数 (2300-01-01から9999-12-31までの日付) として解釈されるようになりました。これは、日数の範囲に収まる数値は日数として扱うというルールに沿ったものです。また、0000-01-01の日数を下回る数値や9999-12-31より後のタイムスタンプは、新しい境界値に飽和されます。#111534 (alexey-milovidov).
その他の後方互換性を持たない変更
arrayIntersectとarraySymmetricDifferenceは、1 つの引数内で繰り返し出現する値を、複数の引数に出現したものとして扱わなくなりました。このため、以前の動作に依存しているクエリは異なる結果を返す場合があります。たとえば、arrayIntersect([1], [2], [1, 1])は[1]ではなく[]を、arrayIntersect([1, 2], [2], [1, 1, 2])は[1, 2]ではなく[2]を、arraySymmetricDifference([1], [2], [1, 1])は[2]ではなく[2, 1]を返します。arraySymmetricDifferenceでは引数が 2 つの場合でも影響があり、arraySymmetricDifference([1], [2, 2])は[1]ではなく[2, 1]を返します。今後は、ある値がそれより前のすべての引数に存在する場合にのみ、その引数でカウントされます。これにより、結果にはすべての引数に存在する値だけが正確に含まれます。また、この変更に伴い、arrayIntersectはすべての引数ではなく最小の引数からハッシュテーブルを構築するようになりました。その結果、引数のサイズが大きく異なる場合には、最大 1.85 倍高速化され、メモリ使用量も 3 分の 1 削減されます。arrayUnionは影響を受けません。#113021 (alexey-milovidov)。minmaxカラム STATISTICS タイプを非推奨にしました。#108680 (hanfei1991)。SYSTEM PREWARM PRIMARY INDEX CACHE ... ON CLUSTERのアクセスチェックを修正しました。これまでは、SYSTEM PREWARM PRIMARY INDEX CACHE権限ではなくSYSTEM PREWARM MARK CACHE権限が誤って要求されていました。#109198 (Algunenano)。SYSTEM STOP/START CLEANUPおよびSYSTEM STOP/START VIRTUAL PARTS UPDATE ON CLUSTERの実行時に、SYSTEM CLEANUP/SYSTEM VIRTUAL PARTS UPDATEではなくSYSTEM PULLING REPLICATION LOGが要求されていた問題を修正しました。#110289 (groeneai)。/glob (任意の数のディレクトリ) が、同じディレクトリにも一致するようになりました。これまでは glob パターン内の/が特別扱いされていなかったため、data/**/file.txtはdata/file.txt(ディレクトリ階層ゼロ) に一致しませんでした。#97676 (alexey-milovidov)。
新機能
関数とデータ型
- AST を JSON としてシリアル化およびデシリアル化するための
parseQueryToJSON関数とformatQueryFromJSON関数、ならびにenable_json_ast_dialectで有効化される実験的なclickhouse_jsonダイアレクトを追加しました。#100412 (alexey-milovidov)。#113480 (fm4v)。 stem関数に指定可能なすべてのステマー言語を表示するシステムテーブルsystem.stemmersを追加しました。#100611 (Ergus)。toTimeZoneのシンタックスシュガーとして、Standard SQL の後置演算子AT TIME ZONEおよびAT LOCALのサポートを追加しました。式expr AT TIME ZONE zoneはtoTimeZone(expr, zone)と同等になり、expr AT LOCALはtoTimeZone(expr, timeZone())と同等になります。#106092 (lvzhipin03)。URLテーブルエンジンおよびurlテーブル関数は、URL スキームに応じて適切なバックエンドへ処理を振り分けるようになりました。file://はFileエンジン、s3:///gs:///gcs:///oss://はS3、az:///azure:///abfss:///abfs://はAzureBlobStorage、hdfs://はHDFSが処理し、http(s)://は従来どおりURLエンジンが処理します。url_base設定はスキームによる振り分けの前に適用されます。振り分けの対象となるのは、デフォルトのurl_scheme_mappersで解決される S3 スキームのみです。その他の S3 互換ベンダーのスキーム (cos、obsなど) は対象外のため、s3エンジン/関数を直接使用する必要があります。#106093 (alexey-milovidov)。QBitカラムと参照ベクトルの近似内積を計算するdotProductTransposed関数 (エイリアスscalarProductTransposed) を追加しました。既存のL2DistanceTransposed関数およびcosineDistanceTransposed関数を補完するものです。#108100 (alexey-milovidov)。QBitデータ型に任意の stride パラメータ (QBit(T, dimension, stride)) を追加しました。次元をグループ単位で個別のストリームに格納するため、ベクトル検索で先頭の次元だけを効率的に読み取れます (例: Matryoshka embeddings) 。また、転置距離関数では、読み取る次元数を減らすための任意の第 4 引数used_dimsを指定できます。#108103 (alexey-milovidov)。QBitデータ型でInt8要素型をサポートし、量子化された 8 ビット整数ベクトルの格納と、転置距離によるベクトル検索 (L2DistanceTransposed、cosineDistanceTransposed) が可能になりました。#108105 (alexey-milovidov)。- 新しい関数
randomHadamardTransform(vector[, seed[, output_dims]])を追加しました。浮動小数点ベクトルに対する決定論的なランダム化アダマール変換で、ノルムを保存する直交回転として量子化前の埋め込みの前処理に役立ちます。また、切り詰めて使用すれば、Johnson–Lindenstrauss/サブサンプリング・ランダム化アダマールによるランダム射影としても利用できます。#108227 (alexey-milovidov)。 - JSON 値に対して RFC 7396 形式の merge-patch 集約を行う集約関数
mergedJSONPatchを実装しました。ステートのマージや AggregatingMergeTree での利用にも対応しています。タイムスタンプなどの順序付けカラムをソートキーとして JSON カラムを集約することで、最新のステートを算出できます。#108349 (larryluogit)。 - 関数
xxHash64Sparkを追加しました。この関数は、StringおよびNULLの入力に対して、シード42を用いて Spark 互換のxxHash64値を計算し、Int64を返します。#108436 (lalitium)。 digits(n, offset[, length])関数を追加しました。この関数は、nの数値のうち、インデックスoffset(1-indexed)から始まるlength桁分の数値を返します。lengthを省略した場合は、offset から末尾までの数値を返します。#109012 (1000ms)。- 数値の二乗を計算する算術関数
sqrを追加しました。#109061 (lalitium)。 - 量子化された転置距離関数
cosineDistanceTransposedQuantized、L2DistanceTransposedQuantized、dotProductTransposedQuantizedを追加しました。これらはquantizeBFloat16ToInt8の Lloyd-Max コードからなるQBit(Int8)を対象とし、格納されたコードをその場で逆量子化します。浮動小数点の参照ベクトルはフル精度のクエリとして扱われ、Float32の精度で比較されます (Float64のクエリは精度が縮小されます)。Array(Int8)の参照ベクトルはそれ自体も逆量子化され、量子化されたベクトル同士の対称的な距離が計算されます。#109405 (alexey-milovidov)。 - 階層型ディクショナリにおいて、キーの最上位の祖先 (ルート) を返す新しい関数
dictGetRootを追加しました。これはdictGetHierarchy(dict_name, key)[-1]と同等の処理を簡潔に記述できる関数です。#109459 (alexey-milovidov)。 MergeTreeテーブルの (パーツ、カラム、サブストリーム) ごとに、各コーデックを使用している圧縮ブロックの数を報告するテーブル関数mergeTreeCodecBlockCounts(database, table)を追加しました。#109623 (rienath)。- Array、Map、JSON に対する
hasの否定である関数notHasを追加しました。検索対象が定数の Array の場合、notHas(constant_array, x)はoptimize_rewrite_has_to_in(デフォルトで有効) によってx NOT IN constant_arrayに書き換えられます。そのため Set による検索で実行され、NOT INと同様に主キー索引による枝刈りが可能です。#109926 (nihalzp)。 Array(Point)として格納される Geo データ型MultiPointを追加し、Geometry型に含めました。#109951 (davidmenggx)。- 関数
arrayElement(vec[n]演算子) とarraySliceがQBitデータ型に対応しました。qbit[n]は n 番目のベクトル要素を元の精度で返し、arraySlice(qbit, offset, length)は次元の部分集合への射影を返します。いずれも必要なストライドグループのビットプレーンのみを読み取り、ストライドグループの境界に揃ったスライスでは格納済みのストリームをコピーせずに再利用します。#109953 (Utkal059)。 - テキスト索引および
tokens関数向けにsplitByRegexpトークナイザーを追加しました。正規表現を区切り文字として入力をトークンに分割します。例えばtokenizer = splitByRegexp('[^\p{L}\p{N}#+]+')と指定すると、他のトークナイザーでは分割されてしまうC++やC#のような特殊文字を含むトークンをそのまま保持できます。#110002 (Ergus)。 - 2つのジオメトリが交差するかどうかを返す関数
geometryIntersectCartesianおよびgeometryIntersectSphericalを追加しました。polygonsIntersectCartesian/polygonsIntersectSphericalとは異なり、汎用的なGeometry型を含むあらゆるジオメトリデータ型 (Point、LineString、MultiLineString、Ring、Polygon、MultiPolygon) を受け付け、2つの引数の型が異なっていても構いません。#110062 (alexey-milovidov). - ネイティブ ORC リーダーが ORC の
uniontypeをサポートし、ClickHouse のVariant型にマッピングするようになりました (以前は、このようなカラムはUnsupported ORC typeエラーで拒否されていました) 。#110078 (alexey-milovidov). - ネイティブ ORC 出力フォーマットで ClickHouse の
Variant型を ORC のuniontypeにマッピングして書き出せるようになりました (以前はILLEGAL_COLUMNエラーで失敗していました) 。#110085 (alexey-milovidov). - 新しい設定
framing_output_formatで選択できるフレーミングフォーマットを追加しました。これは、クエリのレスポンスを構成するさまざまな要素 (データのチャンク、totals と extremes、進捗パケット、プロファイルイベント、サーバーログ、例外) を単一の HTTP レスポンスストリームに多重化するものです。実装済みのフレーミングフォーマットは、None(デフォルト。従来どおりの動作) 、EventStream(HTTP Server-Sent Events) 、JSONEachPacketBase64、JSONEachPacketString(パケットごとに1つの JSON オブジェクトを出力し、データは base64 エンコードまたは文字列) です。#110127 (alexey-milovidov). - 公開データセットを含む Google BigQuery テーブルの読み書きを行うための
bigqueryテーブル関数およびBigQueryテーブルエンジンを追加しました。テーブル構造は BigQuery テーブルのスキーマから推論されます。認証には、OAuth アクセストークン、JSON フォーマットのサービスアカウントキー、リフレッシュトークン付きの OAuth クライアントを利用できます。#110166 (alexey-milovidov). - LLM プロバイダーを使用して、テキスト内の個人を特定できる情報 (PII) を検出・秘匿化する新しい関数
aiRedactを追加しました。秘匿化するカテゴリ (例:['email', 'name']) を指定するか、空の配列を渡してデフォルトの PII カテゴリ一式を使用します。一致した値はトークン (デフォルトは[REDACTED]) に置き換えられます。#110464 (davidmenggx). - LLM を用いてテキストが自然言語で記述した条件を満たすかを評価し、
WHERE、PREWHERE、JOIN ... ONで使用できるUInt8を返すaiFilter関数を追加しました。#110594 (ylw510). PostgreSQLテーブルエンジン、postgresqlテーブル関数、PostgreSQLおよびMaterializedPostgreSQLデータベースエンジン、PostgreSQLディクショナリで、PostgreSQL への TLS/SSL 接続をサポートしました。sslmodeに加えて、証明書と秘密鍵を、内容を直接記述する形式 (sslrootcert_pem、sslcert_pem、sslkey_pem。パスワードと同様にマスクされます) またはパス (sslrootcert、sslcert、sslkey。サーバー設定ファイルで定義された名前付きコレクションからのみ指定可能) で指定できます。#110615 (alexey-milovidov).postgresqlテーブル関数およびPostgreSQLテーブルエンジンを使用して、PostgreSQL プロトコル経由で別の ClickHouse サーバーに接続できるようになりました (テーブル名を指定する場合に限ります。query(...)バリアントは現時点では未サポートです) 。また、PostgreSQL 互換性関数format_typeとcurrent_settingを追加しました。#110760 (alexey-milovidov).- 埋め込みモデルを使用して 2 つのテキスト間の意味的類似度を計算する新しい関数
aiSimilarityを追加しました。[-1, 1]の範囲のNullable(Float32)を返し、1はテキストが同一であることを表します。オペランドがNULLまたは空の場合、あるいは埋め込みの生成に失敗した場合はNULLを返します。#110777 (davidmenggx)。 - リモートの ClickHouseサーバー上にあるデータベースのテーブルへリアルタイムにアクセスし、
SELECTおよびINSERTクエリを転送するRemoteおよびRemoteSecureデータベースエンジンを追加しました。これらは、MySQLおよびPostgreSQLデータベースエンジンの ClickHouse 版に相当し、ClickHouse 同士の接続に使用します。#110975 (alexey-milovidov)。 - GoogleSQL のパイプ構文と同様に、SQL クエリでパイプ演算子をサポートしました (例:
FROM t |> WHERE x > 1 |> AGGREGATE count() AS c GROUP BY y |> ORDER BY c DESC |> LIMIT 10)。任意のSELECTクエリの後に|>演算子を連ねて記述でき、各演算子は直前のクエリをサブクエリとしてラップするため、生成される AST はサブクエリをネストした等価なクエリと同一になります。また、FROM句で始まるクエリではSELECT句を省略できるようになり、省略時はSELECT *として扱われます。#111151 (alexey-milovidov)。 - 有限かつ非負の数値のジニ係数を計算する集約関数
giniを追加しました。グループ化された集計および分散集計にも対応しています。#112280 (amirreza1307)。#114643 (groeneai)。 PNG出力フォーマットでアニメーション PNG をサポートしました。tカラムを含めるとクエリ結果がアニメーションになり、tの時間スケールはoutput_format_image_time_multiplier_secondsとoutput_format_image_time_divisor_secondsで設定します。また、output_format_image_streaming_animationを有効にすると、フレームをメモリにバッファリングせず、クエリが生成した時点で順次書き出します。#112846 (alexey-milovidov)。- ミューテーションの完了時刻を記録する
finish_timeカラムをsystem.mutationsに追加しました。未完了のミューテーションや完了時刻が不明なミューテーションでは、値はゼロになります。#113474 (nikitamikhaylov)。 system.metric_log用の新しいスキーマタイプbucketedを追加しました。このタイプでは、128 バケットのバケット化Mapシリアライゼーションを用いて、すべてのメトリクスを単一のMap(Enum16(...), Int64)カラムに格納し、互換性のためにメトリクスごとのALIASカラムも提供します。これにより、テーブルは数千ではなく数個のカラムで構成され、ゼロ値は格納されず、単一のメトリクスを読み取る際には 128 バケットのうち 1 つだけを読み取ります。さらに、Enumキーを持つMapを、enum 値の文字列名でインデックス参照できるようになりました (例:map['name'])。#115380 (alexey-milovidov)。tokens関数およびMergeTreeのテキスト索引向けにchineseトークナイザーを追加しました。辞書と隠れマルコフモデル (アルゴリズムは jieba に準拠) を用いて中国語テキストを単語に分割します。粒度はcoarse_grained(デフォルト) とfine_grainedから選択できます。#89945 (amosbird)。- 各グループ内の行を指定した出力フォーマットで整形し、その結果を文字列として返す集約関数
groupFormatを追加しました。#93201 (wandersofb)。 - 集約関数コンビネータ
-Tupleを追加しました。基となる集約関数をTupleカラムの各要素に個別に適用し、要素名を保持したまま結果をTupleとして返します。たとえばt = (a, b)の場合、sumTuple(t)は(sum(a), sum(b))を返します。複数の引数を取る集約関数では、引数ごとに 1 つのタプルを受け取り、位置ごとに対応付けて処理します。たとえばcorrTuple((a1, a2), (b1, b2))は(corr(a1, b1), corr(a2, b2))を返します。Array に対する-ForEachとは異なり、各要素の型が異なっていてもよく、要素ごとの結果の型と名前も保持されます。#98190 (RinChanNOWWW)。
SQL およびクエリ機能
- プロジェクション定義で WHERE 句をサポートしました。WHERE を持つプロジェクションは述語に一致する行のみをマテリアライズします。クエリの WHERE 条件からプロジェクションの WHERE 条件が導かれる場合、オプティマイザは (コストベースで) そのプロジェクションを使用できます。#102347 (SBALAVIGNESH123)。
- HTTP インターフェイスで、URL パスを介してテーブルやデータベースにアクセスできるようにしました (例: `/database/table.format.gz?filter=a>0`) 。あわせて新しい設定 (`http_allow_database_as_path`、`http_allow_table_as_file`、`http_allow_filters_as_path`、`http_allow_filters_as_unrecognized_url_parameters`、`select`、`order`、`sort`、`filter`、`page`、`compression`、`format`、`input_format`、`output_format`、`default_format`、`database`) を追加しました。これらは相互に組み合わせられるほか、既存の `query` URL パラメータとも併用できます。#105249 (alexey-milovidov)。
remoteおよびremoteSecureテーブル関数の永続版であるRemoteおよびRemoteSecureテーブルエンジンを追加しました。CREATE TABLE ... AS remote(...)に加えて、CREATE TABLE ... ENGINE = Remote('addresses', db, table, ...)も使用できるようになりました。#106189 (alexey-milovidov)。- クエリパフォーマンスを調査するための
EXPLAIN ANALYZEを追加しました。クエリを実際に実行し、その実行メトリクスを見慣れたクエリプラン形式で表示します。#106586 (Fgrtue)。#110668 (Fgrtue)。 - エンジンに依存しない
SYSTEM STOP、SYSTEM START、SYSTEM PAUSE、SYSTEM CANCEL、SYSTEM REFRESHコマンドと、サーバー全体を対象とするその... ALL BACKGROUND形式を追加しました。これにより、Kafka、RabbitMQ、NATS、S3Queue/AzureQueueテーブルおよびリフレッシャブルmaterialized view のバックグラウンド処理を、単一の統一されたインターフェイスで制御できます。リフレッシャブルmaterialized view に対しては、既存のSYSTEM ... VIEWコマンドのエイリアスとして動作します。NATS でこれらの制御をサポートする一環として、JetStream テーブルは挿入が成功した後にのみメッセージを確認応答するようになりました (at-least-once。以前は配信時にメッセージが自動的に確認応答されていたため、挿入に失敗するとメッセージが失われる可能性がありました) 。新しい設定nats_wait_for_flush_interval(デフォルトはfalseで、従来の低レイテンシな動作を維持) を有効にすると、キューが空になった時点ですぐに flush するのではなく、flush インターバルの間ずっと消費サイクルを維持できます。新しい設定nats_commit_on_selectを有効にすると、JetStream テーブルに対して直接SELECTを実行した際に、読み取ったメッセージが消費 (確認応答) されます。#107476 (NIKTONIKTO717)。 mysql、postgresql、sqliteのテーブル関数およびテーブルエンジンで、テーブル名の代わりにユーザー定義のクエリを受け取り、それをそのまま外部データベースに渡せるようになりました。クエリはサブクエリ(SELECT ...)またはquery('SELECT ...')のいずれかの形式で記述できます。生成されるテーブルの構造はクエリ結果から推論され、このテーブルは読み取り専用となります。#107740 (alexey-milovidov)。QueryRunnerテーブルエンジンを導入しました。QueryRunnerテーブルに挿入されたレコードは、エンジンが実行するクエリを表します。このエンジンは、非同期クエリ実行、生成したクエリのバッチ実行、リモートクラスターへのクエリの振り分け、ベンチマーク、ファジング、シャドートラフィックを用いたテストなどに利用できます。#107888 (mstetsyuk)。- ウィンドウ関数で
GROUPSフレームモード (SQL:2011) をサポートしました。例:any(price) OVER (PARTITION BY symbol ORDER BY ts GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING)。GROUPSフレームでは、境界をピアグループ (ORDER BYキーの値が等しい行の集合) 単位で数えます。そのためN PRECEDING/N FOLLOWINGは、物理的な行数 (ROWS) やORDER BYの値の差 (RANGE) ではなく、現在の行が属するピアグループの前後N個のピアグループを意味します。#108653 (nihalzp)。 - 通常の
CREATE MATERIALIZED VIEW ... POPULATEがローカルでアトミックに動作するようになりました。ソーステーブルに短時間の排他ロックをかけた状態で、ビューによるソーステーブルへの新規挿入の購読と既存データのスナップショット取得をまとめて行うため、データ投入中に同じサーバー経由で並行して挿入された行が欠落したり重複したりすることがなくなりました (新しい設定materialized_views_populate_atomically、デフォルトで有効)。この保証の対象はローカルの挿入経路のみで、別のレプリカに到着した挿入や分散書き込み経路を経由する挿入は対象外です。また、固定されたスナップショットを提供できるソース (MergeTreeファミリーおよびMemory) が必要です。それ以外のソースや、CREATE OR REPLACE/REPLACE、Replicatedデータベースで作成されたビューでは、引き続き従来の非アトミックなデータ投入が行われます。さらに、POPULATEをTOと組み合わせて使用し、ターゲットテーブルをバックフィルできるようになりました。#108715 (alexey-milovidov)。 ALTER USER、ALTER ROLE、ALTER SETTINGS PROFILEで、MODIFY SETTING name = valueのエイリアスとしてSET name = valueを使用できるようになりました。設定リスト全体を置き換える素のSETTINGS句とは異なり、他の設定はそのままに、個々の設定のみを変更します。これにより、ユーザーの他の設定を誤って消してしまうリスクが低減されます。#108722 (groeneai)。- 既存の制約の式をその場で変更できる
ALTER TABLE ... MODIFY CONSTRAINT [IF EXISTS] name CHECK exprをサポートしました。#108768 (alexey-milovidov)。 ON句に結合対象テーブル間の不等号比較 (<、<=、>、>=) を 2 つ含む結合向けに、ソートベースの IEJoin アルゴリズムを追加しました。join_algorithm設定にie_joinを追加すると有効になります。サポートされる種類はALL INNER/LEFT/RIGHT/FULL JOINおよびSEMI/ANTILEFT/RIGHT JOINです。従来、このようなクエリはフィルター付きのCROSS JOINとして実行されており (INNERのみ対応)、大規模なテーブルでは大幅に低速でした。#109920 (vdimir)。- 新しいシステムテーブル
system.user_query_logを追加しました。各ユーザーは、クエリログテーブルへのアクセス権がなくても、自分自身のクエリログレコードを参照できます。元の実装とアイデアは Yue Ni (@niyue) によるものです。#110156 (alexey-milovidov)。 - 新しい設定
run_query_in_backgroundを追加しました。サーバーはクエリを受け付けると即座に空の結果を返し、接続がどうなってもクエリを最後まで実行します。結果は破棄されます。クエリはquery_idを使ってsystem.processesおよびsystem.query_logで追跡できます。INSERT ... SELECT、CREATE TABLE … AS SELECT、CREATE MATERIALIZED VIEW … POPULATEなど、接続が切断されても中断させたくない長時間実行クエリでの使用を想定しています。#112816 (mstetsyuk)。 - ALTER TABLE … MODIFY PROJECTION をサポートし、既存のプロジェクションを再構築せずに、プロジェクションレベルの設定 (例: index_granularity) を変更できるようになりました。新しい設定はマージ時に遅延適用されます。#113343 (diegomestre2).
- データレイク向けの S3 テーブルエンジンのカタログで、既存テーブルへのクエリに加えて
INSERTもサポートされるようになりました。#113505 (scanhex12). Icebergカタログがcatalog_type = 'horizon'により Snowflake Horizon Catalog をサポートするようになり、Snowflake が管理するIcebergテーブルの読み取りと書き込みが可能になりました。#114547 (melvynator).skip_unavailable_shards_mode設定 (Distributedエンジンの設定としても利用可能) を追加しました。skip_unavailable_shardsが有効な場合に、リモート分片から返されるどの例外をエラーとせずに無視するかを制御できます。これにより、分散環境におけるクエリの挙動をより細かく制御できるようになります。#79091 (byte-sourcerer).
ストレージ、データレイク、オブジェクトストレージ
- Puffin ファイルフォーマット (https://iceberg.apache.org/puffin-spec/) のサポートを追加しました。これにより、
file、url、s3などのテーブル関数でこのフォーマットを使用できるようになりました。 #103936 (scanhex12)。 MergeTreeテーブル向けに「packed」データパーツストレージを追加しました。ストリームごとに個別のファイルを作成するのではなく、パーツのすべてのファイルを単一のアーカイブ (data.packed) にまとめて格納します。この機能はmin_bytes_for_full_part_storage、min_rows_for_full_part_storage、min_level_for_full_part_storageの各設定で制御され、デフォルトでは無効です。互換性に関する注意: テーブルで一度 packed パーツが書き込まれると、それより古いバージョンのサーバーでは読み取れなくなるため、このフォーマットを有効にするとサーバーをダウングレードできなくなります。 #108118 (Algunenano)。- NATS テーブルエンジンに
nats_credentials設定を追加しました。これにより、NATS の認証情報を文字列 (.credsファイルのペイロードと同じ内容) として設定内に直接指定できるようになりました。 #110733 (addshore)。
データフォーマットとインジェスト
- Apache Hive の
LazySimpleSerDeテキスト形式でデータを書き出すHiveText出力フォーマットを追加しました。フィールドは\x01で区切られ、行は新しいformat_hive_text_rows_delimiter設定 (デフォルトは\n) で区切られます。ネストされたArray、Map、Tupleの値には、Hive の区切り文字リストが使用されます。この出力は Hive のデフォルトのLazySimpleSerDeを対象としているため、ネストされた値やカスタムの行区切り文字については、ClickHouse のHiveText入力との対称性はありません。#107582 (alexey-milovidov)。 - 1 行を 1 つの Feature として GeoJSON の
FeatureCollectionドキュメントを書き出すGeoJSON出力フォーマットを追加しました。新しいformat_geojson_validate_geometry設定 (デフォルトで有効) により、読み取り時と書き込み時に GeoJSON の形状が検証されます。また、GeoJSON入力フォーマットはidをNullable(String)として推論するようになりました。これにより、ID が存在しない場合やnullの場合を空文字列と区別できます。#108065 (nihalzp)。
設定、アクセス、オブザーバビリティ
- HTTP インターフェイスの
/docsパスで利用できる組み込みのドキュメント検索ページを追加しました。system.documentationテーブルを対象としたインスタント検索が可能で、リファレンスドキュメントをシンタックスハイライト、数式、相互リンク付きでレンダリングします。#108345 (alexey-milovidov)。 - テキスト索引および tokens/hasAnyTokens/hasAllTokens 関数で使用できる、MeCab 形態素解析器ベースの日本語トークナイザーを追加しました。辞書はサーバー設定で指定された場所から実行時に読み込まれ、使用前に SHA-256 チェックサムで検証されます。#111420 (Ergus)。
- 新しいファイルシステムキャッシュ設定
system_cache_extensionsを追加しました。use_split_cacheが有効な場合に、どのファイルをシステムキャッシュに格納するかを制御します。#111575 (kirillgarbar)。 always_fetch_mutated_part設定を追加しました。この設定により、レプリカはミューテーションをローカルで実行せずに、ミューテーション適用済みのパーツを他のレプリカからダウンロードできるようになります。#113020 (rorylshanks)。
その他の新機能
- 負の
LIMITに対するWITH TIESのサポートを追加しました。#100930 (nihalzp). - 復元対象をきめ細かく制御するための復元設定
restore_table_data、restore_access_entities、restore_functionsを追加しました。これらを使用すると、カテゴリごとにstructure_onlyを上書きできます。たとえばstructure_only=true, restore_access_entities=trueと指定すると、テーブルデータは復元せず、テーブル定義とアクセスエンティティのみを復元します。#102402 (fm4v). - Dictionary 定義内で
dictionary_lazy_loadを指定することで、Dictionary ごとに遅延ロードを個別に設定できるようになりました。この設定はグローバルなサーバー設定dictionaries_lazy_loadよりも優先されます。これにより、一部の Dictionary は遅延ロードし、その他の Dictionary は即時ロードするといった使い分けが可能になります。#108314 (mstetsyuk). - 配列の添字演算子で、整数の配列をインデックスとして指定できるようになりました。
arr[indexes]は指定されたすべての位置の要素を返します。これはarrayMap(i -> arr[i], indexes)と同等です。#108371 (ucasfl). - WGS84 地理座標と UTM 座標系および MGRS 座標系との相互変換を行う関数
geoToUTM、UTMToGeo、geoToMGRS、MGRSToGeoを追加しました。#108939 (alexey-milovidov). - Dictionary 定義を削除せずに Dictionary のメモリを解放する
SYSTEM UNLOAD DICTIONARYおよびSYSTEM UNLOAD DICTIONARIESコマンドを追加しました。解放された Dictionary は、次回アクセス時に遅延ロードで再ロードされます。#109639 (Manerone). - テキスト索引および
tokens、hasAnyTokens、hasAllTokens関数向けに、新しいicuトークナイザーを追加しました。ロケールに応じた Unicode の単語分割 (中国語、日本語、タイ語などの言語に対する辞書ベースの分割を含む) を行えます。#109940 (Ergus). - 新しいコーデック
ZXCを追加しました。圧縮は低速ながら伸長は非常に高速な非対称 LZ コーデックで、圧縮率はLZ4とZSTDの中間です。#110620 (alexey-milovidov). s3_base設定を追加しました。これにより、s3、s3Cluster、gcs、ossテーブル関数およびS3テーブルエンジンで、相対 URL を S3 のベース URL を基準に解決できるようになります。また、URLデータベースエンジンを追加しました。このエンジンは、テーブル名を任意のベースを基準とした URL として解決し、適切なバックエンドに振り分けます。#111512 (alexey-milovidov).- HTTP のインデックスページ (HTML またはプレーンテキスト形式のディレクトリ一覧) を取得し、一致する URL を抽出することで、
url()およびURLエンジンでワイルドカード展開を利用できるようにしました。ワイルドカードは URL のパス部分に対して照合されます。また、インデックスページのサイズと読み取るディレクトリ数には上限が設けられています。#95181 (niyue). kafka_sasl_mechanismでサポートされる値としてAWS_MSK_IAMを追加しました。これにより、ClickHouse は SASL/SCRAM の認証情報を管理することなく、IAM ロールを使用して Amazon MSK の認証を行えるようになります。#96100 (kalavt).- トークン化後のトークンを変換するポストプロセッサをテキスト索引に追加しました。#98939 (Ergus).
実験的機能
クエリプランニングと実行
- 実行可能なユーザー定義関数向けに「ドライバー」を追加しました。
<user_defined_executable_function_drivers_config>で宣言されたドライバーは、CREATE FUNCTION name ARGUMENTS (...) RETURNS T ENGINE = DriverName(...) AS '...code...'で使用でき、関数作成時にユーザーのコードスニペットをコンパイルするなどの処理を行い、実行可能な実行可能 UDF を生成します。生成された設定は<dynamic_user_defined_executable_functions_path>に保存され、元のクエリはATTACH FUNCTIONとして永続化されるため、サーバーを再起動しても関数は保持されます。概念実証として提供されるc_function_bodyドライバーは、executable_poolモードで、サンドボックス化された Docker コンテナ内で C の関数本体をコンパイルして実行します。#105131 (alexey-milovidov)。 /api/v1/queryおよび/api/v1/query_rangeへの Prometheus Query API リクエストが、read_rowsおよびread_bytesメトリクスとともにsystem.query_logに記録されるようになりました。#106611 (JTCunning)。make_distributed_planが有効な場合、MergeTree ファミリーのテーブルに対するSELECT ... FINALで、分散クエリプランによる読み取りをサポートしました。#108148 (davenger)。- MergeTree に対するクエリ向けに、実験的なプランベースの並列レプリカ実行を追加しました。#108504 (devcrafter)。
- 実験的なテーブル関数
evalを追加しました。定数式を評価してクエリ文字列を生成し、得られた単一のSELECTクエリを実行します。この機能はデフォルトで無効になっており、設定allow_experimental_eval_table_functionで有効化できます。作成者: Yue Ni #110132 (alexey-milovidov)。 - プランベースの並列レプリカ (
parallel_replicas_plan_based): ローカル/リモートの境界を、通常のクエリプランに対するプランレベルの最適化で決定するようになりました。また、UNIONを含むビューに対するクエリは、parallel_replicas_allow_view_over_mergetreeを指定しなくても並列化されるようになりました。IN (subquery)を使用するクエリは、エラーにならずローカルプランにフォールバックするようになりました。#111063 (devcrafter)。#112443 (devcrafter)。 - 実験的な AI 関数のセキュリティを強化しました。リモートホストへの安全でない (
http) エンドポイントをデフォルトで拒否するようにし (新しい設定ai_function_allow_insecure_endpoint)、クエリごとの外部 API 呼び出し回数にデフォルトで上限を設け (ai_function_max_api_calls_per_queryのデフォルト値が1000になりました)、ログに書き込まれるプロバイダーのエラーレスポンスをサニタイズするようにしました。#111286 (george-larionov)。 - プランベースの並列レプリカ (
parallel_replicas_plan_based) で、対象となる JOIN (INNER、LEFT、RIGHT。SEMI/ANTIを含む) を分散実行できるようになりました。結合全体が分散プランのフラグメント内で実行され、一方の側はレプリカ間で協調して処理され、もう一方の側はブロードキャストされます。#112268 (davenger)。 - 分散クエリ (
make_distributed_plan = 1) がキャンセルされた際、単にQUERY_WAS_CANCELLEDを返すのではなく、キャンセルの原因となったエラーを報告するようになりました。これまでは、失敗した worker タスクの実際のエラーはサーバーログでしか確認できませんでした。#112590 (davenger)。 IN (subquery)を含むクエリプランを、JOINに書き換えずに分散実行できるようにしました。Set はイニシエーター上で一度だけ構築され、その値は worker タスクとともに送信されます。rewrite_in_to_joinを強制的に上書きする処理は削除されましたが、この書き換えは明示的な設定として引き続き利用できます。#113826 (davenger)。- 分散プランのクエリ (
make_distributed_plan) は、LIMITが満たされた時点で上流のステージを停止するようになりました。これまでのように結果全体を計算したうえで破棄することはなくなります。#114806 (davenger). - PromQL クエリでレンジセレクター内に
offsetを使用した場合 (例:rate(m[2m] offset 5m)) に、エラーIllegal type Decimal(18, 0) of argument of function toIntervalNanosecondが発生する問題を修正しました。#114997 (nikitamikhaylov). - Cascades オプティマイザが構築する分散プラン (
make_distributed_plan = 1, enable_cascades_optimizer = 1) で、GROUPING SETSによる集約をサポートしました。#115426 (davenger). TimeSeriesテーブルで「recent samples」テーブルを保持できるようになりました。新しいエンジン設定recent_samples_ttl_secondsに 0 以外の値を指定すると、エンジンは samples テーブルの有効期限 (TTL) 付きコピー (recent_samples_partition_byでパーティション分割され、デフォルトは日単位) を作成し、挿入のたびにそこへ書き込みます。時間範囲が TTL ウィンドウ内に収まる PromQL クエリは自動的にこのテーブルから読み取るため、大規模なテーブルではアラートルールやレコーディングルール、短期間を対象とするダッシュボードが数倍高速になります。この優先動作は、新しいクエリレベルの設定time_series_prefer_recent_samples_tableで無効にできます。#115441 (nikitamikhaylov).- 分散クエリプラン (
make_distributed_plan) は、LIMITが満たされた後、アイドル状態の上流ステージを速やかに停止するようになりました。アイドル状態の exchange シンクはNoMoreDataNeededが届くとすぐにそれを読み取り、アイドル状態の exchange ソースは自身の出力が閉じられたことを検知して停止を上流へ伝播します。従来は、こうしたステージが誰も消費しないデータの読み取りと計算を続けていました。#115690 (davenger). parallel_replicas_plan_basedが有効な場合、自動並列レプリカ機能が実行時統計を収集し、対応するクエリで並列レプリカを有効化できるようになりました。#115788 (devcrafter).- 分散クエリプラン向けに、実験的な Cascades コストベースオプティマイザを追加しました。
make_distributed_plan = 1とあわせてenable_cascades_optimizer = 1を指定すると有効になります。このオプティマイザは推定コストに基づき、結合戦略 (shuffle、broadcast、replicated、local) 、集約方式 (2 フェーズ、shuffle、local) 、2 段階の分散 top-N、読み取り方式 (並列読み取り、レプリケート読み取り) を選択し、必要に応じて exchange 演算子を挿入します。#86353 (davenger).
ストレージ、データレイク、索引
- デシリアライズ済みの Paimon メタデータファイル (マニフェストリストおよびマニフェスト) 用に、インメモリの SLRU キャッシュを追加しました。
use_paimon_metadata_files_cache設定で有効にすると、同じ Paimon テーブルに対してクエリを繰り返し実行する際に、オブジェクトストレージからメタデータを再ダウンロード・再パースする処理が省略されます。#104657 (Binnn-MX). - 実験的機能の
ReaderExecutor(use_reader_executor、デフォルトでは無効) で、リモートのソース接続を開いたまま保持し、連続する読み取りで再利用できるようになりました。これにより、スキャン時のオブジェクトストレージへのリクエスト数が削減されます。#107735 (CheSema). - 実験的機能の
ReaderExecutorの読み取りパス (use_reader_executor、デフォルトでは無効) に、リードスルー方式のファイルシステムキャッシュを追加しました。#110029 (CheSema). - 実験的な
MergeTree設定allow_experimental_adaptive_codec_selectionを追加しました。有効にすると、デフォルトのコーデックを使用するカラムに対し、マージとミューテーションの際にブロックごとに出力サイズが最小となるコーデックが選択されます。#111834 (rienath). - 実験的機能の
ReaderExecutorの読み取りパス (use_reader_executor、デフォルトでは無効) に、ユーザー空間ページキャッシュの階層を追加しました。キャッシュミス時には executor がユーザー空間ページキャッシュにデータを格納し、以降の読み取りはそこからゼロコピーで処理されます。#114890 (CheSema). OPTIMIZE TABLE ... MANIFESTによりIcebergのマニフェストファイルのコンパクションを実行できるようになり、メタデータファイルの数を削減できます。この機能はallow_experimental_iceberg_compaction設定で有効化できます。#98178 (SmitaRKulkarni).
関数、フォーマット、AI
- 実験的機能: 述語によってカラムがデフォルト値と非デフォルト値に厳密に分割される場合、
SELECT count(*) FROM t WHERE col <op> default(col)をserialization.json内のカラムごとのスパース性統計情報から処理し、データスキャンを一切行わないようにしました。#105890 (Algunenano)。 - 実験的な
Quantize(...)ベクトルコーデックファミリーを追加しました。また、量子化されたコンパニオンストリームを用いる、オプトイン方式の2段階近似ベクトル検索へのクエリ書き換えも追加しました。#108565 (shankar-iyer)。 Float32/Float64カラム (およびそれらの配列) 向けの、誤差制限付き非可逆圧縮コーデックである実験的なSZ3を復活させました。使用するにはallow_experimental_codecsが必要です。#108788 (alexey-milovidov)。- 実験的な
SZ3('ALGO_LORENZO_REG', ...)コーデックで圧縮されたデータの読み取りがCORRUPTED_DATAで失敗していた問題を修正しました。また、実験的なSZ3コーデックで非有限の浮動小数点値 (NaNおよび無限大) を圧縮する際に未定義動作が発生しないようにしました。#110762 (alexey-milovidov)。 - PromQL: 日付/時刻関数 (
hour()、minute()、month()、year()、day_of_week()、day_of_month()、day_of_year()、days_in_month()) を引数なしで呼び出せるようになりました。この場合、Prometheus と同様にvector(time())がデフォルトとして使用されます。#111869 (valerypetrov)。 - PromQL:
vector(1) + vector(2)、topk(1, vector(1))、label_replace(vector(1), ...)、on()を伴う二項演算子など、タグを持たないインスタントベクトルに対する操作が型エラーで失敗していた問題を修正しました。#111872 (valerypetrov)。 - PromQL: 関数
derivを実装しました。あわせて、その内部で使用される集約関数が、ミリ秒精度のタイムスタンプに対して本来の1000分の1の値を返していたバグを修正しました。#112360 (valerypetrov)。 parallel_replicas_plan_basedが有効な場合に、ORDER BYクエリへ read-in-order 最適化を適用するようにしました。ソート処理がレプリカに送られ、イニシエーター上でマージされるため、各レプリカは sorting key の順序でデータを読み取ります。また、この設定を有効にした状態で主キー以外のカラムにORDER BYを実行するとUnknown function __topKFilterが発生する問題も修正しました。#114315 (devcrafter)。- データパーツの再読み込み後 (
ATTACHの実行後やサーバー再起動後など) のベクトル検索における読み取りを修正しました。パーツからQuantizedコーデックのサブカラムが失われなくなったため、検索時にフル精度のカラムへフォールバックせず、量子化されたサブカラムを読み取るようになりました。#114763 (shankar-iyer)。 - 実験的な
TimeSeriesテーブルエンジンで、samples 内部テーブルに自動作成されるvalueカラムにGorillaコーデックを適用しないようにしました。今後はデフォルトでCODEC(ZSTD(1))が使用されます。明示的に宣言されたカラムでは、ユーザーが指定したコーデックがそのまま維持されます。timestampカラムのデフォルト (CODEC(DoubleDelta, ZSTD(1))) に変更はありません。#112110 (nikitamikhaylov)。#114790 (nikitamikhaylov)。 make_distributed_plan = 1で実行されるクエリにおいて、ROLLUP、CUBE、GROUPING SETSおよびgrouping関数をサポートしました。#114950 (davenger)。- 実験的機能である ALP コーデックに、Real Doubles (RD) バリアントと任意の
ALP(AUTO|STD|RD)引数を追加しました。引数を指定しない ALP は、常に STD を使用するのではなく、既存の STD 認証スキームと RD のいずれかを自動的に選択するようになりました。#99654 (nazarii-piontko)。
その他の実験的機能
- kafka_partition_shard_num および kafka_shard_count 設定により、StorageKafka2 にパーティションと分片の静的なアフィニティを追加しました。これにより、複数の ClickHouse 分片が、Kafka パーティションのうち互いに重複しないサブセットを決定論的に消費できるようになります。#108886 (JingYanchao)。
onelake_client_idとonelake_client_secretの代わりに、onelake_bearer_token設定で事前に取得した Bearer トークンを指定して OneLake に認証できるようになりました。これにより、長期間有効なクライアントシークレットを共有せずに済みます。トークンは更新されないため、有効期限が切れた場合はデータベースを再作成する必要があります。#109104 (asya-ch)。- (
packed_skip_index_max_bytesにより)skp_idx.packedにパックされたスキップ索引のdata_uncompressed_bytesを修正しました。非圧縮サイズとして圧縮サイズが報告されており、その影響でdistributed_index_analysisが有効にならない場合もありました。#109272 (Algunenano)。 - 実験的な Prometheus remote-write v1 HTTP ハンドラーで Zstandard 圧縮をサポートしました。#110907 (JTCunning)。
- PromQL: 関数
clamp、clamp_min、clamp_max、roundを実装しました。#111870 (valerypetrov)。 - PromQL: 分位レベルが [0, 1] の範囲外の場合、
quantileはエラーをスローせず、Prometheus と同様に -Inf/+Inf/NaN を返すようになりました。また、histogram_quantileも Prometheus と同様に、leラベルが存在しないか解析できない入力系列を無視するようになりました。#111871 (valerypetrov)。 - PromQL: 関数
changes()とresets()を実装しました。#112352 (valerypetrov)。 - Prometheus remote-write エンドポイント経由の挿入について、統計とクエリが正しく収集されるようにしました。#112825 (JTCunning)。
- PromQL: 除数が無限大の剰余演算で、有限値がそのまま保持されるようにしました。#113746 (fallintoplace)。
- 通常の引用符付き PromQL 文字列内にリテラルの改行が含まれている場合は拒否するようにしました。#114381 (fallintoplace)。
- 実験的な
make_distributed_planとenable_cascades_optimizerが有効な場合に、非常に大きなdistributed_plan_workers_numを指定するとサーバーがstd::length_errorで異常終了する問題を修正しました。このようなノード数はINVALID_SETTING_VALUEとして拒否されるようになりました。#115398 (groeneai)。 TimeSeriesテーブル向けに、Prometheus HTTP API の/api/v1/seriesエンドポイントを実装しました。match[]系列セレクタ (複数指定した値は和集合として扱われます) 、任意のstart/end時間範囲、任意のlimitパラメータをサポートします。#115676 (nikitamikhaylov)。
パフォーマンス改善
JOIN と集約のパフォーマンス
- TopK の動的フィルタリング (
ORDER BY ... LIMIT n) を経由するクエリでも、クエリ条件キャッシュを有効にしました。QCC のエントリは TopK プランのパラメータごとに分けて管理されるため、同一のクエリではキャッシュ済みの WHERE フィルタ結果が再利用され、LIMIT、ソート列、ソート方向のいずれかが異なる場合は新しいエントリが作成されます。#104478 (alexey-milovidov). - GROUP BY キーが ORDER BY キーおよびテーブルの sorting key と一致する場合、LIMIT を順序付き集約 (aggregation-in-order) にプッシュダウンして早期終了できるようにしました。これにより、読み取る行数が大幅に削減されます。#104859 (thevar1able).
allow_aggregate_partitions_independentlyをデフォルトで有効にしました。GROUP BYキーがパーティションキーに適合する場合、ClickHouse は各パーティションを独立して集約し、グローバルなマージ処理を省略できます。パーティション構成上この最適化が不利になる場合 (パーティション数が少なすぎる・多すぎる、またはパーティションサイズに大きな偏りがある場合) は、実行時のヒューリスティクスによって自動的にスキップされます。#105128 (alexey-milovidov).read_in_order_use_virtual_rowをデフォルトで有効にしました。多数のパーツを持つテーブルを主キーの順序で読み取る場合 (例:ORDER BY primary_key LIMIT n) 、実際に結果に寄与し得るパーツのみを読み取るようになりました (これに加え、読み取りの並列性を保つため、最大max_threadsパーツ分の read-ahead ウィンドウも読み取ります) 。これにより、ピークメモリ使用量が大幅に削減されます。#106215 (alexey-milovidov).JOINのメモリ使用量を削減し、パフォーマンスを向上させました。ハッシュ結合の右側で 8 バイトのインデックスベースのコンパクトな行参照を使用するようになったため、すべてのキー型において、ALL結合のハッシュテーブルエントリがANY結合と同等のサイズになりました。大規模なparallel_hash結合クエリ (UInt64およびStringキーを用い、一意キーと重複キーの両方を含む 1 億〜3 億行のテーブルに対するINNER結合とANY結合) でベンチマークを実施したところ、クエリの中央値で約 12% 高速化し、ピークメモリ使用量は約 15% 減少しました。遅くなったクエリはありませんでした。最も効果が大きかったのはUInt64キーでのINNER結合です (中央値で約 21% 高速化、メモリ使用量は 38% 減少) 。#107189 (harikrishnan94).- 結合順序を列挙するアルゴリズム dpsub を追加しました。dpsize より少ない最適化オーバーヘッドで最適な結合プランを得られ、内部結合以外の結合にも対応しています。#107351 (fkastrati).
- クエリ全体のメモリではなく、集約状態専用のメモリトラッカーを用いるようにしました。これにより、メモリ使用量の小さい単一レベル集約が二段階集約に変換されることを防ぎます。#107490 (m-selmi).
- 集約ハッシュテーブルのサイズ統計 cache のキーを AST ではなくクエリプランから算出するようにし、集約クエリの解析時に完全なクエリ AST を構築しなくて済むようにしました。#107643 (novikd).
- 初回実行時に収集したランタイム統計に基づき、初回は
hash結合で実行されたクエリを、2 回目以降の実行でparallel_hashに切り替えられるようにしました。#108125 (m-selmi). - ランタイム結合統計から得たハッシュテーブルサイズを用いて、以降のクエリ実行における結合ランタイムフィルタのサイズを最適化するようにしました。新しい設定
join_runtime_filter_size_from_hash_table_statsで制御できます。#108313 (m-selmi). - パーティション化された
MergeTreeテーブルに対するDISTINCTクエリについて、各パーティションの行を単一のストリーム内に保持することで、高速化とメモリ使用量の削減を実現しました。これにより、同じキーの集合が複数の preliminaryDISTINCTに重複して現れることがなくなり、各ストリームの preliminaryDISTINCTは互いに重複しないキーの集合を処理するようになります。この最適化は、パーティション expression がDISTINCTカラムの決定的な関数である場合に適用され、パーティション数と偏りに基づくコストヒューリスティックによって適用可否が判断されます (設定force_distinct_partitions_independentlyで切り替え可能で、デフォルトでは無効です)。パーティション単位で重複しないというこの性質は、Expression、Filter、ARRAY JOINの各ステップを経由して、最終段のDISTINCT、LIMIT BY、GROUP BYにも伝播されるため、これらの処理でもマージを省略できます。この機能は、新しい設定allow_distinct_partitions_independently(デフォルトで有効) で制御でき、ヒューリスティックはmax_number_of_partitions_for_independent_distinctで調整できます。#108326 (nihalzp)。 ON句に非等値述語が含まれる場合でも、等値比較のキーに対してランタイムフィルタが構築されるようになりました。これにより、等値結合と非等値結合が混在する場合に、ハッシュ結合に入力される行数が削減されます。LEFT ANTI JOINは影響を受けません。#108579 (29antonioac)。- 集約および結合のハッシュテーブルに対するソフトウェアプリフェッチのしきい値を
4 * L2 cache sizeからL2 cache sizeに引き下げ、ハッシュテーブルが L2 に収まらなくなった時点でプリフェッチが有効になるようにしました。これにより、報告される L2 サイズが大きいプラットフォーム (例: 2 MiB の L2 を持つ aarch64) で発生していた、中規模のハッシュテーブル (約 1~8 MiB) に対するGROUP BYおよびJOINの性能低下が解消されます。#108655 (groeneai)。 - ウィンドウ関数の性能を改善しました。カラム数の多いテーブルに対する
SELECT *を含むウィンドウクエリは、メモリ使用量が大幅に減少し、より高速に実行されるようになりました。quantile*、uniq*、groupArrayなどのウィンドウ集約は、OVER ()およびOVER (ORDER BY ... RANGE ...)で高速化されています。cume_dist関数も高速化され、PARTITION BYまたはORDER BYを使用するウィンドウは、重複値の多いカラムでの性能が向上しました。#108688 (nihalzp)。 - 集約関数を含まない集約クエリでは、(サポートされるキーの型に限り)
HashMapではなくHashSetベースの方式を使用するようになりました。最大 1.8 倍の高速化が確認されています。#108862 (nickitat)。 parallel_hash結合アルゴリズムにおけるロック競合によるオーバーヘッドを削減しました。#108938 (m-selmi)。join_algorithmに新しい値parallel_full_sorting_mergeを追加しました。ハッシュ互換の等値結合において、full sorting merge join を結合キーのハッシュに基づいて分片し、すべてのスレッド上で並行して動作する、分片ごとの独立したマージ結合として実行します。マージ結合の特長である、ストリーミング処理による低いメモリ使用量を維持したまま並列化できます (ベンチマークでは、parallel_hashと比べて約 2.4 倍高速で、メモリ使用量は約 3.3 分の 1)。ASOF結合は単一のfull_sorting_mergeにフォールバックします。ハッシュ非互換のキー型 (浮動小数点、JSON、Object、Dynamic) では、ハッシュによる分散への書き換えのみがスキップされ、query_plan_join_shard_by_pk_rangesが有効な場合は、引き続き主キーの範囲に基づいてソース側で分片できます。結果の順序は保証されません。#109005 (alexey-milovidov)。- カラム統計は、テーブルの現在のアクティブサイズに書き込まれるブロックのサイズを加えた値が新しい設定
materialize_statistics_on_insert_max_table_size(デフォルト 25 GiB) 以下である場合、デフォルトでINSERT時にマテリアライズされるようになりました。このチェックは書き込まれるブロックごとに行われるため、空のテーブルへの最初の一括ロードでも、書き込まれる各ブロックについて統計がマテリアライズされる場合があります。これにより、コストベースの結合オプティマイザがロード直後のディメンションテーブルについて正確な推定値を得られるようになり、極端に非効率な結合順序を回避できます (例えば、TPC-H の Q5 と Q8 はスケール係数 40 でタイムアウトしなくなりました) 。一方、既存の大規模なファクトテーブルでは、引き続きマージ時に統計がマテリアライズされます。#109454 (alexey-milovidov)。 - キーなしの集約における集約関数
uniqCombinedを最適化しました。#109794 (CurtizJ)。 - 集約関数
uniqHLL12およびuniqCombinedを最適化しました。#109831 (CurtizJ)。 parallel_hash結合アルゴリズムにおける結合されなかった行の処理を、新たに 2 つのケース (残余フィルタがある場合と、結合キーが小さい場合 (シングルレベルのハッシュマップ) ) でも並列化しました。#110008 (m-selmi)。- 述語がウィンドウの
PARTITION BYカラムのみを参照している場合、フィルタをウィンドウ関数より下にプッシュダウンするようにしました。ウィンドウの後に記述されたこのような述語 (ウィンドウ処理を行うサブクエリを囲む外側のWHERE、またはQUALIFY内の連言項) がストレージまで到達するようになり、主キー/パーティションによるプルーニング、スキップ索引、プロジェクションが有効に機能します。例えばSELECT ... row_number() OVER (PARTITION BY key ORDER BY ts) AS rn ... QUALIFY rn = 1 AND key = 'x'は、テーブル全体を読み込んでウィンドウ処理することがなくなりました。#110114 (groeneai)。 join_use_nulls = 1の場合でも、外部結合の両側のカラムを参照する NULL 拒否のWHERE(例:WHERE l.k = 42 AND r.k = 42) によって、join_use_nulls = 0の場合と同様に結合がINNER(またはLEFT/RIGHT) に変換され、主キーによるプルーニングが行われるようになりました。以前はこのケースでは変換が行われず、両方のテーブルが全件読み込まれていました。#110121 (groeneai)。- キーなしの集約における関数
uniq、uniqExact、uniqHLL12を最適化しました。#110150 (CurtizJ)。 ON条件が定数 false となるJOIN(例:ON 1 = 2、ON NULL、またはa.t = 'A' AND a.t = 'B'のように false に畳み込まれる条件) は、結果に寄与しない側を読み込まなくなりました。新しいクエリプランの最適化により、行を生成し得ない入力側が空のソースに置き換えられます。この動作は設定query_plan_short_circuit_constant_false_join(デフォルトで有効) で制御されます。#110234 (groeneai)。- シングルレベルの集約ハッシュテーブルの最終マージを並列化しました。キー空間を互いに素なハッシュパーティションに分割し、各スレッドがそれぞれ独立してマージします (設定
enable_parallel_single_level_merge、デフォルトで有効) 。これにより、スレッドごとのハッシュテーブルが 2 レベル化のしきい値を下回る一方で、マージが実行時間の大半を占めていたGROUP BYクエリが高速化されます。#110395 (nihalzp)。 - 単一の
String集約キーで、よりコンパクトなハッシュテーブル表現が使用されるようになり、文字列を多用するGROUP BYワークロードのパフォーマンスが向上しました。新しいenable_packed_string_keys_in_aggregation設定はデフォルトで有効です。この設定を無効にするか、compatibilityを26.8未満に設定すると、従来のStringHashTableパスに戻ります。このパスは、11 バイトを超える非常に低カーディナリティのキーでは高速になる場合があります。#110573 (harikrishnan94). #112089 (harikrishnan94). - データが疎なシナリオにおいて、full sorting merge join のパフォーマンスを最大 1.5〜3 倍向上させました。#111200 (vdimir).
- プローブ側とビルド側の結合キーの型が異なる場合 (例: Nullable のプローブキーと非 Nullable のビルドキー) でも、
join_runtime_filter_from_fixed_hash_tableが有効になるようにしました。#111244 (m-selmi). - 右側に
NULLの結合キー、またはONexpression によってフィルタされた行が含まれる場合に、null マップの再構築を回避することで、parallel_hashアルゴリズムを使用したRIGHTおよびFULL結合のパフォーマンスを向上させました。#111258 (m-selmi). - 並列
GROUP BY向けの新しいアダプティブアルゴリズムを追加しました (設定enable_adaptive_aggregatorで制御され、デフォルトで有効) 。各スレッドは、自身のハッシュテーブルがadaptive_aggregator_freeze_threshold個のキーを保持するまでそのテーブルに集約し、その後テーブルを凍結します。これにより、頻出キーは協調なしでキャッシュに収まる小さなテーブルを更新し続ける一方、出現頻度の低いキーはハッシュに基づいてバケットごとのバックログに振り分けられ、バケット並列のマージ内で 1 回だけ集約されます。#111459 (nihalzp). - 値ごとの
ColumnDynamicの再構築を回避することで、shared data に格納された JSON/Objectカラム値の行単位のハッシュ計算を高速化しました (JSON カラムに対するuniq/uniqExactや、ハッシュ化されたGROUP BY/DISTINCTキーなどで使用されます) 。ハッシュ値に変更はありません。#111501 (valerypetrov). - ON 句に複数の
OR選言を含む RIGHT および FULL ハッシュ結合、ならびに残余 (不等価) 条件を持つ RIGHT/FULL JOIN のパフォーマンスを向上させました。#111590 (m-selmi). - ハッシュ結合に自動ディスクスピルのしきい値が設定されている場合 (26.5 以降のデフォルト) でも、JOIN を経由した順序どおりの読み取り (read in order) が機能するようになりました。この最適化が適用されると、結合は左側の順序を維持するためにメモリ上に留まります。以前の動作 (このような結合は read-in-order に使用されず、自由にスピルできる) に戻すには、
query_plan_read_in_order_through_spilling_join = 0を設定してください。あわせて、順序どおりに読み取られるLEFT JOINに対するORDER BY ... LIMITが、読み取り予定の行数としてテーブル全体の行数を報告しなくなりました。これにより、read_overflow_mode = 'throw'の場合でも、早期に停止する読み取りがmax_rows_to_readに抵触することはなくなりました。#111973 (alexey-milovidov). - マージ中の
TTL ... GROUP BY集約に対して、連続キー最適化を再び有効にしました。アグリゲータの構築時に、min_hit_rate_to_use_consecutive_keys_optimization([0, 1]のヒット率、デフォルト 0.5) を受け取るべき引数位置にmin_chunk_bytes_for_parallel_parsing(バイト単位のしきい値、デフォルト 10 MiB) が渡されていたため、このパスでは最適化が常に無効になっていました。結果には影響しません。#112314 (groeneai). - クエリプランをシリアル化した際に、
ARRAY JOINのカラムの遅延レプリケーションが失われなくなりました。serialize_query_plan = 1の場合、リモートのプランフラグメントを実行するノードは、enable_lazy_columns_replication設定がデフォルトで有効であるにもかかわらずこれを無視し、複製されたすべてのコピーを常にマテリアライズしていました。#112330 (groeneai)。 WHEREの等価条件のオペランドの型が異なっていても、Int32とNullable(Int32)のように共通のスーパータイプを持つ場合は、その条件がJOIN条件にマージされるようになりました。これにより、CROSS 結合を INNER 結合に変換できるようになります。#112630 (m-selmi)。- 共有データ内に
JSON値を保持する要素を持つArray(例: 集約関数に渡される定数のArray(JSON))を複製する際に、再割り当てが二次的に発生する問題を修正しました。このようなクエリでは、コピーされるバイト数が行数の二乗に比例して増加していました。#112897 (groeneai)。 - MergeTree のプライマリキーまたはパーティションキーに対する範囲述語の境界値が、単一行の定数側との
JOIN ON句を通じて与えられる場合に、パーツおよびグラニュールの枝刈りが再び行われるようになりました。例:SELECT count() FROM t JOIN bounds ON t.d >= bounds.lo AND t.d <= bounds.hi。このようなクエリは 25.2 以降すべてのパーツを読み取っていました。また、以前は枝刈りを復元する手段だったquery_plan_use_logical_join_step設定が 26.5 で廃止されたため、枝刈りを有効にする方法がありませんでした。#112957 (groeneai)。 - 構造の異なる多数のテーブルを対象とする
Mergeテーブルとの JOIN において、クエリプランニングの計算量が三次になる問題を修正しました。このようなクエリは、これまでmax_execution_timeやKILL QUERYに応答しないまま、クエリプランニングに数分を要することがありました。#113140 (alexey-milovidov)。 GROUP BYキーのない集約が、実際には使用されることのないハッシュテーブルサイズのキャッシュキーを計算するために、定数畳み込みされたリテラルの全内容を含む入力プランのサブツリー全体を実行のたびにシリアル化していた性能劣化を修正しました。SELECT quantileMerge(arrayJoin(arrayMap(x -> state, range(5000000))))のようなクエリでは、クエリプランの最適化に 1 回の実行あたり約 63 ms かかっていましたが、0.15 ms に短縮されました。#113333 (groeneai)。- PromQL の集約演算子
topk、bottomk、limitkの評価方式を変更しました。すべての系列を単一の行に集めてO(time_steps * series^2)の中間メモリを使用する代わりに、選択ステートがO(time_steps * k)に収まるストリーミングプランで評価します。これまでMEMORY_LIMIT_EXCEEDEDで失敗していた高カーディナリティなメトリクスに対するクエリも、限られたメモリ内で実行できるようになり、評価もシングルスレッドではなく並列で行われます。#113656 (nikitamikhaylov)。 timeSeries*ToGrid集約関数内のバケットごとのハッシュマップを、サンプルのフラットなソート済み配列に置き換えました。これにより、入力が順序どおりの場合(大半のケースが該当)はサンプルの取り込みが O(1) の追記で済み、最終化時のバケットごとのコピーとソートも不要になりました。#113681 (nikitamikhaylov)。- 複数のプランステップで共有される PromQL の部分式(
topk/bottomk/limitkのオペランドやorの左辺)を、2 回ではなく 1 回だけ評価するようにしました。PromQL から生成される SQL で、共有サブクエリをマテリアライズするようになったためです。これにより Samples テーブルの重複スキャンが解消され、rateに対するtopkはコールド状態で約 2 倍高速化し、kubernetes-mixin のルールクエリは 10〜29% 改善します。#113772 (nikitamikhaylov)。 ORDER BY <column> LIMIT n(TopK) 最適化を使用するクエリで、クエリ条件キャッシュがデフォルトで有効になりました。無効にするにはuse_query_condition_cache_for_top_k = 0を設定してください。#111492 #114539 (alexey-milovidov)。- マージ前に行う、スレッドごとの集約状態のシングルレベルから2レベルへの変換を並列化しました。これにより、非常に多くのコアを搭載したマシンにおいて、重い集約状態 (例:
COUNT(DISTINCT ...)、ClickBench Q10/Q11) を伴う短いGROUP BYクエリで発生していた2〜3倍の性能低下が解消されます。この性能低下は、26.7 の開発ビルドで集約のメモリ計上を正確にした際に生じたものです。#114691 (alexey-milovidov)。 - パーティション化された
MergeTreeテーブルに対するウィンドウ関数を高速化しました。各パーティションを個別のストリームで読み取り、パーティションごとにウィンドウを評価することで、通常はウィンドウのソート前にすべての行をスレッド間で再分配するハッシュ分散処理を省略します。この最適化は、テーブルのパーティション式がウィンドウのPARTITION BYカラムの決定論的関数である場合に適用され、パーティション単位のGROUP BY/DISTINCTと同じコストヒューリスティック (max_threadsに対して十分な数のパーティションがあり、突出して大きいパーティションがないこと) に基づいて適用可否が判断されます。新しい設定allow_window_partitions_independently(デフォルトで有効) 、force_window_partitions_independently、max_number_of_partitions_for_independent_windowで制御できます。#114783 (nihalzp)。 timeSeries*ToGrid集約関数を高速化しました。サンプルごとのバケット計算で Int128 の除算を回避するようになり、同じバケットに属する連続したサンプルではハッシュマップの検索を省略します。#114889 (nikitamikhaylov)。timeSeries*ToGrid集約関数で、同じグリッドバケットに含まれる連続したサンプルをまとめて処理するようにしました。これにより、ソート済みの時系列データでは、timeSeriesRateToGridおよび関連関数のサンプル取り込み処理が1.2〜2倍高速になります。#115041 (nikitamikhaylov)。GROUP BYキーを持たない集約が、単一行の出力をmax_threads個のストリームに展開しなくなりました。これにより、そのような集約の後にも処理が続くクエリでは、並列性を損なうことなく、はるかに小さなパイプライン (作成・スケジューリング・プロファイリングの対象となるプロセッサが少ない) で実行されます。#115170 (nikitamikhaylov)。- PromQL のインスタントクエリの評価を高速化しました。
timeSeries*ToGrid集約関数は単一ポイントのグリッドに対してベクトル化されたサンプル分類処理を使用し、timeSeriesIdToGroupは結果カラムに直接値を書き込むようになりました。#115267 (nikitamikhaylov)。 ON句にORでつながれた複数の等価条件を持つJOINで、クエリで選択されない右側のキーカラムをマテリアライズしなくなりました。#115465 (nickitat)。- 右側で同じ結合キーが何度も繰り返される場合の、
ANY、SEMI、ANTI結合におけるハッシュテーブルの構築を高速化しました。右側の行ごとにjoin_any_take_last_row設定をメモリから読み直すことがなくなりました。#115820 (nickitat)。 String、FixedString、LowCardinalityキーに対する集約関数なしのGROUP BYを高速化しました。未使用のプレースホルダーを行ごとにハッシュテーブルへ書き直すことをやめ、新しいキーを追加する行に対してのみ書き込むようになりました。#115834 (nickitat)。- 大きな定数畳み込み済みリテラルに対するキー付き集約で、メモリ使用量とクエリプランの最適化時間を削減しました。集約のハッシュテーブル統計キャッシュのキーを、いったんメモリ上に蓄積してからハッシュ化するのではなく、シリアル化と同時にハッシュ化するよう変更しました。これにより、大きなリテラルを含むプランが最適化中にそのコピーを保持しなくなりました。80 MB のリテラルの場合、ピークメモリは約 250 MB 減少し、最適化時間は約 2.5 倍高速化します。算出されるキー自体に変更はありません。#115847 (groeneai)。
GROUP BY ... ORDER BY ... LIMITおよびGROUP BY ... LIMITクエリを最適化しました。集約中にサイズ上限付きのヒープを保持し、結果に含まれ得ないグループを除外することで、高カーディナリティのグループ化におけるメモリ使用量と実行時間を大幅に削減します。この最適化はenable_group_by_top_k_optimization設定で制御できます。Dmitriy Terenichev による初期実装をベースにしています #96630 (thevar1able)。
クエリ最適化と実行
- Parallel Replicas を用いた順序どおりの読み取りで、ローカル読み取りと同じくテーブルを
max_threads個のパーツに分割するロジックを使用するようになり、並列性が向上しました。#101434 (nickitat). - Parquet リーダーに、行グループレベルおよびページレベルでの GeoParquet 空間枝刈りを追加しました。行グループの枝刈りでは、バウンディングボックスがクエリのジオメトリと重ならない行グループを丸ごとスキップします。ページレベルの枝刈りでは、
covering.bbox列索引を使用して行グループ内の無関係なページをスキップします。また、IFunctionBase::isSpatialPredicate()を介して空間述語のプッシュダウンを汎用化し、Parquet の行読み取り時に空間述語を評価するGeoFilterを追加しました。#104435 (bacek). use_constant_folding_in_index_analysis設定を追加しました (デフォルトでは無効) 。有効にすると、MergeTreeのプライマリキー、MinMax、およびスキップ索引の解析において、パーティションレベルの定数をパーツごとにフィルタ述語へ畳み込むようになります。これにより、分岐がパーティション値に依存するフィルタ (例:PARTITION BY aにおける(a = 1 AND b >= 1) OR (a = 2 AND b > 10)) の枝刈りが改善されます。#104582 (Michicosun).vector_search_with_rescoringを使用するベクトル検索クエリで、クエリパイプライン内の厳密な距離評価の前に、厳密な行位置決めを適用するようにしました。#105591 (skuznetsov).- データ量を削減する関数 (
length、lengthUTF8、empty、notEmpty) をSortingステップおよびFilterステップの下へプッシュダウンするクエリプランの最適化を追加しました。これにより、サイズの大きいString/FixedString引数が固定サイズの結果に置き換えられ、ソート時のバッファリングやフィルタ時のコピーが不要になります。新しい設定query_plan_push_down_volume_reducing_functionsで制御でき、デフォルトで有効です。#106199 (fastio). - 各キャッシュファイルのサイズをファイル名に埋め込む (
<offset>_<size>) ことでファイルごとのstat呼び出しを不要にし、起動時のファイルシステムキャッシュの読み込みを高速化しました。旧バージョンで書き込まれたキャッシュファイルも引き続き読み込めます。#107415 (alexey-milovidov). - プライマリキーのフィルタと組み合わせたテキスト検索クエリのパフォーマンスを改善しました。#108114 (CurtizJ).
- 定数ポリゴンを使用する
pointInPolygon関数のパフォーマンスを改善しました。前処理済みポリゴンのキャッシュが生の定数引数をキーとするようになったため、定数ポリゴンは入力ブロックごとに再パースされることなく、 (キャッシュミス時に) 一度だけパースされます。#108184 (groeneai). - 機能が無効な場合 (デフォルトの
predicate_statistics_sample_rate = 0) は、MergeTree の読み取りパスでsystem.predicate_statistics_logの選択率カウンタを更新しないようにしました。これにより、すべての読み取りからグラニュールごとのアトミック更新とO(rows)のフィルタ popcount がなくなり、aarch64 で特に顕著だったパフォーマンス低下が解消されます。#108190 (groeneai). - 通常の
MergeTreeのマージでバッチソートキューを使用できるようにするmerge_use_batch_sorting_queueMergeTree設定を追加しました。ソート済みマージのコストが大きいマージ処理で、CPU 時間と実時間を削減できます。#108468 (rorylshanks). - 同じ
WITHエイリアスを参照する式や、同じ部分式を何度も繰り返す式 (例: 深くネストしたif/multiIfチェーン) について、アクション DAG の構築時に共有部分式を再構築しないようにし、アナライザー使用時のクエリプランニングを高速化しました。#108523 (novikd). - 比較からなる
ANDチェーンを多数含む、または非常に大きなANDチェーンを含むクエリについて、クエリ解析を高速化しました。optimize_and_compare_chain最適化は、クエリツリーの大部分をハッシュ化するのではなく、作業量の上限 (新しい設定optimize_and_compare_chain_max_hash_work) の範囲内で実行されるようになりました。また、lambda の解決時に、再帰ガードのために lambda 本体のハッシュを再計算しないようになりました。#108757 (alexey-milovidov). - フィルタのみを行うポストプロセッサ (
if(..., '', token)) では、生のトークンからグラニュールをビルドし、空のトークンをビルド時に除外するようになりました。これにより、汎用パスで発生する出現ごとのマテリアライズやActionsDAGの実行が不要になります。#109049 (ahmadov). - 分散クエリプランの
ShuffleSendStepにおけるシングルスレッドのボトルネックを解消しました。フラグメント全体を 1 つのScatterByPartitionTransformに集約するのではなく、各上流ストリームがそれぞれ独立して行を宛先バケットごとに振り分けるようになりました。#109206 (davenger). - 多数のカラムを含むクエリにおける式評価の CPU オーバーヘッドを削減しました (例:ストライドの小さい
QBitカラムに対するベクトル検索。この場合、各ベクトルが数百のビットプレーンのサブカラムに展開され、そのすべてが単一の*DistanceTransposed呼び出しに渡されます) 。#109380 (alexey-milovidov). - 述語が
LIMIT BYのキーカラムのみを参照し、かつ句が空でない各グループにつき少なくとも 1 行を保持する場合 (n >= 1かつOFFSET 0のLIMIT n BY) 、フィルタをLIMIT BYの下にプッシュダウンするようにしました。これにより、こうした述語 (LIMIT BYサブクエリを外側から囲むWHEREとして記述されたもの) がストレージまで到達し、主キーによる枝刈り、スキップ索引、プロジェクションを活用できるようになります。テーブル全体を読み込んでからグループごとの上位 N 件を適用する必要はありません。なお、OFFSET、LIMIT 0 BY、負の値を用いたLIMIT BY形式における例外のセマンティクスは変わりません。#110116 (groeneai). - 主キー索引の解析において、超矩形チェックのたびに発生していたヒープ割り当てを回避しました。これにより、クエリの形状に応じてマークのフィルタリングが 5~26% 高速化されます。#110153 (raimannma).
- Parquet のフィルタプッシュダウン (行グループの枝刈りおよびカラム索引) が、
DateTime64のバリアント間、Decimalのバリアント間、およびFloat32/Float64間の変換に対応しました。#110457 (al13n321). - sparseGrams トークナイザーを使用するテキスト索引およびブルームフィルタベースのスキップ索引のビルドを最適化しました。#110541 (UnamedRus).
- PREWHERE 条件の順序付けにおいて、I/O コストと選択度を組み合わせて考慮するようにしました。これにより、https://github.com/ClickHouse/ClickHouse/pull/101275 以降に一部のケースで発生していた PREWHERE 実行のパフォーマンス低下が解消されます。https://github.com/ClickHouse/ClickHouse/issues/110462 の対応の一部です。#110695 (Avogar).
- ポストプロセッサの
IN/NOT INフィルタで定義されたトークンのハッシュ計算を削減しました。#111690 (ahmadov). - 関数 mapContainsKeyLike、mapContainsValueLike、mapExtractKeyLike、mapExtractValueLike で非定数のパターンを使用する場合、enable_lazy_columns_replication が有効であれば、メモリ使用量と処理時間が削減されるようになりました。キャプチャ時にパターンを Map のエントリごとに即座にコピーすることはなくなり、コピーは内部 lambda の実行時まで遅延され、より早く解放されます。その結果、ピーク時に存在するパターンの展開済みコピーが 1 つ減ります。#111749 (diegomestre2).
- 2つのオンディスク機能をデフォルトで有効化しました (あわせてベータに昇格しました) 。1)
packed_skip_index_max_bytes = '1M': 1 MiB 以下のスキップ索引サブストリームが、パーツごとに単一のskp_idx.packedアーカイブへ書き込まれるようになり、オブジェクトストレージ上のオブジェクト数と書き込みリクエストが削減されます。互換性: 影響を受けるのは新たに書き込まれたパーツのみで、それらは旧バージョンでも完全に読み取り可能です。26.6 より前のバージョンでは、パック済みの索引がプルーニングに使用されないだけです (マテリアライズされていないものとして扱われます) 。ファイルごとに独立した従来のレイアウトを維持するには、packed_skip_index_max_bytes = 0を設定してください。2)compute_exact_num_defaults_for_sparse_columnsとoptimize_trivial_count_with_sparsity_filter: カラムごとの正確なnum_defaultsカウンターが永続化され、述語によって行がデフォルト値と非デフォルト値に分かれる場合に、データをスキャンせずにSELECT count() FROM t WHERE <pred>に応答できるようになりました。互換性:serialization.json内のexact_num_defaultsフラグは旧バージョンでは無視されるため、ダウングレード後もパーツは完全に読み取り可能です。count の書き換えは正確なカウンターを持つパーツにのみ適用されるため、新旧のパーツが混在するテーブルでも正しい結果が得られます。#111816 (Algunenano)。 - 推移的条件の最適化において、フィルタ全体を適用できない場合は、追加フィルタを索引解析にのみ使用するようになりました。詳細は
optimize_and_compare_chain設定を参照してください。#112076 (yariks5s)。 - 実験的な TimeSeries エンジンの Prometheus クエリ API (
/api/v1/query、/api/v1/query_range) が、クエリをシングルスレッドではなく並列に実行するようになりました。#112108 (nikitamikhaylov)。 - 定数ベクトルに対する
randomHadamardTransformが、行ごとではなく1回だけ評価されるようになりました。これにより、QBitカラムと比較する前にrandomHadamardTransformでクエリベクトルを回転させるベクトル検索クエリが高速化されます。#112921 (alexey-milovidov)。 - 主キーカラムに対する
IN (subquery)でフィルタリングを行うミューテーションにおいて、同一ミューテーション内のパーツタスク間でセットが再び共有されるようになりました。enable_sharing_sets_for_mutationsはデフォルトで有効ですが、主キー解析用に構築されたセットが共有キャッシュの対象外になっていたため、N 個のパーツを持つテーブルでは同じセットが N 回マテリアライズされていました。#112941 (groeneai)。 - 分散クエリプラン (
make_distributed_plan) において、ORDER BY ... LIMIT kが各レプリカで遅延マテリアライゼーションを使用するようになりました。サイズの大きいカラムは、すべての候補行ではなく、そのレプリカのローカルな上位 k 行についてのみ読み取られます。#113111 (shankar-iyer)。 uniq_v2カラム STATISTICS を使用する場合のクエリプランニングを高速化しました。ユニーク値数の推定値は、リクエストのたびに再計算せずキャッシュされるようになりました。このリクエストはクエリプランニング中に1クエリあたり何度も発行されます。#113357 (groeneai)。- Parquet および ORC ファイル内の
Tupleサブカラムに対してフィルタプッシュダウンが機能するようになりました。file()、s3()、url()に対するWHERE tup.1 = 555555のような述語は、ファイル全体を読み取るのではなく、タプル要素自体の統計情報を使用して行グループおよび行索引ストライドをプルーニングするようになりました。#113383 (groeneai)。 - TimeSeries エンジン上の PromQL のクエリパフォーマンスを改善しました。内部のセレクター SQL が、サンプルテーブルの主キーカラムを (無意味なキャストを挟まずに) 直接読み取り、系列 ID のセットよりも先にタイムスタンプの範囲をチェックするようになったため、セレクターを多用するコールドクエリが 30〜44% 高速化されます。#113768 (nikitamikhaylov)。
- 1つのメトリクスのすべての系列にマッチする PromQL セレクタは、id レイアウトが標準の id ジェネレーターを用いた2要素のタプルである場合、索引解析時に大規模な
id IN <set>条件ではなく、id上の連続した主キー範囲を使ってTimeSeriesテーブルのサンプルテーブルをフィルタするようになりました。これにより、セレクタを多用する PromQL クエリで大半を占めていた、シングルスレッドによる索引解析のコストが解消されます。620億サンプルのテーブルにおいて、ダッシュボードおよびルールのクエリパターンでコールドレイテンシが最大 45% 短縮され、スイート全体のコールド幾何平均でも 11% 短縮されました。#114131 (nikitamikhaylov)。 - Prometheus HTTP API のエンドポイント
/api/v1/queryおよび/api/v1/query_rangeは、複数のプランステップで共有される PromQL サブクエリを、prometheusQueryおよびprometheusQueryRangeテーブル関数と同様に1回だけ評価するようになりました。これまでは、enable_analyzer = 0を指定したリクエストや、プロファイルでこの設定が有効になっているユーザーのリクエストでは、共有サブクエリを参照するステップごとに再スキャンが発生していました。#114261 (groeneai)。 - 26.7 で発生した回帰を修正しました。
DateTime64カラムにtoUnixTimestamp(またはその他の整数変換)を適用した式で並べ替えられたMergeTreeテーブルにおいて、そのカラムに対する単純な範囲フィルタで主キーが使用されず、マッチしたパーツのすべてのグラニュールが読み取られていました。さらに、生のDateTime64カラムで並べ替えられたテーブルに対するtoInt64(ts) >= cのようなフィルタでも、主キーが使用されるようになりました。#114413 (alexey-milovidov)。 - クラスタ化された(例: 主キーでソートされた)カラムに対する
INの実行を高速化しました。値の等しい行が連続する場合、直前の行の結果を再利用します。#114853 (nikitamikhaylov)。 - 関数
h3kRing、h3ToChildren、h3PolygonToCells、h3PolygonToCellsWithContainmentが多数の行にわたって結果を構築する際、処理時間が二次関数的に増加する問題を修正しました。CI のストレステストでは、196 000 行に対するクエリがメモリコピーだけで 838 秒を費やしていましたが、現在は約 5 秒で完了します。#115773 (groeneai)。 - Dictionary の逆引きルックアップを最適化しました。
WHERE dictGet(dict, attr, key_expr) = valueのような定数との等値述語は、IN (SELECT ... FROM dictionary(...))サブクエリに書き換えられる代わりに、キーフィルタ(key_expr = const、key_expr IN [...]、またはWHERE 0)へ直接定数畳み込みされるようになりました。また、dictGetKeysの定数パスが並列実行されるようになりました。#91164 (nihalzp)。 - 汎用排除検索アルゴリズムが各データパーツの主キー索引の解析に費やすステップ数を制限する新しい設定
merge_tree_generic_exclusion_search_max_stepsを追加しました。このステップ数の上限は、残りのキー範囲のうち大きいものから順に消費されるため、上限が小さくてもデータの大部分を枝刈りできます。解析しきれなかった範囲は丸ごと読み取られるため、クエリ結果の正しさは保たれますが、読み取るグラニュールが増える場合があります。この制限は厳密には適用されず、最大でmerge_tree_coarse_index_granularityステップに加え、パーツがすでに分割されている範囲(例: クエリ条件キャッシュによる分割)1つにつき1ステップまで超過することがあります。デフォルト値の 0 はステップ数無制限を意味します。#92779 (EmeraldShift)。 - 分散テーブル上の
VIEWに対してORDER BYとLIMITを指定したクエリで、ソート済みストリームのマージ最適化が使用されるようになりました。外側のORDER BY/LIMITが単純なビューの内側のクエリにプッシュダウンされるため、マージコーディネーター上で完全なソートを行うのではなく、各シャードがローカルでデータをソートし、マージコーディネーターはソート済みのストリームをマージするだけで済みます。#94102 (matanper)。
ストレージ、I/O、データレイクのパフォーマンス
- 主キーのカラムがパーティションキーの入力カラムでもある場合、
MergeTreeテーブルの主キー解析時にパーティションの minmax 索引の境界値を利用して、より多くのグラニュールを枝刈りするようになりました。たとえば、ORDER BY (id, event_time)およびPARTITION BY toYYYYMM(event_time)を指定したMergeTreeテーブルでは、ClickHouse は主キー索引解析時にevent_timeのパーティション minmax 索引を使用し、グラニュールの枝刈りをより的確に判断します。この動作は新しい設定use_partition_minmax_for_primary_key_pruning(デフォルトで有効)で制御されます。#103480 (UnamedRus)。 - ソート済みストリームを走査して同一キー値の連続を検出する演算子(順序付き
DISTINCT、順序付きLIMIT BY、順序付きの負のLIMIT BY、full_sorting_mergeおよびpartial_merge結合)を高速化しました。#106502 (nihalzp)。 - Parquet v3 リーダーは、カラムチャンクが完全に辞書エンコードされている場合、等価条件および
IN条件に対して(min/max 統計情報とブルームフィルタに加えて)辞書ページを使って行グループ全体をスキップできるようになりました。この動作は新しい設定input_format_parquet_dictionary_filter_push_downで制御されます。#106952 (alexey-milovidov)。 - gzip/zlib/deflate の圧縮および伸長に libdeflate を使用するようにし、
.gz/HTTP/url/s3データおよび Parquet の GZIP コーデックの処理を高速化しました(圧縮は約 1.15 倍かつ圧縮率も向上、伸長は約 1.4〜1.5 倍)。#108074 (alexey-milovidov)。 - デフォルトの空白文字を対象とする
trimLeft/trimRight/trimBoth関数(およびそのエイリアスltrim/rtrim/trim)を高速化しました。トリムが不要な行が連続する場合はまとめて一括コピーし、行ごとの空白走査は先頭または末尾に実際に空白がある行に対してのみ実行します。#108177 (groeneai)。 - 現在のマニフェストをパースしている間に次のマニフェストファイルをプリフェッチし、I/O と CPU 処理をオーバーラップさせることで、Iceberg テーブルの読み取りを高速化しました。#108543 (asya-ch)。
- 再スコアリングを使用するベクトル検索クエリで、同じ
MergeTreeグラニュール内の隣接行を総当たりで再スコアリングするのではなく、正確な距離計算をベクトル索引の候補行のみに限定するようになりました。#108846 (skuznetsov)。 - コア数の多いサーバーで、通常のローカルかつ順序なしの narrow カラム
MergeTreeスキャンにおける過剰な読み取りストリームとパイプラインのオーバーヘッドを削減するため、merge_tree_min_bytes_per_read_stream設定を追加しました。#109035 (jiebinn)。 - 共有データに疎なパスを多数含む
JSONカラムのシリアライゼーションとマージを高速化しました。共有データをパスごとのカラムに展開する際、flattenAndBucketSharedDataPathsが行ごとに蓄積済みの全パスカラムを走査したり、デフォルト値を 1 セルずつ挿入したりすることはなくなりました。全パスに対する行ごとの走査を廃止し、欠損部分は一括で埋めるようになっています。#109341 (groeneai)。 - ネイティブプロトコルでは、双方のピアがプロトコルリビジョン 54489 以降の場合、
Stringカラムを値ごとの varint 長プレフィックスではなく、累積バイトオフセットの独立したストリーム (Arrayがオフセットに使用するのと同じレイアウト) に続けて連結データを送信する形式に変更されました。これによりクライアントは、バッファを正確に事前割り当てし、1 回の一括コピーでStringカラムを読み取れるようになり、値ごとのレイアウトと比べて約 4 倍高速になります。レイアウトはプロトコルリビジョンを通じてネゴシエートされるため、古いクライアントやサーバーには影響しません。同じレイアウトは、新しい設定output_format_native_write_string_with_size_stream/input_format_native_read_string_with_size_streamによりNativeおよびBuffersフォーマットでも利用できます (フォーマットの可搬性を保つため、デフォルトでは無効です) 。#110320 (vahid-sohrabloo)。 - 主キーの順序で読み取り (sorting key のプレフィックスによる
ORDER BY) 、かつ小さなLIMITを指定したFINAL付きクエリでは、split_intersecting_parts_ranges_into_layers_finalが使用されなくなりました。#110431 (KochetovNicolai)。 - Iceberg テーブルを含む、オブジェクトストレージ上の Parquet ファイルの読み取りで遅延マテリアライゼーション (late materialization) に対応しました。
ORDER BY ... LIMIT nクエリでは、ソートやフィルタに不要なカラムは、LIMIT後に残ったn行分のみ読み取られます。S3 上の 200 MB の Parquet ファイルに対して、SELECT k, s ... ORDER BY k DESC LIMIT 10の読み取り量は 171 MB から 3.3 MB に減少します (I/O は 51 分の 1、速度は 8 倍) 。新しい設定query_plan_optimize_lazy_materialization_for_object_storage(デフォルトで有効、query_plan_optimize_lazy_materializationの有効化も必要) で制御します。#110970 (alexey-milovidov)。 - 削除ファイルが多数ある Iceberg テーブルに対するクエリの開始が高速になりました。ClickHouse は削除マニフェストファイルを 1 つずつではなく並行して読み取り・デコードするため、ストレージからの読み取りが並行して行われます。同時にデコードする数は、新しい設定
iceberg_delete_manifest_decode_concurrency(デフォルト4) で制御します。#112679 (asya-ch)。 - 行グループおよびページのプルーニングを可能にするため、UInt128/UInt256/Int128/Int256 を DECIMAL として Parquet にシリアライズするオプトイン機能を追加しました。#113347 (bobrik)。
- リーダーチェーンのステップが断片化したマーク範囲 (例:主キーやスキップインデックスでフィルタされた範囲) を読み取る際に、リモートディスクへの読み取りリクエストが何倍にも増える問題を修正しました。#113584 (CurtizJ)。
- sorting key がすべて定数である
MergeTreeパーツの書き込み時に、不要なソート済み判定スキャンを省略するようにしました。#113899 (perfloop-agent)。 ORDER BY ... LIMIT nクエリに対する遅延マテリアライゼーションが、fileテーブル関数およびFileテーブルエンジンで読み取るローカルの Parquet ファイルにも適用されるようになりました。ソートやフィルタに不要なカラムは、LIMIT後に残ったn行分のみ読み取られます。2 回の読み取りの間にファイルが変更された場合、2 回目の読み取りは新しいエラーFILE_CHANGED_DURING_READを返して安全に失敗します。新しい設定query_plan_optimize_lazy_materialization_for_file(デフォルトで有効) で制御します。また、要求されたサブカラム (例:JSONカラムのサブカラム) の読み取りが遅延された場合に、オブジェクトストレージ向けの遅延マテリアライゼーションがNot found column or subcolumn ... in blockで失敗する問題も修正しました。#114262 (alexey-milovidov)。- パーティション化された
MergeTreeテーブルに対するIN (subquery)のセット構築を高速化しました。各パーティションの行を単一ストリーム内にまとめ、ストリームごとに独立して重複排除を行うことで、これまですべての行を逐次ハッシュしていた単一のセット充填変換処理が、一意な行のみを処理するようになります。この最適化は、パーティション式がサブクエリの出力カラムに対する決定論的関数である場合に適用されます。ただし、最大のパーティションの行数が平均的なパーティションの 2 倍を超える場合は適用されません。新しい設定force_creating_set_partitions_independently(デフォルトでは無効) を使用すると、このチェックを回避できます。この機能は新しい設定allow_creating_set_partitions_independently(デフォルトで有効) で制御されます。#114645 (nihalzp). - 有効期限 (TTL) が設定されていない、ローテーション済みの非レプリケート
MergeTreeシステムログテーブルをtable_readonlyとしてマークし、不要なバックグラウンド処理が発生しないようにしました。table_readonlyMergeTree設定は、通常のMergeTreeテーブルにおけるすべてのバックグラウンド処理 (通常のマージ、TTL (DELETE/MOVE/再圧縮) マージおよび再圧縮マージ、バックグラウンドミューテーション、バックグラウンドでのパーツ移動) も抑止するようになりました。また、従来から拒否していた挿入処理、ミューテーション、OPTIMIZEに加えて、データを変更するパーティションコマンド (ATTACH/MOVE/DROP/DROP DETACHED/FETCH/REPLACE PARTITION、および当該テーブルへのMOVE PARTITION ... TO TABLE) も拒否するようになりました。そのため、有効期限 (TTL) が設定されたtable_readonlyテーブルでは、この設定が有効な間、期限切れのデータが削除されなくなります。#95079 (matt-metivier).
メモリおよびリソース効率
UNLOCK SNAPSHOTのメモリ使用量を削減しました。ロック解除処理で使用されないデータパーツごとのメタデータを読み込まないようにしたことで、パーツ数が非常に多いスナップショットでもメモリ不足が発生しなくなります。#111849 (jkartseva)。- バックアップのメタデータ読み込み時のメモリ割り当てを削減しました。各ファイルエントリをインメモリの Map にコピーせず、ムーブするようにしました。#111718 (jkartseva)。
関数、型、フォーマットのパフォーマンス
Decimal値のテキストへのフォーマットが大幅に高速化されました。スケールの大きいDecimal256では最大 190 倍、Decimal64では約 1.6 倍高速です。AVX-512 IFMA を備えたプロセッサでは、64 ビット整数のテキストへの変換が約 1.4 倍高速になりました。また、toDecimalStringの丸め処理で小数部からの繰り上がりが失われていた問題を修正しました。toDecimalString(toDecimal64('9.995', 3), 2)はこれまで9.00を返していましたが、現在は10.00を返します。#112457 (thevar1able)。FixedStringキーに対するpartial_merge結合アルゴリズムのパフォーマンスを改善しました。値ごとに比較関数を呼び出すのではなく、連続する値をまとめて比較するようになっています。#105737 (4ertus2)。- 単一カラムの非 Nullable な文字列型 LowCardinality キーが、
HashJoinでネイティブにサポートされるようになりました。#107264 (nickitat)。 - パターンと置換文字列がいずれも 1 文字の場合 (例:
replaceRegexpAll(s, ' ', '_')) のreplaceAllおよびreplaceRegexpAllのパフォーマンスを改善しました。このような置換では文字列のレイアウトが変化しないため、マッチごとに検索ループを実行するのではなく、カラムを一度だけコピーし、一致したバイトをその場で書き換えるようになりました。#108178 (groeneai)。 - デフォルトである best-effort モード (
date_time_input_format = 'best_effort'、cast_string_to_date_time_mode = 'best_effort') において、標準的なYYYY-MM-DD hh:mm:ss形式の日時表現のパースを高速化しました。これにより、これらのデフォルト値をbasicからbest_effortに切り替えた際に生じたパース性能のリグレッションが解消されます。#108187 (groeneai)。 - 深くネストされた配列およびタプルのリテラルを、二次時間ではなく線形時間でパースするようにしました。#108892 (alexey-milovidov)。
SECOND、MINUTE、HOURインターバルにおける関数toStartOfInterval(エイリアス:time_bucket、date_bin) を最大 5 倍高速化しました。#109729 (raimannma)。- 関数
arraySortおよびarrayReverseSortをラムダなしで呼び出した場合、数値型の Array (DecimalおよびDateTime64を含む) に対する処理が数倍高速になりました。#109832 (raimannma)。 - 固定オフセットのタイムゾーン (UTC など) の
DateTimeおよびDateTime64値に対するaddDays、addWeeks、subtractDays、subtractWeeksについて、算術演算による高速パスを導入して高速化しました。#109836 (raimannma)。 Deltaコーデックの伸長処理をベクトル化しました。8/16/32 ビットのデータ型ではデコードが 1.5〜5 倍高速になり、Deltaで圧縮されたカラムのスキャンが最大 20% 高速化されます。#110189 (raimannma)。- 検索文字列が定数の場合の、
Enumカラムに対する文字列検索関数 (like、position、match、countSubstrings、hasTokenなど) を高速化しました。全行を検索するのではなく、重複を除いた enum 名のみを検索し、その結果を各行に対応付けるようになっています。#110325 (alexey-milovidov)。 - needle が定数でない場合の部分文字列検索関数 (
position、countSubstrings、multiSearch*、replaceAll/replaceOne、およびそれらの大文字と小文字を区別しないバリアントと UTF-8 バリアント) の性能を最大 1.5 倍向上させました。行ごとの処理パスで、単純なフォールバックではなく SIMD ベースの文字列検索器を使用するようにしています。#110580 (Algunenano)。 - 多数の動的バリアントまたは JSON パスを持つ
DynamicカラムおよびObjectカラムについて、ブロックをまとめる処理とマージ処理の性能を向上させました。#110583 (cv4g)。 NONEコーデック使用時のestimateCompressionRatioを高速化しました。#111107 (rienath)。- パスが共有データに格納されている
JSONカラムに対するソートなど、比較ベースの操作を高速化しました。従来は値を比較するたびに一時的なDynamicカラムをマテリアライズし、比較する両方の値に対して完全なバイナリデシリアライゼーションを実行していたため、このようなカラムに対するORDER BYが極端に遅くなっていました。#111894 (groeneai)。 - 256 ビット整数 (
Int256、UInt256、Decimal256) の除算で、シフトと減算による筆算方式で 1 ビットずつ商を求める代わりに、64 ビットのリム単位で商を計算するようになりました。除数が 64 ビットに収まる場合は 128 / 64 除算のループを、それ以外の場合は Knuth の Algorithm D を使用します。この変更はintDiv、modulo、Decimal256の算術演算、およびこれらの型からテキストへの変換に影響します。#112477 (thevar1able)。 - バイナリエンコードされた型 (
Native、input_format_binary_decode_types_in_binary_formatを指定したRowBinary) からNestedカラムを読み取る際に、型をいったん型名に戻して再度パースする処理を行わなくなりました。また、不正なネストされたTuple型名は、ネストの深さに対して指数関数的な時間を費やした末にTOO_SLOW_PARSINGで失敗するのではなく、構文エラーとして報告されるようになりました。#112560 (alexey-milovidov)。 - TimeSeries テーブルに対する PromQL クエリを高速化しました。
timeSeriesIdToGroupは、連続する行が同じ系列 ID を持つ場合に前の行のグループを再利用するようになり、行ごとの ID のシリアライゼーションとハッシュ検索が不要になりました。#113580 (nikitamikhaylov)。
その他のパフォーマンス改善
- Apache Arrow ライブラリを使用しない、
ArrowおよびArrowStreamフォーマット向けのネイティブなリーダーとライターを実装し、余分なデータコピーや変換を不要にしました。現在はこれがデフォルト (設定input_format_arrow_use_native_readerおよびoutput_format_arrow_use_native_writer) となっており、読み込みと書き込みのいずれも高速化されています。#106522 (alexey-milovidov). nullIf(key, sentinel) = const述語を最適化し、キー範囲を構築することで、主キー、パーティション、スキップ索引による枝刈りが行えるようにしました。#107308 (adityaksolves).- 各行を SipHash でハッシュする代わりに、行の値をキーとしてマルチセットを構築することで、`INTERSECT ALL` および `EXCEPT ALL` (`INTERSECT` と `EXCEPT` のデフォルトモード) のパフォーマンスを数倍向上させました。#107649 (Algunenano).
- 単純な正規表現を LLVM でネイティブコードにコンパイルすることで、
match、extract、extractAll、replaceRegexpOne、replaceRegexpAll関数を高速化しました。この機能は新しい設定compile_regular_expressions(デフォルトで有効) で制御されます。サポート対象外のパターンは、透過的に RE2 エンジンへフォールバックします。#108004 (alexey-milovidov). - 短いオフセットの重複コピーを NEON でベクトル化することで、AArch64 (ARM) 上で、固定幅の整数カラムなどマッチオフセットが小さいカラムの ZSTD 伸長を高速化しました。たとえば AWS Graviton 4 では、
UInt64カラムの伸長が最大で約 2.3 倍高速になります。#108049 (alexey-milovidov). - 固定サイズかつ低カーディナリティのカラムにおける LZ4 の伸長速度を改善しました。#108175 (nickitat).
- blocked Myers のコードパスで行ごとのヒープ割り当てをなくすことで、ARM 上での中程度の長さの文字列に対する
levenshteinDistance(およびeditDistance) のパフォーマンスを改善しました。#108185 (groeneai). precise_float_parsing = 1使用時のテキストからの浮動小数点数のパースを高速化し、ほぼすべての入力でデフォルトのパーサーと同等以上の速度を実現しました。あわせて、同梱のfast_floatライブラリを v8.2.10 に更新しました。#108205 (Algunenano).- Base64 のエンコード/デコード関数が
simdutfを使用するようになり、パフォーマンスが向上しました。#108333 (thevar1able). - 処理コストの高い高カーディナリティキーに対する
DISTINCTを最適化しました。#108366 (nihalzp). errnoを保持しないコンパイラ最適化を有効にすることで、数学関数のパフォーマンスを改善しました。#108628 (nickitat).- 実際に圧縮するのではなく圧縮サイズを解析的に算出することで、
T64エンコードされたカラムに対するestimateCompressionRatioを高速化しました。#109054 (rienath). - JOIN で、左側テーブルの主キー索引またはスキップ索引を使用してグラニュールを枝刈りできるようになりました。#109085 (shankar-iyer).
- H3 の Geo 関数 (
h3ToGeoBoundary、h3ToGeo、h3CellAreaM2/h3CellAreaRads2、geoToH3) のパフォーマンスを改善しました。対になる正弦/余弦をまとめて計算し、座標変換における冗長な三角関数呼び出しを排除しています。結果は変わりません (ビット単位で同一) 。#109399 (alexey-milovidov). - 比較処理と符号拡張のコードをブランチレス化することで、ワイド整数型 (
Int128、UInt128、Int256、UInt256、およびDecimal128などそれらをベースとする型) の比較 (<、>、<=、>=) を最大 7 倍、符号付き整数からInt256への変換を最大 7 倍 (符号が混在するデータの場合) 高速化しました。#109474 (raimannma). - 非定数の
Nullable引数を 1 つだけ持つ関数では、新しい null マップを割り当ててマージするのではなく、引数の null マップを結果と共有するようになりました。#110151 (raimannma). - 要素ごとの比較ループではなくベクトル化されたリダクションを使用することで、数値配列に対する関数
arrayMinおよびarrayMaxのパフォーマンスを約 1.3〜1.5 倍改善しました。#110163 (raimannma). - 入力ストリームが DISTINCT 対象カラムのプレフィックスでソートされている場合 (例:
SELECT DISTINCT a, b FROM table ORDER BY a) のDISTINCTのパフォーマンスを改善しました。このようなクエリは最大 2.4 倍高速になります。#110170 (nihalzp). groupBitOr/groupBitAnd/groupBitXorおよび分散系関数 (varPop、varSamp、stddevPop、stddevSamp、skewPop、skewSamp、kurtPop、kurtSamp、covarPop、covarSamp、corr) にベクトル化されたバッチ処理パスを追加しました。予測困難な条件で-Ifコンビネータを使用した場合は最大 4 倍、コンビネータなしの分散系関数では最大 3 倍高速化されます。#110461 (raimannma).- テキスト索引の解析を最適化しました。#110530 (CurtizJ).
- 16 進数の検証と変換を 2 パスではなく 1 パスで行うことで、テキストからの
UUID値のパース (例:LowCardinality(UUID)へのJSONExtract、toUUID、CAST AS UUID) を高速化しました。#110625 (groeneai). - 固定幅整数カラムなど、マッチオフセットが小さいカラムを対象に、短いオフセットの重複コピーを SSSE3
pshufbでベクトル化することで、x86_64 上での ZSTD の伸長を高速化しました (#108049 で導入された AArch64 NEON 最適化の x86_64 版です) 。#110909 (thevar1able). - CRC32 ハッシュ (
uniqExactと同様) を使用し、行ごとの挿入処理をインライン化することで、数値型に対するgroupUniqArrayを最大 3 倍高速化しました。#110917 (raimannma). - 浮動小数点カラムに対する minmax および基本的なカラム STATISTICS の効率を改善しました。#111221 (cv4g).
COUNT()クエリの結果を、テキスト索引のカーディナリティのメタデータから直接返すようにしました。#111494 (ahmadov)。- 128 ビットおよび 256 ビット型 (
Int128、UInt128、Int256、UInt256、Decimal128、Decimal256) に対するminとmaxを高速化しました。多倍長整数型では最大 1.8 倍、多倍長 10 進数型では最大 3.4 倍高速になります。#111965 (raimannma)。 system.query_logへの取り込みにおける性能低下を修正しました。Settingsおよびasynchronous_read_countersの Map カラムの構築が以前より約 6 倍遅くなっていたため、多数の設定を変更したクエリを大量にログ記録するサーバーでは、SYSTEM FLUSH LOGS query_logが 180 秒のタイムアウトを超過する可能性がありました。#112210 (groeneai)。- テキスト索引に存在しないトークンをキャッシュするオプションを追加しました。#112742 (rorylshanks)。
- 非同期ロギングで、上限付きのロックフリーキューを使用するようになりました。ログメッセージを書き込むスレッドが、ミューテックスでブロックされたり、ロギングスレッドを起床させたりすることはなくなります。#112803 (alexey-milovidov)。
- point 引数が
Point型 (または 2 つの数値要素からなる他のTuple) のキーカラム全体である場合に、pointInPolygonで主キー索引を使用するようになりました。例えば、coordでソートされたテーブルに対するpointInPolygon(coord, [...])などが該当します。これまでは、2 つのスカラーのキーカラムを用いるpointInPolygon((x, y), [...])形式のみが解析対象でした。#112956 (alexey-milovidov)。 text_index_posting_list_apply_modeのデフォルトがlazyになりました。これにより、posting_list_codecが設定されたテキスト索引では、テキスト索引クエリがポスティングリストをビットマップへ事前にマテリアライズせず、カーソルを用いてパック済みブロック単位でオンデマンドにデコードするようになります。#113521 (CurtizJ)。- タググループ ID が狭い範囲に収まる場合に、ハッシュベースの再マッピングを直接インデックス参照に置き換えることで、ベクトル化された TimeSeries のタグ変換を高速化しました。#114244 (fallintoplace)。
- テキスト索引のマージ性能を改善しました。#114525 (CurtizJ)。
- PromQL の集合演算子でコンパクトな存在マスクを使用するようにしました。#115224 (fallintoplace)。
- システムテーブルのアタッチ時に、テーブルコメントを設定するためだけに各テーブルのメタデータ (フルカラム定義を含む) を 2 回コピーすることがなくなりました。#115490 (thevar1able)。
- すべての要素がゼロの PromQL 条件ベクトルに対する重複系列チェックを高速化しました。#115822 (fallintoplace)。
DateTime64引数に対するtoUTCTimestamp/to_utc_timestampおよびfromUTCTimestamp/from_utc_timestampを高速化し、以前のオーバーフロー修正によって低下していたスループットを回復しました。結果に変更はありません。#115838 (groeneai)。- x86-64 環境におけるランダムデータ生成 (
rand、rand64、randomString、randomFixedString、generateUUIDv4、generateUUIDv7) の固定的なセットアップコストを削減しました。ブロックが小さい場合に特に効果があります。生成される値に変更はありません。#116158 (Algunenano). enable_function_early_short_circuit設定を使用すると、解析時に組み込みのandおよびorに対する早期の short-circuit 畳み込みを有効化できるようになりました。これにより、通常の型推論とセマンティック検証を維持したまま、実行する必要のない単一行のcount()スカラーサブクエリをスキップできます。#83505 (fhw12345).- 自明にシリアライズ可能なベクトルに対して、バッファ I/O 呼び出しを 1 回で済ませるようにしました #89842 (Ergus).
optimize_or_like_chainをデフォルトで有効化しました。#94517 (alexey-milovidov).- サーバーに多数のユーザーが存在する場合に、system.users から単一のユーザーレコードを取得する処理のパフォーマンスを改善しました。#96699 (alistairjevans).
改善
クエリおよび SQL の改善
UNIONクエリの複数の分岐から参照されるマテリアライズド CTE は、一度だけマテリアライズされ、すべての分岐で共有されるようになりました。以前は各分岐がそれぞれ CTE のコピーを持ち、個別にインライン展開・評価されていました。#102107 (novikd)。- プローブ側が小さいと推定される場合は JOIN ランタイムフィルタをスキップするようにしました。しきい値は新しい設定
join_runtime_filter_min_probe_rows(デフォルト1000) で制御します #104860 (vdimir)。 EXPLAIN [PLAN] actions=1, compact=1, pretty=1をデフォルトにしました。#105036 (Fgrtue)。- LIMIT BY の肯定形 (LimitByTransform、LimitBySortedStreamTransform) におけるキャンセルの遅延を短縮しました。KILL QUERY や Ctrl+C を実行すると、ステップ全体の完了を待たずに、1 チャンク以内で処理が中断されるようになりました。#106070 (rvasin)。
- 自動並列レプリカで JOIN クエリがサポートされるようになりました。#106073 (nickitat)。
- 新しい非同期メトリクス UntrackedMemory (
system.asynchronous_metricsで確認可能) を追加しました。このメトリクスは、スレッドがすでに割り当て済みであるものの、グローバルなメモリ追跡カウンタにはまだ計上されていないメモリ量を示します。各スレッドは小さな割り当てをローカルに蓄積し、まとめて報告します。これにより、MemoryTrackingとプロセスの実際のメモリ使用量との差異を説明しやすくなります。また、MEMORY_LIMIT_EXCEEDEDエラーメッセージに未追跡メモリの量も含まれるようになり、クエリやサーバーがメモリ制限に達した原因を把握しやすくなりました。#106386 (mstetsyuk)。 - 挿入パイプラインの構築中に materialized view の
TOターゲットテーブルが書き込みを拒否してINSERTが失敗した場合 (たとえばターゲットがViewである場合や、トランザクションをサポートしていない場合)、エラーメッセージにストレージエラーだけでなく、該当する materialized view とそのターゲットテーブルの名前も表示されるようになりました。#107234 (groeneai)。 - 名前付き
Tupleに対するALTER TABLE ... MODIFY COLUMN <col> Tuple(...)は、サブフィールドを追加するだけの場合はメタデータのみの操作となり、トップレベルのADD COLUMNと同等の速度で実行されるようになりました。この機能はSET allow_metadata_only_named_tuple_alter = 1で有効化できます。#107305 (amosbird)。 MaterializedPostgreSQLデータベースエンジンに、作成時に指定する設定materialized_postgresql_use_extended_date_and_time_typesを追加しました。デフォルト (有効) では、PostgreSQL のdate/timestampカラムはDate32/DateTime64として推論されます。CREATE DATABASE時にこの設定を0にすると、より範囲の狭いDate/DateTime型として推論されます。この設定はMaterializedPostgreSQLテーブルエンジンには適用されません。#107428 (alexey-milovidov)。EXPLAIN PLANで、結合の推定結果行数がテーブル統計ではなくヒントやランダム化されたフォールバックに基づく場合、近似値 (~~...) として表示されるようになりました。これにより、結合順序の最適化に必要な信頼できる統計が不足しているプランを特定しやすくなります。#107666 (vdimir)。MergeTreeテーブルへのINSERTが、多数のパーツの書き込み中もクエリのキャンセルやmax_execution_timeに従うようになりました。これにより、強制終了後も長時間実行され続けることがなくなりました。#107929 (al13n321)。arrayFoldがクエリのキャンセルとmax_execution_timeを考慮するようになりました。以前は、非常に長い配列に対する fold (例:arrayFold(acc, x -> arrayPushFront(acc, x), range(number), emptyArrayUInt64())) は fold 全体を単一の関数呼び出し内で実行していたため中断できず、fold が完了するまでKILL QUERYや時間制限が無視されていました。#108192 (groeneai).- クエリ実行前のフェーズごとの
ProfileEventsとして、QueryParseMicroseconds、QueryAnalysisMicroseconds、QueryPlanBuildMicroseconds、QueryPipelineBuildMicrosecondsを追加しました。これらにより、クエリ実行前のどの段階 (パース、解析、クエリプランのビルド、パイプラインのビルド) で時間がかかっているかを把握できます。system.query_logおよびsystem.eventsで参照できます。#108282 (jrdi). max_query_sizeを超えるテーブルメタデータを生成するALTER TABLE操作を事前に拒否するようになりました。これにより、DDL の分散やレプリカの復旧などのコンポーネントがテーブルを読み込めなくなる事態を防ぎます。#108283 (lockie).- デカルト結合およびアナライザが計画する定数述語の結合向けに
ConstantJoinを追加しました。これにより、アナライザ使用時にjoin_algorithm設定との非互換が原因でこれらのクエリが失敗することがなくなりました。#108289 (antaljanosbenjamin). system.documentationに、各エンティティのドキュメントが定義されているソースファイルのパスを格納するsourceカラムを追加しました。また、このテーブルには圧縮コーデック、プロファイルイベント、現在のメトリクス、非同期メトリクス、およびシステムテーブル自体 (カラムを含む) のドキュメントも含まれるようになり、設定のドキュメントには型とデフォルト値が記載されるようになりました。#108346 (alexey-milovidov).- WHERE で
tableおよびdatabaseのフィルタを指定すると、system.iceberg_historyは一致したデータベースのみを列挙するようになりました。サーバー上に無関係なリモートデータベースが多数ある場合に、処理時間を短縮できます。#108492 (Diskein). - クエリパラメータ (
{name:Type}による置換) を設定値として使用できるようになりました。クエリ (SELECTやINSERTなど) のSETTINGS句と、単独のSETクエリの両方で使用できます。例:SELECT ... SETTINGS max_threads = {threads:UInt64}、SET max_threads = {threads:UInt64}。#108760 (alexey-milovidov). - EXPLAIN WHATIF でスキップインデックスを組み合わせた場合の効果を計算できるようになりました。適用可能なすべての既存の仮想インデックスの効果の共通部分として、データ比率を表示します。#108934 (yariks5s).
- CTE が 1 つだけのクエリも、複数の CTE を持つクエリと同じ改行とインデントでフォーマットされるようになりました。以前は
WITH a AS (...)では CTE がWITHと同じ行に置かれていましたが、CTE が 2 つ以上の場合はWITHが独立した行に置かれ、各 CTE がインデントされていました。#109092 (groeneai). Fileテーブルエンジン経由で読み込むローカルの Parquet ファイルで Query Condition Cache をサポートしました (以前はオブジェクトストレージとデータレイクのみ対応) 。#109247 (alexey-milovidov).- リモート (オブジェクトストレージ) の Parquet ファイルに対する Query Condition Cache のキーとして、パスに加えて ETag も使用するようにしました。これにより、オブジェクトを同じ場所で上書きした場合に、古いキャッシュ結果が返されることがなくなりました。#109310 (alexey-milovidov).
ON条件で等値比較されているINNER JOINキーを修飾なしで参照した場合 (例:SELECT id FROM a INNER JOIN b ON a.id = b.id) 、両側が同じ値を持つことが保証されているため、あいまいな識別子として報告されなくなりました。#109366 (alexey-milovidov).QBitに対する転置版の距離関数 (L2DistanceTransposed、cosineDistanceTransposed、dotProductTransposed、およびそれらの量子化版であるL2DistanceTransposedQuantized、cosineDistanceTransposedQuantized、dotProductTransposedQuantized) が、検索対象の次元数より長い参照ベクトルを受け付けるようになりました。余分な末尾の要素は無視されます。これにより、フルサイズのクエリベクトルを事前にスライスすることなく、次元削減 (Matryoshka) 検索にそのまま再利用できます。#109388 (alexey-milovidov).- 分散クエリが常に既知のクライアントバージョンを保持していることを確認するサニティチェックを追加しました。バージョン 0 をリモートシャードに暗黙的に転送するのではなく、論理エラーをスローします。サーバー起点のクエリ (バックグラウンド flush、ストリーミングコンシューマー、Dictionary の再読み込み、非同期挿入の flush) は、イニシエーターのバージョンとしてサーバー自身のバージョンを報告するようになりました。#109408 (alexey-milovidov).
- MergeTree 系テーブルエンジンに対するミューテーション操作の WHERE 句で、修飾付きカラム名を使用した場合の問題を修正しました。#109491 (Michicosun).
- 分散クエリプラン (
make_distributed_plan) で、パーティション指定のないウィンドウ関数 (OVER (ORDER BY ...)) をサポートしました。これまではWindowStepをリモート実行用にシリアライズできなかったため、ウィンドウ関数を含むクエリはすべて失敗していました。なお、PARTITION BYを含むウィンドウは現時点では引き続き拒否されます。#109802 (VighneshPath). ALTER DATABASE ... MODIFY SETTING = 'xxx'を使用して、one-lake カタログの一部の認証設定を変更できるようになりました。#110019 (alesapin).INの右辺にあるサブクエリの単一カラムが、左辺の引数より 1 次元深い配列である場合、わかりにくい型不一致エラーで失敗するのではなく、 (配列リテラルや配列を返す関数と同様に) その配列の要素の集合として解釈されるようになりました。例えば、x IN (SELECT groupArray(x) FROM ...)が動作するようになりました。#110169 (alexey-milovidov).- TopK 動的フィルタリング (
ORDER BY ... LIMIT k) で高速化されたクエリが、クエリ条件キャッシュをより有効に活用できるようになりました。遅延マテリアライゼーションが適用される場合でもキャッシュにエントリが格納されるほか、同じWHERE述語を持つ通常のクエリが以前に書き込んだエントリも再利用できます。#110507 (shankar-iyer). SHOW CREATE TABLE(およびSHOW CREATE VIEW/SHOW CREATE DICTIONARY) で、要求されたテーブルが存在しない場合に、SELECTクエリと同様にエラーメッセージで似た名前のテーブルを提案するようになりました。#110633 (alexey-milovidov).- STREAM BOUNDED 修飾子を追加しました。この修飾子を指定すると、ストリーミングクエリは最初のスナップショットのみを読み取り、更新を購読せずに終了します。#110653 (SmitaRKulkarni).
- PromQL クエリにおけるクエリ結果キャッシュを修正しました。
promql方言では非決定論的関数のチェックが行われず、now()を基準とした古い結果が返される可能性がありました。また、Prometheus HTTP API (/api/v1/query、/api/v1/query_range) ではキャッシュエントリがまったく保存されていませんでした。#110887 (nikitamikhaylov)。 EXPLAIN ANALYZEが、結合の左右それぞれの行数、一致率、ファンアウトに加え、ハッシュテーブルのメモリ使用量やスピルなどのアルゴリズム固有の状態を報告するようになりました。追加の記録処理が必要な一致メトリクスを収集するには、matches = 1を指定してください。#110892 (Fgrtue)。- クエリが実行時にプロセッサを削除する場合 (遅延読み取りを伴う
FINALや外部ソートなど) に、サーバーがクラッシュする可能性があったパイプラインエグゼキューターの heap-use-after-free を修正しました。この問題は AST fuzzer によって発見されました。#111017 (groeneai)。 - 共有ストレージスナップショット (設定
enable_shared_storage_snapshot_in_query) を使用するクエリがスナップショットからデータパーツを除去した際に発生する use-after-free (セグメンテーションフォールト) を修正しました。たとえば、クエリ内の別の箇所が同時に読み取っているMergeTreeテーブルを、ストリーミングサブクエリも読み取るケースが該当します。#111192 (alexey-milovidov)。 - 空の
MergeTreeテーブルからの読み取りなど、プランニング時点でソースが行を生成しないことが確定しているクエリについて、分散クエリプラン (make_distributed_plan) をサポートしました。従来、このようなクエリはSUPPORT_IS_DISABLEDで失敗していました。#111941 (groeneai)。 - 複数の
AND条件を持つWHERE句で、最後の連言以外によって除外されたグラニュールが クエリ条件キャッシュ に登録されない問題を修正しました。#112083 (shankar-iyer)。 - バケット化された共有データシリアル化 (map_with_buckets および advanced) で JSON カラムを書き込む際、すべてのバケットを同時にマテリアライズするのではなく、書き込み時に共有データを 1 バケットずつ分割するようにし、ピークメモリを削減しました。この改善が特に効果を発揮するのは Array(JSON) カラムです。スカラー JSON では共有データがグラニュール単位 (上限は index_granularity_bytes) で分割されるため削減効果は小さいものの、Array(JSON) では単一のグラニュールに多数のネストされた行、つまり大量の共有データが含まれ得るため、1 バケットずつ分割することでピークメモリが大幅に低減されます #112172 (Avogar)。
- メモリ予約スケジューリング (experimental) で、上限を超える予約増加に必要な領域が保留中のメモリ解放によって確保される場合は、割り当てを退避しないようになりました。退避の判断は進行中の減少が反映されるまで待つようになったため、メモリ逼迫時に不要なクエリの強制終了が発生しなくなります。#112299 (serxa)。
SYSTEM DROP FILESYSTEM CACHEがキャッシュメタデータキーを並列に削除するようになり、大規模なファイルシステムキャッシュのクリアが高速化されました。新たに追加されたファイルキャッシュ設定drop_cache_threadsで削除ワーカー数を指定できます (デフォルトは 16) 。値を 1 にすると、削除はクエリスレッド内で実行されます。#112532 (kssenii)。- カラム宣言の修飾子 (
COMMENT、CODEC、STATISTICS、TTL、COLLATE、PRIMARY KEY、およびカラムごとのSETTINGS) を、CREATE TABLEにおいて任意の順序で記述できるようになりました (各修飾子は最大 1 回まで) 。以前は決められた 1 つの順序しか受け付けられず、たとえばx UInt64 CODEC(ZSTD) COMMENT 'text'は構文エラーになっていました。ALTER TABLE ... ADD COLUMN/MODIFY COLUMNにおいても、サポートされている修飾子 (COMMENT、CODEC、STATISTICS、TTL、およびカラムごとのSETTINGS) を任意の順序で記述できます。また、ADD COLUMN内のカラムごとのSETTINGSや、ADD COLUMN/MODIFY COLUMN内で宣言されたSTATISTICSは、これまで警告なしに破棄されていましたが、正しく適用されるようになりました。さらに、これらのALTERコマンド内のCOLLATEとPRIMARY KEYは、これまで警告なしに無視されていましたが、例外をスローするようになりました。#112788 (alexey-milovidov). - 多数のテーブルにマッチする
Mergeテーブル (またはmergeテーブル関数) に対するクエリが、テーブルごとのクエリプランの構築中にもKILL QUERYおよびmax_execution_timeに反応するようになりました。これまでは、すべての子テーブルのプランニングが完了するまで反応しませんでした。#113415 (alexey-milovidov). timeout_overflow_mode = 'break'の設定でmax_execution_timeを超過したMergeテーブルからのSELECTは、残りのマッチしたテーブルに対するクエリプランの構築を停止するようになりました。これまでは、停止する前にマッチしたすべてのテーブルに対して完全なクエリ解析を実行していました。クエリは、このモードのドキュメントに記載されているとおり、エラーなしで終了します。#113642 (groeneai).MergeTreeの読み取り中にカラムの宣言された型と実際のデータが食い違う場合 (型の由来が混在している場合。たとえばミューテーションが完了していないALTER TABLE ... MODIFY COLUMNの後など) 、サーバーは未検査のキャストを行う代わりに、カラム名と両方の構造を示す明確な例外を報告するようになりました。以前は、デバッグビルドやサニタイザービルドではカラム名を含まないBad cast from type A to Bだけを出力して異常終了し、リリースビルドでは不整合なメモリを何の通知もなく走査していました。#114087 (alexey-milovidov).ie_joinをデフォルトで有効化しました。join_algorithmのデフォルト値はdirect,parallel_hash,hash,ie_joinになります。ON句が不等価条件のみ (結合対象テーブルの式同士の<、<=、>、>=による 2 つの比較) で構成されるJOINは、フィルター付きのCROSS JOINではなく、ソートベースの IEJoin アルゴリズムで実行されるようになりました。また、このような条件を持つLEFT/RIGHT/FULL/SEMI/ANTI結合もサポートされます。ie_joinはリストの最後にあるため、他のアルゴリズムが適用できない場合にのみ使用されます。#114327 (vdimir).- 非同期の接続確立およびリモートクエリ実行に使用されるファイバー (ヘッジリクエスト、
async_socket_for_remote、async_query_sending_for_remote) に OpenTelemetry のトレースコンテキストを伝播するようにしました。分散クエリにおけるリモートクエリのスパンは、クライアントから渡されたトレースコンテキストに直接紐付けられるのではなく、イニシエーターのConnection::sendQueryスパンの子として正しく配置されるようになりました。また、非同期タスクの実行ごとに個別のスパンが生成されるようになりました。#114813 (diegomestre2). DROP DATABASEは、ロード依存関係と参照依存関係の両方 (以前はロード依存関係のみ) に基づき、トポロジカル順序の逆順でテーブルを削除するようになりました。これにより、DROP DATABASEの途中でクラッシュしても、依存先がすでに削除されたテーブルが残ることはありません。#114952 (alexey-milovidov).- PostgreSQL 形式の正規表現マッチ演算子をサポートしました:
~(match関数のエイリアス)、~*(大文字と小文字を区別しない照合によるマッチ)、!~および!~*(否定)。PostgreSQL 互換プロトコル経由で ClickHouse に接続した場合にpsqlの\d、\dt、\dvコマンドが動作するようになったほか、クエリが失敗しても接続が切断されなくなりました。#115066 (alexey-milovidov)。 EXPLAIN WHATIFで、経験的推定がスキップされた理由が表示されるようになりました。理由は、empirical_statusがunsupportedの場合に表示される新しいempirical_reason行に示されます。#115140 (yariks5s)。join_algorithm設定で有効化されたどの結合アルゴリズムでもJOINを実行できない場合、エラーメッセージでは、いずれも動作しなかったことだけでなく、試行されたアルゴリズムと、失敗した JOIN の厳密性および種類が示されるようになりました。#115226 (elkinal)。- 参照ベクトルが整数配列リテラルの場合(例:
ORDER BY L2Distance(vec, [1, 2]))でも、ベクトル検索クエリでベクトル類似度索引を使用できるようになりました。以前は、このようなクエリは警告なく総当たりスキャンにフォールバックしていました。#115255 (rschu1ze)。 - ロックファイルを作成した
BACKUPの試行が、何も書き込まないうちに失敗した場合(宛先の確保中・アーカイブのオープン中のいずれであっても)、宛先にロックファイルが残らなくなりました。従来は、このようなロックに一致するバックアップは以降存在し得ないため、ファイルを手動で削除するまで同じ宛先へのリトライはすべて失敗していました。また、S3およびAzureの宛先へのバックアップでもロックが排他的に作成されるようになり、別のバックアップに属するロックは、ストレージが返したエラーそのままではなく、同時実行中のバックアップとして報告されるようになりました。#115387 (jkartseva)。 - サンプリング(
opentelemetry_start_trace_probability)によって開始されたトレースがクエリのクライアント情報に書き戻されるようになりました。これにより、リモートおよび分散のセカンダリクエリや DDL エントリが、別々のトレースを開始せずに同じトレースに参加するようになりました。#115619 (diegomestre2)。 - テーブルの格納場所を自ら管理する Amazon S3 Tables をバックエンドとする Iceberg テーブルに対する
CREATE TABLEを修正しました。#115652 (scanhex12)。 - アダプティブな
GROUP BY集約(enable_adaptive_aggregator)は、出現頻度の低いキーの処理を後回しにすることが有効かどうかを計測し、そのキーや集約関数の引数が大きすぎてコピーのコストに見合わない場合は通常のアルゴリズムに戻るようになりました。これにより、サイズの大きい文字列カラムに対する集計(例: ユーザーごとのmin(URL))が、通常のアルゴリズムと同等の速度とメモリ使用量で実行されます。また、各スレッドの凍結テーブルをバイト数で制限するadaptive_aggregator_freeze_threshold_bytesを追加しました(これとキー数のしきい値のうち、先に到達した方でテーブルが凍結されます)。#115755 (nihalzp)。 - 最終集約の出力に
LIMIT n付きのORDER BYが続く場合に、2 レベルの各バケットの上位nグループのみをマテリアライズする実行計画の最適化について、その有効・無効を切り替える設定query_plan_aggregation_bucket_top_k(デフォルトで有効)を追加しました。この最適化はEXPLAINの出力にも表示されるようになりました。#116124 (nihalzp)。 - パラメーター化ビューに対する
DESCRIBEクエリのサポートを改善しました。また、新しいアナライザーで、スカラー式内でのパラメーター化ビューの使用をサポートしました。#68978 (novikd)。 SELECT * FROM t WHERE idのようなクエリで、idカラムに対するスキップ索引が使用されるようになりました。#89603 (adityachopra29)。query_plan_merge_expression_into_join設定を追加しました。これにより、結合順序の最適化時に Expression ステップを JOIN ステップにマージできるようになります。結合をラップするサブクエリをまたいで結合順序を入れ替えられるようになるため (例: 計算カラムを含むサブクエリ内に JOIN がある場合) 、複雑な結合ツリーをより効果的に最適化できます。#98533 (vdimir)。system.grantsテーブルにis_wildcardカラムを追加しました。このカラムは、権限がワイルドカードによるプレフィックス一致 (例:GRANT SELECT ON db*.*) を使用しているかどうかを示します。これまでは、同じ名前に対するワイルドカード権限と完全一致の権限をsystem.grants上で区別できませんでした。#98577 (il9ue)。
関数とデータ型
- 新しい設定
allow_lossy_numeric_supertypeを追加しました (デフォルトでは無効) 。有効にすると、損失なく変換できる共通型が存在しない数値引数 (例えばDecimalとFloat64、あるいはInt64とFloat64) に対してif、multiIf、coalesce、ifNull、array、mapを使用した場合、結果の型がVariantではなく数値の上位型Float64に解決されます。これにより、結果をsum、avg、min、maxなどの集約関数で使用できるようになります。また、関連する集約関数のエラーメッセージにこの設定名が表示されるようになりました。#107236 (groeneai)。 SOME/ALL配列量化子 (expr OP SOME(array)/expr OP ALL(array)) が、キーワード比較述語IS DISTINCT FROMおよびIS NOT DISTINCT FROM、ならびに文字列検索述語LIKE、ILIKE、NOT LIKE、NOT ILIKE、REGEXPにも対応しました。これらはarrayExists/arrayAllに書き換えられます。#107454 (alexey-milovidov)。- パース時の JSON オブジェクトのサイズを制限する
input_format_json_max_object_size設定を追加しました。#107669 (Avogar)。 - SQLite データベースのオープンに失敗した場合 (例えば、
sqliteテーブル関数やSQLiteデータベースエンジンに開けないパスが指定された場合) に発生していたメモリリークを修正しました。#107807 (alexey-milovidov)。 QBitデータ型でlength関数が使用できるようになりました。ベクトルの次元を定数として返します。#108071 (alexey-milovidov)。QBitからArrayへのCASTをサポートし、元のベクトルを復元できるようにしました。これは既存のArrayからQBitへの変換の逆操作です。#108072 (alexey-milovidov)。MySQLデータベースエンジン、テーブルエンジン、およびテーブル関数で、MySQL の空間カラム型 (LINESTRING、POLYGON、MULTILINESTRING、MULTIPOLYGON、および汎用のGEOMETRY) が、Stringではなく対応する ClickHouse の幾何型にマッピングされるようになりました。この動作はmysql_datatypes_support_level設定の新しいgeometryフラグで制御され、デフォルトで有効です。POINTは従来どおり常にPointに変換されます。汎用のGEOMETRYカラムは、各幾何型を包括するGeometry型にマッピングされます。ClickHouse に対応する型がないサブタイプ (MULTIPOINT、GEOMETRYCOLLECTION) の値は、読み取り時に例外がスローされます。#108944 (alexey-milovidov)。- 浮動小数点数のパースで、精密な (最も近い表現可能な値を求める) アルゴリズムをデフォルトで使用するようにし、
precise_float_parsing設定をtoFloat*/CASTだけでなく、入力フォーマット (CSV、TSV、JSON、VALUES など) や数値リテラルにも適用するようにしました。従来の動作 (精度は劣るものの、場合によっては高速) に戻すには、precise_float_parsing = 0を設定してください。#109086 (Algunenano)。 - 固定サイズ要素の
ArrayをStringとしてreinterpretできるようになりました。これは既存の、String/FixedStringをArrayとしてreinterpretする操作の逆操作です。#109383 (alexey-milovidov)。 - 次元が同じであれば、要素型やストライドが異なる
QBit型間でもCASTできるようになりました (例:QBit(Float32, N)からのCAST(x AS QBit(Float64, N))) 。ストライドのみの変更は可逆です。要素型の変更は対応するArrayの変換セマンティクスに従います (例:Float32からBFloat16への変換では精度が失われる可能性があり、accurateCast/accurateCastOrNullは正確に表現できない行を拒否します) 。#109387 (alexey-milovidov). - 関数
quantizeBFloat16ToInt8およびdequantizeInt8ToBFloat16は、既存のスカラー用オーバーロードに加えて、ArrayおよびQBitの引数も受け付けるようになりました。この場合、Lloyd-Max コーデックをベクトル全体に適用し、対応する要素型のArray/QBitを返します。#109398 (alexey-milovidov). parseDateTime/parseDateTime64(およびそのOrZero/OrNull版) の MySQL 形式の書式指定子%fは、これまでのようにちょうど 6 桁を必須とせず、小数点以下 1〜6 桁を受け付けるようになりました。値は MySQL のSTR_TO_DATEと同様に、左詰めのマイクロ秒として解釈されます。また、組み込み関数ドキュメントの例でPrettyCompactテーブルの表示が崩れていた問題も修正しました。#109421 (alexey-milovidov).basic統計のサブ統計NullCountの名称をDefaultCountに変更しました。buildはNullableカラムのNULL行を数えるのではなく、IColumn::getNumberOfDefaultRowsを用いて、カラム型固有のデフォルト値に等しい行を数えるようになりました。#109977 (hanfei1991).- あまり使用されない混合型の組み合わせ (
Decimalとビット幅の異なる整数、およびInt128/UInt128/Int256/UInt256を含む組み合わせ) に対する比較演算と算術演算を、型の組み合わせごとに専用のコンパイル済みカーネルを用意するのではなく、共通型に変換してから実行するようにし、バイナリサイズを約 10.5 MB 削減しました。同一型の組み合わせ、よく使われる組み合わせ、およびメモリ律速のplus/minus/multiplyについては、引き続き専用カーネルを使用します。結果、結果の型、例外的なケースの挙動に変更はありません。#110131 (alexey-milovidov). SQLiteテーブルエンジンまたはsqliteテーブル関数からの読み取り時に、SQLite データベースが別の接続によってロックされていても、ビジースピンで CPU コアを 1 つ丸ごと占有することがなくなりました。読み取りはロックの待機中アイドル状態となり、引き続きキャンセルも可能です。#110248 (groeneai).- ログおよび例外メッセージ内の経過時間、レート、比率の値を 3 桁に丸め、
1.345844286 sec.のような数値が元の精度のまま出力されないようにしました。#110277 (alexey-milovidov). - サイズストリームが分離された
StringカラムをMergeTreeから読み取る際、先頭の行をスキップした後に、誤ったデータが返されたり、サブストリームキャッシュの境界外が読み取られたりする可能性があった問題を修正しました。また、map 形式の shared-data シリアライゼーションで格納されたJSONサブオブジェクトに同時実行または繰り返しの読み取りでアクセスした際、誤ったデータが返される可能性があった問題も修正しました。#110471 (alexey-milovidov). PostgreSQLテーブルエンジンおよびpostgresqlテーブル関数でSETTINGS句をサポートし (例:SETTINGS postgresql_connection_pool_size = 50) 、MySQLエンジンと同等の機能を備えました。#110614 (alexey-milovidov).- 関数
bitmaskToArrayとbitmaskToListが(U)Int128および(U)Int256の引数をサポートするようになりました。また、関数bitPositionsToArrayは、大きな整数の引数に対して、最上位のセットビットの位置ではなく、セットビットの数に比例した時間で実行されるようになりました。#110743 (raimannma)。 - 負の数を含む符号付き固定幅値に対する GCD コーデックの処理を修正しました。従来は符号付きの値から直接除数を計算していたため、共通の除数を検出できず、符号付き整数カラムおよび decimal カラムの圧縮効率が大幅に低下する場合がありました。現在は、符号付き型では絶対値から除数を計算し、符号なし型および伸長処理については従来の動作を維持します。#113798 (kshcherbatov)。
PARTITION BYを含むウィンドウ関数がmake_distributed_plan有効時にも動作するようになりました。プランの構成が許す場合、ウィンドウは、各バケットが完全なパーティションを受け取る形で複数のバケットにわたって並列に実行されます。#114111 (VighneshPath)。- external な nullable 固定幅集約メソッドで 64 ビットハッシュ関数を使用するようになりました (カーディナリティが非常に高い集約で深刻なハッシュ衝突が発生するのを防ぎます) 。#114210 (nickitat)。
LowCardinalityカラムに対するx IN (subquery)が、x IN (literal list)と同じ型であるLowCardinality(UInt8)を返すようになりました。従来はこの 2 つの形式が異なる型を返していたため、このようなINを含む分散プランでは、プランの型チェックに特別な処理が必要でした。#114229 (davenger)。JSONデータ型、JSONExtract、isValidJSONで、64 ビットの範囲を超える整数のパースをサポートしました。このような値によってドキュメント全体が拒否されることはなくなり、Int128/UInt256などのワイド整数型として読み込まれます。#114379 (Avogar)。- OpenSearch、Elasticsearch、SolR、Lucene との互換性を高めるため、テキスト索引のトークナイザー
arrayのエイリアスとしてkeywordを追加しました。#115507 (rschu1ze)。 - 関数
toDateOrNull、toDateTimeOrNull、toDateTime64OrNullが、すべてのネイティブ整数型の引数を受け付けるようになりました (toDate、toDateTime、toDateTime64と同様に解釈され、任意でタイムゾーン引数を指定できます) 。結果の型の範囲外の値に対してはNULLを返します。例えば、toDateTimeOrNull(1583851242, 'Asia/Shanghai')は2020-03-10 22:40:42を返し、toDateTimeOrNull(4294967296)はNULLを返します。#79791 (jitendra1411)。
ストレージ、データレイク、オブジェクトストレージ
- ファイルシステムキャッシュのエビクション動作に関するオプトイン方式の Prometheus メトリクス (
filesystem_cache_evictions_total、filesystem_cache_evicted_bytes_total、filesystem_cache_evicted_segment_hits、filesystem_cache_evicted_segment_size_bytes、およびuser_idラベル付きのユーザーごとのバリアント) を追加しました。これらはキャッシュごとにsystem.dimensional_metrics、system.histogram_metrics、および Prometheus エンドポイントを通じて公開されます。有効化はキャッシュのディスク設定expose_prometheus_eviction_metricsおよびexpose_prometheus_eviction_metrics_per_user(いずれもデフォルトで無効) で制御でき、SYSTEM RELOAD CONFIGにより実行時に切り替えられます。#105020 (sacheendra)。 - 対象テーブルが
MergeTreeファミリーのエンジンである場合、Aliasエンジンで並列レプリカによる読み取りがサポートされるようになりました。#107830 (nauu)。 - Azure Blob Storage の読み取り後書き込み方式のコピー (ネイティブコピーが利用できない場合にバックアップで使用) において、同時にステージングされるパーツ数を max_inflight_parts_for_one_file までに制限しました。これにより、多数の大きなファイルを並列コピーする際にメモリ使用量が過剰に増加するのを防ぎます。#108232 (SmitaRKulkarni)。
- HDFS ストレージで
_etag仮想カラムをサポートしました。#108255 (zhangyifan27)。 system.backupsおよびsystem.backup_logにsettingsカラムとengine_settingsカラムを追加しました。settingsには操作時に指定されたバックアップ/リストア固有の設定 (例:allow_s3_native_copy、deduplicate_files、structure_only) が、engine_settingsにはバックアップエンジンのリーダー/ライターで実際に適用された設定 (例:allow_native_copyなどの S3 リクエスト設定。エンドポイント設定とのマージにより、指定内容と異なる場合があります) が表示されます。これにより、BACKUP/RESTORE操作が実際にどの設定で実行されたかを確認できます。#108334 (jkartseva)。- 登録済みの
S3QueueテーブルおよびAzureQueueテーブルの Keeper 上の状態 (処理済み・処理中・失敗したファイル数など) を確認できるsystem.s3_queue_metadataとsystem.azure_queue_metadataを追加しました。#108522 (kssenii)。 - テキスト索引ヘッダーキャッシュのメモリ使用量を 2~2.5 分の 1 に削減しました。キャッシュ (設定
text_index_header_cache_size) により多くのデータパーツのヘッダーを格納できるようになり、テキスト検索クエリでのディスク読み取りが減少します。#109332 (CurtizJ)。 INFORMATION_SCHEMAビューに MySQL 互換のカラムを追加しました。対象はSCHEMATA.DEFAULT_COLLATION_NAMEおよびDEFAULT_ENCRYPTION、TABLES.ENGINEと関連する MySQL カラム、そしてCOLUMNS.COLUMN_KEY、PRIVILEGES、GENERATION_EXPRESSION、SRS_IDです。これにより、MySQL 対応クライアントがUNKNOWN_IDENTIFIERエラーを起こすことなくカタログのイントロスペクションクエリを実行できるようになります。#109351 (alexey-milovidov)。- 多数のデータパーツを持つ
MergeTreeテーブルのメモリ使用量を削減しました。スキーマから導出されるパーツごとのメタデータ (カラムリスト、カラム定義、シリアライゼーション、カラムのサブストリーム) を、各パーツにコピーする代わりにテーブル内のパーツ間で共有するようにしました。特に、小さなパーツを多数持つワイドテーブルで大きな効果があります。#109816 (Algunenano)。 - 新しい設定
use_projection_index_in_read_poolsを追加しました (デフォルトでは無効) 。有効にすると、プロジェクション索引によって完全に除外されるマーク範囲は、読み取り時にグラニュール単位でスキップされるのではなく、読み取りタスクが作成される前にMergeTreeの読み取りプール内で破棄されます。これにより、読み取られないデータに対して読み取りタスクを作成したりリーダーをセットアップしたりする必要がなくなり、読み取りタスクのサイズも残ったマーク数を基準に測られるようになります。#110291 (KochetovNicolai)。 MergeTreeにおけるパーツごとのプライマリキー二分探索の診断ログについて、ログレベルを trace から test に下げ、出力量を抑えました。#110324 (alexey-milovidov)。- TLS (HTTPS、S3) 経由でプールされた HTTP keep-alive 接続が不必要に再接続される問題を修正しました。古い接続の検出には socket に対する
pollを使用していましたが、未読の TLS ハンドシェイク後レコード (セッションチケットやKeyUpdate) を含む生存中のセキュア接続を、切断済みと誤判定していました。現在は、通常の socket ではノンブロッキングのMSG_PEEKを、TLS socket ではSSL_peek/SSL_has_pendingを使用しており、TLS の正常なシャットダウンや部分的にしか到着していない TLS レコードも正しく検出できます。#110402 (alexey-milovidov)。 - OneLake カタログで、OAuth リフレッシュトークンを使用してアクセストークンを更新できるようになりました。#110413 (alesapin)。
DuplicationDataHashComputationsProfileEvent を追加しました。*MergeTreeテーブルへ INSERT されたブロックの重複排除時に実行される、カラム単位のデータハッシュ計算の回数をカウントします。#111173 (valerypetrov)。- UNIQUE KEY 索引の SST を、ローカルの一時ファイルを経由せず、ストレージ抽象化を通じてパーツに直接書き込むようにしました。#111189 (JingYanchao)。
- ローカルディスク上の Iceberg テーブルへの同時実行書き込みをサポートしました。
LocalObjectStorageが条件付き書き込みを実装したことで、version-hint.textを通じて新しいスナップショットを公開する compare-and-swap がローカルディスクでも機能するようになり、同時に書き込む複数のライター間で互いの更新が失われることがなくなりました。#112556 (alexey-milovidov)。 S3クライアントのバケットリージョンキャッシュがデータレイクカタログでも機能するようになりました。これまでは、データレイクカタログへのリクエストのたびにリージョンを再解決していました。#113330 (scanhex12)。- Azure のクライアント側ネットワーク障害 (接続のリセット/拒否、DNS および TLS エラー) は、擬似的な
500エラーとして返されるのではなく、S3 クライアントと同様にトランスポートエラーとして再試行されるようになりました。#115269 (arsenmuk)。
フォーマットとインジェスト
- HTTP インターフェイスで snappy 圧縮 (
Accept-Encoding: snappy) をサポートしました。また、汎用のfile/urlにおける snappy I/O で、Hadoop snappy ブロックフォーマットと snappy フレーミングフォーマットのどちらを使用するかを選択できるsnappy_mode設定を追加しました。#100752 (alexey-milovidov)。 - 設定
input_format_csv_missing_nullable_as_empty_string(デフォルトでは無効) を追加しました。有効にすると、CSV 入力におけるNullable(String)の欠損値は、input_format_csv_empty_as_defaultの値にかかわらず、NULLではなく空のStringとして読み込まれます。#107577 (alexey-milovidov)。 input_format_protobuf_oneof_presenceを使用して protobuf メッセージを処理する際、スキーマ変更に対応できるよう、タグの完全一致を必須としないようにしました。#109174 (ilejn)。- Apache Arrow ベースのレガシー ORC リーダーを削除しました。ORC 入力フォーマットでは、常に ClickHouse のネイティブデコーダ (従来のデフォルト) が使用されるようになりました。
input_format_orc_use_fast_decoder設定は廃止されました (指定は引き続き可能ですが、効果はありません) 。#110074 (alexey-milovidov)。 - Hive エンジンでは、ORC ファイルのメタデータ (min/max 索引、行数) の読み込みに、Apache Arrow ORC アダプターではなく ClickHouse のネイティブ ORC リーダーを使用するようになりました。#110086 (alexey-milovidov)。
セキュリティ、アクセス、オブザーバビリティ
system.tablesテーブルに新しいカラムskipping_indices_typesを追加しました。このカラムには、各テーブルに定義されているデータスキッピングインデックスの種類が重複なく格納されます。#106388 (CurtizJ)。max_threadsなどの設定の自動値が、system.settingsで'auto(8)'ではなくauto(8)と表示されるようになりました。値を囲むシングルクォートは、長年にわたって値に埋め込まれていた不要な名残です。バージョン間の互換性は維持されており、古いサーバーから受信した設定をパースする際は、従来のクォート付き形式も引き続き受け付けます。#108657 (alexey-milovidov)。system.documentationで、設定のデフォルト値が空の場合に、空のバッククォートではなく empty string と表示するようにしました。#108708 (alexey-milovidov)。system.documentationに含まれる設定のドキュメント (組み込みの/docsページやhelpコマンドで表示されるもの) に、デフォルト値の変更履歴が記載されるようになりました。設定が導入されたバージョンに加え、それ以降のデフォルト値の各変更について、変更前の値、変更後の値、変更理由が示されます。#112177 (alexey-milovidov)。- すべての SQL ステートメントのドキュメント (名前、構文、説明、例など) を、システムテーブル
system.statementsから取得できるようになりました。#115341 (rschu1ze)。
設定と構成
- 新しいサーバー設定
memory_worker_rss_speculative_reserve_ratio(デフォルト1.0、sanitizer ビルドでは0)を追加しました。この設定により、グローバルな memory tracker はMemoryWorkerのティックごとに、観測された RSS に加えてratio * min(resident - previous_resident, resident - tracked)を投機的に予約します。サンプル間で RSS の増加が tracker の記録に追いついていない場合に tracker の値を上方向に補正するため、メモリ割り当てがより早い段階でMEMORY_LIMIT_EXCEEDEDとなり、カーネルの OOM-killer が先に発動しにくくなります。投機的予約を無効にするには、ratio を0に設定してください。sanitizer ビルドではresident - trackedの差の大部分を sanitizer のシャドウメモリが占めるため、デフォルト値は0です。#104976 (alexey-milovidov). - テキスト索引の遅延実行型ポスティングリスト適用モードが実験的機能ではなくなり、
allow_experimental_text_index_lazy_applyを指定しなくてもtext_index_posting_list_apply_mode = 'lazy'で選択できるようになりました。また、密度しきい値の設定名がtext_index_density_thresholdからtext_index_lazy_intersection_density_thresholdに変更されました。#108814 (CurtizJ). merge_selector_enable_heuristic_to_lower_max_parts_to_merge_at_once設定がデフォルトで有効になりました。merge selector は、パーティションの充填状況に応じて、一度にマージするパーツの最大数を自動的に引き下げます。#110726 (Michicosun).- PostgreSQL ワイヤプロトコルで、PostgreSQL のクリーンアップコマンド
RESET、UNLISTEN、DISCARDを構文エラーとして失敗させず、何もしない操作(no-op)として受け付けるようにしました。これにより、接続の確立時やクリーンアップ時にRESET ALLやUNLISTEN *を送信する Skunk などのドライバーとの互換性が向上します。#110780 (alexey-milovidov). - AI テキスト関数(
aiGenerate、aiClassify、aiExtract、aiTranslate)は、プロバイダーからの応答が途中で切れているなど不完全な場合(例: モデルがmax_tokensの上限に達した場合)、部分的な出力を黙って返すのではなく、その応答を拒否するようになりました。この動作はai_function_throw_on_error設定に従います。#111830 (george-larionov). p < 8QBit(Int8)のコードをガウス条件付き平均に基づくプレフィックスセントロイドで再構成することで、低精度時のL2DistanceTransposedQuantized、cosineDistanceTransposedQuantized、dotProductTransposedQuantizedを改善しました。元の精度(p = 8)では、引き続きビット単位で完全に一致する結果が得られます。低精度時の近似距離は変わる可能性があり、再現率やレイテンシの改善効果はワークロードによって異なります。#111867 (skuznetsov).write_snapshot_version設定をホットリロードできるようにしました。#112150 (alesapin).- リモートレプリカとの非同期通信に使用されるファイバーのスタックのオブザーバビリティを利用できるようにしました。プロファイルイベント
FiberStackAllocs、FiberStackAllocBytes、FiberStackAllocNanoseconds、FiberStackFreeNanoseconds、およびメトリクスFiberStacks、FiberStackBytesを利用できます。#114541 (alexey-milovidov). - Prometheus remote-write プロトコルが非同期挿入に対応しました。
async_insert設定に従い、同時に送信された複数の remote-write リクエストのデータは、パーツが作成される前にバッチにまとめられます(デフォルトで有効。従来の同期動作を維持するには、ハンドラー URL にasync_insert=0を追加してください)。リクエストへの確認応答は、対象のTimeSeriesテーブルのすべての内部テーブルにデータがフラッシュされた後に返されます。#115688 (nikitamikhaylov).
その他の改善
shrink_over_allocated_columns_min_waste_ratioとshrink_over_allocated_columns_min_waste_bytesの 2 つの設定を追加しました。これらを有効にすると、INSERT 時に過剰割り当てされたカラム (可変長カラムが 2 のべき乗で拡張されるために、予約メモリが使用メモリを上回っているカラム) が、マテリアライズおよびパーツの書き込み前に適切なサイズまで縮小され、ピークメモリ使用量が削減されます。デフォルトでは無効です。 #112161 (Avogar).TTLDropマージではデータ読み取りステップを完全にスキップするようにし、特に読み取り/プリフェッチバッファの割り当てによる過剰なメモリ使用を回避しました。 #105859 (Avogar).dotProductでBFloat16をサポートし、SIMD パスをバッチ化することで内積の性能を向上させました。 #106569 (nickitat).max_named_collection_num_to_throw、max_table_num_to_throw、max_replicated_table_num_to_throw、max_view_num_to_throw、max_dictionary_num_to_throw、max_database_num_to_throwをサーバーを再起動せずに変更できるようにしました。 #106821 (UberDever).allow_experimental_delta_lake_writesで制御されるDeltaLakeテーブルへの書き込みを Beta に昇格しました。 #107034 (kssenii).uniqCombined64スケッチをベースとした、uniqの軽量な代替となるカラム STATISTICS タイプuniq_v2を追加しました。 #107863 (hanfei1991).- make_distributed_plan の実行状況を監視するための ProfileEvents
DistributedPlanRemoteTasks、DistributedPlanLocalExecution、DistributedPlanHostsUsedを追加しました。 #107985 (shankar-iyer). - OneLake などの REST データレイクカタログへのリクエストに、ClickHouse の
User-Agentヘッダーが含まれるようになりました。 #108117 (scanhex12). MVTEncodeGeomは、クリッピング前にジオメトリを整数ピクセルグリッドにスナップし、wagyuを使ってポリゴンをクリッピングするようになりました。これにより、クリッピング結果は有効 (自己交差するリングは修復されます) かつエッジに揃ったものとなり、PostGIS のST_AsMVTGeomと同じ結果になります。 #108248 (saarthak2002).- 3 つのテキスト索引キャッシュすべてをグローバルに有効化しました (以前はクエリ内でのみ有効でした) 。なお、ポスティングリストのキャッシュサイズは 0 になりました (つまり実質的には再び無効化されています) 。ポスティングリストはサイズが大きく、キャッシュするコストが高すぎるためです。 #108274 (rschu1ze).
- Prometheus エンドポイント (メトリクスのみの設定の場合) と非同期メトリクスの収集をテーブルのロード前に開始するようにしました。これにより、長時間かかる場合があるメタデータのロード中もメトリクスを監視できます。 #108402 (cwurm).
- 二項数学関数で BFloat16 をサポートしました #108442 (zhangyifan27).
- 転置ベクトル距離関数
L2DistanceTransposed、cosineDistanceTransposed、dotProductTransposedで、Nullable(QBit)カラムにも部分的なビットプレーン読み取りの最適化が適用されるようになり、カラム全体ではなく要求されたビットプレーンのみを読み取るようになりました。 #109358 (alexey-milovidov). BFloat16の Array でarraySum、arrayAvg、arrayProductを使用できるようになりました。#109420 (alexey-milovidov).- 関数
L1Normalize、L2Normalize、LinfNormalize、LpNormalize(およびそれらの別名) が、L2Normや距離関数と同様に、タプルだけでなく Array でも動作するようになりました。#110052 (alexey-milovidov). - プールされた接続に対して、使用のたびに ping を送信しないようにしました。これにより、再利用される接続ごとに発生していた
Ping-Pongの往復通信がなくなり、分散クエリおよびclickhouse-benchmarkのレイテンシが低減されます。古くなったプールされた接続は、タイムアウトをゼロにした poll (往復通信を伴わないノンブロッキングなチェック) で検出し、再接続によって復旧します。#110068 (alexey-milovidov). - 分散索引解析において、大きなパーツのリストをスカラーとして送信するようにしました (max_ast_elements/max_query_size による失敗の可能性を回避し、AST のパースによるオーバーヘッドを解消します) #110419 (azat).
- Playground でクラウドのロゴをクリックすると、Clickhouse の Web サイトが新しいタブで開くようになりました。これにより、クエリの実行中に作業内容が失われなくなります。#110422 (williamhatcher).
auto_statistics_typesのデフォルトをbasic, uniqからbasic, uniq_v2に変更しました。#110878 (hanfei1991).RWLockImpl::getLock()の再入アサーション (RWLock is already locked in exclusive mode/Cannot acquire exclusive lock while RWLock is already locked) が発生した場合、現在そのロックを保持している他のquery_idと、要求元のquery_idがすでに保持しているロック数をエラーメッセージに表示するようにしました。これにより、ロック順序に起因するこの種のエラーを診断しやすくなります。#110971 (groeneai).randomHadamardTransformは、最大の奇数因数が 64 以下である任意のベクトル長 (例:埋め込みモデルでよく使われる3584 = 512 * 7) に対して、長さを保存する厳密な変換を計算できるようになりました。これにより、従来の2^N、2^k * {12, 20}、2^k * 9の系列に加えて対応範囲が広がります。厳密に表現できない長さで完全な変換を行おうとした場合、より長いベクトルへ暗黙的にゼロ埋めするのではなく、例外を発生させるようになりました。任意の長さで切り詰められた射影を計算するには、output_dimsを指定してください。#111006 (alexey-milovidov).- HTTP インターフェイス経由の
ACCESS_DENIED例外に対して、500 Internal Server Errorではなく HTTP コード403 Forbiddenを返すようにしました。#111043 (Schum-io). UTMToGeoの第 4 引数として、整数の半球フラグに加え、geoToUTMが返す MGRS の緯度帯文字も受け付けるようになりました。これにより、geoToUTMの結果をそのままUTMToGeoに渡して往復変換できます。#111521 (alexey-milovidov).MaterializedPostgreSQLで、更新時に変更されていない PostgreSQL のTOAST値がデフォルト値に置き換えられず、そのまま保持されるようになりました。#111552 (OrpheusAgent).- テキスト索引ビルダーが一時セグメントを flush するタイミングを制御する設定
text_index_max_processed_tokens_before_flushおよびtext_index_max_memory_usage_before_flushを追加しました。#111573 (rorylshanks). - STREAM UNORDERED 修飾子を追加しました。この修飾子を指定すると、スナップショットごとのコミット順ソートが省略されます。#111794 (SmitaRKulkarni).
make_distributed_plan=1の場合、まだサポートされていない機能が無効化されるようになりました。#112463 (alesapin).- stdout が tty の場合に、INTO OUTFILE の出力先へ ANSI エスケープシーケンスを書き込まないようにしました。#113252 (azat).
allow_experimental_delta_kernel_rsをallow_delta_kernel_rsにリネームしました。旧名称もエイリアスとして引き続き利用できます。#113476 (kssenii).- 実験的な圧縮コーデックを個別に有効化するための設定
enable_alp_codec、enable_sz3_codec、enable_zxc_codec、enable_quantized_codecを追加しました。#113824 (rienath). - スタックオーバーフロー発生時に、何も出力せずに終了するのではなく報告するようにしました。致命的シグナルのハンドラーが代替シグナルスタック上で実行されるようになったため、障害が発生したスレッドがスタックを使い果たしていても、
SIGSEGV、SIGABRT、SIGILL、SIGBUS、SIGSYS、SIGFPE、SIGTRAPの発生時にスタックトレースが出力されます。#113927 (groeneai). - インスタントクエリおよびレンジクエリで、Prometheus HTTP API の lookback_delta パラメータをサポートしました。#113971 (fallintoplace).
- QueryRunner テーブルは、テーブルのライフタイム全体にわたってスレッドを占有するのではなく、必要に応じてワーカースレッドを起動し、アイドル状態になると解放するようになりました。#114522 (mstetsyuk).
- この変更により、WHATIF 索引の使用時に、プロジェクションで処理されるベースラインがステートメントを失敗させるのではなく、候補ごとに
not_applicableを報告するようになりました。#114846 (yariks5s). - 同一の expression に対する複数の比較条件を含む AND チェーンを最適化しました。矛盾を検出し (例:
a < 3 AND a > 5→false) 、冗長な条件を除去します (例:a = 3 AND a < 5→a = 3) 。#99736 (wudidapaopao).
バグ修正
MergeTree、レプリケーション、ストレージに関する修正
MergeTreeにおいて、ALTER TABLE ... RENAME COLUMNと、同時に実行されるOPTIMIZE TABLE ... FINAL(または任意のバックグラウンドマージ)との間で競合状態が発生し、リネームされたカラムのデータが警告なくデフォルト値に置き換えられる可能性があった問題を修正しました。新しいインメモリメタデータの公開から、current_mutations_by_versionへのリネームミューテーションの登録までの間に存在した競合ウィンドウは、両方の操作の間currently_processing_in_background_mutexを保持し続けることで解消されました。#104822 (groeneai).- GROUP BY と ORDER BY を使用し、かつプロジェクションに
arrayJoinが含まれる場合に、誤ったクエリ結果が返される問題を修正しました。#101775 (Onyx2406). - 無効な Azure アップロードサイズ設定(例:
azure_min_upload_part_size = 0やazure_max_blocks_in_multipart_upload = 0)は、書き込みパスの深い箇所で内部例外(second_size > 0)を引き起こすことなく、早い段階でわかりやすいエラーとして拒否されるようになりました。これはクエリ設定と Azure のディスク設定の両方に適用されます。#103394 (statxc). - 粒度設定に互換性のない(一方がアダプティブ、もう一方が非アダプティブ)2 つの
MergeTreeテーブル間でALTER TABLE ... MOVE/REPLACE/ATTACH PARTITIONを実行した場合に、LOGICAL_ERRORではなくBAD_ARGUMENTS例外をスローするようにしました。#103881 (groeneai). KILL QUERY/KILL MUTATION/KILL PART_MOVE_TO_SHARD/KILL TRANSACTIONにおいて、WHERE句に行ごとのサブクエリが含まれる場合や、max_block_sizeが小さいために関連するsystem.*テーブルに対する内部SELECTが複数のブロックを出力する場合に、LOGICAL_ERROR“Expected one block from input stream” がスローされる問題を修正しました。#104927 (groeneai).- リフレッシュ可能なマテリアライズドビュー(
MATERIALIZED VIEW ... REFRESH ...)において、リフレッシュタスクがEXCHANGE TABLESによって入れ替えた一時内部テーブルのサイズがサーバーのmax_table_size_to_dropを超えていると削除できず、リークが発生する問題を修正しました。この問題により、リフレッシュのたびに新たな一時内部テーブルが作成される一方で以前のテーブルはクリーンアップされず、ディスク容量が尽きるまでビューのデータディレクトリが増大し続けていました。リフレッシュタスクによる内部的な削除処理は、max_table_size_to_dropおよびmax_partition_size_to_dropの制限を受けなくなりました。なお、ユーザーがビュー自体に対して発行するDROP TABLEには、これらの安全策が引き続き適用されます。#105106 (groeneai). - sorting key に
SimpleAggregateFunction(またはallow_suspicious_primary_key = 1の場合にのみ許可されるその他の型)を含むMergeTreeテーブルで、sorting key を変更しないALTERクエリ(設定、コメント、コーデックの変更や、キー以外のカラムの追加など)を実行すると、予期しないDATA_TYPE_CANNOT_BE_USED_IN_KEYエラーが発生する問題を修正しました。#105111 (groeneai). - クエリのタイムアウト(
timeout_overflow_mode = 'break'を指定したmax_execution_time)によってOPTIMIZE ... DRY RUNが中断された場合、rows_sourcesに関する論理エラー(デバッグビルドおよびサニタイザービルドではサーバーが異常終了していました)ではなく、TIMEOUT_EXCEEDEDが返されるようになりました。#107114 (groeneai). use_hive_partitioning=1を指定して Hive パーティション形式のファイルを読み取る際に、Hive パーティションカラムを選択しつつ、実カラム(仮想カラム以外)をフィルタリングするWHERE/PREWHERE句を使用するとNOT_FOUND_COLUMN_IN_BLOCKが発生する問題を修正しました。#107505 (groeneai).toStartOfDay、toStartOfISOYear、toDaysSinceYearZero、toRelativeSecondNum、toRelativeMinuteNum、toRelativeHourNum、toRelativeWeekNum、toRelativeDayNum、toMonthNumSinceEpoch、toYearNumSinceEpochを、関数が表現できる範囲外の日付 (特に1970-01-01より前の日付) を含むDate32キーカラムに適用した場合に、主キーおよびパーティションの枝刈りが誤って行われ、誤ったクエリ結果が返される問題を修正しました。これらの関数は主索引に対して単調であると報告しますが、従来はこのような引数に対して値がラップアラウンドしていたため、実際には一致する行を含むグラニュールが索引によって枝刈りされることがありました。現在は結果型の境界値で飽和し、Date32の全範囲で単調性が保たれるため、枝刈りが正しく行われます。#108018 (nihalzp).CREATE TABLE dst AS src SETTINGS ...(およびENGINEを明示せずにORDER BY/PARTITION BYを指定する類似の形式) で、ソーステーブルのエンジン、ストレージ句 (テーブルのTTLやキーなど) および設定が警告なしに失われる問題を修正しました。現在は、エンジンと上書きされていないストレージ句がソーステーブルから継承され、指定した設定はソーステーブルの設定に上乗せする形でマージされます。#108085 (alexey-milovidov).- Windows をバックエンドとするファイルシステム (WSL、CIFS/SMB、Docker Desktop のバインドマウント) 上で、
MergeTreeテーブルへのINSERTがfilesystem error: in rename: Permission deniedで失敗する問題を修正しました。原因は、パーツライターがパーツディレクトリのリネーム時にファイルディスクリプタを開いたままにしていたことでした。#108089 (alexey-milovidov). - レガシーな
hypothesisスキップ索引 (ATTACHとの互換性のためだけに残されている、削除済みの索引種別) を持つ状態でアタッチされた MergeTree テーブルが操作不能になる問題を修正しました。従来、このようなテーブルに対する軽量DELETE、OPTIMIZE、通常のINSERT、またはフィルタ付きのSELECTはILLEGAL_INDEX(“Index of type ‘hypothesis’ is no longer supported”) で失敗し、DELETEミューテーションは無限に再試行されていました。現在、この無効な索引は何も作用しないものとして扱われます。マージ/ミューテーション時にはそのまま引き継がれ、挿入時およびクエリプランニング時にはスキップされます。また、引き続きALTER TABLE ... DROP INDEXで削除できます。#108217 (groeneai). - 並列レプリカ使用時に
MergeTreeテーブルから仮想カラムを選択すると (asterisk_include_virtual_columns = 1を指定したSELECT *による場合を含む) 、NOT_FOUND_COLUMN_IN_BLOCKエラー (例:Column _part not found) が発生する問題を修正しました。#108451 (groeneai). - 主キーが等価であるにもかかわらず宣言方法が異なる (一方は明示的な
PRIMARY KEY、もう一方はORDER BYによる暗黙的な指定) テーブルを、ATTACH PARTITION ... FROMが拒否する問題を修正しました。#108590 (jordiori). join_any_take_last_rowが、ディスクへの自動スピルを使用する結合も含め、サポートされているすべてのハッシュベースの結合パスで反映されるようになりました。#108936 (antaljanosbenjamin).query_plan_optimize_lazy_finalが有効で、かつWHEREフィルタの一部が (optimize_move_to_prewhere_if_finalにより)PREWHEREにプッシュダウンされている場合に、NOT_FOUND_COLUMN_IN_BLOCKエラーが発生する問題を修正しました。遅延実行 FINAL 最適化は、PREWHERE で計算される述語カラムをストレージに要求しなくなりました。#109073 (groeneai).- セッションで
optimize_respect_aliases = 0が設定されている場合に、テーブルレベルのALIASカラムに対してALTER TABLE ... ADD PROJECTIONを実行するとテーブルが使用不能になる問題 (以降のINSERTがUNKNOWN_IDENTIFIER、“Missing columns” で失敗する) を修正しました。#109091 (groeneai)。 - 旧アナライザ (
allow_experimental_analyzer = 0) で、別のテーブルと結合したMergeエンジンのテーブルに対してORDER BY ALL(またはGROUP BY ALL) を実行すると、ヌルポインタのアサーション (TreeRewriter::analyzeSelect内のpx != 0。デバッグビルドおよびサニタイザビルドではサーバーが異常終了する) が発生する問題を修正しました。#109139 (groeneai)。 - 相関がサブクエリのプロジェクション内にのみ存在し、かつ非相関の
WHERE句を伴う場合に、相関EXISTSサブクエリおよびスカラーサブクエリが誤った結果を返す問題 (サブクエリがすべての行で false /NULLと評価されることがある) を修正しました。https://github.com/ClickHouse/ClickHouse/issues/105760 を解決します。#109186 (novikd)。 enable_block_number_columnまたはenable_block_offset_column設定が有効な状態で、プロジェクションを持つMergeTreeテーブルをマージすると、不要な_block_number/_block_offsetカラムを含むプロジェクションパーツが生成されるバグを修正しました。この場合、マージ後のプロジェクションパーツがプロジェクション定義や挿入時に生成されたプロジェクションパーツと一致しなくなるため、CHECK TABLEとOPTIMIZE ... DRY RUNがこれを破損 (CORRUPTED_DATA) として報告していました。#109284 (groeneai)。- 永続仮想カラム
_block_numberまたは_block_offsetに対する暗黙的な min-max 索引 (add_minmax_index_for_block_number_column/add_minmax_index_for_block_offset_columnで有効化) を持つ MergeTree テーブルでALTER TABLE ... RENAME/ADD/MODIFY COLUMNを実行すると、UNKNOWN_IDENTIFIERエラーが発生する問題を修正しました。#109428 (groeneai)。 Wideパーツに対して、MATERIALIZEDカラムのALTER TABLE ... DROP COLUMNなど、パーツ全体を書き換えるミューテーションを実行した後に、データパーツからスキップ索引が削除される問題 (またはCHECK TABLEがUNEXPECTED_FILE_IN_DATA_PARTで失敗する問題) を修正しました。#109616 (groeneai)。ALTER TABLE ... APPLY PATCHESで軽量更新をマテリアライズした後も、スキップ索引 (text、bloom_filterなど) やプロジェクションが古い状態のまま残る問題を修正しました。従来は、パッチで更新されたカラムに依存する索引ファイルやプロジェクションファイルが更新されなかったため、それらを使用するクエリが誤った結果を返すことがありました (例:hasTokenが更新された行を見落とす、使用済みのパッチパーツが削除された後にプロジェクションが古い集約結果を返す、など) 。#109709 (groeneai)。_sample_factor仮想カラムを参照するミューテーションが実行途中にUnexpected const virtual column: _sample_factorで失敗し、停止したままになる問題を修正しました。ミューテーションでは、この値がSAMPLEを指定しないクエリと同じく1として読み取られるようになりました。#109813 (groeneai)。GROUP BY GROUPING SETSを含むクエリ (またはそれを含むスカラーサブクエリやミューテーションのサブクエリ) をforce_aggregation_in_order = 1で実行した際に発生する 2 つのエラーを修正しました。1 つは旧アナライザ (enable_analyzer = 0) で発生するTrying to get name of not a column: ExpressionList、もう 1 つはアナライザ使用時にenable_memory_bound_merging_of_aggregation_results = 1を指定した分散クエリで発生するMemory bound merging of aggregated results is not supported for grouping sets.です。#109862 (groeneai)。use_constant_folding_in_index_analysisに関する 3 つの問題を修正しました。1 つ目は、テーブルでpart_minmax_index_columns = 'with_block_number_offset'が設定されている場合に、通常のプロジェクションを使用するSELECTが論理エラーInvalid partition key sizeで中断されることがある問題です。2 つ目は、PARTITION BY id % 200のような剰余演算によるパーティションキーに対するフィルタで、誤った結果が返される(行が警告なしに欠落する)問題です。3 つ目は、sparseGramsトークナイザーを使用するtext索引に対し、max_threads > 1の状態で多数のパーティションにまたがるLIKE述語のクエリを実行するとクラッシュ(データ競合)が発生する問題です。#109896 (groeneai)。LowCardinality(Nullable(...))カラムにminmaxスキップ索引を構築した場合に誤った結果が返される問題を修正しました。従来は、ストレージにプッシュダウンされたWHERE/PREWHERE/HAVING ... IS NULL述語によってすべてのグラニュールがプルーニングされ、カラムに NULL が含まれているにもかかわらず 0 行が返されていました。#110061 (groeneai)。prefer_localhost_replicaによってローカルレプリカが選択される場合に、Distributedテーブルに対するORDER BY ... LIMITクエリが遅くなる問題を修正しました。#110136 (EmeraldShift)。DELETEまたはALTER UPDATEミューテーションのWHERE条件内、あるいはUPDATEの代入式内のサブクエリで集合演算(UNION/UNION ALL/UNION DISTINCT/EXCEPT/INTERSECT)を使用すると、例外(UNION mode UNION_DEFAULT must be normalized)が発生する問題を修正しました。#110196 (alexey-milovidov)。x IN (subquery)を含むミューテーションがプライマリキー解析中にサブクエリのセットを構築している間、サーバーのシャットダウンに時間がかかり、KILL MUTATIONも応答しなくなる問題を修正しました。セットの構築は速やかにキャンセルされるようになりました。#110198 (alexey-milovidov)。KILL TRANSACTIONと、トランザクション内で実行されるALTER TABLE ... UPDATE/DELETEとの間の競合を修正しました。ミューテーションがトランザクションに登録されてからテーブルに登録されるまでの間にロールバックが発生すると、孤立したミューテーションエントリが残っていました。その結果、バックグラウンドジョブで論理エラー(Cannot find transaction ... that has started mutation ...)が発生し、サーバーを再起動するまで、影響を受けたパーツに対する以降のミューテーションがすべてブロックされていました。#110226 (tiandiwonder)。DataLakeCatalog(Iceberg/Glue)データベースに対してsystem.tablesを参照した際、1 つのテーブルのメタデータを解決できないだけでクエリ全体が中断される、またはテーブルが警告なしに一覧から欠落する問題を修正しました。このようなテーブルは、database_datalake_require_metadata_accessの設定にかかわらず名前が一覧に表示されたままとなり、開かれたストレージオブジェクトを必要とするカラム(engine、total_rowsなど)にはデフォルト値/NULL が設定されるようになりました。破損したテーブルに直接アクセスした場合は、引き続きエラーが報告されます。#110242 (groeneai)。- 結合順序のカーディナリティ推定において、すべてのアクティブなパーツではなく、パーティション/PK によるプルーニング後に残ったパーツを対象に列統計を合成するようになりました。従来は、小さなパーティションに絞り込まれたクエリでもテーブル全体の統計に基づいて実行計画が立てられていたため(行数を 2500 倍過大に推定し、ハッシュ結合のビルド側が入れ替わる事例が確認されています)、統計を無効にした方がかえって良い実行計画になるという逆転現象が起きていました。あわせて、結合順序オプティマイザがメモ化した索引解析結果が適用済みのプロジェクションと誤認され、JOIN 配下の MergeTree リレーションで lazy FINAL が警告なしに無効化されていた問題も修正しました。#110283 (skuznetsov-clickhouse)。
- グラニュラリティに互換性のない(一方がアダプティブ、もう一方が非アダプティブ)2 つの MergeTree テーブル間で
ALTER TABLE ... MOVE/REPLACE PARTITIONを実行した場合、LOGICAL_ERRORではなくBAD_ARGUMENTSをスローするようになりました。この状況はユーザー操作によって起こりうるものであり、内部エラー(デバッグ/サニタイザービルドではサーバーが中断される)として扱うべきではないためです。#110535 (groeneai)。 WHEREで参照されているカラムに対するALTER TABLE ... UPDATEによって<cond>に一致するようになった行が、TTL ... DELETE WHERE <cond>で削除されない問題を修正しました。ミューテーション時に行の有効期限 (TTL) が再計算されるようになったため、新たに条件に一致した期限切れの行は、気付かれないまま残り続けることなく削除されます。#110648 (groeneai).non_replicated_deduplication_windowを有効にしたパーティション化されたMergeTreeテーブルへのINSERTにおいて、非同期 INSERT のバッチが部分的にのみ重複排除された場合 (一部のinsert_deduplication_tokenが重複し、一部が新規であった場合) に、LOGICAL_ERROR“Invalid partition key size: 0” が発生して処理が中断されることがある問題を修正しました。#110651 (groeneai).- 新しいアナライザーでの定数畳み込みにより、定数の
Geometry値の型が暗黙的に変わってしまう問題を修正しました。Geometryは名前付きのVariantであり、その候補型の中には同じストレージレイアウトを共有するものがあります (LineString/Ring、MultiLineString/Polygon、および空の値) 。そのため、候補型だけが異なる 2 つの畳み込み済み定数が 1 つにまとめられてしまい、たとえば定数MULTIPOLYGON EMPTYがLINESTRING()として出力されていました。#110709 (groeneai). - read-in-order クエリにおいて、
distinct-in-orderまたはaggregation-in-orderによって読み取り範囲が、ORDER BYが read-in-order の仮想行を設定した際のソートキーのプレフィックスよりも長く拡張される場合に、誤った結果 (マージ順序の誤り) が返される問題を修正しました。仮想行の追加のソートカラムがデフォルト値で埋められていたため、MergingSortedTransformの順序が狂うことがありました (debug/sanitizer ビルドではLOGICAL_ERRORで異常終了) 。#110725 (groeneai). - interserver secret を使用するクラスター上での並列レプリカ読み取りおよび Distributed 読み取りにおいて、クエリの有効なロール (SET ROLE / role=) をリモートノードへ伝播するようにしました。これまではユーザーのデフォルトロールにフォールバックしていたため、行ポリシーがイニシエーターとは異なる形で評価されていました。#110867 (evillique).
ReplicatedMergeTreeテーブルに対するコメントのみまたは設定のみのALTERが、同時実行されたALTER ... ADD COLUMNで追加されたカラムを暗黙的に削除してしまい、レプリカが古いテーブル構造のまま取り残されることがある、まれな競合状態を修正しました。#111029 (tiandiwonder).DistributedテーブルをラップするMergeテーブルに対して集約を伴うGROUP BYを実行する際、グループ化キーがカラムの関数であり、かつ集約が同じカラムを読み取る場合 (例:SELECT toString(g), min(g) FROM merge_over_distributed GROUP BY toString(g)) に発生するNUMBER_OF_COLUMNS_DOESNT_MATCHエラーを修正しました。#111334 (groeneai).- 左側のキーが
Nullableで、ストレージのキーがNullableでない場合に、USINGを伴うJoinエンジンテーブル (StorageJoin) に対するFULL JOINが誤った結果を返す問題を修正しました。キーがNULLで一致しなかった左側の行に対して、NULLではなく0が返されていました。#111371 (groeneai). - テーブルの
fsync_part_directory設定が有効な場合、ALTER TABLE ... DETACH PARTITION/PARTがdetached/配下に作成するクローン(パーツのサブツリーと、ディスクルートまでのディレクトリチェーン)を fsync するようになりました。これは Full(ディレクトリ)形式と Packed 形式の両方のパーツストレージに適用されます。以前は、アクティブセットから行を除外する空のカバーパーツは fsync される一方で、クローンは一切 fsync されていませんでした。そのため、確認応答の直後に電源が失われると、btrfs 上でデタッチされたデータが消失する可能性がありました(同期されていないクローンのディレクトリエントリがロールバックされ、detached/が空になり、ATTACHできるものが何も残らなくなります)。この動作は既存のfsync_part_directory設定で制御され、デフォルトの動作に変更はありません。#111426 (groeneai)。 - スキーマがストレージから推論される場合(例:
SELECT NULLを実行するビューを参照する、カラム定義のないremote()/Remote/Distributedテーブル)、Nullable(Nothing)(またはテーブルで許可されていないその他の型)のカラムをCREATE TABLEの時点で拒否するようになりました。以前はメタデータがそのまま永続化され、次回のサーバー再起動時に読み込みに失敗するうえ、無関係なテーブルの読み込みまで妨げていました。#111487 (groeneai)。 - 並列レプリカで読み取りを行う際、イニシエーター上でクエリがプロジェクション最適化(exact-count、minmax-count、またはレンジを選択しない保存済みの集約/通常プロジェクション)だけで完全に応答される場合に、サーバーが異常終了する可能性があった
LOGICAL_ERROR(Got read request from replica N for unknown stream ...)を修正しました。#111689 (groeneai)。 - DeltaLake へのパーティション分割された
INSERT(allow_experimental_delta_lake_writes=1)で、パス文字を含むパーティション値が破損し、NULLが拒否される問題を修正しました。これまでは、a/bのような値が何の警告もなくaとしてコミットされ、%を含む値では読み戻せないデータファイルが生成され、NULLのパーティション値はNOT_IMPLEMENTEDで失敗していました。今後は、パーティション値はパーセントエンコードされて単一のパスセグメントとなり、実際の値はパスから解析し直すのではなくpartitionValuesに保存されます。また、NULL(または空文字列)のパーティション値は、partitionValuesエントリを null として__HIVE_DEFAULT_PARTITION__という名前で書き込まれます。#111793 (groeneai)。 enable_parallel_blocks_marshalling(デフォルトで有効)が設定されたシャード上で分散クエリを実行した際に発生する、Expected UInt64 column for __grouping_set, got BLOBおよびColumnBLOB should be converted to a regular column before usageという論理エラーを修正しました。この問題は、例えばローカルレプリカを含むクラスターに対してGROUP BY GROUPING SETSを実行した場合や、ローカルテーブルと分散テーブルにまたがるMergeテーブルを読み取った場合に発生していました。ブロックが同一プロセス内で消費されるプランには、BlocksMarshallingStepを追加しないようになりました。#111997 (groeneai)。- 統計情報を持つカラムの型を、メタデータのみを変更する
ALTER MODIFY COLUMN(例:Enum8からInt8、DateTimeからUInt32)で変更したテーブルに対してMergeTreeのミューテーションを実行すると、LOGICAL_ERROR(Type mismatch when building statistics for column)が発生する問題を修正しました。ミューテーションは実際に書き換えるカラムの統計情報のみを再計算し、それ以外はそのまま引き継ぐようになりました。また、MATERIALIZE COLUMN、MATERIALIZEDカラムの依存元カラムに対するUPDATE、またはCLEAR COLUMNによって書き換えられたカラムについては、古い統計情報を保持し続けるのではなく、再計算するようになりました。#112009 (groeneai)。 intDiv(constant, key)またはdivide(constant, key)でフィルタリングするクエリにおいて、行が警告なく欠落する問題を修正しました。定数をキーカラムで除算する場合に、主キーおよびパーティションの解析が単調性の向きを誤って報告していたため、条件に一致するグラニュールが除外され、クエリはエラーを出さずに本来より少ない行を返していました。あわせて、最上位ビットが立った符号なし定数を被除数とするintDivの問題を修正し、Decimalオペランドによって除算が decimal 本来のビット幅で計算される場合には単調性を主張しないようにしました。また、IPv4/IPv6定数をキーカラムで除算する正当なクエリに対して、キー解析がCannot compare DB::IPv4 with longを発生させないようにしました。#112156 (groeneai)。SELECT本体でINTERSECT/EXCEPTを使用する、またはUNION DISTINCTとUNION ALLを混在させたUNIONチェーンを使用するパラメーター化ビューが、通常のビューとして分類されてしまう問題を修正しました。このようなビューは作成自体には成功するものの、メタデータを読み戻すことができず、ロード時にInvalid storage definition in metadata fileがスローされていました。その結果、ビューが恒久的にロード不能となり、デバッグビルドやサニタイザービルドのサーバーは起動時に異常終了していました。また、これらのビューについてsystem.tables.parameterized_view_parametersがパラメータを報告していませんでした。#112211 (groeneai)。- クエリが
geohashesInBoxを評価している間、max_execution_timeおよびKILL QUERYが無視される問題を修正しました。このようなクエリは中断可能になる前にブロックの全行を展開していたため、キャンセルが反映されるまで数分かかっていました。現在は、この関数が行を処理しながらクエリの制限時間を確認します。ソートキー、スキップ索引、PARTITION BYなど、永続化されたテーブル expression 内での評価は対象外であり、別途対応が進められています。#112273 (groeneai)。 - 別の Merge テーブル、またはカラム型が異なる materialized view を対象とする Merge テーブルで PREWHERE を使用した際に発生する論理エラーを修正しました。あわせて、リモートサーバーから読み取るテーブル (Distributed テーブル、またはそれをラップするテーブル) において行ポリシーが警告なく無視され、ポリシーで隠すべき行が露出する可能性があった問題も修正しました。このようなクエリは現在 ILLEGAL_PREWHERE エラーで拒否されます。代わりに、各リモートサーバー上の基盤となるローカルテーブルにこれらのポリシーを定義してください。なお、
serialize_query_plan = 1で送信される読み取りには依然としてこのポリシーが適用されませんが、これは以前から存在する別のバグです。#112326 (PedroTadim)。 - 型を変更する
ALTER TABLE ... MODIFY COLUMNのミューテーションが、たとえばKILL MUTATIONによって削除されるなどして実行されなかった場合に、古いセカンダリ (スキップ) 索引が読み取られる問題を修正しました。ディスク上のグラニュールは古い型で書き込まれているにもかかわらず新しい型でデコードされるため、LOGICAL_ERRORが発生したり、エクサバイト規模のメモリ割り当てが要求されたり、誤った結果が警告なく返されたりしていました。また、格納されているバイト列がまったく変わらないまま意味だけが変わるため、ミューテーションが一切作成されない expression に対する索引が誤った結果を返す問題も修正しました。たとえば、DateTimeのタイムゾーンのみを変更するMODIFY COLUMNや、UInt8からBoolのようにカスタム型名のみを変更する場合が該当します。このような索引は、影響を受けるパーツではスキップされるようになりました。#112484 (groeneai)。 - クラスター全体で集約を行うクエリを
serialize_query_plan = 1と計画ベースの並列レプリカで実行した際に、マージステップがパイプラインをストリーム数ゼロにリサイズすることでLOGICAL_ERROR(Cannot add transform Resize to Pipes because it has no outputs) が発生する問題を修正しました。#112506 (groeneai)。 ReplicatedMergeTreeのレプリカが、自身の保留中のALTER ... ADD COLUMNを適用する前に、別のレプリカから取得したパーツに対してミューテーションを実行した場合に、LOGICAL_ERROR(“Part … contains column … that is absent in table …”) が発生する問題を修正しました。このようなミューテーションは、メタデータの変更が適用されるまで延期されるようになりました。#112510 (groeneai)。ORDER BYがディスクへスピルするクエリにおいて、読み取りカウンター (read_rows、read_bytes、ProfileEvents['SelectedRows']、ProfileEvents['SelectedBytes']) およびREAD_ROWSとREAD_BYTESのクォータが過剰に計上される問題を修正しました。外部ソートの一時ファイルから再読み込みされた行がソース読み取りとして二重にカウントされていたため、スピルするクエリでは読み取り量が実際より多く報告され、クォータの範囲内であってもQUOTA_EXCEEDEDで拒否される可能性がありました。#112645 (groeneai).- ディスクへスピルする
JOINの結果サイズがProfileEvents['JoinResultRowCount']で過少に報告される問題を修正しました。遅延バケットから出力された行はJoinDelayedJoinedTransformRowCountにのみカウントされ、合計に含まれていませんでした。クエリ結果は常に正しく、誤っていたのはプロファイルイベントのみです。#112673 (groeneai). - レプリカへの接続を確立中の分散クエリに対して、
max_execution_timeおよびKILL QUERYがエラーも出さずに機能しない問題を修正しました。このようなクエリは、残りのすべてのレプリカとリトライを順に試行し続けるのではなく、次の接続試行時に停止するようになりました。#112689 (groeneai). - 未完了の
RENAME COLUMNの ALTER ミューテーションが進行中であるにもかかわらず、MergeTreeテーブルに対するALTERが適用されてしまう問題を修正しました。これにより、ストレージのメタデータが互換性のない形で更新され、以降のミューテーションが完全にブロックされる可能性がありました。#112783 (Michicosun). Distributedテーブルを対象とするMergeテーブルから読み取る際に、ORDER BYが誤った結果を返す問題を修正しました。行が順序どおりに返されないことがあり、LIMITを使用した場合には結果に含まれるべき行が欠落することがありました。#112931 (alexey-milovidov).share_nested_offsetsが有効 (デフォルト) なテーブルにおいて、ファイルシステムの読み取りプリフェッチが有効な状態で、削除後に再追加されたサブカラムと一緒にNestedカラムを読み取ると誤った結果が返される問題を修正しました。このようなクエリは、ALTERの影響を一切受けていない、物理的に存在するカラムに対してデフォルト値を返す可能性がありました。オブジェクトストレージではremote_filesystem_read_prefetchのデフォルトが1であるため、デフォルト以外の設定をしなくても発生します。ローカルディスクではlocal_filesystem_read_prefetch = 1の場合に発生します。なお、範囲が複数のブロックにまたがる場合にこのような読み取り結果が破損する、プリフェッチとは無関係の別の不具合は依然として残っており、本修正の対象外です。#112997 (groeneai).PARTITION BYを使用するウィンドウ関数やjoin_algorithm = 'parallel_full_sorting_merge'を使用する結合など、パーティションごとにデータを分散するクエリにおいて、ブロックの分配が途中の状態で1つのシャードの下流が終了した場合に発生するPipeline stuck論理エラーを修正しました。#113190 (groeneai).ReplicatedMergeTreeでalter_sync = 2を指定したALTER、OPTIMIZE、TRUNCATEおよびパーティション操作のステートメントが別のレプリカを待機している間に、 (たとえば同時実行されたDROP DATABASE ... SYNCによって) テーブルのシャットダウンが開始されるとハングする問題を修正しました。このようなステートメントはUNFINISHEDで失敗するようになり、max_execution_timeおよびKILL QUERYにも従うようになりました。#113228 (groeneai).read_in_order_use_virtual_rowが有効な状態で、MergeTreeの read-in-order クエリにおいてWITH FILL ... INTERPOLATEとINまたはhasフィルターを組み合わせた場合に発生するCannot insert element into Set(NOT_IMPLEMENTED) エラーを修正しました。#113264 (groeneai).- 設定
inject_random_order_for_select_without_order_byが有効で、集計クエリがDistributedの子テーブルを含むMergeテーブルから読み取る場合に発生する論理エラー (例外)Chunk info was not set for chunk in MergingAggregatedTransformを修正しました。中間ステージまでしかプランニングされないクエリには、ランダムなORDER BY rand()ラッパーを注入しないようになりました。#113266 (alexey-milovidov). MergeTreeテーブルに、時間式が同一でWHERE条件のみが異なるTTL ... DELETE WHEREルールが 2 つ以上ある場合に、行がまったく削除されない問題を修正しました。TTL による削除マージの後、パーツのrows_where_ttl_infoがゼロにリセットされていたため、そのパーツに対して以降の TTL マージがスケジュールされず、期限切れの行がエラーもログメッセージも出ないまま無期限に保持されていました。#113384 (groeneai).- sorting key、スキップ索引、
PARTITION BYキーなど、テーブルメタデータに格納された式の中でgeohashesInBox、arrayFold、sleep、base58Decode、h3PolygonToCells、h3PolygonToCellsWithContainmentを評価している間、max_execution_timeとKILL QUERYが無視される問題を修正しました。#113456 (groeneai). - 複数の子テーブルを持つ
Mergeテーブルが、外側のクエリで参照されるマテリアライズド CTE を読み取る際に発生するLOGICAL_ERROR(Reading from materialized CTE '...' before its materialization completed - DelayedPortsProcessor gate is missing in the query plan) を修正しました。#113558 (alexey-milovidov). - 複数の子テーブルを持つ
Mergeテーブルに対し、カラム単体のPREWHEREと別途WHEREを指定したEXPLAIN ANALYZEで発生するLogical error: 'Required output position N is out of range for pass-through inputs'を修正しました。#113725 (groeneai). - カラム型が基盤ストレージと異なるビュー (例:
engineがStringであるsystem.tables上に定義され、engineがNullable(String)となっているinformation_schema.tables) に対するフィルタがストレージへプッシュダウンされた際に発生する論理エラー (Unexpected return type) を修正しました。#113984 (alexey-milovidov). - 述語に
IN (subquery)を含むミューテーションが、サブクエリのセットを構築している最中にKILL MUTATIONやDETACH DATABASEなどによってキャンセルされた場合に発生するNot-ready Set is passed as the second argument for function 'in'エラーを修正しました。#114463 (groeneai). - sorting key、プライマリキー、またはパーティションキーで使用されているカラムに対する
ALTER TABLE ... DROP COLUMNは、ALTER TABLE ... CLEAR COLUMNと同様に、説明付きのALTER_OF_COLUMN_IS_FORBIDDENで失敗するようになりました。以前は、キー式の再計算に起因するわかりにくいUNKNOWN_IDENTIFIER: Missing columnsエラーで失敗していました。グループ内のカラムがキーで使用されている場合に、共通プレフィックスを指定してNestedグループ全体を削除またはクリアするときも同様です。以前は、グループのデータが何の通知もなく破壊されたり、いつまでも完了しないミューテーションが残ったりする可能性がありました。また、TTL式でのみ使用されているカラムを削除する場合も、どの TTL 式が壊れるかを報告するようになりました #114468 (m7kss1). - 1 つの
ALTERでリネーム、削除、再追加されたカラムが、ミューテーションの保留中に自身のデフォルト値ではなく削除前のカラムの値を返す問題を修正しました。#114601 (tiandiwonder). - 基になるテーブルが親カラムを
ALIASとして宣言している場合に、Mergeテーブル経由でサブカラム (.size0、.null、タプル要素、String.size) を読み取る際の問題を修正しました。このような読み取りでは型のデフォルト値が返され、同じクエリで親カラムも選択されていると、無関係なカラムの値が返されることがありました。#114673 (groeneai). - polygon 引数が無効な定数リテラルで、かつ
validate_polygons = 0の場合に、MergeTree の主キーに対するpointInPolygonでフィルタしたSELECTの結果から行が欠落する問題を修正しました。主キー解析が未検証のポリゴンを基にグラニュールのプルーニングを行っていたため、一致する行を含むグラニュールが除外されていました。#114710 (groeneai). ALTER TABLE ... MATERIALIZE INDEX、MATERIALIZE STATISTICS、MATERIALIZE PROJECTIONのフォーマット処理でIF EXISTS句が欠落し、フォーマットされたクエリがパースされたクエリと一致しなくなる問題を修正しました。また、SQL パーサーでは生成されず、フォーマットすると別のコマンドになってしまう 4 種類のALTER ... STATISTICSの AST JSON ペイロードを拒否するようにしました。#115099 (groeneai).- 集約中に Dictionary が拡張される
LowCardinality(String)キーで集約または結合を行う際に、キャッシュされた Dictionary のハッシュに対して範囲外読み取りが発生する問題を修正しました (TTL ... GROUP BY経由で発生し得ます) 。これにより誤ったハッシュが生成されることがあり、サニタイザービルドでは heap-buffer-overflow が報告されていました。#115604 (groeneai). CREATE TABLEおよびALTER TABLEで、パーティションキーに使用されるカラムにSZ3などの非可逆コーデックを指定すると拒否されるようになりました。#115626 (groeneai).- ターゲットがパラメーター化ビューである
AliasテーブルにマッチするMergeテーブル経由で読み取りを行っても、LOGICAL_ERROR: Table has no columns.(デバッグビルドおよびサニタイザービルドではサーバーが異常終了する) が発生しなくなりました。このようなテーブルでは、パラメーター化ビュー自体と同じエラーであるSTORAGE_REQUIRES_PARAMETERが報告されるようになりました。また、カラムを提供できないその他のマッチしたテーブルについては、内部エラーではなくUNSUPPORTED_METHODが報告されるようになりました。#115896 (groeneai). - expression が
_sample_factorを参照する保留中のミューテーションのオンザフライプレビューを修正しました。apply_mutations_on_fly = 1でSAMPLE句を使用した場合、expression はバックグラウンドのマテリアライゼーションで永続化される値ではなく、読み取りクエリのサンプル係数で評価されていました。そのため、プレビューされた行が最終的なマテリアライズ結果と一致せず、保留中のALTER TABLE t DELETE WHERE _sample_factor > 1によってSAMPLE読み取りが 1 行も返さなくなることがありました。クエリ自体の_sample_factorカラムに変更はありません。#115906 (groeneai). - フォーマットバージョン
V3の統計ファイルが、ILLEGAL_STATISTICSで拒否されずに読み取られるようになりました。このようなファイルはごく限られた期間のmasterのビルドでのみ生成されたものですが、これを含むパーツはまったく読み取れず、読み取り専用ディスク上ではALTER TABLE ... MATERIALIZE STATISTICSで再生成することもできませんでした。#116030 (alexey-milovidov). SELECT ... FROM t STREAM ... ORDER BY ... LIMIT nクエリがPROJECTIONを持つテーブルを読み取る際に発生するInvalid number of columns in chunk pushed to OutputPort(LOGICAL_ERROR) を修正しました。STREAM読み取りには遅延マテリアライゼーションが適用されなくなりました。#116187 (groeneai).- Replicated データベースでは
ALTER TABLE ATTACH PARTITION FROMをレプリケートしないようにしました。#94835 (MikhailBurdukov). - ロールバックされたトランザクションの MergeTree パーツがコミット済みパーツと交差している場合に、テーブル起動時にサーバーがアボートする問題 (sanitizer ビルドの場合) と、データがサイレントに失われる問題を修正しました。
PartLoadingTree::addは、交差する 2 つのパーツのうちどちらがロールバックされたものかを正しく判別して除外し、孤立した子パーツを正しい順序でコミット済みパーツの配下に付け替えるようになりました。#100992 (tuanpach)。 - MergeTree テーブルの
Array(LowCardinality(String))カラムに対してindexOfAssumeSortedが誤った結果を返す問題を修正しました。#101771 (Onyx2406)。 Icebergメタデータの同時更新やDeltaLakeテーブルに対するmerge読み取りなど、datalake_table_stateが固定されないまま読み取りパイプラインに到達し得る経路でIcebergまたはDeltaLakeのデータレイクテーブルを読み取ると、LOGICAL_ERROR例外が発生する問題を修正しました。#102033 (groeneai)。Time型のパーティションキーを持つテーブルで、OPTIMIZE TABLE ... PARTITION ...(およびconvertFieldToTypeImplを介してパーティション値を解決するその他のクエリ) がLogical error: Parsed partition value: ... doesn't match partition value for an existing part with the same partition ID: ...をスローする問題を修正しました。#106202 (groeneai)。- 論理削除の結果としてプロジェクションパーツが残らない場合 (プロジェクションが出力行 0 件で再構築された場合、または削除された場合。
lightweight_mutation_projection_mode = 'rebuild'/'drop') に、データパーツのプロジェクションが破損していると誤ってマークされる問題を修正しました。これまでは、この破損ステートにより、そのパーツに対するクエリでプロジェクション最適化が無効になっていました。#106273 (tiandiwonder)。 system.warningsのメモリ/CPU/ミューテーション過負荷警告が、非同期メトリクスのサイクル 1 回分遅れて反映される (さらに最初のサイクルでは表示されない) 問題を修正しました。#108035 (alexey-milovidov)。- 実験的設定
make_distributed_plan = 1を有効にした状態で、Distributedテーブルまたはビューを対象とするMergeテーブルにクエリを実行すると、LOGICAL_ERROR例外 (ScatterExchangeStep should have one source shard, got 8) が発生し、行が重複する問題を修正しました。#108401 (groeneai)。 Nullable(Tuple(...))カラムの非 Nullable なLowCardinality要素をサブカラムとして (例えばソートキーとして) 使用すると、マージ中にサーバーがアボートする問題 (Sort order of blocks violated) と、誤った読み取りが発生する問題を修正しました。#108679 (groeneai)。- アカウントキーが有効な Base64 でない場合に、
azureBlobStorage()(および関連する Azure テーブル関数/ストレージ) 経由で到達し得る、同梱の Azure SDK のBase64Decodeでクラッシュする問題を修正しました。>= 0x80のバイトによってデコードテーブルの範囲外読み取りが発生し、また無効なバイト全般によって負の値に対する未定義の左シフトが発生していました (sanitizer 環境ではアボート) 。無効なキーは適切に拒否されるようになりました。#108716 (groeneai)。 - 以前の同種の操作が中断され (例えばトランザクションのロールバックやクラッシュなど) 、古い
tmp_empty_<part>ディレクトリが残った状態で MergeTree テーブルに対してDROP/DETACH/MOVE/REPLACE PARTITIONを実行すると、debug ビルドおよび sanitizer ビルドでサーバーがアボートする可能性があるLOGICAL_ERROR(“New empty part is about to materialize but the directory already exist”) を修正しました。古いディレクトリは、エラーにせず再利用されるようになりました。#108879 (groeneai)。 - ワイドパーツでカラムの
TTLが期限切れになった後、プロジェクションがカラムの DDLDEFAULT(例:-1) ではなく型のデフォルト値 (例:0) を返す問題を修正しました。#109013 (tiandiwonder)。 - カスタムの
disk設定 (SETTINGS disk = disk(...)) で作成されたMergeTreeテーブルに対するALTERクエリが失敗する問題を修正しました。#109199 (Michicosun)。 MaterializedPostgreSQLデータベースのテーブルをMergeテーブル経由で読み取る際に、古い行や削除済みの行が表示される問題を修正しました。#109339 (vdimir)。- 値が
Int32に収まらないBIGINTカラムでパーティション化された Paimon テーブルを読み取れない問題を修正しました。このようなパーティション値が切り詰められ (例:9223372036854775807が-1になる) 、誤ったパーティションパスが生成された結果、ファイルシステムエラーで失敗していました。#109510 (groeneai)。 - 子テーブルに、既存カラムそのものをフィルタとする行ポリシー (例:
CREATE ROW POLICY ... USING flag) が設定されているMergeテーブルから読み取る際に発生する論理エラー (“Cannot determine row level filter; 0 columns deleted, 0 columns added”) を修正しました。#109843 (groeneai)。 - IcebergLocal がストレージタイプとして Azure を報告していた問題を修正しました。#109872 (PedroTadim)。
CHECK TABLEで、メタデータの読み込みに失敗したプロジェクションパーツについて、誤解を招くColumns doesn't match ... Expected: 0 columnsエラーではなく、実際の破損内容が報告されるようになりました。#110262 (Algunenano)。- 残存している
txn_version.txt.tmpファイルのディスクレベルのメタデータが壊れている場合に、オブジェクトストレージディスク上のMergeTreeテーブルが原因でサーバーの起動に失敗する問題を修正しました。#110519 (alexey-milovidov)。 allow_part_offset_column_in_projectionsまたはallow_commit_order_projectionを無効化した後にテーブルをデタッチするかサーバーを再起動すると、_part_offsetプロジェクションまたはコミット順序プロジェクションを持つ MergeTree テーブルが恒久的にアタッチできなくなる問題を修正しました。これら 2 つの設定は CREATE 時にのみ適用されるチェックであるため、ATTACH 時には再チェックされなくなりました。#110570 (groeneai)。ReplicatedMergeTreeにおいて、2 つのパーティション操作 (例: 2 つのMOVE PARTITION/REPLACE PARTITIONクエリ、またはそのうち 1 つとバックグラウンドのDROP_RANGEとの競合) が、重複する範囲に対するバックグラウンドのパーツチェックを同時にキャンセルした際に、サーバーを異常終了させる可能性があったまれなLOGICAL_ERROR(“Unexpected number of parts to remove from parts_queue”) を修正しました。#110738 (groeneai)。Quantized(...)コーデックを持つカラムがプール可能なシリアライゼーション内にネストされている場合 (例: ソースごとに同名カラムの型が異なり、VariantにマージされるMergeテーブル) に発生する可能性があったHash is not set for serialization論理エラーを修正しました。#110776 (groeneai)。- 極端な
max_streams_for_merge_tree_reading値 (UInt64の最大値付近) をallow_asynchronous_read_from_io_pool_for_merge_tree = 1と併用して MergeTree テーブルを読み取る際に発生するstd::length_error(LOGICAL_ERROR) を修正しました。この設定値はmax_threadsと同じ上限に制限されるようになりました。#110936 (groeneai)。 - 唯一のカラムに完全に期限切れとなるカラム
TTLが設定された単一カラムのMergeTreeテーブル (min_bytes_for_wide_part = 1の場合) のマージ中に、論理エラーCannot calculate columns sizes when columns or checksums are not initializedが発生する問題を修正しました。#111169 (groeneai)。 min_rows_to_fsync_after_merge/min_compressed_bytes_to_fsync_after_merge/fsync_part_directoryが設定されている場合、マージまたはマテリアライズされたパーツのテキスト索引ファイルも fsync するようにしました。従来はパーツ内でこれらのファイルだけが同期されないままだったため、マージ直後に電源断が発生すると、コミット済みにもかかわらず破損したパーツが残り、データ損失につながる可能性がありました。#111335 (groeneai)。- マニフェストのパーティションタプルがパーティション仕様と一致しない場合に、
Icebergテーブルに対するOPTIMIZE TABLE ... MANIFESTが正しく動作しない問題を修正しました #111368 (SmitaRKulkarni)。 - 複数の
text索引を持つMergeTreeテーブルで、テキスト索引からの直接読み取り最適化により未使用の索引仮想カラムが読み取りヘッダーに残った場合に、遅延マテリアライゼーションの最適化で発生する範囲外読み取り (リリースビルド) / 論理エラー (debug ビルド) 、およびMergeテーブルに対するPipe::unitePipesでの論理エラーを修正しました。#111467 (groeneai)。 part_minmax_index_columnsの設定を引き下げた後 (例:with_block_number_offsetからpartition_key_onlyに戻した場合) 、debug/sanitizer ビルドでバックグラウンドマージが中断されることがあったLOGICAL_ERROR(“Part level Min-Max index was constructed from unexpected columns set”) を修正しました。#111511 (groeneai)。- 複数のパーティションを持ち、ROW POLICY が定義されたテーブルに対して
STREAM読み取り (enable_streaming_queries = 1) を実行するとクラッシュする問題を修正しました。debug および sanitizer ビルドでは論理エラーFilter column ... not found in DAG outputsで失敗し、リリースビルドではセグメンテーション違反が発生する可能性がありました。#111572 (groeneai)。 - 現在の設定でポリモーフィックパーツが無効 (非アダプティブ granularity) になっている
MergeTreeテーブルが、既存のCompactパーツをロードする際に発生するLOGICAL_ERROR(Cannot create part with type Compact and storage type Full because table does not support polymorphic parts) を修正しました。この問題は、例えば読み取り専用テーブルが別のテーブルとディスク上のパスを共有しており、SYSTEM RESTART DISKの実行時やサーバー起動時にパーツを再ロードする場合に発生する可能性がありました。debug および sanitizer ビルドでは、この例外によってサーバーが異常終了します。#111626 (groeneai)。 fsync_part_directory = 1の場合、パーツディレクトリを一時名から最終名へリネームする操作自体も、親ディレクトリ (異なる親ディレクトリ間での移動の場合は移動元の親ディレクトリも) を fsync することで永続化されるようになりました。従来は移動したディレクトリのみが fsync されていたため、パーツのコミット直後に電源断が発生すると、ファイル自体は書き込み済みであってもパーツがディスク上から消失し、この設定を有効にしていても行が失われる可能性がありました。#111861 (groeneai)。MergeTreeテーブルからNullable(Tuple(...))カラムを、NULL を保持する要素サブカラム (Variant、Dynamic、またはLowCardinality) のいずれかと一緒に選択した場合に、誤った結果が返されたりLOGICAL_ERRORが発生したりする問題を修正しました。サブカラムの読み取り時に、親タプルでNULLである行が、サブストリームキャッシュ経由ですでに共有されていたカラム内でNULLとしてマークされてしまい、その結果、カラム全体の読み取りでずれた値が参照されていました。#111949 (groeneai)。- 自動ディスクスピルのしきい値が設定されている場合 (26.5 以降はデフォルトで設定) 、ハッシュ結合でビルド後の最適化 (固定ハッシュテーブルへの変換、共有ランタイムフィルタ、右テーブルの範囲再設定) が失われる問題を修正しました。#111972 (alexey-milovidov).
simdcompを使用しないビルド (x86_64 Linux 以外のすべてのターゲット。例: aarch64) でtext_index_posting_list_apply_mode = 'lazy'の場合に、hasAllTokensなどの複数トークンを用いるtext索引検索が誤った結果を返す (行がエラーなく欠落する) 問題を修正しました。ポータブルなビットパッキングデコーダーが、ビット幅が 0 のブロックに対してデコード済みのゼロを書き込んでいなかったため、単一ポスティングのセグメントに含まれるポスティングが失われていました。ディスク上のフォーマットに変更はなく、修正後は既存データも正しく読み取られます。#112178 (groeneai).- 破損した MergeTree の統計情報を読み込んだ場合、エラーを無視せず操作が失敗するようになりました。#112201 (skuznetsov-clickhouse).
- HDFS 上で確認応答済みの Iceberg 書き込みがエラーなく失われる問題を修正しました。Iceberg のコミットは新しいメタデータファイルを条件付き書き込みで公開しますが、
HDFSObjectStorageがその条件を無視して単純な上書きを行っていたため、同時実行された書き込みがすべて確認応答される一方で、いずれかの書き込み側のスナップショットに到達できなくなっていました。今後 HDFS は条件付き書き込みを拒否するため、HDFS 上でストレージ管理される Iceberg 書き込み (明示的なカラムリストを指定したCREATE TABLE ... ENGINE = IcebergHDFS(...)を含む) は失敗するようになります。読み取りには影響しません。#112437 (groeneai). KeeperMapテーブルに対するDELETEが、一致した行のうち先頭のmax_block_size行しか削除しないにもかかわらず、ミューテーションを正常完了として報告する問題を修正しました。また、keeper_map_strict_mode = 1でのDELETEがアトミックでない問題も修正しました。従来は、バージョンなしの削除にフォールバックして同時に更新された行を削除してしまう可能性があったほか、一致した行をブロック単位で適用していたため、競合が発生すると削除が部分的にしか適用されない状態になる可能性がありました。#112777 (alexey-milovidov).- 読み取りまたはマージの処理中に発生する一時的な Azure Blob Storage のエラー (RBAC 権限の伝播待ちによる
403 Forbidden、認証情報による認証の失敗、408として報告される接続タイムアウト) が再試行不可能と誤って分類され、POTENTIALLY_BROKEN_DATA_PART(Code 740) として報告されることで、正常なパーツに対して誤った重大アラートが発生する問題を修正しました。これらの一時的な障害は再試行可能として扱われるようになり、本当に永続的な障害の場合は、実在しない破損データパーツとしてではなく、通常の Azure エラーとして報告されるようになりました。#112871 (arsenmuk). - プレフィックス付きエンドポイントを使用する Azure Blob Storage ディスクで、
listObjectsが 2 ページ目以降のすべてのページで誤ったブロブ名を返す問題を修正しました。原因は、ページネーションがエンドポイントのプレフィックスを除去するクライアントラッパーを経由していなかったことです。ページネーションが継続トークンを介してラッパーを再度経由するようになり、すべてのページで正しいブロブ名が返されるようになりました。#112872 (arsenmuk). - パーツ全体を書き換えないミューテーションによって生成されたパーツで、テーブルの再読み込み後に
_block_numberおよび_block_offsetに対するパーツ単位の minmax 索引が失われる問題を修正しました。#112878 (alexey-milovidov). - ミューテーションの述語で、データベース名を明示せずに
mergeテーブル関数を使用すると例外 (リリースビルドではサーバーが起動できなくなるエラー) が発生する問題を修正しました。テーブル名の場合と同様に、ミューテーション対象テーブルのデータベースが使用されるようになりました。#113185 (alexey-milovidov). share_nested_offsets = 1を設定したMergeTreeテーブルで、削除後に再追加されたNestedメンバーのサブカラムを同じグループ内の既存メンバーと一緒に読み取ると、誤った結果が返されたりLOGICAL_ERRORが発生したりする問題を修正しました。読み取りが複数の block にまたがる場合、既存メンバーが後続の block の値を返していました。#113225 (groeneai)。- 非常に大きな
max_streams_to_max_threads_ratioを指定してMergeテーブルから読み取ると、デバッグビルドおよびサニタイザービルドで算術例外が発生する問題を修正しました。ストリーム数が 32 ビットに切り詰められていたため、2^32の倍数が 0 になっていました。あわせて、Mergeテーブルのストリーム数の乗算結果がsize_tを超える場合は未定義動作を引き起こさずにPARAMETER_OUT_OF_BOUNDをスローするようにし、MergeTreeのストリーム数をデータ量に応じて制限する際のオーバーフローを回避し、合計ソース数が 65536 を超えるMergeテーブルの読み取りを拒否するようにしました。#113382 (alexey-milovidov)。 hdfsディスクへの書き込みがParent directory doesn't existで失敗する問題を修正しました。生成されるオブジェクトキーにはネストされたディレクトリのプレフィックスが含まれますが、blob ストレージとは異なり HDFS には実際のディレクトリが存在し、ファイル作成時に存在しない親ディレクトリを自動作成しないことが原因でした。#113396 (alexey-milovidov)。remote/remoteSecureテーブル関数またはRemote/RemoteSecureテーブルエンジンに、存在しない名前付きコレクションとkey = value形式のオーバーライドを同時に指定した場合のエラー報告を修正しました。このような呼び出しは警告なしに位置引数による呼び出しとして再解析されていたため、オーバーライドがデータの expression として解析され、無関係なエラーが報告されていました(例:remote(collection, database = merge(...))に対して Function with namemergedoes not exist)。現在は、名前付きコレクションが存在しないことが正しく報告されます。#113510 (groeneai)。merge_max_block_size_bytesが空のカラムのbyteSize()より小さく設定されている場合に、バックグラウンドマージおよびOPTIMIZEが無限ループに陥る問題を修正しました。空のLowCardinalityカラムも辞書を保持しているため、1 行もマージしないうちにバイト制限に達することがあり、その結果マージが空の block を延々と生成し続け、CPU コアを 100% 消費したまま background pool のスロットを解放しませんでした。#113585 (groeneai)。- テーブルで
serialization_info_version = 'basic'を使用している場合に、Compact パーツのミューテーション結果が、パーツのシリアライゼーション情報がメモリ上に残っているかserialization.jsonから再読み込みされたかによって異なってしまう問題を修正しました。ReplicatedMergeTreeでは、バイト単位で同一のソースパーツを持つ 2 つのレプリカが異なるミューテーション後のパーツを書き込み、ミューテーションがCHECKSUM_DOESNT_MATCHで失敗していました。#113588 (groeneai)。 - 宛先ストレージが .lock ファイルを読み取れない場合に、バックアップが同時実行中のバックアップがあると誤って報告するのではなく、根本原因であるロックファイルへのアクセスエラーを報告するようになりました。#113637 (kirillshokhin)。
MergeTreeテーブルのバックグラウンドタスク(統計のリフレッシュ、パーツのリフレッシュ、古いパーツ/予期しないパーツの読み込み)とテーブルの破棄との間で発生するデータ競合を修正しました。#113722 (alexey-milovidov)。- 更新対象テーブルのデータベースが session のデータベースと異なる場合に、
UPDATEおよび論理削除(lightweightDELETE)が誤ったテーブルを読み取る問題を修正しました。カレントデータベースを暗黙的に使用するmergeテーブル関数と、修飾されていないテーブル識別子のいずれについても、ミューテーションの expression が更新対象テーブルのデータベースを基準に正規化されるようになりました。以前はこれらの名前が session のデータベースを基準に解決されていたため、ステートメントが別のテーブルから選択した行を、警告なしに更新または削除していました。#113748 (groeneai)。 - 主キー範囲のレイヤー単位で
MergeTreeテーブルを読み取る際に、いずれかのレイヤーが空のパイプを生成すると例外が発生する問題を修正しました。#114177 (alexey-milovidov). BACKUP、RESTORE、およびENGINE = Backupは、s3()、file()、azureBlobStorage()と同様に、ユーザーのSOURCES権限に基づいてバックアップの保存先を認可するようになりました。これまでは、BACKUP権限を持ちながらSOURCES権限を持たないユーザーでも、サーバーから到達可能な任意の場所にバックアップを書き込んだり、任意の場所からバックアップを読み取ったりできました。今後は、バックアップの書き込みには宛先のソースに対するWRITE方向の権限 (WRITE ON S3、WRITE ON AZURE、WRITE ON FILE) が、読み取りにはREADが必要です。なお、Disk(...)の宛先は引き続きbackups.allowed_diskによってのみ制限されます。#114405 (groeneai).- ミューテーション実行中のテーブル読み取りに関する問題を修正しました。
MATERIALIZEDカラムが古い値を返す場合があったほか、更新済みのカラムと一緒に選択するとエラーで失敗する場合がありました。#114561 (tiandiwonder). - 内部に集合演算を含む子テーブルを持つ
Mergeテーブルを、make_distributed_planを有効にした状態で読み取ると論理エラー (Block structure mismatch) が発生する問題を修正しました。#114753 (alexey-milovidov). - コンパクションを実装していないエンジンを使用するオブジェクトストレージテーブルに対して
OPTIMIZE TABLEを実行すると、実際には何も処理していないにもかかわらず成功が返されていました。今後は、このステートメントをサポートしない他のすべてのエンジンと同様にエラーを返します。この変更はDeltaLake、Paimon、Hudi、および通常のオブジェクトストレージエンジン (S3、GCS、COSN、OSS、AzureBlobStorage、HDFS、オブジェクトストレージをバックエンドとするURL) が対象です。コンパクションを実装しているIcebergには変更はありません。#114805 (groeneai). allow_deprecated_syntax_for_merge_treeを有効にし、非推奨の位置指定構文で作成したReplicatedMergeTreeでBAD_DATA_PART_NAME(“Trying to get part name in new format for old format version”) が発生する問題を修正しました。この問題により、ミューテーションを適用していないレプリカでそのミューテーションが完了済みとして報告されたり、再起動後にテーブルが読み取り専用のままになったりすることがありました。#114980 (groeneai).- 論理更新を使用するテーブルで
Found patch part ... that intersects mutation with version ...(LOGICAL_ERROR) が発生する問題を修正しました。パッチパートのマージによって、データバージョンの範囲が既存パーツのデータバージョンをまたぐパッチが生成されることがありました。このようなパッチは適用もスキップもできないため、そのパーティションに対する以降の操作がすべて失敗し、レプリケーションキューが停止していました。今後、このようなマージは割り当てられません。#115064 (alexey-milovidov). Backupデータベースエンジンが利用できなくなったバックアップ (ファイルが削除された場合や、基盤となるストレージにアクセスできない場合など) を参照していると、サーバーの起動に失敗する問題を修正しました。今後は、サーバー全体の起動が妨げられることはなく、該当するデータベースはテーブルなしの状態でロードされます。#83188 (orloffv).- ディスクフルエラー発生後にログが復旧しない問題を修正しました。これまでは、ログ用ディスクが満杯になると ClickHouse が失敗状態に陥り、syslog にエラーメッセージを大量に出力し続け (1 時間あたり 100 GB 以上に達する可能性がありました)、ディスク容量が解放された後も復旧しませんでした。今後は、ディスク容量が確保されると、サーバーを再起動しなくてもロギングシステムが自動的に復旧します。#93127 (jaehanbyun).
- DeltaLake ストレージのスキーマビジターで発生するクラッシュを修正しました。#97112 (kssenii).
データレイクおよび外部ストレージ関連の修正
- S3 のマルチパートアップロード (例:
INSERT INTO ... hits_s3) で一時的に発生するCode: 499 ... InvalidPart(S3_ERROR) エラーを修正しました。MinIO はCompleteMultipartUploadの実行時に、アップロード直後のパーツを一時的に存在しないものとして報告することがあります。このエラーは、従来から処理されていたNoSuchKeyと同様に、s3_max_unexpected_write_error_retriesを上限として再試行されるようになりました。#109364 (groeneai)。 - データファイル形式が
Parquet以外の Iceberg テーブルに対するALTER TABLE ... DELETEおよびALTER TABLE ... UPDATEは、サーバーをクラッシュさせたりテーブルを気付かないうちに破損させたりせず、明確なNOT_IMPLEMENTEDエラーで拒否されるようになりました。#105893 (groeneai)。 file、s3、inputなどのテーブル関数からのINSERT SELECTで、同じソースカラムを複数回選択した場合に発生するエラーCannot add column ...: column with this name already existsを修正しました。#105982 (crakjie)。- HTTP クエリ文字列のパラメータとして渡される機密値 (例:
param_secret_key/param_aws_secret_access_keyなどのparam_*クエリパラメータバインディング、passwordパラメータ、S3 形式のsignatureパラメータなど) が、system.text_logや OpenTelemetry のスパンにそのまま書き込まれなくなりました。Request URIのログ行では、機密情報と思われる名前を持つパラメータの値が[HIDDEN]に置き換えられてマスクされます。#108475 (groeneai)。 S3QueueおよびAzureQueueテーブルエンジンの_etag仮想カラムを修正しました。このカラムは宣言されているものの値が設定されていなかったため、SELECT _etagは常に空文字列を返していました。現在はS3エンジンやs3()テーブル関数と同様に、オブジェクトの ETag を返します。#108625 (groeneai)。- S3 への読み書きを行うクエリが、S3 リクエストの処理中に (例:
KILL QUERYによって) キャンセルされた場合、誤解を招くネットワークエラーや S3 エラーではなく、キャンセルとして報告されるようになりました。特に、S3 へのバックアップまたはリストアがキャンセルされた場合は、system.backupsにBACKUP_CANCELLED/RESTORE_CANCELLEDと記録されるようになりました。#108673 (jkartseva)。 S3Queueテーブルエンジンの_tags仮想カラムを修正しました。このカラムは宣言されているものの値が設定されていなかったため、SELECT _tagsは常に空のマップを返していました。現在はS3エンジンやs3()テーブル関数と同様に、オブジェクトのタグを返します。#108676 (groeneai)。- データレイクカタログのデータベースで、SHOW TABLES と SELECT … FROM system.tables が異なる結果を返す問題を修正しました。ClickHouse が読み取れないテーブルは、どちらでも一貫して非表示になります。#109273 (SmitaRKulkarni)。
- Delta Lake テーブル (
DeltaLakeLocal/deltaLake) へのINSERTが、シンクによる書き込み開始後に失敗した場合 (例: ソースクエリが挿入途中で例外をスローした場合やクエリがキャンセルされた場合) に、サーバーがアボートする (リリースビルドではデータファイルが未完了のまま気付かれずに残る) 問題を修正しました。#109328 (groeneai)。 optimize_functions_to_subcolumns=1(デフォルト) の状態で、古いデータファイルの書き込み後にスキーマ進化によって追加された Iceberg カラムに対してWHERE col IS NULL/IS NOT NULLを実行すると、Not found column or subcolumn c.null in block(debug/sanitizer ビルドではBad cast from ColumnConst to ColumnNullable) が発生する問題を修正しました。#109515 (groeneai)。CREATE TABLE ... AS SELECTクエリにおいて、s3テーブル関数の URL 引数として (または他の任意のテーブル関数の引数として) スカラーサブクエリを使用するとHost is empty in S3 URIエラーが発生する問題を修正しました。テーブル関数の引数に含まれるスカラーサブクエリは、クエリ解析の段階で評価されるようになりました。#110254 (CheSema).- Iceberg テーブルに対して
UPDATE ..., DELETE ...のような複数コマンドを含むALTERを発行すると、論理エラー (debug/sanitizer ビルドではサーバーが異常終了) が発生する問題を修正しました。このようなミューテーションは、明確なNOT_IMPLEMENTEDエラーで拒否されるようになりました。#110347 (groeneai). - 初期スキーマにネストされたフィールド (
Tuple/Array/Map) が含まれる場合、ALTER TABLE ... ADD COLUMNの実行後に Iceberg テーブルでフィールド ID が重複する問題を修正しました。last-column-idには、ネストされた子要素も含めて割り当て済みの最大フィールド ID が記録されるようになりました。これにより、後から追加したカラムがネストされたフィールドの ID を再利用することはなくなり、読み取りがICEBERG_SPECIFICATION_VIOLATION(Duplicate field id) で失敗することもなくなりました。#110884 (groeneai). ALTER TABLE ... ADD COLUMNの実行前と実行後の両方で書き込まれたデータファイルがテーブルに含まれ、かつoptimize_move_to_prewhereが有効な場合に、Iceberg テーブルに対するDELETE/UPDATEが誤った行を警告なしに削除する (またはNOT_FOUND_COLUMN_IN_BLOCKをスローする) 問題を修正しました。#111693 (groeneai).- Iceberg テーブルに対して
ALTER TABLE ... EXECUTE expire_snapshotsを実行すると、保持されたスナップショットのsystem.iceberg_historyにおけるmade_current_atが1970-01-01になる問題を修正しました。また、メタデータにsnapshot-logがないテーブルについてsystem.iceberg_historyが行を返さない問題も修正しました。#111781 (groeneai). MATERIALIZED VIEW経由で Iceberg テーブルに挿入する際に発生するデータ破損を修正しました。データファイルがターゲットの現在の Iceberg スキーマではなくCREATE時点のカラム型に基づいて書き込まれていたため、DateTime値が素の Avrointとして格納されてマイクロ秒として読み出され、DateTime64(0)やDateTime64(9)の場合にはファイル自体を読み出せませんでした。この修正に伴い、Iceberg スキーマがビューで宣言されたカラムよりも多いターゲットに対してINSERT INTO <materialized view>を実行すると、破損した行を書き込むのではなくTYPE_MISMATCHが発生するようになりました。#112359 (groeneai).- タプル内にネストされたタプルをスキーマに含む Iceberg テーブルへの書き込みを修正しました。公開されるテーブルメタデータで内側のタプルのフィールド名が位置ベースの名前
1、2、… に置き換えられていたため、デフォルトのParquetフォーマットではINSERTがINCORRECT_DATAで失敗し、Avroではカラムを読み出せませんでした。#112480 (groeneai). - 2 つのクエリが同じテーブル名を同時に解決すると、
FilesystemまたはHDFSデータベースが永続的に停止してしまうデッドロックを修正しました。この状態になると、以降そのデータベースに対するすべてのクエリが無期限にブロックされて中断もできず、復旧にはサーバーの再起動が必要でした。#112495 (groeneai). WHERE述語のNOT配下に delta-kernel の述語変換器が処理できない部分式が含まれている場合に、DeltaLakeテーブルが本来より少ない行を返す問題を修正しました。このような部分式は、子イテレータの終端としてではなく、明示的な不明述語として delta-kernel に通知されるようになりました。従来は、これにより外側の論理積が警告なしに切り詰められていました。#112652 (groeneai).ALTER TABLE ... EXECUTE remove_orphan_filesが Iceberg テーブルの使用中のmetadata/version-hint.textを削除してしまう問題を修正しました。到達可能セットのエントリは、末尾にスラッシュが付くことのない値に末尾スラッシュがあると仮定して文字列を連結することで構築されていました。そのため、実際のヒントファイルが到達可能と認識されず、older_thanのしきい値より古くなった時点で削除されていました。その結果、iceberg_use_version_hint = 1の場合はテーブルをまったく読み取れなくなっていました。#113548 (groeneai)。ALTER TABLE ... MODIFY COLUMNによってNullableに変更された Iceberg のカラムでフィルタリングするとLOGICAL_ERRORが発生する問題を修正しました。#114521 (groeneai)。ENGINE = URL(...)定義を含むATTACH TABLEが、URL スキームに応じた振り分け先エンジンのTABLE ENGINE権限をチェックしていなかった問題を修正しました。これにより、TABLE ENGINE ON URLのみを持つユーザーが、File、S3、AzureBlobStorage、HDFSをバックエンドとするテーブルをアタッチして読み取れてしまっていました (CREATE TABLEでは正しく拒否されます) 。#115914 (groeneai)。- IPv4 と IPv6 の両方を公開しているホストで、一方のアドレスファミリーしかルーティングできない場合に、外部への HTTP リクエスト (例: `aiGenerate`、`url` テーブル関数、S3) が `No route to host` で失敗する問題を修正しました。HTTP 接続プールは、最初のアドレスがネットワークエラーで失敗した場合、最初のリクエストの時点でエラーを伝播させるのではなく、名前解決された次のアドレスにフォールバックするようになりました。#103786 (alexey-milovidov)。
- 2 つのフィールドからなる
{key, value}レコードの Avroarrayを、ClickHouse のMapカラムに読み込めるようにしました。これは、Iceberg や Spark が文字列以外のキーを持つMAP<K, V>に対して生成するエンコーディングです (Avro のネイティブ Map は文字列キーのみをサポートします) 。従来、このようなファイルはArray(Tuple(key, value))としては読み込めましたが、Map(K, V)としては読み込めず、Type Map(...) is not compatible with Avro arrayで失敗していました。#109289 (groeneai)。 - バージョン番号がすべて数字でありながら 32 ビット整数の範囲を超えるメタデータファイル (例:
v99999999999999999999.metadata.json) を持つ Iceberg テーブルを読み取る際の問題を修正しました。従来、このような名前に対しては、明確なBAD_ARGUMENTSエラーではなく、原因のわかりにくいstd::out_of_range(STD_EXCEPTION) が発生していました。#109619 (groeneai)。 - gzip 圧縮された Iceberg メタデータファイルのファイル名を修正しました。ClickHouse はこれらを
v{N}.gzip.metadata.json(HTTP のContent-Encodingトークン) という名前で書き込んでいましたが、Iceberg の仕様ではgz拡張子を用いたv{N}.gz.metadata.jsonが想定されています。そのため、Spark などの Hadoop カタログのリーダーが、ClickHouse が書き込んだメタデータを見つけられませんでした。今後 ClickHouse はv{N}.gz.metadata.jsonで書き込み、後方互換性のため従来のgzip名も引き続き読み取ります。#109812 (groeneai)。 - 書き込みフォーマットが
Avroの Iceberg テーブルで、型がlist、map、structのいずれかで"required": falseと宣言されたフィールドが、["null", T]ユニオンを伴わない必須フィールドとしてシリアライズされていた問題を修正しました。これにより、データファイル自体のスキーマがテーブルのメタデータと食い違い、他の Iceberg リーダーからは必須フィールドとして扱われていました。今後このようなフィールドは、Iceberg の仕様でオプションフィールドに用いられる["null", T]ユニオンとして書き込まれます。#112648 (groeneai)。 - Iceberg の
snapshot-logに同じsnapshot-idが複数回出現する場合 (ロールバック後に発生) に、system.iceberg_historyのmade_current_atが、スナップショットが current になった最後の時刻ではなく最初の時刻を報告していた問題を修正しました。#113598 (groeneai)。 - 名前付きコレクションで
http_client = 'gcp_oauth'が設定されており、Google OAuth2 トークンエンドポイントが接続を受け付けたまま応答を返さない場合に、BACKUP/RESTORE ... TO S3、GCS ディスク、およびs3テーブル関数が最大 1 時間ハングする問題を修正しました。Bearer トークンのリクエストは呼び出し元のデータ転送リクエストのタイムアウトを継承しなくなり、応答の待機時間は STSAssumeRoleリクエストの上限に合わせて 10 秒に制限されます。#115531 (groeneai)。 - バックグラウンドでのキャッシュのダウンロードが
ErrnoException以外の例外で失敗した場合 (例えば Iceberg テーブルに対するOPTIMIZEの実行中) に、空の孤立したキャッシュファイルが残り、ファイルシステムキャッシュで論理エラー (Expected file ... not to exist) が発生する可能性があった問題を修正しました。#110549 (groeneai)。 - 最大エントリ数で設定されたキャッシュ (
SLRUポリシー) において、その上限数のエントリがそれぞれ 2 回以上アクセスされると、新しいエントリを受け入れなくなり、しかもそれが通知されなかった問題を修正しました。影響を受けるキャッシュは、Iceberg および Paimon のメタデータファイルキャッシュ、Parquet メタデータキャッシュ、テキスト索引キャッシュ、ベクトル類似度索引キャッシュ、コンパイル済み式キャッシュ、ObjectStorageQueue のファイルステータスキャッシュです。#115517 (groeneai)。 - 可変の
snapshot/LATESTヒントが同時に置き換えられている最中に、Paimon テーブルの読み取りが失敗する可能性があった問題を修正しました。ヒントが無効または古い場合は、安全にスナップショットの一覧取得へフォールバックするようになりました。#112010 (JiaQiTang98)。 - 入力バッファ (例えば
restricted_seek = trueの S3 読み取りバッファ) が minizip から要求された seek や読み取りを拒否したために zip アーカイブを展開できない場合に、根本原因となった実際の例外を表示するようにしました。これまでは、実際のエラーが汎用的なCouldn't unpack zip archive: Code = -100/Couldn't open zip archiveメッセージに隠れていました。#105103 (groeneai)。 - refs を持たないメタデータに対する Iceberg への書き込みを修正しました #106896 (AVMusorin)。
- 外部エンジンによって作成され、省略可能な
snapshots、metadata-log、snapshot-log配列を含まないメタデータを持つ Iceberg テーブルへの挿入時に例外が発生する問題を修正しました。このような挿入も失敗せず正常に完了するようになりました。#107473 (tiandiwonder)。 - 一時的な読み取りエラーの後に S3 へのアップロード (例えばバックアップ) が再試行された際に、
ReadBuffer is canceled. Can't read from it.エラーが発生する可能性があった問題を修正しました。#108573 (groeneai)。 - 非同期 S3/Azure マルチパートアップロードの最終的な完了タスクのスケジューリングに失敗した場合 (例えばスレッドプールの枯渇時) に、
std::future_error(“The associated promise has been destructed prior to the associated state becoming ready”) が発生し、debug/sanitizer ビルドではサーバーが異常終了する可能性があった問題を修正しました。現在は実際のスケジューリングエラーが報告されます。#108730 (groeneai)。 - 西暦約2262年以降の ORC のタイムスタンプを、スケールが 9 より粗い
DateTime64カラムに読み込めない問題を修正しました。従来、ネイティブ ORC リーダーはすべてのタイムスタンプを固定のDateTime64(9)を中間形式として変換していたため、ナノ秒スケールでInt64がオーバーフローしていました。その結果、要求されたDateTime64のスケール (例えば Iceberg が生成するDateTime64(6)) で値を表現できる場合でも、VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPEでそのような値が拒否されていました。現在はタイムスタンプが要求されたスケールで直接読み込まれ、対象のスケールでも値を保持できない場合にはdate_time_overflow_behaviorが適用されます。#109302 (groeneai)。 - スキーマにサポートされていないネスト型 (例えば
ROWフィールド) を含む Paimon テーブルを読み込む際、エラーコード 0 でメッセージもないDB::Exception. (OK)ではなく、サポートされていない型を明示したBAD_ARGUMENTSエラーが報告されるようになりました。#109762 (groeneai)。 - 同じソースカラムで複数回パーティション化された Iceberg テーブル (例えば
PARTITIONED BY (hours(ts), ts)) を読み込めない問題を修正しました。このようなテーブルは、以前はCannot add column ...: column with this name already exists (ILLEGAL_COLUMN)で失敗していました。#109895 (groeneai)。 - ClickHouse が Iceberg テーブルに書き込むデータファイルに、Avro (
field-id) および ORC (iceberg.id/iceberg.required型属性) フォーマットでも Iceberg のフィールド ID が埋め込まれるようになりました。また、ORC のStringカラムはバイナリではなく ORC のstringとして書き込まれるようになりました。以前はフィールド ID を埋め込むのは Parquet のみだったため、仕様に準拠したリーダー (例: Spark/iceberg-java) では、カラム名の変更後に ClickHouse が書き込んだ Avro の行から警告なく NULL が返され、ClickHouse が書き込んだ ORC ファイルはまったく読み込めませんでした。#109994 (groeneai)。 - すべての position delete ファイルより新しい非 Parquet フォーマット (例:
ORC) のデータファイルを含む Iceberg テーブルに対してOPTIMIZE TABLEを実行すると、論理エラーChunkInfoRowNumbers does not existが発生する問題を修正しました。#110107 (alexey-milovidov)。 s3およびfileを介して、非圧縮のSTOREDzip エントリから大きなParquetファイルを読み込む際の問題を修正しました。#110495 (Gudauu)。- バックグラウンドスケジュールプール (例えばグローバルスレッドプールが枯渇した状態での
icebergプール) の起動に失敗しても、サーバーが異常終了しなくなりました。このエラーは回復可能な例外として扱われます。また、system.background_schedule_poolを読み込んだ際に、副作用としてこれらのプールが作成されることもなくなりました。#111209 (groeneai)。 - Paimon REST カタログにおける DLF 認証を修正しました。リクエストの署名が一度だけ計算されて使い回されていたため、2 回目以降のカタログリクエストがすべて HTTP 401 で失敗し、SHOW TABLES が空のリストを返していました。あわせて、テーブルの存在チェックにおける HTTP 404 の検出も修正しました。#112015 (JiaQiTang98)。
- position delete によって空になった
Icebergデータの chunk をパーティション化する際 (例えば、完全に削除されたデータファイルを含むパーティション化されたIcebergテーブルのコンパクション中) に発生するLOGICAL_ERROR(partitions_count > 0) を修正しました。#112432 (PedroTadim)。 - Azure のバッチによるオブジェクト削除において、バッチリクエスト自体が失敗した場合に
system.blob_storage_logの Delete イベントが記録されず、バッチ全体がログに残らない問題を修正しました。バッチ単位で失敗した場合でも、各オブジェクトについて Delete イベントが記録されるようになりました。#112873 (arsenmuk)。 - ミリ秒より高い精度の
TIMESTAMPカラムでパーティション分割されたPaimonテーブルを読み取ると、scale 6 is not supported, only support scale <= 3で失敗する問題を修正しました。#113401 (JiaQiTang98). - スキーマで空の名前のカラムが宣言されているデータレイクテーブルを読み取るとクラッシュする問題を修正しました。不正な Iceberg メタデータは
ICEBERG_SPECIFICATION_VIOLATIONで拒否され、カタログ、Delta Lake、または Paimon から提供されたスキーマはAMBIGUOUS_COLUMN_NAMEで拒否されます。このチェックは無条件に行われるため、空のフィールド名を持つ未使用の過去のスキーマを保持しているだけの Iceberg テーブルも読み取り不可となります (従来は、そのスキーマが読み込まれた時点で異常終了していました) 。#114394 (groeneai). - Iceberg 仕様で禁止されているスキーマ進化がメタデータに記述された Iceberg テーブルを読み取っても、サーバーが異常終了しなくなりました。
IcebergSchemaProcessorにおける 4 種類の仕様違反は、これまでアサーション失敗として扱われるLOGICAL_ERRORとして報告されるか、チェックされないまま致命的なアサーションに到達していましたが、現在はICEBERG_SPECIFICATION_VIOLATIONを発生させるようになりました。#114518 (groeneai). - musl ベースのビルドで、HTTP
Last-Modifiedヘッダーの移植性のない解析処理が原因で、url/urlClusterテーブル関数の_time仮想カラムが常にNULLになる問題を修正しました。#111619 (thevar1able). allow_experimental_url_wildcard_from_index_pagesを有効にした状態でCREATE TABLE ... AS url('http://host/**/', ...)によりテーブルを作成すると、その後サーバーが起動しなくなる問題を修正しました。このようなテーブルのメタデータを読み込む際に実験的機能のチェックが再評価され、SUPPORT_IS_DISABLEDで失敗して起動が中断されていました。#115095 (groeneai).URLデータベースエンジンのテーブルが、読み取りソース権限を持たないユーザーに対してローカルファイルの存在有無を開示しないようになりました。SHOW TABLES権限のみで実行できるEXISTS TABLEおよびテーブルの解決処理において、権限の確認前にファイルシステムを参照しなくなりました。#113029 (alexey-milovidov).Exception::addMessageで追加されたメッセージにもquery_masking_rulesを適用するようにしました。これにより、マスキングルールが設定されている場合に、jdbc()/odbc()のエラーに含まれる(in file/uri ...)接尾辞内の URL エンコードされた認証情報が漏洩しなくなります。#106916 (gaurav0107).
フォーマットとインジェストの修正
- Arrow の
time32/time64をスキーマ指定なしで読み取る場合 (例:SELECT * FROM file(..., 'Arrow')) 、DateTime64ではなくTime64が推論されるようになりました。以前はDateTime64が推論されていました。従来の推論型を前提としている下流の処理は、アップグレード後に動作しなくなります。また、Time/Time64を Arrow へエクスポートする機能も追加され、精度に応じて適切な Apache Arrow の時刻型が選択されます。#104316 (Maoyao233). - 遅延カラムレプリケーション (
enable_lazy_columns_replication) が有効な状態で、バッチ処理の途中でエラーが発生してINSERTがロールバックされた場合 (例:Bufferテーブル、非同期挿入、Kafka/RabbitMQ/FileLogエンジン) に、誤った結果が返されたり範囲外読み取りが発生したりする可能性があった問題を修正しました。#108935 (groeneai). INSERTのカラムリストで、t.* LIKE '<pattern>'/t.* ILIKE '<pattern>'と記述した修飾付きカラムマッチャーは受け付けられる一方、その正規形であるt.COLUMNS('<regexp>')は拒否されるというパーサーの不整合を修正しました。この不整合により、クエリフォーマットのラウンドトリップが成立しなくなっていました (debug/sanitizer ビルドではサーバーが異常終了していました) 。#109176 (groeneai).- Microsoft Fabric / OneLake の
DataLakeCatalogテーブルへのINSERTがIncorrectEndpointError(HTTP 400) で失敗する問題を修正しました。ADLS Gen2 (DFS) への書き込みを、.blobホストではなく.dfsエンドポイントのホストへルーティングするようにしています。注:remote_url_allow_hostsを使用している場合、INSERTを実行するには Fabric の.blob(読み取り用) と.dfs(書き込み用) の両方のホストを許可リストに登録する必要があります。#110290 (zlareb1). - データレイク用テーブル関数 (例:
INSERT INTO FUNCTION icebergS3(...)) 経由で書き込むと、生成される Parquet ファイルで文字列カラムのString型アノテーションが失われ、書き込まれたデータを Spark などの外部リーダーで読み取れなくなる問題を修正しました。今後は、このような書き込みでもテーブルエンジン経由の書き込みと同じフォーマット設定が使用されます。#110465 (tiandiwonder). - Arrow Flight でログインした後に
system.session_logが読み取れなくなる問題を修正しました。interfaceカラムはEnum8ですが、その列挙値にArrowFlightが含まれていなかったため、Arrow Flight プロトコル経由のログインで生の値10が書き込まれ、そのような行を読み取るSELECTはいずれもUnexpected value 10 in enumという例外をスローしていました。#110758 (alexey-milovidov). TSV系フォーマットのスキーマ推論で、0.0や0.5のように先頭にゼロが付いた小数値に対してStringが推論されていた問題を修正しました (CSVでは正しくFloat64が推論されます) 。加えて、こうした値からなる先頭行がTSVのヘッダー自動検出によってヘッダーとして扱われ、結果から欠落していました。また、x=1\x2E5のようにエスケープシーケンスを用いて記述された値に対してTSKVが数値型を推論し、その後パースに失敗する問題も修正しました。なお、007のように先頭のゼロが整数のパディングである値は、TSVの値パーサーで読み戻せないため、引き続きStringと推論されます。#112226 (groeneai).- 値のパーサーが読み戻せないテキスト値に対して、スキーマ推論が数値型を提案してしまう問題を修正しました。推論では末尾が欠けた指数 (
1e+) 、仮数部の欠落 (.) 、符号の重複 (++inf) が受け入れられていましたが、推定したスキーマで読み取る際にreadFloatTextPreciseがこれらをCANNOT_PARSE_NUMBERで拒否していました。Dynamicカラムでは、これが INSERT 時のエラーとなっていました。今後は、リーダーが実際に使用するパーサーで推論時に数値を検証します。これにより、推論される型がmax_read_buffer_sizeに依存するケースも解消されたほか、0e5のような先頭ゼロを含む有効な指数形式が、CSV と同様に TSV でもFloat64と推論されるようになりました。不正な指数形式の扱いも修正されています。#112453 (groeneai)。 - 行ベースの入力フォーマットが1つのブロックをパースしている間、
KILL QUERYやmax_execution_timeが数分間にわたって無視される問題を修正しました。行ベースの入力フォーマットは 8192 行ごとにクエリのキャンセルを確認するようになりました。これにより、kill された挿入 (特に、ブロックあたり最大max_insert_block_size行をパースするバックグラウンドの非同期挿入のフラッシュ) は、ブロックの最後まで処理を続けることなく速やかに停止します。#112646 (groeneai)。 - スキーマがキャッシュされているソースにおいて、推論されるカラム型がそれまでのクエリの実行順序に左右される問題を修正しました。推論される型に影響する設定がスキーマ推論キャッシュのキーに含まれていなかったため、最初のクエリでの設定値によって、以降のすべてのクエリで得られる型が決まっていました。対象の設定は
input_format_try_infer_exponent_floats、max_parser_depth、input_format_json_infer_array_of_dynamic_from_array_of_different_types、およびParquetの場合はinput_format_parquet_local_time_as_utc、input_format_parquet_allow_geoparquet_parser、input_format_parquet_skip_columns_with_unsupported_types_in_schema_inference、schema_inference_make_json_columns_nullableです。あわせて、Formに欠けていたキャッシュキーのゲッターを登録し、Templateのゲッターが自身の行フォーマットのエスケープルールを使用するようにしました。#113533 (groeneai)。 - 外側のクエリの末尾に
SETTINGS句がある場合に、viewおよびviewIfPermittedテーブル関数のサブクエリ引数が正しくフォーマットされない問題を修正しました。このようなクエリはview((SELECT ...))とフォーマットされて再パースできなくなるため、内部の format-parse-format チェックに失敗し、Inconsistent AST formattingが発生していました。#114658 (groeneai)。 - フォーマットの自動検出時に、JSON データが TSKV と誤検出される問題を修正しました。#106009 (Avogar)。
- 有効な時刻の範囲外 (負の値または
>= 24h) のTime/Time64値をArrowフォーマットにエクスポートしようとした場合、不正な Arrow のtime32/time64データを書き込む代わりに、明確なエラーを返すようになりました。#107179 (tiandiwonder)。 - タイムスタンプカラムのタイムゾーンとして、固定の数値 UTC オフセット (例:
+05:30、-08:00、00:00) または IANA 以外のマーカーfixedが指定されたArrow、ArrowStream、および Arrow ベースのORCファイルを読み取れない問題を修正しました。これまではCannot load time zone ...(BAD_ARGUMENTS) で失敗していました。#108633 (groeneai)。 Nullable(Tuple(...))カラムを、個別のカラムに展開せず、単一の CSV フィールドとしてシリアライズするようにしました。これまでは、非 null 値が複数の CSV フィールドとして書き込まれる一方でNULLは単一の\Nとなっていたため、行によってカラム数が変わり、CSVWithNames/CSVWithNamesAndTypesのヘッダーやラウンドトリップが正しく機能しませんでした。#108959 (groeneai)。MsgPackフォーマットのスキーマ推論時に過剰なメモリ割り当てが発生する問題を修正しました。配列/Map/文字列/バイナリのヘッダーで膨大な要素数が宣言された破損入力やファジング入力によって、数ギガバイト規模の割り当てが一度に行われることはなくなりました (このような入力は不正な入力として拒否されるようになりました) 。これにより、サニタイザー環境でのallocation-size-too-bigによるアボートと、リリースビルドでのメモリ不足が解消されます。#109019 (groeneai)。output_format_arrow_low_cardinality_as_dictionary = 1を指定してLowCardinality(Time)カラムをArrowフォーマットで書き込む際にLOGICAL_ERRORが発生する問題を修正しました。#109730 (groeneai)。Dynamic型の型数、またはJSON/Objectのパス数がSIZE_MAXに近い値となっている破損したNativeフォーマットのストリームを読み込む際の問題を修正しました。このような不正な入力は、捕捉されないstd::length_errorではなく、明確なINCORRECT_DATAエラーで拒否されるようになりました。#110590 (alexey-milovidov)。- 旧形式 (バージョン 0) のステートフォーマットでシリアライズされた
Bool値を持つsumMap/sumMapWithOverflow/sumMapFilteredの集約状態をマージする際に、LOGICAL_ERROR: Cannot sum Bools(debug/サニタイザービルドではサーバーがアボート) が発生する問題を修正しました。この修正により、バージョン 0 のBoolステートでエラーなく誤った結果が返される 2 つのケースも解消されています。具体的には、Bool型の Map キーがステート間で重複排除されない問題と、ゼロ値の圧縮処理で誤ったエントリが削除される問題です。#110922 (groeneai)。 - 入力データのパース結果が 0 行となる場合 (例えば空の JSON や、フィーチャーを含まない GeoJSON の
FeatureCollection) に、formatテーブル関数がNOT_FOUND_COLUMN_IN_BLOCKをスローする問題を修正しました。現在は正しいカラムを持つ空の結果を返します。#111428 (groeneai)。 - WKT エンコードされたジオメトリカラムで、大文字以外の型キーワード (
point(1 2)) や空のコンテナ (LINESTRING EMPTY、POLYGON()、POLYGON(())) を使用している GeoParquet、Arrow、ArrowStream ファイルを読み込めるようになりました。これまでは、同じ文字列がreadWKT関数ではパースできるにもかかわらず、このようなファイルのインポートはBAD_ARGUMENTSまたはCANNOT_PARSE_NUMBERで失敗していました。また、空のジオメトリに対するwktの出力 (LINESTRING()と表記される) を格納したファイルを読み戻せない問題も修正されています。#112020 (groeneai)。 - 圧縮ヒント
autoおよびnoneをすべて小文字以外の表記で指定した場合 (例:file('data.csv.gz', 'CSV', 'x String', 'AUTO')) に、Unknown compression methodがスローされる問題を修正しました。GZIPなどのコーデック名は以前から大文字と小文字を区別せずに受け付けられていましたが、この 2 つの特殊なヒントも同様に動作するようになりました。#113631 (groeneai)。 CSVエスケープルールを使用するCustomSeparated、Regexp、Templateフォーマットにおいて、最初の要素がNULLであるTupleカラムを正しく読み込めない問題を修正しました。これらのフォーマットでは、単独のTupleは要素ごとに 1 つのフィールドを占めるため、先頭の\Nフィールドはカラム全体ではなくその要素を表します。これまではカラム全体として消費されていたため、残りの要素フィールドが後続のカラムにずれ込み、CustomSeparatedが自身の出力を読み戻せませんでした。#114471 (groeneai)。Regexp入力フォーマットが、マッチしたフィールドのうちパースされなかった残りの部分を警告なしに破棄し、エラーを報告せずに切り詰められた値や不正な値を格納していた問題を修正しました。たとえばJSONルールのもとでは、UInt64に対するv=-1は0として、Dateに対するv=2020-01-01junkは1975-07-14として読み取られていました。不正な形式のフィールドは、Escaped、CSV、JSONの各ルールのもとで拒否されるようになり、各ルールの挙動がドキュメントに記載されている対応フォーマットと一致するようになりました。Rawルールでは、タブを含むマッチしたフィールドが、タブの位置で切り詰められることなく全体として読み取られるようになりました。#114520 (groeneai)。- フォーマット→パース→フォーマットの往復変換で同一の結果にならない
CREATE INDEX/CREATE HYPOTHETICAL INDEXの式 (例:CREATE HYPOTHETICAL INDEX i0 ON t0 ((a())) TYPE aやCREATE INDEX i0 ON t0 ((a, b).1) TYPE minmax) で、Inconsistent AST formatting論理エラー (debug ビルドおよび sanitizer ビルドではサーバーが異常終了) が発生する問題を修正しました。#109175 (groeneai)。 - フォーマットレベルのキー条件が、Parquet ファイルから読み取られないカラムを参照している場合に、Parquet v3 リーダーで論理エラー (
Logical error: 'KeyCondition uses PREWHERE output') が発生する問題を修正しました。#109267 (groeneai)。 - ヘッダーが存在しない場合に、事前定義された HTTP ハンドラーで例外が発生する問題を修正しました #108324 (vitlibar)。
- 行ベースの入力フォーマット (例:
TSV/CSV) で入力のパースに失敗した際、下位の読み取り処理がすでにキャンセルされていると (たとえば不正な HTTP チャンクや途中で切れたボディなど) 、Logical error: 'ReadBuffer is canceled. Can't read from it.'が発生する可能性があった問題を修正しました。詳細なパース診断情報を生成する際に、キャンセル済みのバッファから読み取らないようになりました。#109708 (groeneai)。 Valuesフォーマットで、ストリーミングパースから SQL 式のパースへのフォールバックが成功した場合には、system.errorsおよびsystem.error_logにパースエラーが記録されなくなりました。#111141 (pamarcos)。- 停止中の
RabbitMQテーブルに対するSYSTEM REFRESHで、キューに溜まったバックログを消費できないことがある問題を修正しました。REFRESH は順序外のストリーミングサイクルを 1 回だけ許可しますが、AMQP 配信ループが非同期に開始された直後だと、そのサイクルが 0 行のまま即座に終了してしまうことがありました。その結果、1 回限りの許可が無駄になり、次のSYSTEM STARTまでメッセージが消費されないままになっていました。#111480 (groeneai)。 nats_streamを設定したNATSテーブルが、NATS サーバーの再起動後、エラーを出さないまま何も消費しなくなる問題を修正しました。DETACH TABLEとATTACH TABLEを実行しなくても、JetStreamのサブスクリプションが自動的に再確立されるようになりました。#112828 (groeneai)。- 極端に大きな
kafka_num_consumersが指定された場合、Kafkaテーブルエンジン内でメモリ割り当てに失敗するのではなく、明確なエラーで拒否するようにしました。これまでは、kafka_disable_num_consumers_limitが有効な状態でこのような値を指定すると、std::length_error例外が発生していました。#114764 (alexey-milovidov)。 - Arrow Flight サーバー: ADBC Flight SQL ドライバーなどの Go ベースの Flight クライアントが送信する、パディングなしの Base64 でエンコードされた
Basic認証の認証情報を受け付けるようになりました。また、authorizationヘッダーの形式が不正な場合に、汎用的なUnexpected error in RPC handlingではなく、適切な認証エラーを返すようになりました。#115085 (alexey-milovidov)。 - Arrow Flight サーバー: ユーザー名とパスワードの区切り文字が含まれていない不正な Basic 認証の認証情報を拒否するようにしました。#115347 (alexey-milovidov)。
データ型、関数、シリアライゼーションに関する修正
- Wide パーツを持つテーブルで
ALTER TABLE ... MODIFY COLUMNによりカラムを動的サブカラムを持つ型 (例:VariantからDynamic) に変更した後、そのパーツを読み取るかマージすると発生する論理エラーStream <col>.variant_discr ... is not found(debug ビルドおよび sanitizer ビルドではサーバーが異常終了) を修正しました。#110204 (groeneai). - 要素が非 Nullable の
LowCardinality(T)であるNullable(Tuple(...))カラムについて、同じクエリで親サブカラムも読み取る場合に、そのサブカラムを正しく読み取れない問題を修正しました。抽出されたサブカラムがLowCardinality(Nullable(T))バッファにデシリアライズされ、そのサブストリームが親の読み取りと共有されていたため、compact パーツでは、親が誤った値を返す、クエリがUnexpected return type from assumeNotNullで失敗する、あるいはサーバーがstring_viewのハードニングアサーションによって強制終了される、といった問題が発生していました。#112232 (groeneai). - 統計情報によるパーツ剪枝が索引解析中に
IN/GLOBAL INサブクエリを投機的に実行し、そのサブクエリが失敗した場合に、LOGICAL_ERROR“Not-ready Set is passed as the second argument for functionglobalNullIn” が発生し、クエリ本来のエラーメッセージが失われる問題を修正しました。#114121 (groeneai). Quantized('product', ...)コーデックを持つカラムのproduct_quantization_codebookサブカラムを読み取る際にCannot read all data of type FixedStringが発生する問題を修正しました。パーツごとのコードブックはすべてのグラニュールのデータの後に書き込まれるためマークで区切られておらず、マーク範囲がパーツの最終マークより前で終わる読み取りでは、コードブックを途中までしか読み取れないことがありました。#112818 (alexey-milovidov).Dynamicカラム内のMap値について、Mapのレイアウトが自身のメタデータと矛盾するパーツが書き込まれないようにしました。map_serialization_versionのみが異なるテーブル間でキャッシュされた 1 つのシリアライゼーションオブジェクトが共有されていたため、メタデータではwith_bucketsと宣言されているにもかかわらずパーツがbasicの Map レイアウトで書き込まれることがあり、後でそのパーツを読み取るとLOGICAL_ERROR: Stream ...buckets_info ... is not foundで失敗していました。以前のバージョンですでにこの状態で書き込まれたパーツは引き続き読み取れないため、削除する必要があります。#113514 (groeneai).ALP、FPC、GCDが、型から導出されるパラメータをコーデックのハッシュに含めていなかった問題を修正しました。compact パーツでは、ライターはコーデックハッシュの値ごとに 1 つの圧縮ストリームを共有するため、同じコーデックを使用する値幅の異なる 2 つのカラムが衝突し、誤った幅を持つ 1 つのコーデックオブジェクトを共有していました。その結果、幅が一致しない場合は有効な挿入がCANNOT_COMPRESSで拒否され、そうでない場合もいずれかのカラムの圧縮率が本来より低くなっていました。#114189 (groeneai).- テーブルの sorting key が
DateカラムをtoDateTimeでラップしており (例:ORDER BY toDateTime(date_column)) 、クエリがWHERE date_column >= '...'のような比較で元のカラムをフィルタリングする場合に、索引の枝刈りが誤って行われる問題を修正しました。toDateTime(Date)はDateTimeの範囲を超える (2106-02-07より後の)Date値でオーバーフローするため、格納されたキーは単調になりません。一致する行を含むグラニュールが除外されるおそれがあるため、ClickHouse はこのキーと述語の組み合わせでは主キーによる枝刈りを行わなくなりました。#101814 (nihalzp). DEFAULTを持つNullableカラムを別の型 (例:Nullable(UInt8)→String、LowCardinality(String)、Array(UInt8)) に変換する際にALTER MODIFY COLUMNが失敗する問題を修正しました。#102156 (il9ue).StorageSQLiteおよびsqlite()テーブル関数でWHERE述語を SQLite にプッシュダウンする際の、SQL リテラルのエスケープ処理の誤りを修正しました。シングルクォートおよび制御文字 (\n、\r、\t、\) がバックスラッシュでエスケープされていましたが、SQLite はこれを解釈しないため、構文エラーや誤ったクエリ結果が発生していました。また、PostgreSQL にプッシュダウンされる文字列リテラルのエスケープも修正しました。INリスト内にネストされた文字列に ClickHouse のエスケープが残っていたほか、制御文字がバックスラッシュシーケンスとして送信され、PostgreSQL 側で別のバイトとして解釈されていました。#104217 (tiandiwonder)。query_plan_convert_join_to_inが有効で、SELECT がソース配列カラムを参照している場合に、INNER JOIN ... ON arrayJoin(...) = ...クエリでNOT_FOUND_COLUMN_IN_BLOCK例外が発生する問題を修正しました。#104809 (tiandiwonder)。- 右辺オペランドが非定数で、現在の行のカラムを参照する IN および NOT IN 式の問題を修正し、新しいアナライザにおけるタプル右辺の扱いを既存の ClickHouse の IN セマンティクスに合わせました。なお旧アナライザでは、右辺にソースカラムを単独で指定した場合 (
x IN (arr)) 、引き続きテーブル名として解決され、スコープ外のままとなります。#104993 (niyue)。 StringまたはNullable(String)キーでDirectKeyValueJoinを使用した場合に、EmbeddedRocksDB、Redis、KeeperMapテーブルに対するJOINがエラーを出さずに 0 行を返すことがある問題を修正しました。#105253 (vdimir)。- 非等価の
JOIN ... ON述語が、ARRAY JOIN []によって生成されるようなNothing型のカラムを参照した場合に発生するLOGICAL_ERROR(“Unexpected expression in JOIN ON section. Expected boolean (UInt8), got ‘Nothing’”) を修正しました。#106981 (groeneai)。 - エイリアス付きのラムダが、式リストの先頭以外の位置でアクセス演算子 (
.Nによるタプル要素、または[]による配列要素) のオペランドとして使用された場合 (例:SELECT 1, ((p0, p1) -> p0 AS a7).4[3] FROM t) に、デバッグビルドおよびサニタイザービルドでサーバーが異常終了する可能性のあるInconsistent AST formatting論理エラーを修正しました。#107092 (groeneai)。 clusterAllReplicas(..., urlCluster(...))のように、別の分散クエリ内にネストされたクラスターテーブル関数 (urlCluster、fileCluster、s3Clusterなど) は、論理エラー (Distributed task iterator is not initialized) で失敗するのではなく、BAD_ARGUMENTSエラーとして拒否されるようになりました。#107107 (groeneai)。- 精度の低い浮動小数点カラムで正確に表現できない小数リテラル (
Float32カラムに対する0.1など) を使用した場合 (例:SELECT * FROM values('x Float32', 0.1)) に、valuesテーブル関数がARGUMENT_OUT_OF_BOUNDで失敗する問題を修正しました。このような値も受け入れられるようになり、CASTやINSERT ... VALUESと同様に、表現可能な最も近い値に変換されます。#108055 (alexey-milovidov)。 mapFilter、mapSort(およびそのバリエーション) 、mapConcatが、Mapのキー型および値型からLowCardinalityを除去してしまう問題を修正しました。以前は、Map(LowCardinality(String), String)カラムに対するmapFilterがMap(String, String)を返していたため、CREATE TABLE ... AS SELECTで作成されたテーブルのメタデータが破損し、CHECK TABLEが失敗する可能性がありました。#108057 (alexey-milovidov)。- キャンセルされた、または
KILLされたINSERTが、スキップ索引 (例えば高カーディナリティのカラムに対する無制限のset(0)索引) のビルド中に長時間実行され続ける問題を修正しました。クエリがキャンセルされると、索引のビルドが速やかに停止するようになりました。#108351 (tiandiwonder)。 primesテーブル関数からのSELECTがキャンセルに応答しない問題を修正しました。大きなstep(またはlimit) を指定した場合、KILL QUERYの実行後やタイムアウト後もクエリが長時間実行され続けることがありました。現在は速やかに停止します。#108353 (tiandiwonder)。- 名前に部分文字列
INTを含むデータ型名 (例えばデータ型の位置で使用されたquantileInterpolatedWeightedのような関数風の名前) のパースを修正しました。このような名前は MySQL の整数型と誤認され、最初の(...)引数グループが表示幅修飾子として暗黙的に消費されていたため、クエリのフォーマットのラウンドトリップが成立しなくなる可能性がありました。#108354 (groeneai)。 - 不正な形式の
ARRAY JOINの後にカンマと括弧で囲まれたテーブルリストが続く場合に、エラーとして拒否されず、クロス結合として誤ってパースされる不整合を修正しました。#108365 (Algunenano)。 - 分散クエリにおいて、構造的に同一な重複
ALIASカラムの重複排除が行われ、かつkey = value形式の名前付きコレクション引数を持つテーブル関数 (例えばoss(s3_conn, filename = '...')) が参照された場合に発生するLOGICAL_ERROR(“Invalid action query tree node …”) 例外を修正しました。#108435 (groeneai)。 - 分散テーブルに対して複数の
LowCardinality引数を持つ関数を呼び出した場合 (例えばremote()と組み合わせてconcatAssumeInjective((SELECT toLowCardinality('p')), s)をGROUP BYキーとして使用した場合) に発生し得る論理エラー (リリースビルドでは例外、デバッグビルドおよびサニタイザービルドではサーバーのアボート) を修正しました。エラーメッセージはDefault functions implementation for LowCardinality is supported only with a single LowCardinality argumentまたはExpected the argument ... to have N rows, but it has Mでした。#108871 (groeneai)。 - サーバー側で解釈される
DateTime/DateTime64の文字列リテラル (非同期INSERT、SELECTのリテラル) に対してuse_client_time_zoneが無視される問題を修正しました。use_client_time_zoneが有効な場合、クライアントはローカルのタイムゾーンをsession_timezoneとして伝播するようになり、サーバー側のパース結果が同期INSERTの場合と一致するようになりました。#109051 (groeneai)。 max_execution_time(timeout_overflow_mode = 'throw'指定時) によってクエリがキャンセルされない場合がある問題を修正しました。内部のタイムアウト監視機構が、より遅いデッドラインを持つクエリをすでに待機している状態で、より早いデッドラインを持つクエリが後から登録されると、そのクエリが完全に見逃され、制限時間を大幅に超えて実行され続けることがありました。#109792 (tiandiwonder)。- アナライザーが有効な状態で、
Distributedテーブルに対するクエリにおいてNullableとなる_shard_num(またはshardNum()) (例えばjoin_use_nulls = 1を指定したFULL JOINの場合) をORDER BYと組み合わせて使用するとNOT_FOUND_COLUMN_IN_BLOCKが発生する問題を修正しました。#109798 (groeneai)。 enable_join_runtime_filters = 1(26.2 以降デフォルトで有効) を指定した結合において、ビルド側の結合キーが NULL を含むLowCardinality(Nullable(...))で、かつランタイムフィルタがブルームフィルタにフォールバックした場合に、NOT_IMPLEMENTEDエラー (“Method getDataAt is not supported for Nullable(String)”) がスローされることがある問題を修正しました。#109824 (groeneai)。- 高階関数が具体的な値を期待する箇所 (例えば
arrayFold(lambda, arr, another_lambda)におけるarrayFoldのアキュムレータ) にラムダ式が渡されると、サーバーがクラッシュする問題を修正しました。enable_analyzer = 0の場合でも、このようなクエリはクラッシュせず、ILLEGAL_TYPE_OF_ARGUMENTで拒否されるようになりました。#109840 (groeneai)。 - ROW POLICY のフィルタで
arrayJoinのエイリアスであるunnestを拒否するようにしました。これにより、そのようなポリシーが読み取り時にcolumn->size() == num_rowsの論理エラーを引き起こしうる抜け穴を塞ぎました。#109973 (Algunenano)。 - 同一クエリ内でタプル全体も読み取られる場合 (例:
SELECT *) に、tupleElement(t, 'name')、tupleElement(t, N)、またはt.Nでフィールドにアクセスすると、Tupleのサブカラムに定義されたスキップ索引が使用されない問題を修正しました。これらの形式はいずれも、名前付きサブカラムアクセスt.nameと同様にグラニュールを枝刈りするようになりました。#110056 (groeneai)。 text、tokenbf_v1、またはngrambf_v1のスキップ索引を持つArray(String)カラムを配列リテラルと比較した場合 (arr = ['x']) に発生するBAD_GETエラーを修正しました。このような比較では、クエリ全体を失敗させる代わりに、索引側でフルスキャンとして扱うようになりました。#110057 (groeneai)。- 適用時点でカラムが既に存在する場合に、
ALTER TABLE ... ADD COLUMN IF NOT EXISTSで誤ってILLEGAL_COLUMNエラーが発生する問題を修正しました。この問題は、1 つのステートメント内で同じカラムをIF NOT EXISTS付きで 2 回追加した場合や、準備フェーズと適用フェーズの間に同時実行のALTERがカラムを追加した場合に発生していました。#110080 (groeneai)。 identity()(またはスカラーサブクエリの結果) がネストされたLowCardinalityを含む値をラップし、かつクエリでWITH TOTALS/WITH ROLLUPを使用している場合に発生するLOGICAL_ERROR(Bad cast from type ColumnLowCardinality to ColumnString) を修正しました。#110138 (groeneai)。- タプル式に対する
GROUP BY ALLをORDER BYと併用した場合に発生するNOT_FOUND_COLUMN_IN_BLOCKエラーを修正しました。#110206 (alexey-milovidov)。 - サブカラム (
Nullableカラムのx.nullやArrayのarr.size0など) を参照するCHECK制約を持つテーブルにINSERTするとNOT_FOUND_COLUMN_IN_BLOCKエラーが発生する問題を修正しました。#110208 (alexey-milovidov)。 - optimize_and_compare_chain 最適化 (デフォルトで有効) によって誤ったクエリ結果が返される問題を修正しました。チェーン内にペアごとに固有の変換規則を持つ型が混在している場合 (例: Enum と String、Decimal と Float64、幅の異なる FixedString) 、a < b AND b < c から推移律によって導出された条件が、元の条件とは異なる比較セマンティクスを用いる可能性がありました。今後、推移的な条件は、単一の比較順序を共有する型のグループ内でのみ導出されます。#110621 (yariks5s)。
optimize_injective_functions_in_group_byがGROUP BY GROUPING SETSおよびGROUP BY ... WITH TOTALSのクエリ結果を変えてしまう問題を修正しました。この設定は結果を変えないものとしてドキュメントに記載されていますが、グルーピングキーに対する単射関数を除去すると、そのキーが集約対象のセットに含まれない行 (GROUPING SETSの非メンバーセット) やWITH TOTALS行で誤った値が生成される (または行が欠落する) ことがありました。この誤った値が実在するキー値と偶然一致すると、同じ結果セット内でスーパー集約行と実際のグループを区別できなくなっていました。#110721 (groeneai)。median/quantile(ReservoirSampler ベース) の集約関数ステートに巨大な整数定数を掛けた場合 (例:medianState(x) * 18446744073709551615) にサーバーがハングする問題を修正しました。このクエリはキャンセルを受け付けなくなり、無期限に実行され続けるおそれがありました。#110779 (groeneai)。JSON引数に対して、内部の型ヒント用サブカラム名 (バッククォートの型マーカーで始まる名前) を指定してgetSubcolumnを呼び出すとクラッシュ (クエリ解析中のヌルポインタ参照) が発生する問題を修正しました。#110940 (groeneai)。map[key]が最初のキーではなく、後に出現する重複キーの値を返してしまう問題を修正しました。Mapカラムに重複キーが含まれる場合、map[key]の結果が同じブロック内の先行する行やoptimize_functions_to_subcolumns設定によって変わることがあり、同じ行に対するSELECTとWHEREの結果が食い違う可能性がありました。#111246 (groeneai)。use_variant_default_implementation_for_comparisons = 0の場合に、ANDチェーンでカラムを非Nullable型の NULL 値定数 (例えば NULL 値のVariant) と比較すると、論理式オプティマイザで論理エラー!rhs_literal->getValue().isNull()が発生する問題を修正しました。#111292 (groeneai)。- クエリに
setスキップ索引があり、(x AND <null-value>) OR yという形の述語の NULL が関数によって生成される場合 (例:toInt64OrNull('x')、nullIf(1, 1)、CAST(NULL AS Nullable(Int64))) に誤った結果が返される問題を修正しました。このような値は__bitWrapperFuncでラップされ、「不明」マスクではなくNULLを伝播していたため、set 索引が実際には条件に一致するグラニュールまで除外してしまい、クエリが本来より少ない行を返していました。#111604 (groeneai)。 - アナライザ有効時の
CREATE TABLE/ALTER TABLEで、_tableや_databaseなどの仮想カラムを参照するカラムのDEFAULT/MATERIALIZEDexpression が受け入れられてしまう問題を修正しました。このようなテーブルへの挿入はNOT_FOUND_COLUMN_IN_BLOCKで失敗し、MATERIALIZEDカラム (値を明示的に指定できない) の場合はテーブルへの挿入が恒久的に不可能になっていました。これらの expression は定義時に拒否されるようになり、アナライザ無効時と同じ動作になりました。仮想カラムを参照するALIASカラム (読み取り時に評価) およびEPHEMERALカラム (保存されない挿入用入力) は引き続き使用できます。#111776 (groeneai)。 - 型が
Array、Tuple、LowCardinalityのいずれかであるサブクエリ値を引数としてパラメーター化ビューを呼び出すと (例:SELECT * FROM v(param = (SELECT groupArray(x) FROM t))) 、UNKNOWN_QUERY_PARAMETERが発生する問題を修正しました。#111790 (groeneai)。 - 比較の連鎖を
IN/NOT INに変換するアナライザの書き換え(x = c1 OR x = c2 OR ...、x != c1 AND x != c2 AND ...、およびhas(const_array, x))における 3 つのバグを修正しました。use_variant_default_implementation_for_comparisons = 0が指定されたVariant型の expression では、書き換えによって expression の結果の型がUInt8からNullable(UInt8)に変わり、debug ビルドおよび sanitizer ビルドでクエリツリーの検証チェックによりLOGICAL_ERRORが発生していました。動的な構造を持つ expression(Dynamic、Array(Dynamic)、JSON)では、INがそのような引数を受け付けないため、本来正常に動作するクエリが書き換えによってIllegal type ... of argument of function inで失敗していました。また、時刻を含むDateTime定数をDateカラムと比較する場合のように、定数を expression の型へ損失なく変換できない場合には、どちらの方向の書き換えでも誤った結果が返されていました。#111924 (groeneai)。 - クエリで並列レプリカ、分散テーブル、または external aggregation を使用する場合や、ステートがテーブルに格納されている場合(
Dynamicの値内を含む)に、quantileDeterministic、quantilesDeterministic、medianDeterministicが同じデータに対して実行のたびに異なる結果を返す問題を修正しました。このバージョンより前にバージョン指定のない型表記で書き込まれたステートは、レイアウトを変更できないため、従来の動作が維持されます。#112052 (alexey-milovidov)。 - ベクトル検索クエリがクエリ条件キャッシュを汚染し、誤った結果が返される問題を修正しました。
vector_similarityインデックスを持つテーブルに対するSELECT ... WHERE <condition> ORDER BY <distance function> LIMIT nクエリが、グラニュールを<condition>に一致しないものとして記録してしまうことがあり、その結果、同じテーブルに対して後から実行した通常のSELECT ... WHERE <condition>が、エラーを出すことなく本来より少ない行を返していました。今後、ベクトル検索の読み取りではクエリ条件キャッシュへの書き込みを行いません。#112086 (groeneai)。 - シリアル化されたクエリプランから
serialize_string_in_memory_with_zero_byteが欠落する問題を修正しました。serialize_query_plan = 1の場合、この設定を無効にして稼働しているクラスタでは、イニシエーターとデシリアライズされたプランを実行するノードとの間で、メモリ上の文字列表現が食い違う可能性がありました。これは、この設定がデシリアライズ時には読み取られるものの、シリアル化時には書き込まれていなかったため、実行側のノードでは常にデフォルト値になっていたことが原因です。#112131 (groeneai)。 ONexpression に定数の連言を含むJOIN(例:ON l.id = r.id AND CAST(NULL AS Nullable(UInt8)))が誤った結果を返す問題を修正しました。クエリプランの最適化によってこの定数が暗黙的に削除され、結合はその条件が存在しないものとして実行されていました。そのため、決して真にならない条件であれば行を返さないはずのところ、INNER、LEFT SEMI、RIGHT SEMI結合が一致した行を返し、RIGHT ANTIはすべての行を返すべきところで 1 行も返していませんでした。#112155 (vdimir)。- パラメーター化ビューが
parameter = value形式の代入ではない引数で呼び出された場合に、誤った結果が返される問題を修正しました。enable_analyzer = 0の場合、およびデフォルト設定でのEXPLAIN SYNTAXにおいて、pv(concat(name, '!'))、pv(name, 'a')、pv(name != 'a')、pv(tuple(name = 'a'))のような呼び出しは、アナライザのようにUNKNOWN_QUERY_PARAMETERを報告せず、ビューのパラメータを無関係な expression に暗黙的に束縛していました。現在は、このような呼び出しはどちらの実行パスでも同じように拒否されます。#112194 (groeneai)。 substringの文法で再パースできない形式でsubstr、mid、byteSliceを呼び出す定義を持つCREATE VIEWまたはCREATE FUNCTIONが受け付けられてしまい、ClickHouse が書き込むメタデータが有効な SQL にならないバグを修正しました。この定義を後から読み込むとSYNTAX_ERRORで失敗し、サーバー起動時にはメタデータの読み込みが中断されるため、サーバーがまったく起動できなくなっていました。このような定義は正しく往復変換されるようになり、substring(x, a, b, c)形式の既存のメタデータファイルも再び読み込めるようになったため、影響を受けたサーバーも手動で対応することなく起動できます。#112195 (groeneai)。- 主キーが
ArrayまたはTupleで、クエリがそれにplus、minus、multiply、divide、intDivを適用する場合に、誤った結果、ORDER BYの出力順序の誤り、およびBAD_TYPE_OF_FIELD例外が発生する問題を修正しました。複合値に対する算術演算は要素ごとに評価される一方、複合値の比較は辞書順で行われるため、主キー解析ではこのような式を単調とみなさないようになりました。#112339 (groeneai)。 - 左テーブルが
Distributedテーブルまたは*Clusterテーブル関数である場合など、PASTE JOINを含むクエリが別のサーバーに送信される際に、リモートサーバーでCode: 62 ... You must not specify ANY or ALL for PASTE JOIN. (SYNTAX_ERROR)が発生する問題を修正しました。フォーマッタがパーサーで受け付けられない表記ALL PASTE JOINを出力していたため、受信側のサーバーが送られてきたクエリをパースできませんでした。#112404 (groeneai)。 (SELECT 1) AS t(x)やWITH t(x) AS (SELECT 1)のようなカラムエイリアスリストがviewテーブル関数内で参照できず、viewの外では同じ構文が動作するにもかかわらず、t.xへの参照がUNKNOWN_IDENTIFIERで失敗する問題を修正しました。#112690 (groeneai)。ARRAY JOIN句に式が含まれない場合に、クエリのフォーマット処理で論理エラーが発生する問題を修正しました。このような句は、受け付けられた後にパースし直せないテキストへフォーマットされるのではなく、空のUSINGと同様にパース時点でSYNTAX_ERRORとして拒否されるようになりました。#112699 (groeneai)。- サブクエリ用に準備された式アクションが、ビルド時のコンテキストが解放された後に実行されると、
connectionIdがContext has expiredをスローする問題を修正しました。#112870 (clickgapai)。 - 結合中に評価される非等価の
JOIN ON条件にarrayJoinが含まれる場合に、論理エラーや誤った結果が発生する問題を修正しました。hash、parallel_hash、grace_hashの結合では、このような条件をINVALID_JOIN_ON_EXPRESSIONで拒否するようになりました。展開が片側のみに依存する場合は、結合前のサブクエリ内でARRAY JOINに置き換えてください。arrayJoinの引数が両側のカラムを参照する条件については、クエリの構造を見直す必要があります。#112889 (groeneai)。 geohashesInBox(0., 0., 180., 0., 12)のような面積ゼロのボックスに対して、geohashesInBoxの処理時間が際限なく長くなる問題を修正しました。このようなクエリは正しい geohash を 1 つ返すものの、1 行あたり約 5e8 回の空ループを実行し、max_execution_timeとKILL QUERYのいずれも効きませんでした。#112976 (groeneai)。- 値なしで記述されたものとしてマークされた
SETTINGSの変更がtrue以外の値を持つ場合は拒否し、またクエリのフォーマット時にそのような変更の値を省略しないようにしました。以前は、細工された AST JSON ペイロードによって、system.query_logやformatQueryFromJSONには値なしの形式が表示される一方で、Bool設定が実際にはfalseとして実行される可能性がありました。#113025 (alexey-milovidov)。 - 宣言されたカラム型が内部クエリの生成する型と異なる
VIEWから SELECT する際に発生するUNKNOWN_IDENTIFIERを修正しました。例えば、vがStringカラムに対してarr Array(UInt8)を宣言している場合のSELECT sum(length(arr)) FROM vなどが該当します。デフォルトのoptimize_functions_to_subcolumns = 1では、オプティマイザがlength(arr)をarr.size0サブカラムの読み取りに書き換え、その名前を内部クエリに渡していましたが、内部クエリにはそのようなサブカラムが存在しませんでした。#113057 (groeneai)。 postgresqlテーブル関数および PostgreSQL エンジンによる読み取りのキャンセルを修正しました。読み取りの開始処理中にキャンセルするとトランザクションポインタで競合が発生する可能性があり、さらにキャンセル自体が失われて、PostgreSQL が処理を終えるまでクエリが実行され続けることがありました。なお、COPYステートメントの実行開始前に PostgreSQL に届いたキャンセルは、引き続き破棄される場合があります。#113150 (groeneai)。- クラスターテーブル関数 (
s3Cluster、urlCluster、fileCluster) を参照するSQL SECURITY DEFINERまたはSQL SECURITY NONEビューが、remoteやclusterAllReplicasなどを経由してセカンダリクエリとして読み取られた際に発生するLOGICAL_ERROR(Next task callback is not set for query) を修正しました。サポートされていないこのネストは、debug ビルドや sanitizer ビルドでサーバーを異常終了させるのではなく、通常のクエリエラーとして拒否されるようになりました。#113371 (groeneai)。 analyzer_compatibility_join_using_top_level_identifier = 1の設定下で、view(...)引数を持つ remote 系テーブル関数を、キーがSELECTリストの別名であるJOIN ... USINGの左側で使用した場合に発生する論理エラーIDENTIFIER is not a table expressionを修正しました。#113400 (groeneai)。indexHint内のサブクエリを用いてsystem.databasesをnameカラムでフィルタリングするクエリ (例:SELECT count() FROM system.databases WHERE indexHint(name IN (SELECT 'foo'))) で発生するNot-ready Set is passed as the second argument for function 'in'を修正しました。このようなクエリは、リリースビルドではLOGICAL_ERRORで拒否され、debug ビルドや sanitizer ビルドではサーバーが異常終了していました。#113556 (groeneai)。Variantカラムに対するクエリがmax_execution_timeおよびKILL QUERYを無視する問題を修正しました。複数のVariant引数を持つ関数を呼び出すと、各引数のすべての候補型ごとに関数の解決が行われますが、この処理を行う 2 つのループのいずれもキャンセルを確認していなかったため、そのようなクエリは完了するまで停止できませんでした。#113612 (groeneai)。- 1 つのステートメントで
ALIASカラムを物理カラム (DEFAULTまたはMATERIALIZED) に変換すると同時にCODECを指定した場合に、ALTER TABLE ... MODIFY COLUMNがCannot specify codec for column type ALIASで失敗する問題を修正しました。#113853 (groeneai)。 ARRAY JOINを含む右側に対して定数のON式で結合した際に発生するサーバークラッシュを修正しました。遅延レプリケートされた右側カラムの読み取り時に、解放済みのColumnReplicatedを使用していました。#113901 (groeneai)。- テーブルの sorting key が
GROUP BYキーの真のプレフィックスであり、かつquantileDDのように状態がヒープメモリを保持する集約関数を使用している場合に、optimize_aggregation_in_order = 1でメモリリークが発生する問題を修正しました。このようなクエリを実行するたびに、再起動するまでサーバーのメモリ使用量が増え続けていました。#114010 (groeneai)。 UInt128/UInt256に対するisProbablePrimeがmax_execution_timeおよびKILL QUERYを無視する問題を修正しました。幅の広い値のブロックが、キャンセルポイントのない単一の関数呼び出し内で最後まで処理されるため、クエリが期限を過ぎても数分間実行され続けることがありました。#114032 (groeneai)。PREWHERE句にIN (subquery)述語が含まれ、かつrewrite_in_to_join = 1(またはこれを強制的に有効化するmake_distributed_plan = 1) が設定されている場合に、Code: 46. DB::Exception: Unknown function exists. (UNKNOWN_FUNCTION)がスローされる問題を修正しました。同じクエリをWHEREで記述した場合は正しく動作していました。#114067 (RohithPariki)。- 引数が要素型
Nothingの空でない配列である場合 (例:SELECT arrayAutocorrelation([arrayMax([])])) に、arrayAutocorrelationでLOGICAL_ERRORが発生する問題を修正しました。このような引数はILLEGAL_COLUMNで拒否されるようになりました。空の配列リテラル[]は引き続き[]を返します。#114249 (groeneai)。 CREATE TABLEおよびALTER TABLEで、sorting key に使用されるカラムにSZ3などの非可逆コーデックを指定すると拒否されるようになりました。#114531 (groeneai)。- インターバル引数の秒単位の長さが 2^32 の倍数である場合 (例:
toIntervalDay(2147483648)) に、関数hopおよびwindowIDでキャンセル不可能な無限ループが発生する問題を修正しました。減算がラップアラウンドすることで時間のオーバーフローチェックをすり抜けており、引数が定数の場合はループが解析時に実行されるため、クエリを kill することすらできませんでした。また、同じインターバルによってWINDOW VIEWのバックグラウンドスレッドが永久に空回りすることもありました。このような window view は作成時に拒否されるようになりました。#114607 (alexey-milovidov)。 - リモートクラスタから読み取る
INサブクエリを含むクエリで、論理エラーNot-ready Set is passed as the second argument for function 'in'が発生する問題を修正しました。今後は、接続失敗など、サブクエリで実際に発生したエラーでクエリが失敗するようになります。#114983 (alexey-milovidov)。 Log、TinyLog、またはStripeLogテーブルへのINSERTが、記録済みファイルサイズのコミット中に失敗した場合の問題を修正しました。このような挿入では、エラーが報告されたにもかかわらず行がテーブルに残ったり、Array カラムのデータファイル間で不整合が生じたりすることがありました。また、Array カラムに要素がないにもかかわらずオフセットが要素の存在を示しているLogまたはTinyLogテーブルを読み取ると、要素の末尾を越えて読み取るのではなく、該当カラム名を含むエラーが発生するようになりました。部分的に書き込まれた要素カラムについては、以前から拒否されていました。#115027 (groeneai)。has([map('k', 'v')], m)のようにArray(Map(...))型の定数を含むクエリを、Distributedテーブルに対して、または並列レプリカを使用して実行した場合に、TYPE_MISMATCH(“CAST AS Array can only be performed between same-dimensional array types”) が発生する問題を修正しました。#115883 (alexey-milovidov)。- ビューまたは
view()との結合時に、射影されたカラムがその内部リレーションのいずれかのカラムと同名である場合 (例:SELECT expr(x.c0) AS c0 FROM a AS x, b AS y) 、誤った結果が返される問題を修正しました。join order optimizer がこのような expression をフラット化された結合グラフにマージしたうえで二重に適用していたため、クエリはエラーを出さないまま偏った値を返していました。expression がカラムの型も変更する場合は、同じ原因によりプラン作成時にAMBIGUOUS_COLUMN_NAMEが発生していました。#116152 (groeneai). - ROLLUP/CUBE と
group_by_use_nullsを併用した際に外部カラムがNullableになると、相関サブクエリで例外が発生する問題を修正しました。#100365 (alexey-milovidov). Replicatedデータベースでmax_replication_lag_to_enqueue = 0を拒否するようにしました。この値を指定すると、リカバリ後の未同期チェックが常に真となり、デバッグビルドおよびサニタイザービルドでサーバーがLOGICAL_ERRORにより異常終了していました。現在は、あらゆる指定元 (CREATE DATABASE ... SETTINGS、サーバー設定の<database_replicated>ブロック、ATTACHのリプレイ、アップグレード時の既存メタデータのリプレイ) で指定された0が、パース時にBAD_ARGUMENTSとして拒否されます。有効な最小値は1です。#106006 (groeneai).- 型が混在した配列の挿入時に NO_COMMON_TYPE 例外が発生するのを防ぐため、JSON (Object) カラムに対する minmax スキップ索引の作成を禁止しました。代わりに型付きサブカラムを使用してください (例:
INDEX idx json.field TYPE minmax) 。#106094 (linhaojie). - Dynamic 型の引数を渡した場合に、
JSON_QUERY/JSON_VALUE/JSON_EXISTSが String/UInt8 ではなく Dynamic を返す問題を修正しました。#106877 (Avogar). interactive_delayなどの待機タイムアウト設定に極端に大きな値を指定した場合に発生する符号付き整数オーバーフローを修正しました。この問題により、待機せずに即座にタイムアウトしたり、Undefined Behavior Sanitizer 環境下でサーバーが異常終了したりすることがありました。#106961 (groeneai).geohashesInBox関数で、座標引数に定数値と非定数値が混在している場合、または座標がBFloat16の場合にLOGICAL_ERROR(“Unsupported argument types”) が発生する問題を修正しました。定数と非定数が混在したFloat32引数が正しく動作するようになり、BFloat16引数は明確なエラーメッセージとともに拒否されるようになりました。#107063 (groeneai).output_format_csv_serialize_tuple_into_separate_columnsが有効な場合 (デフォルト) に、CSVWithNamesおよびCSVWithNamesAndTypesのヘッダーのカラム数がデータより少なくなる問題を修正しました。ヘッダー (および型の行) ではTupleカラムがドット区切りの名前 (例:t.a、t.b) を持つリーフフィールドに展開されるようになり、ヘッダーのカラム数がデータと一致します。この動作は新しい設定output_format_csv_header_serialize_tuple_into_separate_columns(デフォルトは1) で制御でき、0に設定すると従来の単一名のヘッダーに戻せます。#107371 (groeneai).- 同梱の
mongo-c-driverで、MongoDB からの読み取り時 (例: MongoDB ディクショナリやmongodbテーブル関数の使用時) に、再試行可能な読み取りエラーの後、再試行用のサーバー選択に失敗した場合に発生し得るメモリリークを修正しました。#107448 (groeneai). pointInPolygonがVariantやDynamicなどのラッパー型の定数ポリゴン引数で呼び出された場合 (例:pointInPolygon((x, y), if(c, [(0, 0), ...], NULL))) に、プライマリキー解析中に論理エラー (WhichDataType(const_type).isArray()) が発生してサーバーが異常終了する問題を修正しました。#107589 (groeneai)。VariantおよびDynamicカラム内にネストされたLowCardinalityの除去処理に一貫性がなかったため、concat、format、プライマリキー解析などで論理エラー (Bad cast) が発生する問題を修正しました。#107773 (Avogar)。- 実行可能なユーザー定義関数のコマンドパラメータのパース処理を修正し、名前が空または無効なプレースホルダーをパラメータとして受け付けないようにしました。#107983 (goutamadwant)。
- 要素が
Dynamic/VariantであるTupleに対するaccurateCastOrNullで、ソース側の本来のNULLが変換失敗として扱われていた問題を修正しました。ターゲット要素がNullableの場合、ソースのNULLは要素のNULLとしてそのまま維持されるようになりました (通常のTuple(Nullable(...))ソースと同じ動作) 。ターゲット要素がNullableでない場合、ソースのNULLは要素のデフォルト値を生成するのではなく、タプル全体を NULL にするようになりました (Dynamicを含まない場合の基準動作と同じ) 。パースやオーバーフローに失敗した場合は、従来どおりタプル全体が NULL になります。#108023 (groeneai)。 mongodbテーブル関数で、名前付き引数として渡されたoid_columns(例:oid_columns='_id') がBAD_ARGUMENTSで拒否されず、正しく受け付けられるようになりました。#108039 (alexey-milovidov)。DateTime64、Decimal、または浮動小数点の範囲を使用するrange_hashedまたはcomplex_key_range_hashedDictionary に対して、対応する型の引数をdictGet/dictHasに渡してクエリできるようになりました。以前はこのようなクエリがmust be convertible to Int64で失敗していたほか、Decimal/DateTime64の範囲で上限または下限のない区間に対して誤ってデフォルト値が返されていました。#108052 (alexey-milovidov)。accurateCastOrNullでArray(Dynamic)またはArray(Variant)をQBitにキャストする際 (例:accurateCastOrNull(CAST(range(114), 'Array(Dynamic)'), 'QBit(Float32, 114)')) に、サーバーが異常終了する問題 (IColumn::insertFromにおけるLogical error) を修正しました。#108288 (groeneai)。- 不正な形式または同期のずれたネイティブ TCP プロトコルストリームによって発生する可能性のあるサーバークラッシュ (
Received signal 4、不正命令) を修正しました。ClientInfoのinitial_addressフィールドは、パース前に数値形式のhost:portであるかを検証するようになり、数値でないポートがトラップ対象の libc 関数getservbynameに渡されることはなくなりました。#108410 (groeneai)。 mannWhitneyUTest、rankCorr、largestTriangleThreeBuckets、quantileGK、sequenceMatch/sequenceCount、groupArrayIntersectの細工された集約関数ステートをデシリアライズする際に、過剰なメモリ割り当てが発生する問題を修正しました。不正なステートが巨大な要素数を宣言すると、わずか数バイトの入力からサーバーが数十ギガバイトものメモリを割り当てようとする可能性がありました。現在、このようなステートはTOO_LARGE_ARRAY_SIZEで拒否されます。#108465 (groeneai)。GROUPING SETS/ROLLUP/CUBEでLowCardinalityの定数グルーピングキーとgroup_by_use_nullsを併用した場合に発生する論理エラー (Bad cast from type DB::ColumnNullable to DB::ColumnString) と、誤った結果が返される可能性がある問題を修正しました。#108771 (alexey-milovidov).Mapの値にLowCardinalityを含むネストされたMapがある場合 (例:mapFilter((k, v) -> 1, map('a'::LowCardinality(String), map('x'::LowCardinality(String), 'y')))) に、mapFilter、mapSort、mapReverseSort、mapPartialSort、mapConcatでTYPE_MISMATCHが発生する問題を修正しました。#108798 (groeneai).- 名前付き要素と名前なし要素が混在する
Tupleデータ型 (例:Tuple(a UInt8, UInt16)) をフォーマットする際にLOGICAL_ERROR(“Inconsistent AST formatting”) が発生し、debug ビルドおよび sanitizer ビルドでサーバーが異常終了する問題を修正しました。#108915 (groeneai). JSONExtractで文字列の JSON 値をDateTime/DateTime64に変換する際、CASTと同様にcast_string_to_date_time_modeが適用されるようになりました。#109252 (Utkal059).- 右側の引数に配列カラムを直接指定した
INが、誤った結果 (常に false) を警告なく返す、または例外をスローする問題を修正しました。これにより、x IN arrはhas(arr, x)と同様に動作します。#109416 (alexey-milovidov). - 非定数の
Array(LowCardinality(T))引数に対してarrayFoldを使用した場合 (例:arrayFold((acc, x) -> acc + x, materialize([1, 2, 3]::Array(LowCardinality(Int64))), toInt64(0))) に、“Arguments of ‘plus’ have incorrect data types” で失敗するLOGICAL_ERROR(debug ビルドおよび sanitizer ビルドではサーバーが異常終了) を修正しました。#109462 (groeneai). FixedString引数をStringに正しくキャストするようにし、convで発生するILLEGAL_COLUMN例外を修正しました。#109771 (hp77-creator).serialize_query_plan = 1の場合に、FINAL/SAMPLEを指定したテーブル関数の読み取りが誤った結果を返す問題を修正しました。また、テーブル関数に対する集約ハッシュテーブル統計キャッシュのキーも修正しました (以前はすべてのテーブル関数が 1 つの事前割り当てエントリを共有していました) 。#109847 (azat).- コンテナ型 (例:
Array(Bool)、Tuple(Bool, ...)) 内で数値の1/0をBool値としてパースできるよう修正しました。以前は[true,false]は動作する一方、[1,0]はCANNOT_READ_ARRAY_FROM_TEXTで失敗していました。#109976 (groeneai). Array(LowCardinality(Nullable(String)))(この形式で格納されたNestedフィールドを含む) にtext索引を構築し、索引対象の配列にNULL要素が含まれる場合に発生するNOT_IMPLEMENTEDエラー (Method getDataAt is not supported for Nullable(String) in case if value is NULL) を修正しました。Array(Nullable(String))と同様に、索引構築時にはNULLの配列要素がスキップされるようになりました。#110055 (groeneai).- 小さい表現のまま保持されている bitmap に対して、
subBitmap、bitmapSubsetInRange、bitmapSubsetLimitが誤った結果を返す問題を修正しました。2^32を超えるUInt64およびInt64の要素値が 32 ビットに切り詰められていたケースも含まれます。符号付き要素型に対する bitmap 関数での比較では、要素型の符号なし値が一貫して使用されるようになりました。そのため、Int8の bitmap では、要素-1は符号拡張された4294967295ではなく255として比較されます。この変更により、小さい表現を超えて拡張された bitmap に対するbitmapMin、bitmapMax、bitmapContains、bitmapTransformの問題も解消されます。符号拡張されたしきい値を渡していたクエリは修正が必要です。たとえばInt8の bitmap では、bitmapSubsetInRange(bm, 4294967168, 4294967296)をbitmapSubsetInRange(bm, 128, 256)に変更してください。また、groupNumericIndexedVectorがInt8およびInt16の索引カラムに対して、より幅の広い索引タイプとは異なる結果を返す問題と、numericIndexedVectorGetValueが負の索引に対して0を返す問題も修正しました。あわせて bitmap 関数のドキュメントも修正し、1 始まりのインデックスを使用すると誤って記載されていた subset 関数の説明や、符号付き型に対するbitmapBuild/bitmapToArrayのサポートに関する記述を訂正しました。#110072 (RamiDarwiche)。 - インターバル種別の
WITH FILL STEP、および極端な差分を指定したadd*/subtract*日付・時刻インターバル関数において、インターバル演算で未定義の符号付きオーバーフローが発生し得る箇所を修正しました。これにより、極端なインターバル値でも符号付きオーバーフローに依存せず、決定論的な結果が得られるようになりました。また、巨大なYEARステップを指定したインターバル種別のWITH FILLで、カレンダーが逆方向に進んで処理が停止する問題も修正しました。#110158 (groeneai)。 - 複数のキーでグループ化し、ソート順がグループ化キーのプレフィックスにすぎない場合に、順序付き集約の処理時間が二次関数的に増大する (さらに
max_execution_timeが効かなくなる) 問題を修正しました。#110159 (alexey-milovidov)。 - オペランドに最小共通スーパータイプが存在しない場合に、比較で
ILLEGAL_TYPE_OF_ARGUMENTがスローされていた問題を修正しました。Array(Int64)とArray(UInt64)、Array(Int256)とArray(UInt256)などの Array を、=、!=、<、<=、>、>=、IS DISTINCT FROM、IS NOT DISTINCT FROMを使って辞書式順序で比較できるようになりました。isDistinctFrom/isNotDistinctFromなどの NULL セーフな比較でも、サポート対象の配列以外の数値型または decimal 型の組み合わせについて、例外をスローせずに値で比較するようになりました。さらに、ネストされたTuple(Nullable(...))要素を持つ Array でも等価比較が可能になりました。#110245 (diegomestre2)。 - 負のオフセットを持つタイムゾーンで、極端な
DateTime64値 (例:INT64_MIN) をTime/Time64に変換する際に発生する符号付き整数オーバーフロー (UBSan) を修正しました。#110451 (groeneai)。 - 範囲外の浮動小数点値 (
BFloat16、Float32、Float64) およびInt64::max()を超えるUInt64値をDateTimeやTimeに変換した場合、すべてのアーキテクチャで確実に範囲の境界値へ飽和するようになりました (以前は範囲外の変換結果がアーキテクチャに依存しており、x86-64 ではラップアラウンドすることがありました) 。また、非有限値 (NaN、inf) は不定の結果を返すのではなく、例外をスローするようになりました。同様の修正は、toDateにおける浮動小数点からDateへの変換経路、およびUInt64やワイド整数 ((U)Int128、(U)Int256) からDateおよびDate32への変換にも適用されています。これらの変換では、飽和せずにエポック以前の日付が返される場合がありました。数値からTimeへの変換は、すべての数値ソース型で型の範囲内に飽和するようになりました (以前は、幅の狭い符号なし整数やワイド整数からの値はクランプされないまま格納され、出力時にのみクランプされていました) 。さらに、Timeへの厳密なキャストでは、Timeがサポートする負の値が拒否されなくなり、収まらない値が暗黙的に飽和されることもなくなりました。数値からDate32への厳密なキャスト (accurateCast、accurateCastOrNull) では、範囲外または非有限の値が暗黙的に飽和されなくなり、DateやDateTimeと同様に例外をスローするかNULLを返すようになりました。また、OrDefault系の関数は、そのような入力に対してDate32のデフォルト値を返します。整数でない浮動小数点数からDate、Date32、DateTime、Timeへの厳密なキャストは、暗黙的に切り捨てられるのではなく、拒否されるようになりました。あわせて、toDateTime32関数のドキュメントで、誤ってtoDateTime64の例が掲載され、DateTime64の値の範囲が説明されていた問題も修正しました。#110459 (alexey-milovidov). - Map のキーが Dictionary エンコードされた ORC ファイル (Spark が書き出した ORC ファイルや、
output_format_orc_dictionary_key_size_thresholdを有効にして ClickHouse 自身が書き出したファイルを含む) を読み込む際に、スキーマ推論がMap cannot have a key of type LowCardinality(Nullable(String))というエラーで失敗する問題を修正しました。#110492 (tiandiwonder). optimize_or_like_chainが有効な状態で、ORチェーン内のLIKE/ILIKE/matchの左辺に集約関数またはウィンドウ関数が含まれている場合に発生することがあった論理エラー (Function node with name '...' is not resolved as ordinary function) を修正しました。#110641 (groeneai).Date/Date32/DateTime64値に対して極端なMONTH、WEEK、DAYのインターバル数を指定すると、toStartOfIntervalで符号付き整数オーバーフローが発生する問題を修正しました。#110688 (groeneai).readWKTおよびreadWKTPointがPOINT EMPTYに対して、未初期化の座標 (スカラー版) または前の行の古い座標 (ベクトル化版) を返す問題を修正しました。ClickHouse のPointは空の表現を持たない固定のTuple(Float64, Float64)であるため、POINT EMPTYはCANNOT_PARSE_TEXTエラーで拒否されるようになりました。#110692 (groeneai).flipCoordinatesでGeometry型が失われる問題を修正しました。Geometry型の引数を渡した場合、結果は内部のVariant(...)ではなく再びGeometry型になるため、areaCartesianなどの関数に直接渡せるようになりました。#110694 (groeneai).- 空のポリゴンの WKB シリアライゼーションが標準形式になっていなかった問題を修正しました。
wkb(POLYGON EMPTY)は、余分な点数ゼロのリングを 1 つ出力する代わりにnumRings = 0を出力するようになったため、標準的な空ポリゴンを WKB で往復変換しても同一性が保たれるようになりました。#110796 (groeneai). - JSON の
Boolパースにおける数値の1/0が、allow_special_bool_values設定に従うようになりました。従来は JSON のBoolパーサーがこの設定を無視しており、さらにBoolは整数型よりもVariantのデシリアライズ優先度が高いため、allow_special_bool_values_inside_variant = 0であっても、Variant(Bool, UInt32)に対する{"v":1}のような JSON 入力がBoolとして読み込まれていました。#110835 (groeneai). colがLowCardinalityの場合に、throwIf(notLike(col, pattern))(および関数を引数に取るその他のthrowIf)が無条件に例外をスローする問題を修正しました。デフォルトのLowCardinality実装では辞書全体に対してthrowIfを実行していましたが、辞書にはそれを参照する行がなくても予約済みのデフォルト値が常に含まれています。そのため、この未使用スロットに 0 以外の値があると、条件を満たさないデータに対してもthrowIfが例外をスローしていました。#110864 (groeneai).-Tupleコンビネータ付きの集約関数をRESPECT NULLSとともに使用し、中間ステート(-State、分散集約、WITH ROLLUP/WITH CUBE)を生成した場合に発生するクラッシュを修正しました。結合後の関数名が誤ったステートのバリアントに基づいて付けられていたため、シリアル化されたAggregateFunction型がラウンドトリップ時に互換性のないメモリ内レイアウトとして再解決されていました。#110930 (groeneai).mysqlテーブル関数、またはMySQLテーブル/データベースエンジンを介して Nullable な MySQL 空間カラム(LINESTRING、POLYGON、MULTILINESTRING、MULTIPOLYGON、MULTIPOINT、または汎用のGEOMETRY)を読み込む際に発生するNested type LineString cannot be inside Nullable type (ILLEGAL_TYPE_OF_ARGUMENT)エラーを修正しました。このようなカラムは、MySQL が返す値(4 バイトの SRID プレフィックスと、それに続く WKB ペイロード)をそのまま保持するNullable(String)にフォールバックするようになりました。POINTは引き続きNullable(Point)にマッピングされます。#110943 (groeneai).- 旧バージョンのピア向けに、バージョン付き集約状態を含む
SimpleAggregateFunctionラッパーをNative形式でシリアライズする処理を修正しました。#110997 (groeneai). - 分散クエリおよび並列レプリカを使用するクエリにおいて、
Variant型(Geometryを含む)の定数で発生するCANNOT_CONVERT_TYPEエラーを修正しました。#111136 (fm4v). - 高階関数のラムダ本体が、
Boolリテラルの分岐とUInt8比較の分岐が混在する定数条件のif/multiIfである場合(例:arrayFilter(p -> multiIf(false, true, p = 'ALL'), ['ALL']))に発生するLOGICAL_ERROR(“Lambda resolved type … is not equal to type from actions DAG …”)を修正しました。#111245 (groeneai). - サブ秒単位のインターバルを指定した
toStartOfIntervalにおける符号付き整数オーバーフローを修正しました。Int64の下限から 1 インターバル以内にあるDateTime64値では、丸め結果が何の警告もなくラップアラウンドし、無意味な正の値になっていました。現在はDECIMAL_OVERFLOW例外をスローします。#111370 (alexey-milovidov). - ネストされたコンビネータ内で
-TupleコンビネータをRESPECT NULLS/IGNORE NULLS修飾子とともに使用する分散クエリ(例:anyRespectNullsStateTuple(...) IGNORE NULLS)で発生する例外(CANNOT_CONVERT_TYPEまたは論理エラー)を修正しました。#111570 (alexey-milovidov). - パースに失敗した際に、部分的に追加されたバイトがカラムに残ってしまう
FixedStringのテキスト try-parse の問題を修正しました。この問題により、Variant/Array/Nullableカラムのシリアライゼーション中にSizes of nested column and null map of Nullable column are not equalという論理エラーが発生したり、結果のバイトが気付かないうちにずれたりする可能性がありました。#111908 (groeneai)。 Bufferテーブル経由で動的サブカラム (JSONカラムまたはDynamicカラム内のパス) を読み取る際に、例外が発生したり、データが警告なしにスキップされたりする問題を修正しました。#111948 (alexey-milovidov)。countSubstringsCaseInsensitiveUTF8の計算量が二次関数的に増加する問題を修正しました。これにより、数メガバイトの haystack に多数のマッチがある場合、関数の実行に数分かかっていました。各マッチの文字オフセットは、行の先頭から数え直すのではなく、インクリメンタルに保持されるようになりました。#112003 (groeneai)。toStartOfIntervalの 3 引数オーバーロードにおける符号付き整数オーバーフローを修正しました。origin引数がInt64の下限付近の値である場合、関数はエラーを報告せず、ラップアラウンドした値を返していました。#112045 (alexey-milovidov)。- テーブル関数のパラメータでの集約状態の使用を禁止しました。この用途は一切サポートされていないためです。#112087 (PedroTadim)。
valuesテーブル関数で、String/テキスト系カラムに挿入された非リテラルのBool定数 (例:CAST(true, 'Nullable(Bool)')) がtrue/falseではなく1/0として出力される問題を修正しました。#112308 (yakov-olkhovskiy)。- ステート表現は共通でも確定後の型が異なる別々の関数に由来する集約状態を含むカラムに対して
finalizeAggregationを適用すると、論理エラー (debug ビルドおよび sanitizer ビルドではアボート) が発生する問題を修正しました。たとえば、UNIONでまとめられた、あるいはarrayReduceで生成されたquantileStateとquantilesState(0.9)が該当します。このようなクエリは、クラッシュせずに通常のエラーを返すようになりました。#112662 (zainulabidin302)。 - JSON の数値の読み取りに使用される
Poco::NumberParserで、変換先の型に収まらない整数のパースを修正しました。このような数値は拒否されずに、警告なしで誤った値としてパースされていました (例:18446744073709551617が1になる) 。また、Int64の最大値を超えるUInt64の数値が、AST の JSON ラウンドトリップで正しく保持されていませんでした。#112904 (alexey-milovidov)。 INの右辺にあるBool定数がString型の左辺に合わせて変換される際、正規の'true'/'false'ではなく'1'/'0'に変換される問題を修正しました (CASTおよびvaluesテーブル関数と一貫した動作になりました) 。#113051 (yakov-olkhovskiy)。viewIfPermittedの AST フォーマットにおける不整合を修正しました。具体的には、テーブル関数形式のELSE分岐内にある、通常は演算子として記述される関数 (例:not) に関する問題と、expression 形式のviewIfPermitted(...)が誤ってELSE付きでフォーマットされる問題です。#113652 (alexey-milovidov)。Date/DateTime/DateTime64/Time/Time64に対するavgで発生していた未定義動作と誤った結果を修正しました。平均値は整数空間で正確に計算されるようになり、Int64の境界でのオーバーフロー (UB、x86 上で誤った結果になる) と、2^53 を超える値でのFloat64の精度低下 (ナノ秒スケールで顕在化) の両方が解消されました。#113912 (alexey-milovidov).- 実験的な
SZ3圧縮コーデックにおけるメモリリークを修正しました。圧縮しにくいデータや破損したデータの圧縮が例外で失敗した場合に、一時的なスクラッチバッファが解放されずに残っていました。#113916 (alexey-milovidov). bloom_filter索引に対してFixedString定数でクエリを実行した場合に、hasAny、hasAll、has、indexOf、mapContainsKey、mapContainsValue、mapContainsが本来より少ない行しか返さない、またはTOO_LARGE_STRING_SIZEで失敗する問題を修正しました。索引ではパディング済みの定数をハッシュ化していた一方、関数はパディングされていない定数で比較していたため、一致するグラニュールがスキップされていました。#114089 (alexey-milovidov).- 集約が JIT コンパイルされ、かつデータに 1970 年より前のタイムスタンプが含まれる場合に、
DateTime64カラムに対するminとmaxが誤った結果を返す問題を修正しました。Decimal64から派生するDateTime64とTime64に対してis_signedが特殊化されていなかったため、生成されたコードがティック数を符号なし整数として比較してしまい、1970 年より前のタイムスタンプがmaxでは選ばれ、minでは選ばれないという状態になっていました。#114168 (groeneai). - 配列要素と検索文字列の文字列型が異なる場合 (例:
Array(FixedString(N))の要素に対してStringの検索文字列を使用する場合) に、arrayExists(x -> x = needle, arr)が誤った結果を返す、またはTOO_LARGE_STRING_SIZEで失敗する問題を修正しました。デフォルトで有効なoptimize_rewrite_array_exists_to_has最適化によってこのような呼び出しがhasに書き換えられていましたが、hasは=とは異なり、ゼロパディングを考慮した比較を行いません。#114496 (groeneai). - Map または JSON コンテナーに対して使用される
LIKE/ILIKEオペレーターのテキスト索引評価を修正しました。#114544 (ahmadov). DateTime64および幅の広いDecimal値に対するquantileとquantilesで発生していた未定義動作と、境界値での誤った結果を修正しました。#114919 (alexey-milovidov).Timeの分岐がTime64、DateTime、またはDateTime64と組み合わされ、かつ expression が JIT コンパイルされた場合に、ifとmultiIfが負の値ではなく大きな正の値を返す問題を修正しました。#115146 (groeneai).- 国際日付変更線をまたいだ後の
Pacific/KiritimatiやPacific/Apiaのように、UTC オフセットが 1970-01-01 時点のオフセットとちょうど 1 日分異なるタイムゾーン、および 1970 年より前のほとんどのタイムゾーンにおいて、timezoneOffset(エイリアスtimeZoneOffset) がちょうど 1 日ずれたオフセットを返す問題を修正しました。この修正により、このオフセットを使用するparseDateTime、parseDateTimeOrNull、parseDateTime64、parseDateTimeInJodaSyntax、EXTRACT(TIMEZONE_HOUR / TIMEZONE_MINUTE ...)、formatDateTimeの%z、toUTCTimestamp、fromUTCTimestampの問題も解消されます。#115332 (groeneai). - 主キーが
String、Array(String)、またはMap(String, String)で、hasまたはnotHasの述語に NULL の配列要素が含まれている場合にCode: 349. Cannot convert NULL value to non-Nullable typeが発生する問題を修正しました。また、その要素が NULL を保持するDynamicまたはVariantである場合に誤った結果が返される問題も修正しました。キー解析時には、他のキー型と同様に NULL が Set から除外されるようになりました。#115647 (groeneai)。 - 変換先の型が
LowCardinalityの場合に、cast_keep_nullableが Nullable 性を保持しない問題を修正しました。これまでは、NULL を取り得る値をLowCardinality(T)に CAST すると、LowCardinality(Nullable(T))が生成されずにCANNOT_INSERT_NULL_IN_ORDINARY_COLUMNがスローされていました。#115851 (groeneai)。
索引およびクエリキャッシュの修正
DEFAULTexpression を持ち、パーツ内でマテリアライズされていないカラム (例:ALTER TABLE ADD COLUMNの実行後やALTER TABLE MATERIALIZE COLUMNの実行中) のサブカラムの読み取りを修正しました。これまでは、サブカラムが評価済みのDEFAULTexpression ではなく型のデフォルト値で埋められていたほか、そのようなQBitカラムに対する転置ベクトル距離関数 (cosineDistanceTransposedなど) がSIZES_OF_ARRAYS_DONT_MATCHエラーで失敗していました。#110636 (alexey-milovidov).- 主キー解析中に
INサブクエリのセット構築が通知なく失敗した場合 (例:overflow_mode = 'break'指定時のサブクエリのタイムアウト) 、クエリパイプライン用のセットが未構築のまま残り、Not-ready Set is passed as the second argument例外が発生することがある問題を修正しました。#107924 (alexey-milovidov). setデータスキップ索引を持つテーブルに対し、常に真となる条件と索引のないカラムに対するチェックを組み合わせた行ポリシーでフィルタすると、SELECTがNOT_FOUND_COLUMN_IN_BLOCKで失敗する問題を修正しました。#107971 (tiandiwonder).getClientHTTPHeaderが正しく非決定的関数として扱われるようになり、その結果がクエリ結果キャッシュによって誤って再利用されなくなりました。#108029 (alexey-milovidov).- クエリ条件キャッシュ (
use_query_condition_cache = 1) が、スキップ索引由来のマーク除外を、異なるスキップ索引の組み合わせを実行したクエリ (例:use_skip_indexes = 0、ignore_data_skipping_indices、または異なるuse_skip_indexes_for_disjunctionsモードの使用時) に再利用し、誤った結果が返される問題を修正しました。スキップ索引由来の cache エントリは、実際に実行されたスキップ索引の組み合わせをキーとするようになりました。一方、行レベルのクエリ条件キャッシュのエントリは、これらいずれの場合でも引き続き再利用できます。#108548 (groeneai). - ファイルシステムキャッシュ経由で読み取るクエリが、
KILL QUERYでキャンセルされた後も進行中のダウンロードを待ち続けてハングすることがある問題と、リフレッシュがそのような待機で停止しているリフレッシャブルmaterialized view を削除またはSYSTEM STOP VIEWしようとするとブロックされる問題を修正しました。#109116 (murphy-4o). - パーツに最終マークがない場合 (非適応型グラニュラリティ、
index_granularity_bytes = 0) に、降順 (DESC) のキーカラムを持つテーブルで主キー索引がグラニュールを誤って除外し、誤ったクエリ結果が返される問題を修正しました。#109901 (nihalzp). - サブクエリに相関サブクエリが含まれ、かつ索引解析中にセットが構築される
IN (subquery)で発生する、論理エラーExpected CommonSubplanReferenceStep to reference CommonSubplanStep、エラーSubplan cannot be used to build pipeline、および論理エラーTrying to extract chunk from ChunkBuffer before all inputs are finishedを修正しました。#110491 (alexey-milovidov). - 並列レプリカが有効な場合に、
QBitカラムに対する転置距離関数 (cosineDistanceTransposedなど) をスカラーサブクエリまたは定数の参照ベクトルを指定して呼び出すと発生するNOT_FOUND_COLUMN_IN_BLOCKエラーを修正しました。#110729 (alexey-milovidov). - テキスト索引の expression に
arrayFilter(s -> s != '', ...)のような空文字列との比較が含まれる場合に、その索引が使用されない問題を修正しました。原因は、設定optimize_empty_string_comparisonsがクエリ側でのみ比較をnotEmptyに書き換えていたことです。#112115 (Ergus). - カラムが
PREWHEREとWHEREの両方のフィルタ条件で参照されている場合、テキスト索引の仮想カラムに書き換えられていても、そのカラムを削除しないようにしました。#114460 (ahmadov). - lazy posting-list 適用モードでテキスト索引を持つテーブルに対してクエリを実行した際、読み取り中にクエリがキャンセルされると論理エラー
Multi-block postings must be compressedが発生する問題を修正しました。#114636 (CurtizJ). WHERE句でNOTの内側にNULL式が含まれる場合 (例:SELECT count() FROM t WHERE NOT (id >= 20 AND NULL)) に誤った結果が返される問題を修正しました。索引解析がこのような条件を範囲全体で常に真になると判定していたため、フィルタがスキップされていました。その結果、count()がクエリで除外されるはずの行まで返し、この条件を指定したALTER TABLE ... DELETEが本来残すべき行を削除していました。#115152 (groeneai).query_plan_join_shard_by_pk_rangesを有効にしたfull_sorting_mergeJOIN で、片側の入力が主キーやカラム統計によるプルーニング、またはテーブルが空であることによってパーツが 1 つも残らなくなった場合に発生するLOGICAL_ERROR(Join is supported only for pipelines with one output port) を修正しました。#115352 (alexey-milovidov).- _part_starting_offset に対するフィルタではクエリ条件キャッシュを無効にしました。#115358 (azat).
- 暗黙的な minmax 索引 (
add_minmax_index_for_numeric_columnsなど) を持つテーブルで、1 つのALTER TABLEステートメント内にRENAME COLUMNとMODIFY SETTINGなどの別のコマンドを組み合わせた場合に発生するLOGICAL_ERROR: Index with name auto_minmax_index_<column> already existsを修正しました。あわせて、通常のカラムの名前を変更した後、続くDROP COLUMNがUNKNOWN_IDENTIFIERで失敗したり、続くADD COLUMNで暗黙的な索引が作成されなかったりする問題も解消しました。#116063 (groeneai). - ワイルドカード (
%、_) を含まないLIKE/NOT LIKEパターンで、正確な主キー範囲を使用するようにしました。これにより、より広いプレフィックス範囲を読み取ることなく、同等の=/!=述語と同じ数のグラニュールだけを読み取るようになりました。#107077 (groeneai). - 主キーに対する
IN/NOT IN条件でキーが定数によるintDivでラップされており、かつキーが符号なし整数で、その値がintDivの結果型の符号付き境界をまたぐ場合 (例:intDiv(uint64_column, -9223372036854775807)) に、LOGICAL_ERROR(Invalid binary search result in MergeTreeSetIndex) が発生する問題と、リリースビルドで索引プルーニングが行われない問題を修正しました。#107586 (groeneai). - BSI ビット構成が異なる、全要素が 1 のベクトルとの乗算時に
numericIndexedVectorPointwiseMultiplyが空の結果を返す問題を修正しました。#108027 (alexey-milovidov). - 多数の異なる短いトークンに対して
positions = 1でテキスト索引をビルドする際に発生する heap-buffer-overflow を修正しました。#108659 (groeneai). - テキスト索引の
preprocessorおよびpostprocessor式からALIASカラムを参照できるようにしました。#110014 (Ergus). LIMIT ... WITH TIESが使用されている場合は、vector search の最適化をスキップするようにしました。この最適化は ANN 検索の対象を厳密に n 個の候補に絞り込むため、n 番目の行と同順位の行が欠落していました。#110453 (tamish560)。- 索引が単純なカラムではなく expression に対して定義されている場合 (例:
lower(...)プリプロセッサを伴うassumeNotNull(col)) に、ILIKEでテキスト索引が使用されない問題を修正しました。このようなクエリでは、すべてのグラニュールを読み込むのではなく索引が使用されるようになりました。#110595 (ahmadov)。 vector_search_with_rescoring = 1と遅延マテリアライゼーションを組み合わせた vector search クエリで、複数の距離が同値になると発生することがあったLOGICAL_ERROR(LazyMaterializingTransform: Number of rows in lazy chunk N does not match number of offsets M) を修正しました。#111003 (groeneai)。i8量子化を用いたvector_similarity索引の使用時に、二乗ノルムがオーバーフローして無限大になるベクトルを拒否するようにしました (従来はこのようなベクトルが usearch で未定義動作を引き起こし、エラーを出さずに不正なデータを生成していました) 。#111085 (groeneai)。- ページキャッシュが有効な
plain_rewritableディスクで古いデータが読み込まれる問題を修正しました。#111105 (Michicosun)。 String(またはより幅の狭いFixedString) のキーまたは minmax スキップ索引に対して、より幅の広いFixedString定数との比較 (例:toFixedString('abc', 257) = string_col) でフィルタすると、count()の結果が誤ったり行が欠落したりする問題を修正しました。プライマリキーおよび minmax による枝刈りが NUL パディングされた定数から範囲を構築していたため、条件に一致するグラニュールが誤ってスキップされていました。#111106 (groeneai)。- オフセット索引が行 0 から始まっていない Parquet ファイルを正しく読み込めない問題を修正しました。このようなファイルでは、ネイティブ Parquet リーダーが誤った行を返したり、
INCORRECT_DATAではなくLOGICAL_ERRORを報告したりすることがありました。現在は、オフセット索引を読み込む際に検証するようになっています。#114530 (groeneai)。
セキュリティ、アクセス、バックアップ、復元に関する修正
- 宛先テーブルで
fsync_after_insertが有効になっている場合、RESTOREはリストアしたパーツファイルを fsync するようになりました。これにより、リストアされたパーツも挿入されたパーツと同等の電源断耐性を持つようになります。以前は、リストアされたファイルは書き込みとクローズのみが行われ (fsync は一切行われず) 、RESTOREがRESTOREDを返した直後に電源断が発生すると、パーツが破損してテーブルが空になる可能性がありました。#111378 (groeneai). - 認証されていない TCP クライアントが interserver ポート経由でテーブルの存在やレプリケーションの状態を探れてしまうセキュリティ上の問題を修正しました。#99854 (tiandiwonder).
DELETE FROM(論理削除) の実行にALTER DELETEに加えてALTER UPDATE権限が必要になっていた問題を修正しました。ドキュメントに記載されているとおり、ALTER DELETEのみが付与されたユーザーでもDELETE FROMを実行できるようになりました。#107491 (tiandiwonder).- Atomic データベース上で
CREATE TABLE ... AS SELECTのクエリが失敗した場合 (たとえば、サブクエリから参照されるテーブルへのアクセス権がユーザーにない場合など) に、空のテーブルが残ってしまう問題を修正しました。以前は、再試行すると元のエラーではなく、テーブルが既に存在するというエラーが報告されていました。現在は、テーブルは一時テーブルを介して作成され、データの投入が完了した後にはじめて参照可能になります。#108048 (alexey-milovidov). - ユーザーに
ALIASカラムに対するSELECTアクセスのみが付与されているテーブルでSELECT count()(またはその他の単純なクエリ) を実行すると、LOGICAL_ERROR(No available columns) が発生する問題を修正しました。#108056 (alexey-milovidov). - 認証されていないリクエストによって、転送元クライアントアドレスを示すヘッダーで指定されたホスト名を ClickHouse に名前解決させることができてしまう問題を修正しました。ClickHouse は今後、これらのヘッダーから数値形式の IP アドレスのみを受け付けます。無効な値は、転送アドレスに基づくクォータの割り当てでは DNS による名前解決を行わずに無視されます。
auth_use_forwarded_addressが有効な場合、無効な転送アドレスは認証時に拒否されます。拒否はデバッグレベルでログに記録されます。#111060 (otselnik). - アナライザが無効 (
enable_analyzer = 0) の場合に、パラメーター化ビューでSQL SECURITY DEFINER(およびSQL SECURITY NONE) が適用されない問題を修正しました。以前は、基になるテーブルに対する権限を持たないユーザーがこのようなビューから SELECT すると、アナライザが有効な場合は同じビューが正常に動作するにもかかわらず、ACCESS_DENIEDで失敗していました。#111458 (groeneai). MySQLインテグレーションにおいて、名前付きコレクションが認証情報をコンテンツ形式で保持している場合に、その TLS 認証情報を空のssl_ca_pem/ssl_cert_pem/ssl_key_pem値で上書きすると、上書きが拒否されずに受け入れられ、設定済みの CA またはクライアント証明書が警告なく破棄されてしまう不具合を修正しました。#113947 (alexey-milovidov).- 本体に JOIN を含み、
SQL SECURITY DEFINERまたはSQL SECURITY NONEとして宣言されたビューで、EXPLAIN ANALYZEが結合の統計情報を失ってしまう問題を修正しました。デバッグビルドおよびサニタイザービルドでは、クエリが論理エラーJoinStep analyzed without the analyze modeで異常終了していました。#115156 (groeneai). RESTORE ... AS <new name>を実行すると、リフレッシャブルmaterialized view のREFRESH ... DEPENDS ONリストが元のデータベースを指したままになる問題を修正しました。これにより、リストアされたビューは、すでに読み取り対象ではないテーブルに反応してリフレッシュされる一方で自身の親のリフレッシュは無視し、元のデータベースが削除されるとリフレッシュが完全に停止していました。#115689 (groeneai).- ドロップと再作成が同時に行われている
Replicatedデータベースをバックアップする際に、LOGICAL_ERROR例外が発生する問題を修正しました。このようなバックアップは、CANNOT_GET_REPLICATED_DATABASE_SNAPSHOTエラーで適切に失敗するようになりました。#100651 (alexey-milovidov). - 同一ロールに対する
GRANT role TO roleは、system.role_grantsに自己参照エントリを暗黙的に作成するのではなく、BAD_ARGUMENTSエラーで拒否されるようになりました。#103315 (zxuhan). MaterializedPostgreSQLデータベースのBACKUPが「Table … were created or changed its definition during scanning」というメッセージを出したまま無期限にハングしなくなり、テーブルデータが実際にバックアップされるようになりました (処理は基盤となるReplacingMergeTreeに委譲されます) 。このバックアップは、単独のReplacingMergeTreeとして復元できます。#107433 (alexey-milovidov).- Dictionary に対する
SHOW DICTIONARIES権限のみを持つユーザーでも、EXISTS <dictionary>を実行できるようにしました (従来はSHOW TABLES権限が必要でした) 。#108084 (alexey-milovidov). - ファイナライズ前に失敗した
BACKUP ... TO Memory(...)のクリーンアップ処理を修正しました。これまでは失敗したバックアップが登録されたまま残り、同じ名前を再利用できませんでした。#109947 (jkartseva). - 同じアーカイブからの読み取りがストリームの途中で失敗した後、そのzip アーカイブを再度読み取る際 (例: zip バックアップからの
RESTORE中) に、ReadBuffer is canceled. Can't read from it.という論理エラー (debug/sanitizer ビルドではサーバーが異常終了) が発生する可能性があった問題を修正しました。#110197 (groeneai). constメソッドであるAccessRights::getFiltersが、同時実行クエリ間で共有されるアクセス権ツリーを変更していたことによるヒープ破損を修正しました。この問題により、シャットダウン時にサーバーがクラッシュする可能性がありました。#112692 (groeneai).
分散実行、テーブル、ビュー、Dictionary
ALTER TABLE ... MOVE PART ... TO SHARD '<path>'に対して誤ってInconsistent AST formattingエラーが発生する問題を修正しました。クエリフォーマッタがSHARDキーワードを落としていたため、再フォーマットしたクエリを再びパースできず、LOGICAL_ERRORが発生していました (リリースビルドではハンドリングされる例外、デバッグビルドおよびサニタイザービルドではアボート) 。#109060 (groeneai)。- リモートデータベース名を空にして定義された
Distributedテーブルを、distributed_product_mode = 'local'の状態で JOIN に使用すると論理エラー (!part.empty()) が発生する問題を修正しました。#110677 (groeneai)。 - DISTINCT の早期停止用 limit ヒントで結果の先頭を制限できない場合に、順序付きの
LIMIT/OFFSETを伴うDISTINCTが誤った行を返す問題を修正しました。対象となるのは、負のLIMIT(末尾ではなく先頭を返していた) 、小数のLIMIT/OFFSET(小数は全件読み取り後にしか確定しない) 、およびLIMITを伴わない単独のOFFSET(オフセット以降の末尾が欠落していた) です。たとえば、複数パーツから成るテーブルに対してSELECT DISTINCT intDiv(x, 100) FROM t ORDER BY intDiv(x, 100) LIMIT -1を実行すると、最大の distinct 値ではなく最小の値が返されていました。#111326 (groeneai)。 - DESCRIBE TABLE でサブクエリの後に指定した別名をパーサーが受け付けず、構文エラーになる問題を修正しました。https://github.com/ClickHouse/ClickHouse/issues/100031 を修正します。#100205 (yariks5s)。
DETACH DATABASE/ATTACH DATABASE後のlazy_load_tables = 1が設定されたAtomicデータベースにおいて、ALTER RENAME COLUMNの実行中にINSERTが並行して行われると、サーバーがアボート (Logical error: 'Block structure mismatch') することがある問題を修正しました。#104852 (groeneai)。- 設定
inject_random_order_for_select_without_order_byに起因するカラム名の破損およびBAD_ARGUMENTS例外を修正しました。この設定を有効にしても複数カラムの SELECT が失敗しなくなり、出力カラム名 (例:CREATE TABLE AS SELECT、CREATE VIEW AS SELECT、JSONEachRow) が内部の__subquery_column_<UUID>別名に置き換えられず、そのまま保持されるようになりました。#105896 (groeneai)。 - サーバー再起動後 (または
DETACH/ATTACH DATABASE後) に削除済みのテーブルを再度削除しようとすると、削除したばかりの名前を候補として提示する紛らわしい “Maybe you meant X?” ヒントが表示される問題を修正しました。デタッチ時に、非同期ロードタスクがDatabaseOrdinary::startup_tableおよびload_tableからクリアされるようになりました。#106238 (groeneai)。 MaterializedPostgreSQLテーブルエンジンおよびデータベースエンジンを修正し、単一のテーブルまたはデータベースをデフォルト以外の PostgreSQL スキーマ (materialized_postgresql_schema) からレプリケーションできるようにしました。同一データベース内の複数のスキーマに同名のテーブルが存在する場合にも対応しています (従来はこれらが publication と replication slot を共有してしまい、相互に干渉していました) 。#107425 (alexey-milovidov)。- 並列レプリカを使用するクエリが
GLOBAL JOINの一時テーブルとして送信されたテーブルのALIASカラムを選択した場合のNO_SUCH_COLUMN_IN_TABLE、分散JOINの両側で同名のALIASカラムが宣言されている場合のMULTIPLE_EXPRESSIONS_FOR_ALIAS、およびDistributedテーブルで別のALIASカラムを参照するALIASカラムが宣言されている場合 (JOIN USINGのキーとして使用する場合を含む) のUNKNOWN_IDENTIFIERを修正しました。#107700 (yakov-olkhovskiy)。 refresh_retriesに非常に大きな値 (Int64の最大値付近) が設定されている場合に、リフレッシャブルmaterialized view が失敗したリフレッシュを再試行する際、符号付き整数のオーバーフローが発生する問題を修正しました。このオーバーフローにより、未定義動作サニタイザーを有効にしたビルドではサーバーが異常終了する可能性がありました。#108005 (groeneai).- 明示的なクエリを使用するローカルの
ClickHouseソースを持ち、キーカラムが Dictionary 定義の先頭カラムではない複合キーの Dictionary を読み込む際に、例外 (CANNOT_PARSE_TEXT) が発生する問題を修正しました。ソースカラムは、位置ではなく名前で Dictionary の構造と対応付けられるようになりました。#108053 (alexey-milovidov). WHERE句なしでHiveテーブルにクエリを実行した場合 (例:SELECT * FROM hive_table) に、クラッシュ (ヌルポインタ参照) が発生する問題を修正しました。#108094 (alexey-milovidov).- 分散クエリがまだマテリアライズされていない
MATERIALIZEDCTE を外部テーブルとして参照し、かつリモートソースが遅延生成 (delayed source) された場合に、サーバーがクラッシュ (セグメンテーション違反) する可能性があった問題を修正しました。このクラッシュは、RemoteQueryExecutor::sendExternalTables()内でヌルのLoggerを参照していたことが原因でした。#108547 (groeneai). STREAM読み取り (SELECT DISTINCT ... FROM table STREAM) に対してDISTINCTを実行した際に、論理エラー (Equal values are not contiguous within the range assumed to be sorted) が発生する問題を修正しました。STREAM読み取りはソートキー順ではなくコミット順で行を出力するため、読み取り順序の最適化を適用しないようにしました。#108568 (groeneai).optimize_skip_unused_shards = 1の設定下で、Distributedテーブルのシャーディングキーがアナライザーによって定数畳み込みされる expression (例:if(1, toInt32(id), toInt32(id) + 1)) である場合に、例外 (Cannot find sharding key column。debug/サニタイザービルドではサーバーが異常終了) が発生する問題を修正しました。#108737 (groeneai).Aliasテーブルを介したINSERT ... SELECTが例外なしでキャンセルされた場合 (例:timeout_overflow_mode = 'break') に、サーバーが異常終了する問題 (debug およびサニタイザービルドでのLOGICAL_ERROR/ アサーション) を修正しました。#108783 (groeneai).TimeSeriesテーブルへのINSERT ... SELECTが例外なしでキャンセルされた場合 (例:timeout_overflow_mode = 'break') に、サーバーが異常終了する問題 (debug およびサニタイザービルドでのLOGICAL_ERROR/ アサーション) を修正しました。#108796 (tiandiwonder).- 以前にキャンセルされたクエリによって同期が崩れた接続がプールから再利用された際に、分散クエリが
UNEXPECTED_PACKET_FROM_SERVER(“expected TablesStatusResponse, got ProfileInfo”) でまれに失敗する問題を修正しました。#108854 (alexey-milovidov). Distributedテーブルに対するクエリで、MATERIALIZEDCTE が結合ツリー内の複数の位置 (例: 結合された 2 つのサブクエリ、または結合されたサブクエリとWHERE内のスカラーサブクエリ) から参照された場合に、LOGICAL_ERROR(CTE '...' does not have query tree, but was not planned yet) が発生する問題を修正しました。このようなクエリは、例外を発生させずに実行されるようになりました (以前は debug/サニタイザービルドでサーバーが異常終了していました) 。#108924 (groeneai).- materialized view の処理からスケジュールされた非同期処理が、クエリの終了後もクエリレベルのアカウンティングを使い続ける可能性があったメモリ安全性の問題を修正しました。#108988 (filimonov).
- アナライザーを使用しない場合に、一方のブランチで並列レプリカとともに
GROUP BY GROUPING SETSを使用し、もう一方のブランチでFINALを使用するUNION ALL/INTERSECT/EXCEPTにおいて発生する可能性があったLOGICAL_ERROR(“Cannot find__grouping_setcolumn in header of MergingAggregatedTransform with grouping sets”、または “Chunk info was not set for chunk in MergingAggregatedTransform”) を修正しました。#109003 (groeneai). Replicatedデータベース内でCREATE TABLE ... AS SELECT FROM s3Cluster(...)(およびfileCluster/urlClusterなどの他のクラスターテーブル関数) がNOT_FOUND_COLUMN_IN_BLOCKで失敗する問題を修正しました。#109266 (groeneai).- 2 つ以上のシャードを持つクラスター上で、
Distributedテーブルを読み取るCREATE TABLE ... ON CLUSTER ... AS SELECTを実行した際に発生するエラー (NOT_FOUND_COLUMN_IN_BLOCK、旧バージョンではstd::bad_function_call) を修正しました。#109407 (alexey-milovidov). - テーブル式を
IN演算子の左引数として使用した場合に発生する、わかりにくい内部エラー (Method getResultType is not supported for TABLE query tree node) を修正しました。このようなクエリでは、わかりやすいエラーメッセージが表示されるようになりました。#109412 (alexey-milovidov). optimize_const_name_sizeが小さい値に設定された状態でDistributedテーブルに対してSELECT ... ORDER BY ... WITH FILLを実行した際に発生するBad cast from type DB::FunctionNode to DB::ConstantNodeという論理エラー (debug/sanitizer ビルドではサーバーが異常終了) を修正しました。#109938 (groeneai).query_plan_merge_expression_into_joinが有効な場合に、複数テーブルからなるビューに対するカンマ結合によって join order optimizer で発生する可能性があったLOGICAL_ERROR(Left and right columns have same names) を修正しました。#110227 (groeneai).LIMITを含む正当な分散クエリでまれにLogical error: 'No more packets are available.'が発生し、debug および sanitizer ビルドでサーバーが異常終了する問題を修正しました。#110334 (groeneai).- SELECT クエリが修飾なしのテーブル識別子の直後で終わる場合 (例:
... FROM t COMMENT 'x')、COMMENT が暗黙のエイリアスとして誤って解釈され、コメントがビュー/テーブルに適用されずに誤解を招く構文エラーが発生するパーサーのバグを修正しました。#110372 (adityaksolves). - 選択性の高いフィルターを含むクエリを並列レプリカで実行した場合に、
FixedStringカラムに対するlength()(および QBit の次元) が固定長Nではなく0を返すという、誤った結果になる問題を修正しました。#110427 (groeneai). - 並列レプリカが
custom_key_sampling/custom_key_rangeモードで実行される場合に、FROMにサブクエリを含むクエリで発生するNOT_FOUND_COLUMN_IN_BLOCKエラーを修正しました。このようなクエリ (例:SELECT * FROM (SELECT id, k, v FROM t WHERE id < 20) ORDER BY k) は、これまでNot found column __table2.id in block ...で失敗していました。#110690 (groeneai). - ストリーミング (
FROM ... STREAM) 読み取りが単純なトップレベルのテーブル式ではない場合、つまりサブクエリ内にネストされている場合 (例:WHERE ... IN (...)や CTE の内部) や、通常のビューまたはパラメーター化ビューの背後に隠れている場合に、そのクエリに対してEXPLAIN ANALYZEを実行するとLogical error: 'clock'が発生する問題を修正しました (debug/sanitizer ビルドではサーバーがクラッシュし、リリースビルドでは無限にハングします) 。EXPLAIN ANALYZEは、トップレベルのストリーミング読み取りと同様に、このようなクエリもNOT_IMPLEMENTEDで拒否するようになりました。#110935 (groeneai)。 - データベースと同じ名前のテーブルについて、アナライザで
db.table.columnのような完全修飾カラム名が正しく解決されない問題を修正しました。#110976 (alexey-milovidov)。 parallel_replicas_min_number_of_rows_per_replicaが設定され、左テーブルのカラムが射影されている場合に、RIGHT JOINでNOT_FOUND_COLUMN_IN_BLOCK/THERE_IS_NO_COLUMNエラーが発生する問題 (一部のリリースではエラーにならずに誤った結果が返される問題) を修正しました。#111332 (groeneai)。- 実行可能 UDF、
executableテーブルエンジン、および実行可能ディクショナリにおける競合状態を修正しました。既にクローズされたファイルディスクリプタに対するfcntlが、並行実行中の別クエリの無関係なディスクリプタを破損させ (O_NONBLOCKが外れる) 、クエリが無期限にハングする可能性がありました。#111779 (Algunenano)。 - 2 つ以上の分片を持つ
Distributedテーブル、clusterAllReplicas、またはカスタムキーによる並列レプリカに対してORDER BY ... WITH FILL ... INTERPOLATEを実行した場合 (結果が空の場合を含む) に発生するLOGICAL_ERROR(“Invalid number of rows in Chunk”) と、hardened ビルドで発生する関連の範囲外アクセスによるアボートを修正しました。WITH FILLは最終結果を生成するノードでのみ適用されるようになり、分片/レプリカ間で補完行が重複して生成される問題も解消されました。#111919 (yakov-olkhovskiy)。 system.replicasに対するクエリがステータスリクエストの処理前に kill されていた場合に、DROP TABLE ... SYNCが永久にハングする問題を修正しました。#112164 (evillique)。- 2 つのサブ結合がいずれも出力カラムを生成しない複数テーブルの結合で、
LOGICAL_ERROR例外 (Block structure mismatch in joined block stream) が発生する問題を修正しました。例えば、query_plan_optimize_join_order_limitを0または1に設定した状態でSELECT count() FROM t1, t2, t3, t4 WHERE (t1.b = t2.b) AND (t3.a = t4.a)を実行した場合が該当します。#112205 (groeneai)。 FINAL、PREWHEREフィルター、小さなLIMIT、make_distributed_plan = 1を含むクエリで、SELECT するカラムがテーブルのカラム順序と異なる順序で指定されている場合に、論理エラーCannot add step Expression to QueryPlan because it has incompatible header with root step JoinLazyColumnsStepが発生する問題を修正しました。遅延マテリアライゼーションがプランノードを置き換える際にそのノードの出力ヘッダーを保持していなかったため、クエリプランに不整合が生じていました。#112303 (groeneai)。- 旧アナライザの使用時に、
toDecimal32のスケールやtoDateTimeのタイムゾーンなど定数でなければならない引数がスカラーサブクエリから渡されると、誤った結果や論理エラーが発生する問題を修正しました。このような引数は値がゼロまたは空であるものとして解析されていたため、宣言された結果の型と実際に計算された値が食い違い、CREATE VIEWやCREATE MATERIALIZED VIEWで誤ったカラム型が永続化されていました。#112492 (groeneai)。 - 通常の
VIEWの本体がCREATE VIEW v AS SELECT x FROM {db:Identifier}.tのようにクエリパラメータを介してテーブルまたはディクショナリを参照している場合に、論理エラーが発生し、誤った依存関係が記録される問題を修正しました。このようなビューは、現在のデータベース内にある同名テーブルへの参照依存関係を記録しなくなったため、無関係なテーブルを再び削除できるようになりました。#112704 (groeneai)。 ONセクションに両方のテーブルのカラムを参照する条件 (例:ON (t.key = j.key) AND (t.a < j.a)) を含む JOIN の右側でJoinテーブルエンジンを使用した場合に、論理エラーが発生する問題を修正しました。このようなクエリは、required columns: ... but not found any in left tableやstd::bad_variant_accessを発生させるのではなく、明確な例外を返して拒否されるようになりました。#112815 (groeneai)。- 非常に大きな遅延を指定してバックグラウンドタスクがスケジュールされた場合 (例: 巨大な
REFRESH AFTER期間を持つリフレッシャブルmaterialized view) に発生する未定義動作と、エラーとして検知されないスケジューリングの不具合を修正しました。遅延はオーバーフローせず、表現可能な最大値に制限されるようになりました。#113041 (groeneai)。 Distributedテーブルへの非同期INSERTにおいて、名前がファイルシステムの 255 バイト制限を超えるキューディレクトリが必要になった場合 (use_compact_format_in_distributed_parts_names = 0で発生し得る) に報告されるエラーを修正しました。従来は、internal_replicationが設定されたシャードではLOGICAL_ERROR、それ以外では発生元が不明なCode: 1001. std::exceptionとなっていましたが、いずれの場合もテーブル、クラスター、制限値を示すARGUMENT_OUT_OF_BOUNDを報告するようになりました。#113083 (groeneai)。UNDROP TABLEが、実行中のクエリによる削除済みテーブルの解放を待機している間でも、KILL QUERYで中断できるようになりました。#113263 (alexey-milovidov)。- マテリアライズド CTE を使用するクエリが失敗した後、
DROP TABLEが永続的にハングし、メモリリークが発生する問題を修正しました。該当テーブルは、サーバーを再起動するまで削除キューに残り続けていました。#113397 (tiandiwonder)。 make_distributed_planの使用時に、サブクエリが自身のSETTINGS句でdistributed_plan_execute_locallyを設定すると、セグメンテーション違反およびLOGICAL_ERROR(No host found for exchange stream final_result__0_0) が発生する問題を修正しました。分散プランとそれを実行するコードがそれぞれ異なるコンテキストから設定を読み取っていたため値が食い違うことがあり、イニシエーターが自己矛盾したパイプラインを構築していました。#113422 (groeneai)。database_atomic_wait_for_drop_and_detach_synchronouslyが有効な場合に、データ投入用のSELECTが失敗したCREATE TABLE ... AS SELECTを強制終了できなくなる問題を修正しました。一時テーブルをクリーンアップするための内部的なDROPがバックグラウンドの削除キューを待機し、KILL QUERYとmax_execution_timeの両方を無視していました。#113504 (groeneai)。join_use_nullsが有効な場合に、ON (t.key = d.key) AND (t.a * 10 < d.a)のようにON句に両方のテーブルにまたがる非等価条件を含む、ディクショナリへのJOINで誤った結果が返され、アサーションを有効にしたビルドではアサーション失敗により異常終了する問題を修正しました。条件が、誤った型で読み取られたカラムに対して評価されていたため、行が無作為にマッチする可能性がありました。#113534 (alexey-milovidov)。- パラメーター化ビューを非修飾名で参照するクエリが分片に送信されると、ビューのデータベース情報が失われ、分片側で自身のデフォルトデータベースに対して名前解決が行われてしまう問題を修正しました。そのデータベースの内容によっては、クエリが
UNKNOWN_FUNCTIONで失敗するか、別のビューの行を何の警告もなく返していました。Distributedテーブルを介したIN、JOIN、remote()が影響を受けます。#113550 (groeneai)。 - キーが複合キー (複数カラム) であるか、
UUID、Int256、FixedString(4)などの 16/32 バイトの単一値であるJoinエンジンテーブルを読み取る際に発生するUnsupported JOIN keys of type keys256 in StorageJoinエラーを修正しました。このようなテーブルは作成、書き込み、結合はできても、SELECTで読み出すことはできませんでした。#113578 (groeneai)。 - リモート分片を対象とする構造定義なしの
Distributedテーブルを、古いバージョンのサーバーで書き込まれたメタデータからアタッチまたはロードした際に発生する論理エラーSending a distributed query with unknown (zero) client versionを修正しました。#113675 (alexey-milovidov)。 - 名前付きテーブルに
STREAM修飾子を使用したSELECTを read-tasks モードの並列レプリカと組み合わせるとLOGICAL_ERRORが発生する問題を修正しました。PREWHERE内のINの集合としてマテリアライズド CTE を使用すると、サーバーがReading from materialized CTE ... DelayedPortsProcessor gate is missing in the query planエラーを送出していました (debug ビルドおよび sanitizer ビルドではサーバーが異常終了) 。今後は、並列レプリカが要求された場合、STREAMが指定されたテーブルは拒否されます。enable_parallel_replicas = 2ではクエリがSUPPORT_IS_DISABLEDで失敗し、1では並列レプリカを使用せずに実行されます。これはFINALの既存の挙動と同じです。#113754 (groeneai)。 remote、mysqlなどのテーブル関数でアドレス引数の解析に二次の計算量がかかっていた問題を修正しました。非常に長いアドレス (例: メガバイト規模のゼロ埋めFixedString) を指定すると、解析中にクエリがハングし、キャンセルもできない状態になっていました。#113918 (alexey-milovidov)。database_atomic_wait_for_drop_and_detach_synchronouslyが有効な状態で、リフレッシャブルmaterialized view のリフレッシュが (サーバーのシャットダウンなどによって) キャンセルされた際に、Failed to drop temporary table after refresh. Table ... is left behind and requires manual cleanup.という誤ったエラーがログに記録される問題を修正しました。実際には一時テーブルは削除されており、手動でのクリーンアップは不要でした。#113957 (groeneai)。materialized_views_ignore_errorsが有効な状態で、依存関係の収集中に失敗した materialized view についてsystem.query_views_logの行が記録されない問題を修正しました。debug ビルドおよび sanitizer ビルドでは、ビューがログに記録されずにstd::out_of_rangeでサーバーが異常終了していました。#114064 (groeneai)。- 右テーブルの非キーカラムに対するフィルタが ANY INNER JOIN の下にプッシュダウンされた場合に、結果が一貫しない問題を修正しました。#114313 (kirillshokhin)。
ignore_drop_queries_probabilityが設定されている場合に、CREATE OR REPLACEが内部の_tmp_replace_*テーブルを残してしまう問題、およびCREATE OR REPLACE VIEWがNOT_IMPLEMENTEDで失敗する問題を修正しました。内部で発行される DROP は 1 つのユーザーステートメントを構成するステップであるため、DROP のフォールトインジェクションは適用されなくなりました。#114420 (groeneai)。metaData.partitionColumnsに、metaData.schemaStringで宣言されていないカラムが指定されている Delta Lake テーブルを読み取る際にLOGICAL_ERRORが発生する問題を修正しました。このようなメタデータは、クエリに述語が含まれる場合に限らず、テーブルまたはそのスキーマをスナップショットから読み取る際には常に拒否されるようになりました (delta-kernel リーダーではBAD_ARGUMENTS、従来のリーダーではINCORRECT_DATA) 。#114538 (groeneai)。- 遅延
FINAL最適化 (query_plan_optimize_lazy_final) を使用するクエリが、サーバー起動後に最初に実行される集約であった場合に、ハッシュテーブル統計 (およびそれに依存する集約用ハッシュテーブルの事前割り当て) がサーバー全体で警告なく恒久的に無効化される問題を修正しました。#114597 (alexey-milovidov)。 ignore_drop_queries_probabilityが有効な場合に、リフレッシャブルmaterialized view がローテーションで不要になった旧ターゲットテーブルをリークする問題を修正しました。リフレッシュが旧ターゲットのクリーンアップのために発行するDROPは、ユーザーが要求したDROPではなくリフレッシュ処理の一部であるため、フォールトインジェクションの対象外となりました。#114622 (groeneai)。ON句にORで結合された複数の条件を含むANY RIGHT JOINおよびSEMI RIGHT JOINで、右テーブルの一部の行が重複して返され、別の行のマッチが失われる問題を修正しました。プランナーがテーブルを入れ替えてANY RIGHT JOINとして実行する場合があるため、ANY LEFT JOINとして記述したクエリも影響を受けていました。#114676 (vdimir)。- テキストインデックス付きカラムが
PREWHEREとWHEREの両方でテキスト検索述語に使用されているテーブルに対し、その上位にJOINを含むクエリを実行すると、LOGICAL_ERROR(Cannot find input column ... on its position in inputs of expression actions DAG) が発生する問題を修正しました。#114771 (groeneai)。 ALIASまたはEPHEMERALカラムにSTATISTICS(...)を宣言したテーブルへのINSERTがすべてNOT_FOUND_COLUMN_IN_BLOCKで失敗し、そのようなテーブルが事実上読み取り専用になっていた問題を修正しました。#115231 (groeneai)。- 分散クエリにおける
dictGetおよびその派生関数の問題を修正しました。修飾されていない Dictionary 名は、各シャードのカレントデータベースではなく、イニシエーターのカレントデータベースに基づいて解決されるようになりました。従来は各シャードで解決されていたため、Dictionary が見つからないか、同名の別の Dictionary が参照されていました。#115541 (alexey-milovidov)。 - データベースまたはテーブルを新しい名前で復元すると、保存済みビューの定義本体からテーブル別名が失われ、復元したビューの読み取りが
UNKNOWN_IDENTIFIERで失敗するバグを修正しました。#115645 (groeneai)。 Distributedテーブルに対するINサブクエリ内からMATERIALIZEDCTE を読み取る際に、LOGICAL_ERROR“Reading from materialized CTE ‘X’ before its materialization completed - DelayedPortsProcessor gate is missing in the query plan” が発生する問題を修正しました。#115740 (groeneai)。- DETACH DICTIONARY … PERMANENTLY が依存関係チェック (HAVE_DEPENDENT_OBJECTS) によって拒否された後に、dictGet で BAD_ARGUMENTS “Dictionary not found” が発生する問題を修正しました。デタッチが拒否された場合、Dictionary はこれまでどおり問題なく使用できます。#105259 (groeneai)。
- バックグラウンドのテーブル削除キューで発生する
Logical error: 'removed'(デバッグビルドではサーバーが異常終了) を修正しました。この問題は、同じ明示的な UUID が複数のCREATE OR REPLACE TABLEクエリで再利用され、その UUID を共有する削除済みテーブルが複数キューに登録された場合に発生する可能性がありました。#107031 (groeneai). - サーバー停止中に単一のレプリケートテーブルの構造が変更された場合に、
MaterializedPostgreSQLがデータベース全体のレプリケーションを停止してしまう問題 (LOGICAL_ERROR: Columns number mismatchが発生) を修正しました。今後は影響を受けたテーブルのみがスキップされ、DETACH/ATTACHで復旧できます。#107427 (alexey-milovidov). - クラスターに非アクティブなレプリカ (例: オートスケーリング後に残った古いエントリ) が含まれている場合に、並列レプリカで処理の分散が大きく偏る問題を修正しました。このようなレプリカは読み取りコーディネーターのカウント対象外となったため、処理が単一のレプリカに集中することなく、オンラインのレプリカ間で均等に分散されるようになりました。#107805 (alexey-milovidov).
- XML で定義された多数の MySQL Dictionary が
share_connectionによって単一の接続プールを共有している場合に、SYSTEM RELOAD DICTIONARIES(およびRELOAD DICTIONARY) がフリーズする問題を修正しました。このような pool も、名前付きコレクションで定義された Dictionary と同様に、設定のconnection_pool_sizeとconnection_wait_timeout(デフォルト 5 秒) に従うようになりました。#108083 (alexey-milovidov). - リーダーが実行するレプリケートされた分散 DDL のリトライが上限に達した場合でも、後続の
ON CLUSTERDDL クエリが恒久的にブロックされないようにしました。#108505 (ahaanlimaye). - 同じ
Distributedテーブルに対してSYSTEM FLUSH DISTRIBUTEDとDROP TABLEが同時実行された場合に発生する可能性のあったクラッシュ (use-after-free) を修正しました。#108684 (groeneai). automatic_parallel_replicas_modeが有効で、かつparallel_replicas_min_number_of_rows_per_replicaが 0 より大きい場合に、自動並列レプリカプランナーで発生する可能性のあったLOGICAL_ERROR(local_replica_plan_reading_step->getAnalyzedResult() == nullptr) を修正しました。#109011 (groeneai).- 非トランザクションの
TRUNCATEが、同じテーブルに挿入を行った未コミットのトランザクションと同時実行された場合にスローされる可能性のあったLOGICAL_ERROR(creation_csn is not set while removal_csn is set to 1) を修正しました。今後、このようなTRUNCATEは未コミットのトランザクションによって作成されたパーツを削除しません。#109598 (tuanpach). - 外部データベースエンジン (例:
PostgreSQL) は、UUIDカラムに対する範囲比較 (>=、>、<=、<) をプッシュダウンしなくなりました。ClickHouse と外部データベースでは UUID の順序付けが異なるため、これらをプッシュダウンすると、結果から行が警告なく欠落していました。今後、このような述語は ClickHouse 側で評価されます。#109833 (vismaytiwari). MaterializedPostgreSQLデータベースエンジンで、同期待ちのキューに入っている間にテーブルがデタッチされた (または構造が変更された) 場合に発生する可能性のあったサーバークラッシュを修正しました。#110596 (alexey-milovidov).EPHEMERALカラムの型がサーバーのquery_masking_rulesによって書き換えられてしまう問題を修正しました。型の内部にマッチするルールがあると、CREATE TABLEで誤った型が保存されるか、処理が失敗していました。#112048 (alexey-milovidov).- テーブル名の長さチェックにおける符号なし整数のアンダーフローを修正しました。この問題により、削除できないテーブルが作成できてしまうことがありました。エスケープ後のデータベース名が 214 バイトに達すると、
metadata_droppedのファイル名に対して計算される上限値がラップアラウンドするため、CREATE TABLEは受け付けられる一方で、その後のDROP TABLEやDROP DATABASEはFile name too longで失敗していました。このような名前は、境界のすぐ下の長さで既に返されていたのと同じエラーARGUMENT_OUT_OF_BOUNDで拒否されるようになりました。#112527 (groeneai)。 RENAME TABLEが、テーブル名の最大長を宛先データベースではなくソースデータベースを基準にチェックしていた問題を修正しました。長い名前のデータベースへテーブルをリネームすると、DROP TABLEで削除できないテーブルができてしまう可能性があり、逆にそのようなデータベースから別のデータベースへのリネームは誤って拒否されていました。#113019 (groeneai)。- ターゲットが materialized view をトリガーする
Aliasテーブルへの挿入処理において、query_logのviewsカラムが常に空になっていた問題を修正しました。#113076 (eclbg)。 tuple()や(x, y)のような無効なparallel_replicas_custom_keyの式は、カスタムキーの型リストの範囲外を読み取ることなく、ILLEGAL_TYPE_OF_COLUMN_FOR_FILTERで拒否されるようになりました。#113359 (nickitat)。RENAME DATABASEが、データベース内のテーブルを削除できなくなるほど長いターゲット名を受け付けていた問題を修正しました。テーブル名の長さチェックはcheck_table_dependenciesの値にかかわらず実行されるようになり、デタッチされたテーブルも対象に含まれるようになりました。デタッチされたテーブルはこれまでチェックの対象外だったため、デフォルト設定でも影響を受けていました。#113557 (groeneai)。Distributedエンジンのテーブルへのバックグラウンド挿入を使用している場合、リモートシャードへのデータ送信時のエラーの繰り返しによって生じた遅延が、エラー解消後に短縮されるようになりました。これまでは、遅延が増加する一方でリセットされることはありませんでした。#87378 (Blackmorse)。- 未知のクラスター、または
<secret>が設定されていないクラスターを指定してUSER_INTERSERVER_MARKERを使用するネイティブプロトコルのハンドシェイクを拒否するようにしました。これまでは、このようなハンドシェイクによって、認証されていないクライアントがサーバー間通信モードに入り、fake_interserver_contextに基づく認証前のプロトコルパケット(例:TablesStatusRequest)を実行できてしまうため、クラスターシークレットを知っていることを証明しないままローカルテーブルに関する情報を取得できていました。#99675 (MillaFleurs)。
SQL、アナライザ、JOIN 関連の修正
- 名前付き
WINDOW句の定義内におけるクエリパラメータの置換を修正しました。以前は、この箇所のパラメータが警告なしに置換されないまま残されており、未設定のIdentifierパラメータによってEXPLAIN SYNTAXの実行中に例外Logical error: '!part.empty()'が発生する可能性がありました。#110506 (alexey-milovidov). - リフレッシャブルmaterialized view が同時に削除または置換された際に、まれにサーバーがクラッシュする問題を修正しました。スケジューリング処理のコードが一時的にミューテックスを解放している間に、別のスレッドがタスクの
viewをnullptrに設定すると、RefreshTask::doScheduling内でヌルポインタの参照外しが発生していました。#105588 (groeneai). EXCEPTまたはINTERSECTを用いて定義され、そのオペランドがUNIONチェーンであるビューが、DETACH/ATTACHまたはサーバー再起動後に誤った結果を返す問題を修正しました。フォーマッタがINTERSECT/EXCEPTの子であるUNIONを括弧で囲んでいなかったため、保存された SQL が逆の優先順位で再パースされていました。#105935 (groeneai).- 同じキーに対して
WITH CUBE、WITH ROLLUP、またはGROUPING SETSを伴うGROUP BYの結果にSELECT DISTINCTを適用した際に、誤った結果 (重複行) が返される問題を修正しました。これらのグループ化修飾子はキーカラムをデフォルト値にした追加の行を出力し、それが実際のグループの値と衝突する可能性があるため、query_plan_remove_redundant_distinct最適化はこのようなケースではDISTINCTを削除しなくなりました。#107072 (groeneai). WHEREフィルタが定数項を含む論理積である場合 (例:p AND 1、またはQUALIFY NULLがWHEREにマージされるWHERE p QUALIFY NULL) に、OUTER JOIN が誤った結果を返す問題を修正しました。定数の論理積項が結合の非保持側にプッシュダウンされ、結合後のフィルタから削除されることがあったため、その側のカラムがデフォルト値となった非一致行が結合によって生成され、それらの行が誤ってフィルタを通過していました。#107084 (groeneai).correlated_subqueries_default_join_kind = 'left'の場合に、同じカラム識別子を 2 回射影するソース (例:SELECT number, *) に対する相関スカラーサブクエリによってサーバーが異常終了するLOGICAL_ERROR(“Cannot find input column … on its position in inputs of expression actions DAG”) を修正しました。#107112 (groeneai).- 旧アナライザ (
enable_analyzer = 0) において、JOINが null 安全な比較演算子 (<=>/IS NOT DISTINCT FROM) を使用し、かつキーの 1 つがスカラーサブクエリである場合 (例:... JOIN t2 ON (SELECT x FROM t1) <=> t2.k) に発生するLOGICAL_ERROR(debug/sanitizer ビルドではサーバーが異常終了) を修正しました。このようなクエリは、論理エラーではなく通常のNOT_FOUND_COLUMN_IN_BLOCKエラーを返すようになりました。#108123 (groeneai). EXISTS相関サブクエリの非相関化によって生成される結合を含め、SEMI/ANTI結合にjoin_algorithm = 'full_sorting_merge'を使用した場合に発生していたLOGICAL_ERROR(Join is supported only for pipelines with one output port) およびNOT_IMPLEMENTED(MergeJoinAlgorithm is not implemented for strictness Semi) の例外を修正しました。full_sorting_mergeは実行できない strictness/kind の組み合わせを受け付けなくなったため、プランナーは有効な別のアルゴリズムにフォールバックするか、結合を実行できないことを報告するようになりました。#108658 (groeneai).JOINのWITH TOTALS行に、結合の一方の側にある定数サブクエリから得られる定数値ではなく、デフォルト値 (0など) が含まれることがあるバグを修正しました。この誤った結果は、特定の結合順序の場合、またはquery_plan_join_swap_table設定を使用した場合にのみ発生していました。#108807 (vdimir)。- シグナルスタックサイズが大きい CPU (例: AMX 対応カーネル上の Intel Sapphire Rapids / Granite Rapids) で動作する glibc ビルドにおいて、起動時に異常終了する問題 (
Cannot allocate ThreadStack、EINVAL) を修正しました。原因は、aligned_allocの呼び出し前にシグナル代替スタックのサイズがページサイズの倍数に切り上げられていなかったことです。#108813 (groeneai)。 - 相関サブクエリが結合に非相関化され、かつソースリレーションに同じカラム名が複数回含まれる場合に発生する
Block structure mismatch in JoinStep論理エラー (debug/sanitizer ビルドではサーバーが異常終了) を修正しました。例:correlated_subqueries_default_join_kind = 'right'を指定したWITH t AS (SELECT number, * FROM numbers(3)) SELECT *, (SELECT t.number WHERE t.number >= 0) FROM t。#109114 (groeneai)。 CREATE USER ... HOST LIKE 'a', 'b'(および同等のALTER USER) で、最初のパターンのみが警告なく保持されていた問題を修正しました。指定したすべてのHOST LIKEパターンが、ユーザーのホスト許可リストに保存されるようになりました。#109187 (groeneai)。- 定数の
ON条件を持つANY JOIN(例:t1 ANY INNER JOIN t2 ON 1) で予期しない結果が返される問題を修正しました。クエリが ANY 結合の結果ではなく、完全なデカルト積を返していました #109207 (vdimir)。 - parallel_hash 結合アルゴリズムでグローバルな
max_rows_in_join/max_bytes_in_join制限が適用されず、join_overflow_mode = 'throw'を指定したクエリがSET_SIZE_LIMIT_EXCEEDEDを発生させずに成功してしまうことがある問題を修正しました。#109488 (m-selmi)。 - サーバー側のインライン挿入パース処理 (
send_table_structure_on_insert_with_inline_data = 0) において、マルチクエリストリーム内のINSERT ... VALUESの後に末尾の SQL コメント (例:VALUES (1) -- comment) が続くと、データが警告なく失われる問題を修正しました。末尾のコメントが終端の;を越えて行データとして読み取られ、ストリーム内の後続クエリが警告なくスキップされていました。#109643 (groeneai)。 PREWHEREがFINALの後に実行される場合における、optimize_move_to_prewhere = 1指定時の遅延PREWHEREの問題を修正しました。クエリ結果が変わる原因となっていた、WHERE条件が遅延された行ポリシーより前に移動される動作が行われなくなりました。#109703 (yariks5s)。- 再帰 CTE が外側のスコープの識別子を相関カラムとして解決した場合 (
allow_experimental_correlated_subqueries = 1指定時) に発生するLOGICAL_ERROR(query tree node does not have valid source node) を修正しました。このようなクエリは、明確なUNSUPPORTED_METHODエラーを返すようになりました。#109863 (groeneai)。 ORDER BY ... WITH FILLがInt64/UInt64カラム上の非常に大きなギャップをスキップする場合 (例: 2^63 付近のギャップをステップ 2 で埋める場合) に発生する符号付き整数オーバーフローを修正しました。このオーバーフローは sanitizer 下では未定義動作となり、リリースビルドでは値が警告なくラップアラウンドしていました。#109937 (groeneai)。- 旧アナライザ (
enable_analyzer = 0) 使用時に、INTERPOLATEの対象がWITH FILLカラムの別名である場合に発生するInvalid number of rows in Chunk論理エラーを修正しました。このようなクエリは、明確なINVALID_WITH_FILL_EXPRESSIONエラーで拒否されるようになりました。#110103 (groeneai)。 - 相関サブクエリ (例:
exists((SELECT ...))) を含むフィルタがconvert_query_to_cnfまたはoptimize_and_compare_chainによって最適化される際に発生する論理エラー (Unexpected number of columns in result sample block) を修正しました。#110187 (alexey-milovidov)。 - ネストされた相関
EXISTSサブクエリが、直近の外側クエリよりさらに外側のスコープ (中間スコープを飛び越えたスコープ) のカラムを参照する場合、内部エラーNOT_FOUND_COLUMN_IN_BLOCKではなく、明確なNOT_IMPLEMENTEDエラーで失敗するようになりました。#110310 (groeneai)。 - 外側のクエリの相関カラムに重複値があり、かつサブクエリが CROSS JOIN 経路で非相関化される場合に、相関スカラーサブクエリが誤った結果を返す問題を修正しました。以前は
count()やsum()などの集約関数の結果が重複数の倍数になっていました。この問題は実験的機能allow_experimental_correlated_subqueriesに影響します。#110311 (groeneai)。 - 大きな補完範囲を生成する際 (特に
INTERPOLATE使用時) に、ORDER BY ... WITH FILLがmax_execution_timeに従わず、キャンセルにも時間がかかる問題を修正しました。#110332 (alexey-milovidov)。 - 遅延実行による
FINAL最適化 (query_plan_optimize_lazy_final、デフォルトでは無効) は、クエリが sorting key の順序で読み取る場合には適用されなくなりました。この最適化の置換プランは sorting key 順に行を生成しない一方、上位のプランは read-in-order 最適化によってその順序を前提としている可能性があり、結果の順序が正しくなくなるおそれがあったためです。また、読み取る行数より小さいLIMITが読み取りステップに直接適用される場合にも適用されなくなりました。この場合、必須のセット構築処理によって早期終了の効果が失われるためです。#110576 (KochetovNicolai)。 - バックグラウンドで実行される非同期挿入の flush が、
KILL QUERYで強制終了された際に速やかに停止するようになりました。以前は、バッファされた大きなペイロードの flush が最後までパースを続け、キャンセルが無視されていました。#110652 (tiandiwonder)。 partial_mergeJOIN の上に配置されたGROUP BY ... optimize_aggregation_in_orderおよびDISTINCT ... optimize_distinct_in_orderが誤った結果を返す問題を修正しました。read-in-order 最適化がPartialMergeJoinを越えて伝播されていましたが、PartialMergeJoinは左側の入力を結合キーで再ソートするため左側ストリームの元の順序が保持されず、行が誤ってグループ化されていました。#110671 (groeneai)。INTERSECTまたはEXCEPTクエリで CTE のカラム別名を使用した場合 (例:WITH t (a, b) AS (SELECT 1, 2 INTERSECT SELECT 1, 2) SELECT a, b FROM t) に、クエリが UNKNOWN_IDENTIFIER エラーで失敗する問題を修正しました。#110885 (yariks5s)。- 複数のスレッドがリーダーを共有している状態でスピルされたブロックの読み取りが途中で失敗した際に、
grace_hash結合で発生する可能性があったLOGICAL_ERROR: ReadBuffer is canceled. Can't read from it.を修正しました。#111056 (groeneai)。 - *_hash JOIN 実行時に右側のカラムをマテリアライズする際、誤ったタイムゾーンが使用されていたバグを修正しました。#111074 (yariks5s)。
COMMENT句を含むCREATE文でコメントの文字列リテラルが欠落している場合、誤ってパースされたクエリを警告なしに受け入れるのではなく、構文エラーを発生させるよう修正しました (例:CREATE VIEW v COMMENT AS SELECT 1でコメントのないビューが作成されることはなくなりました) 。#111159 (tiandiwonder)。- 再利用されるマテリアライズド CTE (
enable_materialized_cte) が、WITH TOTALSまたはextremesの出力が破棄されるブランチ (外側の集約、INSERT ... SELECT、集合演算、EXPLAIN ANALYZEを含む) で読み取られた際に発生するLOGICAL_ERROR(Reading from materialized CTE '...' before its materialization completed - DelayedPortsProcessor gate is missing in the query plan) を修正しました。#111194 (groeneai)。 join_algorithm = 'full_sorting_merge'において、LEFT/RIGHT/FULL/ASOFJOINの結合されなかった行が、カラム型のデフォルト値ではなく生のゼロで埋められていた問題を修正しました。Enumカラム (デフォルト値は0ではなく最初の要素) では、これにより誤った結果が返され (埋められた値に対するフィルタで一致しない行が除外され、外部結合が警告なしに内部結合のように動作していました) 、さらにそのカラムを選択するとUNKNOWN_ELEMENT_OF_ENUMエラーが発生していました。#111197 (groeneai)。optimize_move_to_prewhere_if_final = 1で、かつWHERE句がソートキーのカラムに対する暗黙的なブール条件 (例:WHERE k) である場合に、FINALを指定したSummingMergeTree(およびCoalescingMergeTree) が誤った結果を返す問題を修正しました。キーカラムの値が保持されず、マージされていないパーツ間で合計された値が返されていました。#111342 (groeneai)。- 左側に
UNION ALLを経由しても残る同名の重複カラム (例:1 AS b, 1 AS b) が含まれる場合に、RIGHT/FULL JOINで発生する可能性があった論理エラー (Unexpected number of columns in result sample block) を修正しました。#111554 (groeneai)。 - AST の子ノードが置き換えられた (AST fuzzer が行うような)
EXECUTE ASクエリをフォーマットする際に、クライアントがクラッシュする問題を修正しました。ASTExecuteAsQueryは、childrenを指す所有権のないポインタを保持するのではなく、子ノードであるtarget_userとsubqueryを自身で所有するようになりました。#111725 (groeneai)。 join_any_take_last_row = 1の状態でquery_plan_join_swap_tableがANY JOINを入れ替えた場合に誤った結果が返される問題を修正しました。ClickHouse は元の結合側の順序を維持するようになったため、ANY JOINは引き続き最後に一致した行を返します。#112458 (vdimir)。- サブクエリ内で
getClientHTTPHeaderを使用した際に発生するContext has expired例外を修正しました。#112533 (alexey-milovidov)。 ON句に混合条件、すなわちON (t1.key = t2.key) AND (t1.a * 10 < t2.a)のような両側にまたがる非等価の残余条件を含むJOINが誤った結果を返す問題を修正しました。このような条件を評価できるのはハッシュ系アルゴリズムのみですが、full_sorting_merge、partial_merge、およびダイレクトキー・バリュー結合は、これらの結合を実行可能と判定したうえで残余条件を警告なしに無視し、余分な行を返していました。現在はこれらのアルゴリズムが実行を辞退し、代わりにハッシュアルゴリズムが使用されます。#112831 (groeneai)。WHEREでrandなどの非決定論的な expression を介して 2 つのテーブルのカラムを比較するカンマ結合またはCROSS結合で、誤った結果が返される問題を修正しました。結合をINNER結合に書き換える際に expression が結合キーへ移動され、両側の行ごとに再評価されていたため、このようなクエリは自身のWHERE句と矛盾する行を返す可能性がありました。#112938 (groeneai)。- 認識できない文字が末尾に長く続く PromQL クエリ (例: NUL バイトでパディングされた
FixedString値) をパースする際に、処理時間が二次関数的に増大する問題を修正しました。メガバイト規模の不正な入力をパースすると、スレッドが数十分間占有され続けていました。また、パースはクエリ解析中に行われるため、キャンセルもできませんでした。現在は、パーサーは最初のエラーで停止します。#112944 (alexey-milovidov)。 - 非定数カラムに対して定数の除数 -1 で
intDivを実行した場合、符号付き整数の最小値の除算 (例:intDiv(-9223372036854775808, -1)) が、他の実行パスのようにILLEGAL_DIVISION例外をスローせず、暗黙的にラップアラウンドしていた問題を修正しました。このラップアラウンドにより、ORDER BY/DISTINCTの結果が誤る可能性もありました。read-in-order 最適化は負の定数によるintDivを正しく単調関数として扱いますが、ラップアラウンドした値がその前提となるソート順に違反していたためです。#113048 (alexey-milovidov)。 enable_analyzer = 0の場合に、WHEREがサブクエリ内のuntupleによって生成されたカラムを参照するとUNKNOWN_IDENTIFIERが発生する問題を修正しました (例:SELECT t.keys FROM (SELECT untuple(arrayJoin(m)) AS t FROM ...) WHERE t.values > 0) 。enable_optimize_predicate_expressionによる書き換えにより、このような述語が、その名前がまだ存在しない段階のサブクエリ内へHAVINGとしてプッシュダウンされていました。#113760 (groeneai)。- 右側が totals を持つ場合に、
join_algorithm = 'partial_merge'を指定したJOINで誤った結果が返される問題を修正しました。右側がマージされないまま残ることがあり、その結果LEFT結合では実際に一致する行の代わりにデフォルト値が使われ、INNER/RIGHT結合では行がまったく返されませんでした。また、RIGHT/FULLの非結合パスでは、同じステートが原因でヌルポインタが参照され、サーバーがクラッシュしていました。#113936 (groeneai)。 - 入力全体を読み取る必要がある
LIMITを伴うSELECT DISTINCTで、誤った結果が返される問題を修正しました。LIMIT n WITH TIESでは同順位の行が欠落し、exact_rows_before_limit = 1では切り詰められたrows_before_limit_at_leastが報告され、GROUP BY ... WITH TOTALSではストリームの先頭部分だけから totals 行が計算されていました。#114025 (groeneai)。 FINALがマージに必要とするカラム (ver、is_deleted、sign) をPREWHEREで使用しながら、そのカラムを選択しないSELECT ... FINALで、LOGICAL_ERROR(“Unexpected number of kept output positions after removing unused columns fromReadFromMergeTree”) が発生する問題を修正しました。#114746 (groeneai)。- 非同期 INSERT のフラッシュ、マテリアライズドビューの処理、および
EXPLAIN ANALYZEにおいて、期限切れのクエリ追跡ステートにアクセスする可能性があったライフタイムの問題を修正しました。#114940 (azat)。 - インターバル間を区切るカンマが省略された場合に、
CREATE QUOTAおよびALTER QUOTAが最後のFOR INTERVALブロック以外をすべて暗黙的に破棄していた問題を修正しました。このようなステートメントは成功するものの、それより前の制限は一切設定されていませんでした。現在は、2020 年以前と同様に、インターバルが再び累積されるようになりました。#115320 (groeneai)。 - 呼び出しごとに異なる別名が付与されている場合に、
randConstantが 1 つのクエリ内で 2 つの異なる値を返す問題を修正しました。randConstantはクエリ全体で単一の値を保持すると説明されており、SELECT randConstant() = randConstant()はすでに1を返していましたが、SELECT randConstant() AS a, randConstant() AS bのように別名を付けると、互いに無関係な 2 つの値が返されていました。#115384 (alexey-milovidov). - 破損した
MsgPackまたはProtobufListファイルに対してSELECT count()が終了しない、あるいは実在しない行数を返す問題を修正しました。optimize_count_from_filesの高速パスでは、読み取り位置が進むことを確認せずに行をカウントしていたため、2 バイトのProtobufListファイルから数十億行がカウントされ、結果が返りませんでした。このような入力は、通常の読み取りパスと同じエラーで拒否されるようになりました。#115884 (groeneai). system.distribution_queueのbroken_data_filesおよびBrokenDistributedFilesToInsertメトリクスが常に0を示す問題を修正しました。起動時に非同期挿入キューをスキャンする際、DistributedAsyncInsertDirectoryQueue::initializeFilesFromDiskは破損バイト数をカウントしていた一方で、破損ファイルのカウンターをインクリメントしていませんでした。#92124 (squalfof).
その他のバグ修正
- 内部クエリの一部として実行されるセカンダリクエリが、内部クエリとしてログに記録されるようになりました。#108506 (mstetsyuk)。
- PREWHERE 条件が複数の読み取りステップに分割された場合に、パーツ内に存在しない DEFAULT カラムが DEFAULT expression ではなく型のデフォルト値で埋められてしまう問題を修正しました。#111795 (yariks5s)。
normalized_query_hashをキーとするクォータが、すべてのリソース (read_rows、read_bytes、result_rows、result_bytes、execution_time、written_bytes、errors) を、ユーザーごとに共有される単一のバケットではなく、クエリ数カウンターと同様にクエリパターンごとに計上するようになりました。#107681 (alexey-milovidov)。- MySQL の
connect_timeoutおよび読み取り・書き込みタイムアウトが有効にならない問題を修正しました。サンプリングクエリプロファイラの定期的なシグナルによって MySQL クライアント内部のポーリング期限がリセットされ続けていたため、connect_timeout = 1を指定していても、応答しない MySQL サーバーへの接続試行が 2 分以上ハングすることがありました。#109592 (tiandiwonder)。 - クエリプロファイラが有効な間、ストリーミング挿入のブロック待機タイムアウト (
input_format_max_block_wait_ms) が期限切れにならないことがある問題を修正しました。プロファイラのシグナルを受けるたびにファイルディスクリプタのポーリングがタイムアウト値を最初からやり直して再開されていたため、入力ソースが停滞すると、本来は待機上限に達した時点で行われるはずの部分ブロックの flush が無期限に遅延する可能性がありました。#109602 (tiandiwonder)。 - 実験的な設定
make_distributed_plan = 1を指定したクエリで、distributed_plan_default_reader_bucket_countまたはdistributed_plan_default_shuffle_join_bucket_countに非常に大きな値を指定した場合にLOGICAL_ERROR(std::length_error) が発生する問題を修正しました。このような値はINVALID_SETTING_VALUEとして拒否されるようになりました。#109770 (groeneai)。 distinct_overflow_mode = 'break'の動作を修正しました。DISTINCT は、ドキュメントに記載されているとおり、上限に達するまでに蓄積された部分的な結果を返し、ソースの読み取りを停止するようになりました。以前は、max_rows_in_distinct/max_bytes_in_distinctを超えた chunk が破棄され (結果が切り詰められるか空になる)、クエリは入力の最後まで読み取りとハッシュセットへの挿入を続けていたため、MEMORY_LIMIT_EXCEEDEDで終了することがありました。#110075 (skuznetsov-clickhouse)。optimize_aggregation_in_orderがクエリのキャンセルを無視する問題を修正しました。AggregatingInOrderTransformが chunk の集約中にキャンセルを確認するようになったため、KILL QUERYやmax_execution_time(デフォルトのtimeout_overflow_mode = 'throw'の場合) によって停止されたクエリは、chunk 全体の処理を待たずに速やかに停止します。#110104 (groeneai)。mysql/postgresql/sqlite系の PostgreSQL ソースの値を、パースできない宣言型 (例:Int32として宣言されたtextカラム) に読み込む際に、サーバーが異常終了する問題 (debug ビルドおよび sanitizer ビルド) を修正しました。このような型の不一致は、サーバーを異常終了させずにクエリエラーとして報告されるようになりました。#110264 (groeneai)。- 特定の PRQL クエリ (
SET dialect = 'prql') のパース時にサーバーが異常終了する問題を修正しました。prqlcコンパイラ内部で発生した panic が、クエリエラーとして報告されずにプロセスを異常終了させていました。#110316 (groeneai)。 - row policy と
additional_table_filtersが、クエリ内で他に選択されていない同一のカラムを参照している場合にNOT_FOUND_COLUMN_IN_BLOCKが発生する問題を修正しました。#111099 (groeneai)。 - 極端なパラメータを指定した場合に
randChiSquared、randStudentT、randFisherF、randBinomialがハングする問題を修正しました。この場合、クエリをmax_execution_timeやKILL QUERYで中断できませんでした。現在は、max_rand_distribution_parameterまたはmax_rand_distribution_trialsが 0 に設定されている場合でも、このようなパラメータは拒否されます。また、randBinomialではmax_rand_distribution_trialsをデフォルト値の 10^9 より大きく設定できなくなりました。#111909 (alexey-milovidov). connection_pool_max_wait_msを修正し、ドキュメントに記載されたデフォルト値0が無限のタイムアウトを意味するようにしました。以前は、接続プールが満杯であることを検出したクエリがタイトループで再試行を繰り返し、CPU を消費しながら反復ごとにNo free connections in pool. Waiting 0 ms.をログに出力していました。現在は、接続がプールに返却されるまで待機します。#112380 (groeneai).replaceOne、replaceAll、replaceRegexpOne、replaceRegexpAllがmax_execution_timeとKILL QUERYを無視する問題を修正しました。1 回の呼び出しの処理中にもキャンセルを確認するようになったため、大きな値や大量の行に対する長時間の置換処理は、完了までサーバースレッドを占有し続けることなく停止します。このような呼び出しには返せる部分的な結果がないため、timeout_overflow_mode = 'break'の場合は期限超過をエラーとして発生させます。これは、定数畳み込みされた場合は常に、またパイプラインでは executor のブロック間チェック (こちらは引き続きクエリをエラーなしで停止します) より前にこのチェックポイントに到達した場合に発生します。#112483 (groeneai).countSubstrings、countSubstringsCaseInsensitive、countSubstringsCaseInsensitiveUTF8がKILL QUERYとmax_execution_timeを無視する問題を修正しました。多数の行や多数の一致を対象とする呼び出しが、クエリのキャンセル後も数分間実行され続けることがありました。#113369 (groeneai).- イニシエーター上でクエリが非常に短時間で完了した場合に、クエリが (
receive_timeout秒間) ハングする可能性がある問題を修正しました。#113551 (nickitat). - 1 つの大きな値に含まれる一致数をカウントする際に、
countMatchesとcountMatchesCaseInsensitiveがmax_execution_timeとKILL QUERYを無視し、キャンセルされたクエリが数分間実行され続ける問題を修正しました。引数が定数の場合、呼び出しはクエリ解析中に行われるため、それをキャンセルできるパイプラインが存在しません。#113886 (groeneai). - クエリが
max_execution_timeに達する最大 1 ms 前にキャンセルされ、Timeout exceeded: elapsed 999.672 ms, maximum: 1000 msという矛盾したエラーで失敗することがある問題を修正しました。#114559 (alexey-milovidov). - バウンディングボックスが有界でない定数ポリゴン (例: 座標が
+-DBL_MAXに達する場合) を指定したときに、pointInPolygonで範囲外読み取りが発生する問題を修正しました。このようなポリゴンはBAD_ARGUMENTSで拒否されるようになり、空のリングを持つポリゴンは内部を持たないものとして扱われます。以前は、クエリが誤った結果を返したり、ハードニングやサニタイザを有効にしたビルドではサーバーが異常終了したりする可能性がありました。#115035 (groeneai). STREAM BOUNDEDクエリが、開始前にコミットされた行よりも少ない行 (通常は 0 行) を返す可能性がある競合状態を修正しました。#115543 (alexey-milovidov).make_distributed_plan = 1の場合に、ウィンドウクエリのソート列がその列を参照しないExpressionステップを通過すると、クエリプランの最適化中にUnknown identifierが発生する問題を修正しました。#115890 (groeneai).h3kRing、h3HexRing、h3Line、h3ToChildrenが行のブロックを展開する際にmax_execution_timeおよびKILL QUERYを無視する問題を修正しました。#115893 (alexey-milovidov).- ネイティブ Parquet V3 リーダーにおいて、
PREWHEREの連言が共通の中間 expression を共有している場合にNOT_FOUND_COLUMN_IN_BLOCKが発生する問題 (以前のリグレッションに起因) を修正しました。#107059 (groeneai). output_format_parquet_parallel_encodingが有効 (デフォルト) かつmax_threadsが 1 より大きい状態で Parquet を書き込む際にハングする問題を修正しました。エンコーダーが追加スレッドのスケジュールに失敗すると、稼働中スレッドのカウンターがアンダーフローし、書き込みが完了もエラー報告もしないまま恒久的に停止する可能性がありました。#112959 (groeneai).- Thrift メタデータが、メタデータ自体のサイズを超えるコンテナーまたは文字列の長さを宣言している Parquet ファイルを読み込む際に、メモリが無制限に割り当てられる問題を修正しました。このような長さは、メモリを割り当てずに拒否されるようになりました。#113212 (groeneai).
- Parquet v3 リーダーにおいて、フィルター評価にのみ必要なカラムが、その出力スロットが既に破棄された後にデコード対象としてスケジュールされた場合に
std::out_of_range例外 (Logical error: 'std::exception. Code: 1001, type: std::out_of_range'。debug ビルドおよび sanitizer ビルドではサーバーも異常終了します) が発生する問題を修正しました。#113956 (groeneai). - profile events および memory tracker におけるデータ競合を修正しました。#112466 (mstetsyuk).
trace_profile_events_list設定を使用して特定の profile events のスタックトレースをsystem.trace_logに書き込む際に、profile events で理論上発生し得るデータ競合を修正しました。#113553 (mstetsyuk).- 除算が浮動小数点例外 (ゼロ除算または
INT_MIN / -1) を引き起こす場合に、intDivOrNull、moduloOrNull、positiveModuloOrNullがNULLではなく0を返す問題、およびintDivOrNullとintDivOrZeroがNULL/0を返さずに例外を送出する問題を修正しました。符号付きと符号なしが混在した引数の場合も対象です。#101976 (yariks5s). ArrayおよびMapの値をNULLと比較する場合のIS DISTINCT FROMの問題を修正しました。#103162 (ylw510).- パラメトリック形式と 2 引数形式が混在する場合 (例:
groupConcat(',', 2)(x, '/')) のgroupConcatの問題を修正しました。行数制限のパラメータが警告なく破棄され、要求した行数ではなくすべての行が返されていました。現在は、2 番目の引数で指定した区切り文字がパラメータを正しくオーバーライドします。#104882 (yariks5s). - 小さいインターバル単位から大きいインターバル単位へ CAST する際のバグを修正しました。#105058 (yariks5s).
- read-in-order パイプライン (
optimize_read_in_order = 1およびread_in_order_use_virtual_row_per_block = 1) で実行されるLIMIT ... WITH TIESクエリで発生する論理エラー (Assertion 'row < chunk.getNumRows()' failed) を修正しました。#105102 (groeneai). enable_sharding_aggregator = 1をUNION ALLと併用し、かつmax_streams_for_union_stepがパイプライン幅より小さいクエリでLogical error: 'Pipeline stuck'が発生する問題を修正しました。BufferedShardByHashTransformは、入力が尽きた時点で、キューが空の出力ポートを直ちに終了するようになりました。また、要求された空のポートに排出可能なデータがない場合は、兄弟キューがバックプレッシャーの上限に達していても入力の取得を続けるようになりました。#106251 (groeneai).plainオブジェクトストレージディスク (s3_plainなど) でremoveDirectoryを実行すると、空でないディレクトリであっても再帰的な削除と同様に内部のファイルがすべて削除されてしまう問題を修正しました。空でないディレクトリの削除はCANNOT_RMDIRで失敗するようになり、再帰的な削除では内容を明示的に処理するようになりました。#106281 (RinChanNOWWW).<lifetime>を設定したexecutable_poolユーザー定義関数で、基となるスクリプトの変更が反映されない問題を修正しました。これまでは、編集後のスクリプトを再読み込みできるのはSYSTEM RELOAD FUNCTIONSのみで、<lifetime>による定期的な再読み込みでは古いバージョンが実行され続けていました。#107087 (groeneai).- ワーカースレッドによるプロファイラーの開始とサーバーのシャットダウンが競合した際に、サーバー全体で共有されるトレースコレクターでデータ競合が発生する問題を修正しました。#107307 (groeneai).
threadPoolCallbackRunnerUnsafe経由でスケジュールされたタスクが実行前にスレッドプールのキューから破棄されることで、シャットダウン時にまれにサーバーが異常終了する問題 (std::future_error、“The associated promise has been destructed prior to the associated state becoming ready”) を修正しました。#107383 (groeneai).- 監視対象のファイルが削除され、同じ inode を再利用して再作成された場合に発生することがあった
FileLogの論理エラー (Last stored last_written_position in meta file ... is bigger than current last_written_pos) を修正しました。#107617 (groeneai). saturateおよびignoreオーバーフローモードで、toTime64とCAST(... AS Time64)が範囲外の値をTime64の範囲内に収めない問題を修正しました。この問題により、表示は同じでも比較すると異なる値が生成されることがありました。#108028 (alexey-milovidov).- 正規表現の「全一致」関数
extractAll、extractAllGroupsVertical、extractAllGroupsHorizontal、countMatches、splitByRegexpで、ゼロ幅アサーション (\b、^、$) が正しく処理されない問題を修正しました。たとえば、extractAll('new york is the greatest', '\b(\w)')は、すべての文字ではなく各単語の先頭文字を正しく返すようになりました。#108047 (alexey-milovidov). splitByNonAlpha以外のトークナイザーを使用するテキスト索引に対してhasTokenを使用すると、誤った結果が返される問題を修正しました。#108066 (rschu1ze).- 入力の精度がインターバルの単位より細かい場合に、
toStartOfIntervalとdateTruncが、その値を含むインターバルの開始時点ではなく丸められた値を返す問題を修正しました。たとえば、toStartOfInterval(toDateTime64('2023-10-09 10:11:12.000999', 6), INTERVAL 1 millisecond)は10:11:12.000ではなく10:11:12.001を返していました。明示的な起点を指定するオーバーロードも同様の影響を受けていました。#108186 (yariks5s). replaceRegexpOneおよびreplaceRegexpAllにおいて、他の正規表現関数と同様に、.がデフォルトで改行文字にマッチするよう修正しました。#108265 (linjiayu1025-collab)。- 論理更新 (lightweight UPDATE) /DELETE の条件が 2 回評価される問題を修正しました。#108323 (ofeliacode)。
- 定数でない limit 引数を指定した場合の
arrayPartialSort()の不具合を修正しました。#108327 (vitlibar)。 - パターンに NUL (
\0) バイトが含まれている場合に、正規表現関数 (match、extract、extractAll、replaceRegexpOne、replaceRegexpAllなど) がエラーを出さずに誤った結果を返す問題を修正しました。NUL は RE2 と同様に、通常のリテラルバイトとして扱われるようになりました。#108427 (alexey-milovidov)。 DateTime64(N)型の引数に対してchangeYear/changeMonth/changeDay/changeHour/changeMinute/changeSecondを実行すると、結果カラムがNではなくハードコードされたデフォルトのスケール (3) で作成される問題を修正しました。値はスケールNで計算されていた一方、カラムオブジェクトはスケール 3 として宣言されていたため、型と構造的に整合しない状態になっていました。#108551 (groeneai)。- 集合演算 (
INTERSECT/UNION ALL/EXCEPT) で相関サブクエリを使用する分岐を結合し、かつcorrelated_subqueries_default_join_kind = 'left'が設定されている場合に発生するLOGICAL_ERROR(“Trying to extract chunk from ChunkBuffer before all inputs are finished”) を修正しました。#108554 (groeneai)。 changeYear、changeMonth、changeDay、changeHour、changeMinute、changeSecondにおけるDateTime64の不具合を修正しました。ナノ秒精度 (スケール 9) の入力でDECIMAL_OVERFLOWがスローされなくなり、エポック以前の 1 秒未満の端数を含む入力に対しても正しい暦上の秒が返されるようになりました。#108681 (takumihara)。- 非常に大きな正規表現 (例えば数十万個のワイルドカードを含む
LIKEやmatchのパターン) をコンパイルする際に、サーバーログが過剰に出力されたり、エラーメッセージが過度に長くなったりしないようにしました。このようなパターンは、明確なCANNOT_COMPILE_REGEXPエラーで失敗するようになりました。#108821 (Algunenano)。 - ソースとターゲットの物理型が同じ場合に、
reinterpret(x, 'Decimal128(scale)')(およびDecimal32/Decimal64/Decimal256/DateTime64をターゲットとする場合) が、要求されたターゲットのスケールではなくソースのスケールを内部スケールとして持つ結果カラムを生成する問題を修正しました。値自体は正しかったものの、カラムオブジェクトが宣言された型と構造的に整合しない状態になっていました。#108878 (groeneai)。 - 同期ずれやファジングが発生した接続において、範囲外のプロトコルパケットタイプを文字列化する際 (例: “Unexpected packet from server” / “Received … packet” エラーメッセージ内) に発生する未定義動作を修正しました。#108885 (groeneai)。
DateTime64(N)に対するchangeYear/changeMonth/changeDay/changeHour/changeMinute/changeSecondが、結果カラムをNではなくハードコードされたデフォルトのスケール 3 で構築していた問題と、DateTime64に対するtimeSlotsが、宣言された戻り値の型においてオプションのSize引数のスケールを無視していた問題を修正しました。いずれも物理的なスケールが宣言された型と一致しないカラムを生成していたため、その結果をarrayPushBack/arrayPushFront/arrayConcatに渡すとLOGICAL_ERROR(writeSlice expects same column types) が発生していました。また、Sizeに最大のスケールを指定したtimeSlotsは誤ったタイムスタンプを返していました。#108994 (groeneai)。- ProfileEvents のインクリメントが単調増加にならない問題を修正しました。#109180 (azat)。
- 指数の絶対値が
Int32をオーバーフローするSAMPLE比率 (例:SAMPLE 1e-3000000000) が、警告なしにSAMPLE 1として扱われていた問題を修正しました。#109197 (Algunenano)。 toUTCTimestamp/fromUTCTimestamp(およびそのエイリアスであるto_utc_timestamp/from_utc_timestamp) とtoTime64のDateTime64処理パスにおける 2 つのバグを修正しました。1 つ目は、Int64の境界付近で発生する符号付き整数オーバーフローです (現在はInt128で計算し、表現可能な範囲にクランプします)。2 つ目は、タイムゾーンオフセットの境界付近で負の小数値に対して誤った結果が返される問題です。秒への分割がゼロ方向に切り捨てられていたため、timezoneOffset()が次の秒を参照してしまい、DST/オフセット変更の前後を取り違える可能性がありました。#109738 (groeneai)。- row policy のフィルタ式で
arrayJoinを使用した場合に発生する論理エラー (column->size() == num_rows) を修正しました。今後、このようなフィルタは拒否されます。#109753 (Algunenano)。 - 型のネストが内部の深さ制限を超えた場合に、
generateRandomStructure()が 2 つのデータ型が連結された無効な構造文字列 (例:Decimal32(7)IPv4) を生成することがあり、結果を解析できなくなっていた問題を修正しました。#109928 (groeneai)。 accurateCastOrDefaultにおけるクエリ設定の伝播と、DynamicおよびVariantでエンコードされた元のNULLの保持に関する問題を修正しました。#109946 (Avogar)。#114912 (alexey-milovidov)。max_bytes_in_distinctとmax_bytes_in_setを修正しました。文字列キーは制限チェックの対象外であるアリーナに格納されていたため、文字列キーに対する DISTINCT / IN が、キーのペイロード全体の分だけ (キー長に応じて際限なく) バイト制限を超えてメモリを保持する可能性がありました。現在はドキュメントの記載どおり、アリーナも制限の計算に含まれます。そのため、バイト制限に近い文字列キーを扱うクエリは、以前より早く制限に達する場合があります (これは正しい動作です)。#110120 (skuznetsov-clickhouse)。- 内部次元のサイズがゼロの Npy ファイルを読み取る際に、マテリアライズされた行と、最適化の有無にかかわらず
count()の結果が一致するよう修正しました。#110146 (qiuyanjun888)。 indexHint/ignore/isZeroOrNull関数に、型がNothingに解決される引数が渡された場合 (例:indexHint(assumeNotNull(materialize(NULL)))のような式の内部) に発生する論理エラー (debug/sanitizer ビルドではサーバーがアボートする) を修正しました。#110192 (groeneai)。plain_rewritableディスク上で、既存のパスが異なるサイズの内容で書き換えられた後にファイルを読み取ると失敗する問題を修正しました。インメモリのメタデータが古いファイルサイズを保持し続けるため、読み取りがUNEXPECTED_END_OF_FILEで失敗する可能性がありました。#110304 (thevar1able).- 計算されたフェッチ件数が切り捨てによりゼロになり、ANN 検索結果が空になるのを防ぐため、1.0 未満の
vector_search_index_fetch_multiplierの値を拒否するようにしました。#110452 (tamish560). initializeAggregation('sumState', 0::UInt64)のような数値キャストを含む式を持つ値を挿入する際に、Cannot parse string ... as UInt64 ... While executing ValuesBlockInputFormatエラーが散発的に発生することがある問題を修正しました。#110637 (groeneai).readWKTが先頭に空白文字を含む WKT 文字列 (例:readWKT(' POINT(1 2)')) を拒否していた問題を修正しました。こうした文字列は、型付きのreadWKTPoint/readWKTPolygon/… リーダーや WKT の文法では受け入れられます。#110706 (groeneai).- 長さゼロのインターバルを持つクォータ (例: CREATE QUOTA q FOR INTERVAL 0 SECOND MAX queries = 1000) が消費された際に、サーバーがクラッシュする (整数のゼロ除算) 問題を修正しました。クォータのインターバル期間が正の値でない場合は、クォータ作成時に拒否されるようになりました。#110846 (PedroTadim).
- FIPS ビルドで Ed25519 SSH 鍵 (
CREATE USER ... IDENTIFIED WITH ssh_key ... TYPE 'ssh-ed25519'、またはusers.xml内の同種の鍵) を使用するとクラッシュする問題を修正しました。Ed25519 は FIPS 承認済みではないため、このような鍵はわかりやすいLIBSSH_ERRORエラーで拒否されるようになりました。#110891 (thevar1able). QBitに対する転置距離関数 (cosineDistanceTransposed、L2DistanceTransposed、dotProductTransposed) は、precision個のビットプレーンに切り詰められた値を、粗いセルの下端 (切り捨てたビットをゼロで埋めたもの) に復元する代わりに、有界な低精度の復元を用いるようになりました。ゼロ埋めでは復元されたすべての値がゼロ寄りに偏り、低精度では退化していました。たとえばQBit(BFloat16)の精度 1 では符号ビットしか残らないため、すべての値が±0.0に復元され、距離はどの行でも同じ定数となり、順位付けに使える情報が一切ありませんでした。現在は、どのビットが切り捨てられるかに応じて復元方法が決まります。生のInt8コードはセルの中心に復元されます (...TransposedQuantizedパスですでに使われていたLloyd-Maxの復元と同じです) 。精度 1 の浮動小数点値は適切な符号量子化となります。指数部をすべて保持し、仮数部のビットのみを切り捨てる浮動小数点値は、自身のバイネード内の有界な中点に復元されます (ただし、真のゼロや±0.0は厳密なゼロのまま維持され、非有限のセルは除外されるため、±infも厳密に無限大のままです。曖昧なNaNセルについては後述の注記を参照してください) 。さらに、指数部のビットが切り詰められている段階では有界な下端が維持されるため、precisionを小さくしても値の大きさが桁違いに膨れ上がることはなく、精度と引き換えに速度を得られます。フル精度の結果は変わりません。#110911 (alexey-milovidov).- 型ツリーで宣言されたカラム数がストライプフッターのカラムエンコーディング数を上回る破損した ORC ファイルに対してスキーマ推論を行うと、ネイティブ ORC リーダーで範囲外読み取りが発生する問題を修正しました。debug/sanitizer ビルドでサーバーが異常終了する代わりに、
CANNOT_EXTRACT_TABLE_STRUCTUREで拒否されるようになりました。#110967 (groeneai). - 各 SSH 鍵が
max_authentication_methods_per_userの上限に個別にカウントされるようになり、構文に関係なく上限が一貫して適用されるようになりました。以前は、単一のssh_keyメソッド内の複数の鍵は 1 つとしてカウントされていました。#111181 (TheMC47)。 - Iceberg REST カタログで認証情報が古くなっている場合、
UNKNOWN_TABLEを暗黙的に報告するのではなく、根本原因となったエラーとともに報告するようになりました。#111379 (alesapin)。 POINT M EMPTYのような次元タグ付きの空のポイントに対して、readWKTPoint/readWKTが未初期化の座標 (スカラー) または前の行の座標 (ベクトル化) を返す問題を修正しました。このような入力は、POINT EMPTYと同様にCANNOT_PARSE_TEXTで拒否されるようになりました。#111517 (groeneai)。minmax統計の作成時に、例外をスローするのではなく警告を出すようになりました。#111785 (hanfei1991)。- 退化した確率
0および1の場合でも、試行回数に関係なくrandBinomialを使用できるようにしました。#112021 (alexey-milovidov)。 system.s3_queue_settingsがbucketing_mode、partitioning_mode、partition_regex、partition_componentに誤った値を表示する問題を修正しました。#112300 (bharatnc)。- PromQL クエリのエラー発生位置を正しく報告するようにしました。#112494 (fallintoplace)。
SYSTEM DISABLE FAILPOINTで存在しないフェイルポイント名を指定した場合、SYSTEM ENABLE FAILPOINTと同様にBAD_ARGUMENTSを発生させて拒否するようになりました。以前は、名前を誤入力しても成功と報告され、意図したフェイルポイントは有効なままで、何も無効化されていないことに気付く手段がありませんでした。#112680 (groeneai)。- 削除後に再追加されたカラムの
Nested要素サブカラムを、誤った型で読み取る問題を修正しました。このようなサブカラムをその親カラムと一緒に SELECT すると、ブロック上は要素の型が宣言されたまま、サブカラムの位置に要素全体が返されていました。その結果、リリースビルドでは不定な値が返され、デバッグビルドおよびサニタイザービルドでは論理エラーが発生していました。#112769 (groeneai)。 - 単位が重複している、または大きい単位から順に並んでいない PromQL の期間指定を拒否するようにしました。#112954 (fallintoplace)。
replaceRegexpOne/replaceRegexpAllで、置換文字列がマッチに関与しなかったキャプチャグループを参照する場合 (例:replaceRegexpAll('abc', '(a)|(b)', '\\2')) に発生する未定義動作 (memcpyへの null ポインタの受け渡し) を修正しました。#113012 (alexey-milovidov)。- ClickHouse 26.3 で
unicode_wordトークナイザーを使用して作成したテキスト索引を、それ以降のバージョンで読み込めない非互換性を修正しました #113061 (rschu1ze)。 - PromQL の文字列エスケープで、無効な Unicode サロゲートコードポイントを拒否するようにしました。#113203 (fallintoplace)。
- PromQL 文字列で、区切り文字をまたぐ無効なエスケープを拒否するようにしました。#113587 (fallintoplace)。
- ウィンドウフレーム上で
theilsUを使用した際、最初の引数がフレーム内で定数の場合に 0 ではなく不定の値が返される問題を修正しました。#113691 (alexey-milovidov). - Native プロトコル経由で受信した、
Replicated方式でシリアル化された不正な形式のカラムの一部について、報告されるエラーコードを修正しました。これらはLOGICAL_ERROR(デバッグビルドおよびサニタイザービルドではサーバーが異常終了していました) ではなく、INCORRECT_DATAとして拒否されるようになりました。#114186 (Avogar). - スケールの小さい
Decimal64をリスケールする際にInt64がオーバーフローすると、誤った (多くの場合は符号が反転した)Time64リテラルやINリスト定数が生成される問題を修正しました。このような変換では、DateTime64の分岐や明示的なCASTと同様にDECIMAL_OVERFLOWが報告されるようになりました。#114546 (groeneai). - PromQL セレクターで引用符付きのメトリクス名およびラベル名をサポートしました。#114551 (fallintoplace).
- attach スレッド経由で実行された起動処理が失敗した後、
ReplicatedMergeTreeテーブルがいつまでも読み取り専用のままになる問題を修正しました。再起動のリトライが正しくスケジュールされるようになり、自動復旧とそれに伴うセッションチェックが再び機能するようになりました。#114802 (azat). timeSeriesRangeおよびtimeSeriesFromGridでは、開始/終了タイムスタンプが符号なしの値として読み取られていたため、1970 年より前のタイムスタンプに対して誤ってDECIMAL_OVERFLOWがスローされていました。また、DateTime/UInt32のタイムスタンプでは、ステップが警告なく下位 32 ビットに切り詰められていました。現在はすべての計算がInt64で行われます。#114815 (vitlibar).- クエリが
MEMORY_LIMIT_EXCEEDEDで失敗した後に非同期挿入で例外が発生する可能性がある問題を修正しました。また、async_insert_queue_flush_on_shutdownを修正し、サーバーのシャットダウン時にキュー内の挿入処理が flush されるようにしました。#114839 (azat). sequenceMatch、sequenceCount、sequenceMatchEventsのパターンにイベント番号0が含まれる場合 (例:sequenceMatch('(?0)')) に、out_of_range例外が内部エラーCode: 1001として発生する問題を修正しました。このようなパターンはBAD_ARGUMENTSで拒否されるようになりました。また、sequenceMatch('(?1)(?t>+)(?2)')のように符号のみを含む時間条件は、これまで警告なく(?t>0)として扱われていましたが、SYNTAX_ERRORで拒否されるようになりました。#115056 (groeneai).- 座標が
Float64でない場合に、geoToH3のエラーメッセージで示される引数の位置と型が誤っていた問題を修正しました。デフォルトのgeotoh3_argument_order = 'lat_lon'では、メッセージがもう一方の引数を指し、その引数の型を表示していました。#115503 (groeneai). - text、tokenbf_v1、ngrambf_v1 インデックスにおける不正なバックスラッシュのエスケープ文字を修正しました。#115634 (ahmadov).
TZ環境変数が空の場合にサーバーが起動できない問題を修正しました。#68921 (ardenwick).