> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloud v26.8 변경 로그

> v26.8 변경 로그

<h2 id="backward-incompatible-changes">
  하위 호환되지 않는 변경 사항
</h2>

<h3 id="query-function-and-syntax-changes">
  쿼리, 함수 및 구문 변경 사항
</h3>

* 본문이 단일 `Distributed` 테이블에 대한 단순 `SELECT`인 뷰는 이제 외부 쿼리 전체가 세그먼트로 푸시다운됩니다(새 설정 `optimize_trivial_view_pushdown_to_distributed`, 기본적으로 활성화됨). 이에 따라 이러한 뷰의 관찰 가능한 동작이 달라집니다. 뷰 참조에 지정한 `FINAL`과 `SAMPLE`은 이제 무시되지 않고 세그먼트 로컬 테이블로 전달되며, 단일 세그먼트 클러스터에서는 `extremes`가 보고되지 않습니다. 이전 동작으로 되돌리려면 `optimize_trivial_view_pushdown_to_distributed = 0`으로 설정하십시오. [#101791](https://github.com/ClickHouse/ClickHouse/pull/101791) ([simonmichal](https://github.com/simonmichal)).
* 경량 `UPDATE` 패치 파트는 이제 (`sorting_key..., _block_number, _block_offset`) 기준으로 정렬된 새로운 v2 온디스크 포맷을 사용하며, 새로운 머지 알고리즘으로 적용됩니다. 최대 메모리 사용량은 전체 패치가 아니라 정렬 키가 동일한 가장 큰 구간 크기로 제한되며, 머지 경계를 넘는 업데이트도 더 이상 인메모리 Join 적용 방식으로 대체되지 않습니다. 이전 포맷의 패치 파트도 계속 읽을 수 있습니다. 26.8 이전 버전에서 롤링 업그레이드를 진행하는 동안에는 모든 레플리카의 업그레이드가 완료될 때까지 `patch_parts_version = 'v1'`을 유지하거나 `compatibility` 설정을 사용하십시오. [#103182](https://github.com/ClickHouse/ClickHouse/pull/103182) ([CurtizJ](https://github.com/CurtizJ)).
* `AggregatingMergeTree`는 이제 정렬 키에 속하지도 않고 집계 상태 측정값(`AggregateFunction`/`SimpleAggregateFunction`)도 아닌 컬럼이 포함된 스키마를 테이블 생성 시점에 거부합니다. 이러한 컬럼은 백그라운드 머지 중에 경고 없이 임의의 값 하나로 합쳐지므로, 해당 컬럼으로 `GROUP BY`하거나 필터링하는 쿼리가 잘못된 결과를 반환합니다. 이전 동작으로 되돌리려면 `allow_dimensions_outside_sorting_key = 1`로 설정하십시오. [#108087](https://github.com/ClickHouse/ClickHouse/pull/108087) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* ClickHouse는 이제 동기 및 비동기 삽입 모두에 항상 통합 삽입 중복 제거 해시를 사용하며, 기존의 삽입별 중복 제거 동작은 제거되었습니다. 서버 설정 `insert_deduplication_version`은 마이그레이션 보호 장치로 유지됩니다. 이 설정이 레거시 값(`old_separate_hashes` 또는 `compatible_double_hashes`)으로 지정되어 있으면 서버가 시작되지 않습니다. 레거시 값을 사용하던 버전에서 업그레이드하려면 먼저 `compatible_double_hashes`를 지원하는 릴리스(레거시 해시와 통합 해시를 모두 기록함)를 실행하십시오. 복제된 테이블(Replicated Table)은 최소 `replicated_deduplication_window_seconds`(기본값 1시간) 동안 실행하십시오. 기본 윈도우는 해당 기간 동안 모든 삽입의 통합 해시를 보관하며, 이는 삽입 재시도 루프에 충분한 것으로 간주됩니다. `non_replicated_deduplication_window` > 0인 복제되지 않은 테이블에서는 이 윈도우가 시간이 아닌 개수 기준이므로, 최소한 그 개수만큼 삽입이 이루어질 때까지 `compatible_double_hashes`로 실행하십시오. 그런 다음 이 버전으로 업그레이드하기 전에 설정을 제거하거나 `new_unified_hash`로 설정하십시오. [#108361](https://github.com/ClickHouse/ClickHouse/pull/108361) ([CheSema](https://github.com/CheSema)).
* `use_legacy_to_time` 설정의 기본값이 이제 `0`으로 변경되어, `toTime`은 날짜와 시간을 고정된 날짜로 변환하는 대신 값을 `Time` 데이터 타입으로 변환합니다. 기존 동작은 `toTimeWithFixedDate` 함수를 사용하거나 `use_legacy_to_time = 1`로 설정하여 계속 사용할 수 있습니다. [#108729](https://github.com/ClickHouse/ClickHouse/pull/108729) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Naive Bayes 모델(`naiveBayesClassifier`에서 사용)은 이제 기존의 서버 측 구성(직렬화된 `.bin` 모델 파일을 참조하는 XML 구성 파일) 대신 `NAIVE_BAYES` 레이아웃을 사용하는 딕셔너리로 구성되며, 로드 시점에 클래스별로 사전 집계된 n-그램 개수를 담은 테이블로부터 빌드됩니다. 기존 방식은 더 이상 지원되지 않으므로 기존 모델은 딕셔너리로 다시 생성해야 합니다. `naiveBayesClassifier`와 함께 사용할 수 있는 새로운 함수 3개가 추가되었습니다. `naiveBayesClassifierWithProb`는 예측된 클래스를 해당 확률과 함께 반환하고, `naiveBayesClassifierWithAllProbs`는 모든 클래스를 각각의 확률과 함께 반환하며, `naiveBayesNgrams`는 딕셔너리와 동일한 방식으로 텍스트를 n-그램으로 토큰화하므로 레이블이 지정된 원시 텍스트에서 학습 데이터를 구축하는 데 활용할 수 있습니다. 또한 여러 성능 최적화가 적용되었습니다. 9.7 MiB 크기의 코드 포인트 트라이그램 언어 모델을 기준으로 메모리 사용량은 약 49배 감소했고(1.84 GiB에서 38 MiB로), 로드 속도와 분류 속도는 각각 약 11배 빨라졌습니다. [#108773](https://github.com/ClickHouse/ClickHouse/pull/108773) ([nihalzp](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/109000) ([alexey-milovidov](https://github.com/alexey-milovidov)). [#109006](https://github.com/ClickHouse/ClickHouse/pull/109006) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 CSV에서 bare `Tuple`을 읽을 때 모든 위치에서 원소마다 하나의 필드를 사용합니다. 따라서 최상위 원소의 필드에 있는 `\N`은 해당 원소의 값으로 처리되며, 여기에 `input_format_null_as_default`가 적용됩니다. 이전에는 맨 앞의 `\N`을 컬럼 전체가 null인 것으로 해석하여 행을 컬럼 기본값으로 대체했고, 그 결과 나머지 원소 셀의 파싱이 실패했습니다. 이 변경은 bare `Tuple` 전체에 대해 단일 필드만 제공하는 행과는 하위 호환되지 않습니다. 이러한 행은 이제 나머지 원소만큼 필드가 부족하므로 거부됩니다. 또한 원소가 하나뿐인 `Tuple`은 어느 방식이든 필드 수가 같기 때문에, 오류 없이 컬럼 `DEFAULT` 대신 원소 기본값이 반환됩니다. 이러한 필드를 이전처럼 컬럼 전체로 읽으려면 `input_format_csv_deserialize_separate_columns_into_tuple = 0`으로 설정하십시오. [#109744](https://github.com/ClickHouse/ClickHouse/pull/109744) ([groeneai](https://github.com/groeneai)).
* `CREATE USER` 및 `ALTER USER`에 `VALID UNTIL`의 축약형인 `VALID FOR <interval>` 절이 추가되었습니다. 만료 시각은 쿼리 실행 시점의 현재 시각에 지정된 인터벌을 더해 계산되며, `VALID UNTIL` 형식으로 저장됩니다. 2106년 이후의 만료 시각도 정확히 표현할 수 있도록 `system.users` 테이블의 `valid_until` 컬럼 유형이 `Array(DateTime)`에서 `Array(DateTime64(0))`로 변경되었습니다. 이 컬럼을 읽는 도구는 새 유형을 처리할 수 있어야 합니다. [#110171](https://github.com/ClickHouse/ClickHouse/pull/110171) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `EXPLAIN SYNTAX`는 줄마다 하나의 레코드를 반환하는 대신, 재포맷된 쿼리를 (줄바꿈이 포함된) 단일 `String` 레코드로 반환합니다. 따라서 출력이 그대로 활용할 수 있는 단일 행이 됩니다(예: `SELECT count() FROM (EXPLAIN SYNTAX ...)`는 `1`을 반환합니다). 이 동작은 기본값이 `1`인 새로운 `single_record` 옵션으로 제어되며, 기존처럼 줄마다 하나의 레코드를 출력하려면 `single_record = 0`으로 설정하십시오. 다른 `EXPLAIN` 종류(`PLAN`/`PIPELINE`/`AST`)는 기존과 같이 줄 단위 트리 출력을 유지합니다. [#110479](https://github.com/ClickHouse/ClickHouse/pull/110479) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `hasColumnInTable` 함수는 더 이상 임의의 원격 서버에서 컬럼을 확인하기 위한 선택적 `hostname`, `username`, `password` 인수를 받지 않습니다. 이제 `hasColumnInTable(database, table, column)` 형식만 남아 있습니다. 제거된 원격 모드는 보안상 문제가 있었습니다. 모든 사용자가 임의의 호스트로 외부 연결을 일으킬 수 있었고, 자격 증명이 쿼리 로그에 노출되었으며, 어떠한 권한으로도 제한되지 않았습니다. [#110881](https://github.com/ClickHouse/ClickHouse/pull/110881) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `PostgreSQL` 및 `MaterializedPostgreSQL` 데이터베이스 엔진이 이제 `PostgreSQL` 테이블 엔진, `postgresql` 테이블 함수, DDL로 생성된 딕셔너리와 마찬가지로 서버의 `remote_url_allow_hosts` 구성을 준수합니다. 이 정책은 `CREATE DATABASE`와 사용자가 직접 실행한 `ATTACH DATABASE`에 적용됩니다. 서버에 `remote_url_allow_hosts`가 구성되어 있으면, 허용 목록에 없는 호스트를 가리키는 `PostgreSQL` 또는 `MaterializedPostgreSQL` 데이터베이스를 생성하거나 ATTACH하려고 할 때 `UNACCEPTABLE_URL` 오류와 함께 거부됩니다. 기존 데이터베이스는 서버 시작 시 계속 로드되므로, 업그레이드 후 서버가 부팅되지 않는 상황은 발생하지 않습니다. [#111135](https://github.com/ClickHouse/ClickHouse/pull/111135) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Arrow` 및 `ArrowStream` 포맷용 Apache Arrow 라이브러리 기반 리더와 writer를 제거했습니다. 26.7부터 기본값이었던 ClickHouse 네이티브 구현이 이제 유일한 구현입니다. `input_format_arrow_use_native_reader` 및 `output_format_arrow_use_native_writer` 설정은 더 이상 사용되지 않습니다. 이 설정들은 여전히 지정할 수 있지만 아무런 효과가 없으므로, Apache Arrow 구현을 강제하려고 이를 `0`으로 설정한 쿼리도 이제 네이티브 구현을 사용합니다. [#111996](https://github.com/ClickHouse/ClickHouse/pull/111996) ([alexey-milovidov](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/112070) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `disable_insertion_and_mutation`은 이제 외부 스토리지에 대한 직접 쓰기는 허용하면서 `Kafka`, `RabbitMQ`, `NATS` 테이블의 백그라운드 소비를 차단합니다. 차단된 `Kafka2`, `NATS`, `RabbitMQ` 테이블은 직접 `SELECT`를 실행해도 컨슈머를 초기화하지 않습니다. 최근 도입된 `message_queue_disable_insertion` 설정을 변경하려면 이제 서버를 재시작해야 합니다. [#113660](https://github.com/ClickHouse/ClickHouse/pull/113660) ([cwurm](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/113878) ([groeneai](https://github.com/groeneai)).
* `SYSTEM ... CACHE ON CLUSTER` 명령의 접근 권한 검사를 수정했습니다. 이 명령들은 개별 명령의 권한 대신 `SYSTEM DROP CACHE` 권한 그룹을 요구했기 때문에, 세분화된 단일 캐시 권한만 가진 사용자는 실행이 거부되었고, 반대로 그룹 권한을 가진 사용자는 `SYSTEM SYNC FILESYSTEM CACHE` 권한 없이도 `SYSTEM SYNC FILESYSTEM CACHE ON CLUSTER`를 실행할 수 있었습니다. [#114042](https://github.com/ClickHouse/ClickHouse/pull/114042) ([groeneai](https://github.com/groeneai)).
* `NATS` 테이블 엔진은 이제 새로운 `nats_credentials` 설정을 통해 자격 증명을 인라인으로 지정할 수 있으며(`.creds` 파일과 동일한 payload), SQL에서는 더 이상 `nats_credential_file`을 지정할 수 없습니다. 이 경로는 서버 파일 시스템에 있는 파일을 가리키고 서버는 자체 권한으로 해당 파일을 열기 때문에, 서버 설정 파일에 정의된 명명된 컬렉션이나 서버 구성의 `nats.credential_file`로만 지정할 수 있습니다. 운영자가 `<nats_credential_file overridable="false">`로 고정하지 않았다면, 쿼리에서 이렇게 구성된 경로를 인라인 `nats_credentials`로 대체할 수 있습니다. 이 제한이 도입되기 전에 생성된 테이블은 업그레이드 후에도 정상적으로 동작합니다. [#114644](https://github.com/ClickHouse/ClickHouse/pull/114644) ([alexey-milovidov](https://github.com/alexey-milovidov)).

<h3 id="data-type-and-format-changes">
  데이터 타입 및 포맷 변경 사항
</h3>

* 객체 스토리지에 저장되는 백업, 즉 `S3(...)`/`AzureBlobStorage(...)`를 직접 지정한 대상과 S3 또는 Azure 기반 `Disk(...)` 대상에서는 `BACKUP`과 `RESTORE` 모두 `zip`/`zipx` 백업 아카이브 포맷을 허용하지 않습니다. Zip은 중앙 디렉터리를 읽으려면 탐색(seek)이 필요한데, 객체 스토리지에서는 이 작업이 매우 느립니다. 대신 `tar.gz`와 같은 tar 기반 포맷을 사용하십시오. [#101770](https://github.com/ClickHouse/ClickHouse/pull/101770) ([Onyx2406](https://github.com/Onyx2406)).
* `DateTime64`의 지원 범위를 `[1900-01-01, 2299-12-31]`에서 `[0000-01-01, 9999-12-31]`로 확장했습니다. 이전 범위를 벗어나는 값은 이제 경계값으로 고정되지 않고 cctz를 통해 올바르게 계산됩니다. 정밀도가 8 또는 9이면 틱이 `Int64`로 저장되므로 범위가 여전히 더 좁습니다(나노초 정밀도에서는 최댓값이 여전히 `2262-04-11`입니다). 이전 버전과의 호환성: 이전에 범위를 벗어나는 날짜-시간을 사용하면서 기존 범위 내의 매우 특수한 포화(saturation) 규칙에 의존했다면, 이제 결과가 더 정확하게 바뀐다는 점에 유의하십시오. [#107907](https://github.com/ClickHouse/ClickHouse/pull/107907) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `JSONEachRow` 및 유사한 포맷에서 `DateTime64`/`DateTime` 컬럼에 대한 따옴표 없는 JSON 숫자는 이제 `Values` 포맷, `CAST`, `toDateTime64`와 마찬가지로 Unix 타임스탬프(epoch 이후 경과한 초)로 해석되며, 초 미만 정밀도도 선택적으로 지원합니다. 이전에는 소수부가 있는 숫자(예: `1703363853.035`)는 `CANNOT_PARSE_INPUT_ASSERTION_FAILED` 오류로 거부되었고, 정수만 있는 숫자(예: `1703363853`)는 `DateTime64`의 스케일된 원시 값으로 읽혀 `1970-...` 타임스탬프가 생성되었습니다. 이는 `DateTime64` 컬럼에 입력되는 따옴표 없는 정수에 대한 하위 호환되지 않는 변경 사항입니다. 따옴표로 묶인 문자열과 ClickHouse 자체의 JSON 출력(항상 따옴표로 묶임)은 영향을 받지 않습니다. [#108091](https://github.com/ClickHouse/ClickHouse/pull/108091) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 실험적 기능인 `ALP` 코덱이 이제 `Float32` 스케일링 연산을 `Float64`로 수행하므로, 십진 데이터에서 발생하던 예외가 사라지고 압축률이 크게 향상됩니다. [#111627](https://github.com/ClickHouse/ClickHouse/pull/111627) ([rienath](https://github.com/rienath)).
* Int64 마이크로초 범위를 초과하는 시간 간격 설정(밀리초/초) 값을 거부합니다 [#112757](https://github.com/ClickHouse/ClickHouse/pull/112757) ([azat](https://github.com/azat)).
* 이제 비동기 메트릭에 `Map` 데이터 타입을 사용할 수 있으며, CPU 코어별 및 장치별 메트릭은 단일 키-값 메트릭으로 통합되었습니다. 예를 들어 `OSUserTimeCPU0`, `OSUserTimeCPU1`, ...은 CPU 코어 번호를 값에 매핑하는 맵을 갖는 단일 `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` 컬럼을 사용해 키마다 하나의 행으로 기록합니다. Prometheus 엔드포인트는 이러한 메트릭을 레이블과 함께 내보내며(예: `ClickHouseAsyncMetrics_BlockReadBytes{device="sda"}`), Graphite `MetricsTransmitter`는 `<prefix>.<Metric>.<key>` 형태로 전송합니다. 모니터링 시스템에서 기존 메트릭 이름을 읽는다면 `asynchronous_metrics_key_values_mode`를 `legacy_names`로 설정해 기존 이름을 유지하거나, 마이그레이션 기간에는 `both`로 설정하십시오. 이 서버 설정은 재시작 없이 `SYSTEM RELOAD CONFIG`로 적용할 수 있습니다. [#115333](https://github.com/ClickHouse/ClickHouse/pull/115333) ([alexey-milovidov](https://github.com/alexey-milovidov)). [#116791](https://github.com/ClickHouse/ClickHouse/pull/116791) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 객체 스토리지 디스크는 기본적으로 네이티브 메타데이터 스토리지 트랜잭션을 사용하여 메타데이터 업데이트의 일관성이 향상되었습니다. [#89658](https://github.com/ClickHouse/ClickHouse/pull/89658) ([Michicosun](https://github.com/Michicosun)).

<h3 id="settings-and-configuration-changes">
  설정 및 구성 변경 사항
</h3>

* 오래전에 사용 중단 예정으로 지정되었던 함수 `snowflakeToDateTime`, `snowflakeToDateTime64`, `dateTimeToSnowflake`, `dateTime64ToSnowflake`를 제거했습니다. 이 함수들은 이미 v24.6에서 사용 중단 예정으로 지정되었으므로, 대신 `snowflakeIDToDateTime`, `snowflakeIDToDateTime64`, `dateTimeToSnowflakeID`, `dateTime64ToSnowflakeID`를 사용하십시오. 이 함수들을 다시 활성화하는 데 사용되던 설정 `allow_deprecated_snowflake_conversion_functions`는 이제 더 이상 사용되지 않으며 아무런 효과가 없습니다. [#108711](https://github.com/ClickHouse/ClickHouse/pull/108711) ([alexey-milovidov](https://github.com/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` 이후의 타임스탬프는 새 경계값으로 고정(saturate)됩니다. [#111534](https://github.com/ClickHouse/ClickHouse/pull/111534) ([alexey-milovidov](https://github.com/alexey-milovidov)).

<h3 id="other-backward-incompatible-changes">
  기타 하위 호환되지 않는 변경 사항
</h3>

* `arrayIntersect`와 `arraySymmetricDifference`는 더 이상 한 인수 안에서 반복된 값을 여러 인수에 나타난 것처럼 취급하지 않습니다. 따라서 이전 동작에 의존하던 쿼리는 이제 다른 결과를 반환할 수 있습니다. `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](https://github.com/ClickHouse/ClickHouse/pull/113021) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `minmax` 컬럼 통계(column statistics) 유형이 사용 중단 예정으로 지정되었습니다. [#108680](https://github.com/ClickHouse/ClickHouse/pull/108680) ([hanfei1991](https://github.com/hanfei1991)).
* `SYSTEM PREWARM PRIMARY INDEX CACHE ... ON CLUSTER`의 액세스 검사에서 `SYSTEM PREWARM PRIMARY INDEX CACHE` 대신 `SYSTEM PREWARM MARK CACHE` 권한을 잘못 요구하던 문제를 수정했습니다. [#109198](https://github.com/ClickHouse/ClickHouse/pull/109198) ([Algunenano](https://github.com/Algunenano)).
* `SYSTEM STOP/START CLEANUP` 및 `SYSTEM STOP/START VIRTUAL PARTS UPDATE ON CLUSTER`에서 `SYSTEM CLEANUP` / `SYSTEM VIRTUAL PARTS UPDATE` 대신 `SYSTEM PULLING REPLICATION LOG` 권한을 요구하던 문제를 수정했습니다. [#110289](https://github.com/ClickHouse/ClickHouse/pull/110289) ([groeneai](https://github.com/groeneai)).
* `/` 글롭(임의 개수의 디렉터리)이 이제 같은 디렉터리에도 일치합니다. 이전에는 글롭 패턴의 `/`를 별도로 처리하지 않았기 때문에 `data/**/file.txt`가 `data/file.txt`(디렉터리 깊이 0)와 일치하지 않았습니다. [#97676](https://github.com/ClickHouse/ClickHouse/pull/97676) ([alexey-milovidov](https://github.com/alexey-milovidov)).

<h2 id="new-features">
  새 기능
</h2>

<h3 id="functions-and-data-types">
  함수 및 데이터 타입
</h3>

* AST를 JSON으로 직렬화 및 역직렬화하는 `parseQueryToJSON` 및 `formatQueryFromJSON` 함수와, `enable_json_ast_dialect`로 활성화되는 Experimental `clickhouse_json` 방언을 추가했습니다. [#100412](https://github.com/ClickHouse/ClickHouse/pull/100412) ([alexey-milovidov](https://github.com/alexey-milovidov)). [#113480](https://github.com/ClickHouse/ClickHouse/pull/113480) ([fm4v](https://github.com/fm4v)).
* `stem` 함수에 지정할 수 있는 모든 스테머 언어를 보여주는 시스템 테이블 `system.stemmers`를 추가했습니다. [#100611](https://github.com/ClickHouse/ClickHouse/pull/100611) ([Ergus](https://github.com/Ergus)).
* `toTimeZone`의 문법적 설탕(syntactic sugar)으로 표준 SQL `AT TIME ZONE` 및 `AT LOCAL` 후위 연산자를 지원합니다. 이제 `expr AT TIME ZONE zone` 표현식은 `toTimeZone(expr, zone)`과 동일하며, `expr AT LOCAL`은 `toTimeZone(expr, timeZone())`과 동일합니다. [#106092](https://github.com/ClickHouse/ClickHouse/pull/106092) ([lvzhipin03](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/106093) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `QBit` 컬럼과 기준 벡터 간의 근사 내적을 계산하는 `dotProductTransposed` 함수(별칭 `scalarProductTransposed`)를 추가했습니다. 이 함수는 기존 `L2DistanceTransposed` 및 `cosineDistanceTransposed` 함수를 보완합니다. [#108100](https://github.com/ClickHouse/ClickHouse/pull/108100) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `QBit` 데이터 타입에 선택적 stride 매개변수(`QBit(T, dimension, stride)`)를 추가했습니다. 이 매개변수를 사용하면 차원 그룹이 별도의 스트림에 저장되므로, 벡터 검색 시 앞쪽 차원만 효율적으로 읽을 수 있습니다(예: Matryoshka 임베딩). 전치(transposed) 거리 함수는 일부 차원만 읽을 수 있도록 선택적인 네 번째 인수 `used_dims`를 받습니다. [#108103](https://github.com/ClickHouse/ClickHouse/pull/108103) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `QBit` 데이터 타입에서 `Int8` 타입을 지원하므로, 양자화된 8비트 정수 벡터를 저장하고 전치 거리 기반 벡터 검색(`L2DistanceTransposed`, `cosineDistanceTransposed`)을 수행할 수 있습니다. [#108105](https://github.com/ClickHouse/ClickHouse/pull/108105) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 새 함수 `randomHadamardTransform(vector[, seed[, output_dims]])`를 추가했습니다. float 벡터에 대한 결정적(deterministic) 랜덤 Hadamard 변환으로, 노름을 보존하는 직교 회전입니다. 양자화 전에 임베딩을 전처리하는 데 유용하며, (잘라낸 경우) Johnson–Lindenstrauss / subsampled-randomized-Hadamard 랜덤 투영으로도 활용할 수 있습니다. [#108227](https://github.com/ClickHouse/ClickHouse/pull/108227) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* JSON 값에 대해 RFC 7396 방식의 merge-patch 집계를 수행하는 집계 함수 `mergedJSONPatch`를 구현했습니다. 상태 머지와 AggregatingMergeTree에서의 사용도 지원합니다. 타임스탬프나 다른 정렬 컬럼을 정렬 키로 사용해 JSON 컬럼을 집계하면 최신 상태를 계산할 수 있습니다. [#108349](https://github.com/ClickHouse/ClickHouse/pull/108349) ([larryluogit](https://github.com/larryluogit)).
* `String` 및 `NULL` 입력에 대해 시드 `42`를 사용하여 Spark 호환 `xxHash64` 값을 계산하고 `Int64`를 반환하는 `xxHash64Spark` 함수를 추가했습니다. [#108436](https://github.com/ClickHouse/ClickHouse/pull/108436) ([lalitium](https://github.com/lalitium)).
* `n`에서 인덱스 `offset(1-indexed)`부터 시작하여 `length`개의 자릿수를 갖는 숫자를 반환하는 `digits(n, offset[, length])` 함수를 추가했습니다. `length`를 지정하지 않으면 offset부터 끝까지의 숫자를 반환합니다. [#109012](https://github.com/ClickHouse/ClickHouse/pull/109012) ([1000ms](https://github.com/1000ms)).
* 숫자의 제곱을 계산하는 `sqr` 산술 함수를 추가했습니다. [#109061](https://github.com/ClickHouse/ClickHouse/pull/109061) ([lalitium](https://github.com/lalitium)).
* `quantizeBFloat16ToInt8` Lloyd-Max 코드로 구성된 `QBit(Int8)`에서 동작하며 저장된 코드를 즉석에서 역양자화하는 양자화 전치 거리 함수 `cosineDistanceTransposedQuantized`, `L2DistanceTransposedQuantized`, `dotProductTransposedQuantized`를 추가했습니다. 부동소수점 참조 벡터는 전체 정밀도 쿼리로 취급되어 `Float32` 정밀도로 비교되며(`Float64` 쿼리는 `Float32`로 축소됨), `Array(Int8)` 참조 벡터는 그 자체도 역양자화되어 대칭적인 양자화 대 양자화 거리를 계산합니다. [#109405](https://github.com/ClickHouse/ClickHouse/pull/109405) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 계층형 딕셔너리(hierarchical dictionary)에서 키의 최상위 조상(루트)을 반환하는 새 함수 `dictGetRoot`를 추가했습니다. 이 함수는 `dictGetHierarchy(dict_name, key)[-1]`을 간편하게 대체할 수 있습니다. [#109459](https://github.com/ClickHouse/ClickHouse/pull/109459) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `MergeTree` 테이블의 (파트, 컬럼, 서브스트림)별로 각 코덱을 사용하는 압축 블록 수를 보여 주는 `mergeTreeCodecBlockCounts(database, table)` 테이블 함수를 추가했습니다. [#109623](https://github.com/ClickHouse/ClickHouse/pull/109623) ([rienath](https://github.com/rienath)).
* 배열, 맵, JSON에 대해 `has`의 부정 연산을 수행하는 `notHas` 함수를 추가했습니다. haystack이 상수 배열이면 `optimize_rewrite_has_to_in`(기본 활성화)에 의해 `notHas(constant_array, x)`가 `x NOT IN constant_array`로 재작성됩니다. 따라서 set 조회 방식으로 실행되며, `NOT IN`과 마찬가지로 프라이머리 키 인덱스를 활용한 프루닝이 가능합니다. [#109926](https://github.com/ClickHouse/ClickHouse/pull/109926) ([nihalzp](https://github.com/nihalzp)).
* `Array(Point)`로 저장되는 `MultiPoint` 지리 데이터 타입을 추가하고 `Geometry` 타입에 포함했습니다. [#109951](https://github.com/ClickHouse/ClickHouse/pull/109951) ([davidmenggx](https://github.com/davidmenggx)).
* 이제 `arrayElement`(`vec[n]` 연산자)와 `arraySlice` 함수를 `QBit` 데이터 타입에도 사용할 수 있습니다. `qbit[n]`은 n번째 벡터 원소를 전체 정밀도로 반환하고, `arraySlice(qbit, offset, length)`는 일부 차원에 대한 프로젝션을 반환합니다. 두 함수 모두 필요한 stride 그룹의 비트 평면만 읽으며, stride 그룹 경계에 맞춰 정렬된 슬라이스는 저장된 스트림을 복사하지 않고 그대로 재사용합니다. [#109953](https://github.com/ClickHouse/ClickHouse/pull/109953) ([Utkal059](https://github.com/Utkal059)).
* 텍스트 인덱스와 `tokens` 함수에서 사용할 수 있는 `splitByRegexp` 토크나이저를 추가했습니다. 이 토크나이저는 정규식을 구분자로 사용하여 입력을 토큰으로 분할합니다. 예를 들어 `tokenizer = splitByRegexp('[^\p{L}\p{N}#+]+')`를 사용하면 다른 토크나이저에서는 분리되어 버리는 `C++`나 `C#`처럼 특수 문자가 포함된 토큰을 그대로 보존할 수 있습니다. [#110002](https://github.com/ClickHouse/ClickHouse/pull/110002) ([Ergus](https://github.com/Ergus)).
* 두 지오메트리가 교차하는지 여부를 반환하는 `geometryIntersectCartesian` 및 `geometryIntersectSpherical` 함수를 추가했습니다. `polygonsIntersectCartesian`/`polygonsIntersectSpherical`과 달리 공통 `Geometry` 타입을 포함한 모든 지오메트리 데이터 타입(`Point`, `LineString`, `MultiLineString`, `Ring`, `Polygon`, `MultiPolygon`)을 인수로 받을 수 있으며, 두 인수의 타입이 서로 달라도 됩니다. [#110062](https://github.com/ClickHouse/ClickHouse/pull/110062) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 네이티브 ORC 리더가 이제 ORC의 `uniontype`을 지원하며, 이를 ClickHouse `Variant` 타입으로 매핑합니다(이전에는 이러한 컬럼이 `Unsupported ORC type` 오류와 함께 거부되었습니다). [#110078](https://github.com/ClickHouse/ClickHouse/pull/110078) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 네이티브 ORC 출력 포맷에서 이제 ClickHouse `Variant` 타입을 ORC `uniontype`으로 매핑하여 기록할 수 있습니다(이전에는 `ILLEGAL_COLUMN` 오류가 발생했습니다). [#110085](https://github.com/ClickHouse/ClickHouse/pull/110085) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 새 설정 `framing_output_format`으로 선택할 수 있는 프레이밍 포맷을 추가했습니다. 프레이밍 포맷은 쿼리 응답을 구성하는 여러 부분(데이터 청크, totals 및 extremes, 진행 상황 패킷, 프로파일 이벤트, 서버 로그, 예외)을 하나의 HTTP 응답 스트림으로 다중화합니다. 구현된 프레이밍 포맷은 `None`(기본값, 기존과 동일하게 동작), `EventStream`(HTTP server-sent events), `JSONEachPacketBase64`, `JSONEachPacketString`(패킷마다 JSON 객체 하나를 사용하며, 데이터는 base64로 인코딩되거나 문자열로 표현됨)입니다. [#110127](https://github.com/ClickHouse/ClickHouse/pull/110127) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 공개 데이터셋을 포함한 Google BigQuery 테이블을 읽고 쓸 수 있는 `bigquery` 테이블 함수와 `BigQuery` 테이블 엔진을 추가했습니다. 테이블 구조는 BigQuery 테이블 스키마로부터 자동으로 추론됩니다. 인증 방식으로는 OAuth 액세스 토큰, JSON 포맷의 서비스 계정 키, 리프레시 토큰을 사용하는 OAuth 클라이언트를 지원합니다. [#110166](https://github.com/ClickHouse/ClickHouse/pull/110166) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* LLM 제공자를 사용하여 텍스트에서 개인 식별 정보(PII)를 감지하고 마스킹하는 새 함수 `aiRedact`를 추가했습니다. 마스킹할 카테고리(예: `['email', 'name']`)를 지정하거나, 빈 배열을 전달하여 기본 PII 카테고리 집합을 사용할 수 있습니다. 감지된 값은 토큰(기본값 `[REDACTED]`)으로 대체됩니다. [#110464](https://github.com/ClickHouse/ClickHouse/pull/110464) ([davidmenggx](https://github.com/davidmenggx)).
* LLM을 사용하여 텍스트가 자연어 조건을 만족하는지 평가하고 `UInt8`을 반환하는 `aiFilter` 함수를 추가했습니다. 이 함수는 `WHERE`, `PREWHERE`, `JOIN ... ON`에서 사용할 수 있습니다. [#110594](https://github.com/ClickHouse/ClickHouse/pull/110594) ([ylw510](https://github.com/ylw510)).
* `PostgreSQL` 테이블 엔진, `postgresql` 테이블 함수, `PostgreSQL` 및 `MaterializedPostgreSQL` 데이터베이스 엔진, `PostgreSQL` 딕셔너리에서 PostgreSQL에 대한 TLS/SSL 연결을 지원합니다. `sslmode`와 함께 인증서 및 키를 리터럴 내용(`sslrootcert_pem`, `sslcert_pem`, `sslkey_pem`, 비밀번호처럼 마스킹됨) 또는 경로(`sslrootcert`, `sslcert`, `sslkey`, 서버 설정 파일에 정의된 named collection에서만 허용됨)로 지정할 수 있습니다. [#110615](https://github.com/ClickHouse/ClickHouse/pull/110615) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `postgresql` 테이블 함수와 `PostgreSQL` 테이블 엔진을 사용하여 PostgreSQL 프로토콜로 다른 ClickHouse 서버에 연결할 수 있습니다(테이블 이름을 지정한 경우에 한하며, `query(...)` 변형은 아직 지원되지 않습니다). 또한 PostgreSQL 호환 함수 `format_type` 및 `current_setting`을 추가했습니다. [#110760](https://github.com/ClickHouse/ClickHouse/pull/110760) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 임베딩 모델을 사용하여 두 텍스트 간의 의미적 유사도를 계산하는 새 함수 `aiSimilarity`가 추가되었습니다. `[-1, 1]` 범위의 `Nullable(Float32)` 값을 반환하며, `1`은 두 텍스트가 동일함을 의미합니다. 피연산자가 `NULL`이거나 비어 있는 경우, 또는 임베딩 생성에 실패한 경우에는 `NULL`을 반환합니다. [#110777](https://github.com/ClickHouse/ClickHouse/pull/110777) ([davidmenggx](https://github.com/davidmenggx)).
* `Remote` 및 `RemoteSecure` 데이터베이스 엔진이 추가되었습니다. 이 엔진은 `SELECT` 및 `INSERT` 쿼리를 원격 ClickHouse 서버로 전달하여, 해당 서버에 있는 데이터베이스의 테이블에 실시간으로 접근할 수 있게 합니다. `MySQL` 및 `PostgreSQL` 데이터베이스 엔진의 ClickHouse 간 연결 버전이라고 할 수 있습니다. [#110975](https://github.com/ClickHouse/ClickHouse/pull/110975) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* GoogleSQL의 파이프 구문과 유사하게, SQL 쿼리에서 파이프 연산자를 지원합니다(예: `FROM t |> WHERE x > 1 |> AGGREGATE count() AS c GROUP BY y |> ORDER BY c DESC |> LIMIT 10`). 모든 `SELECT` 쿼리 뒤에 `|>` 연산자를 연이어 붙일 수 있으며, 각 연산자는 앞의 쿼리를 서브쿼리로 감쌉니다. 따라서 생성되는 AST는 중첩 서브쿼리로 작성한 동등한 쿼리의 AST와 동일합니다. 또한 `FROM` 절로 시작하는 쿼리에서는 이제 `SELECT` 절을 생략할 수 있으며, 생략하면 `SELECT *`로 처리됩니다. [#111151](https://github.com/ClickHouse/ClickHouse/pull/111151) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 유한하고 음이 아닌 숫자 값의 지니 계수를 계산하는 집계 함수 `gini`가 추가되었습니다. 그룹별 집계와 분산 집계도 지원합니다. [#112280](https://github.com/ClickHouse/ClickHouse/pull/112280) ([amirreza1307](https://github.com/amirreza1307)). [#114643](https://github.com/ClickHouse/ClickHouse/pull/114643) ([groeneai](https://github.com/groeneai)).
* `PNG` 출력 형식에서 애니메이션 PNG를 지원합니다. `t` 컬럼이 있으면 쿼리 결과가 애니메이션으로 변환되며, `t`의 시간 척도는 `output_format_image_time_multiplier_seconds` 및 `output_format_image_time_divisor_seconds`로 설정합니다. `output_format_image_streaming_animation`을 사용하면 프레임을 메모리에 버퍼링하지 않고 쿼리가 생성하는 즉시 출력합니다. [#112846](https://github.com/ClickHouse/ClickHouse/pull/112846) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `system.mutations`에 뮤테이션 완료 시각을 기록하는 `finish_time` 컬럼이 추가되었습니다. 완료되지 않은 뮤테이션과 완료 시각을 알 수 없는 뮤테이션은 0으로 표시됩니다. [#113474](https://github.com/ClickHouse/ClickHouse/pull/113474) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* `system.metric_log`에 새로운 `bucketed` 스키마 유형이 추가되었습니다. 이 유형은 128개의 버킷으로 나누는 버킷 방식 `Map` 직렬화를 사용해 모든 메트릭을 단일 `Map(Enum16(...), Int64)` 컬럼에 저장하며, 호환성을 위해 메트릭별 `ALIAS` 컬럼도 제공합니다. 이에 따라 테이블이 수천 개가 아닌 몇 개의 컬럼으로만 구성되고, 0 값은 저장되지 않으며, 단일 메트릭을 읽을 때는 128개 버킷 중 하나만 읽습니다. 또한 이제 `Enum` 키를 가진 `Map`을 enum 값의 문자열 이름으로 인덱싱할 수 있습니다(예: `map['name']`). [#115380](https://github.com/ClickHouse/ClickHouse/pull/115380) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `tokens` 함수와 `MergeTree` 텍스트 인덱스에서 사용할 수 있는 `chinese` 토크나이저가 추가되었습니다. 이 토크나이저는 딕셔너리와 은닉 마르코프 모델(Hidden Markov Model)을 사용해 중국어 텍스트를 단어 단위로 분할하며(알고리즘은 [jieba](https://github.com/fxsjy/jieba) 기반), `coarse_grained`(기본값)와 `fine_grained` 두 가지 세분화 수준을 제공합니다. [#89945](https://github.com/ClickHouse/ClickHouse/pull/89945) ([amosbird](https://github.com/amosbird)).
* 각 그룹의 행을 지정한 출력 형식으로 포맷하여 문자열로 반환하는 `groupFormat` 집계 함수가 추가되었습니다. [#93201](https://github.com/ClickHouse/ClickHouse/pull/93201) ([wandersofb](https://github.com/wandersofb)).
* 집계 함수 조합자 `-Tuple`을 추가했습니다. 이 조합자는 기반 집계 함수를 `Tuple` 컬럼의 각 원소에 개별적으로 적용하고, 원소 이름을 유지한 채 그 결과를 `Tuple`로 반환합니다. 예를 들어 `t = (a, b)`일 때 `sumTuple(t)`는 `(sum(a), sum(b))`를 반환합니다. 인수가 여러 개인 집계 함수는 인수마다 튜플을 하나씩 받으며, 각 튜플의 원소는 위치별로 짝지어집니다. 예를 들어 `corrTuple((a1, a2), (b1, b2))`는 `(corr(a1, b1), corr(a2, b2))`를 반환합니다. 배열에 사용하는 `-ForEach`와 달리 원소마다 타입이 달라도 되며, 원소별 결과 타입과 이름도 그대로 유지됩니다. [#98190](https://github.com/ClickHouse/ClickHouse/pull/98190) ([RinChanNOWWW](https://github.com/RinChanNOWWW)).

<h3 id="sql-and-query-features">
  SQL 및 쿼리 기능
</h3>

* 프로젝션(projection) 정의에서 WHERE 절을 지원합니다. WHERE가 있는 프로젝션은 조건식을 만족하는 행만 구체화하며, 쿼리의 WHERE 조건이 프로젝션의 WHERE 조건을 함의하는 경우 옵티마이저가 비용 기반으로 해당 프로젝션을 사용할 수 있습니다. [#102347](https://github.com/ClickHouse/ClickHouse/pull/102347) ([SBALAVIGNESH123](https://github.com/SBALAVIGNESH123)).
* HTTP 인터페이스에서 URL 경로를 통해 테이블과 데이터베이스에 접근하는 방법(예: \`/database/table.format.gz?filter=a>0\`)을 추가했습니다. 또한 서로 조합할 수 있고 기존 \`query\` URL 매개변수와도 함께 사용할 수 있는 새로운 설정(\`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\`)도 추가했습니다. [#105249](https://github.com/ClickHouse/ClickHouse/pull/105249) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `remote` 및 `remoteSecure` 테이블 함수의 영구 버전인 `Remote` 및 `RemoteSecure` 테이블 엔진을 추가했습니다. 이제 `CREATE TABLE ... AS remote(...)`뿐만 아니라 `CREATE TABLE ... ENGINE = Remote('addresses', db, table, ...)`도 사용할 수 있습니다. [#106189](https://github.com/ClickHouse/ClickHouse/pull/106189) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 쿼리 성능 분석을 위한 `EXPLAIN ANALYZE`를 추가했습니다. 쿼리를 실제로 실행한 뒤, 측정된 실행 메트릭을 익숙한 쿼리 플랜 형식으로 표시합니다. [#106586](https://github.com/ClickHouse/ClickHouse/pull/106586) ([Fgrtue](https://github.com/Fgrtue)). [#110668](https://github.com/ClickHouse/ClickHouse/pull/110668) ([Fgrtue](https://github.com/Fgrtue)).
* 엔진에 관계없이 사용할 수 있는 `SYSTEM STOP`, `SYSTEM START`, `SYSTEM PAUSE`, `SYSTEM CANCEL`, `SYSTEM REFRESH` 명령어와 서버 전체에 적용되는 `... ALL BACKGROUND` 형식을 추가했습니다. 이를 통해 `Kafka`, `RabbitMQ`, `NATS`, `S3Queue`/`AzureQueue` 테이블과 갱신 가능 구체화 뷰의 백그라운드 활동을 하나의 통합된 인터페이스로 제어할 수 있습니다. 갱신 가능 구체화 뷰에서는 기존 `SYSTEM ... VIEW` 명령어의 별칭으로 동작합니다. NATS에서 이러한 제어를 지원하면서, 이제 JetStream 테이블은 삽입이 성공한 후에만 메시지에 확인 응답을 보냅니다(at-least-once). 이전에는 메시지가 전달되는 시점에 자동으로 확인 응답되어 삽입이 실패하면 유실될 수 있었습니다. 새로운 `nats_wait_for_flush_interval` 설정(기본값 `false`, 기존의 저지연 동작 유지)을 사용하면 큐가 비는 즉시 플러시하지 않고 플러시 인터벌 동안 소비 주기를 계속 유지할 수 있습니다. 새로운 `nats_commit_on_select` 설정을 사용하면 JetStream 테이블에 직접 `SELECT`를 실행할 때 읽은 메시지를 소비(확인 응답)합니다. [#107476](https://github.com/ClickHouse/ClickHouse/pull/107476) ([NIKTONIKTO717](https://github.com/NIKTONIKTO717)).
* `mysql`, `postgresql`, `sqlite` 테이블 함수와 테이블 엔진에서 테이블 이름 대신 사용자 쿼리를 지정하여 외부 데이터베이스에 그대로 전달할 수 있습니다. 쿼리는 서브쿼리 `(SELECT ...)` 또는 `query('SELECT ...')` 형식으로 작성합니다. 결과 테이블의 구조는 쿼리 결과를 바탕으로 추론되며, 이러한 테이블은 읽기 전용입니다. [#107740](https://github.com/ClickHouse/ClickHouse/pull/107740) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `QueryRunner` 테이블 엔진을 도입했습니다. `QueryRunner` 테이블에 삽입된 레코드는 엔진이 실행할 쿼리를 나타냅니다. 이 엔진은 비동기 쿼리 실행, 생성된 쿼리의 일괄 실행, 원격 클러스터로의 쿼리 전달, 벤치마크, 퍼징(fuzzing), 섀도 트래픽을 이용한 테스트 등에 사용할 수 있습니다. [#107888](https://github.com/ClickHouse/ClickHouse/pull/107888) ([mstetsyuk](https://github.com/mstetsyuk)).
* 윈도우 함수(window functions)에서 `GROUPS` 프레임 모드(SQL:2011)를 지원합니다. 예: `any(price) OVER (PARTITION BY symbol ORDER BY ts GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING)`. `GROUPS` 프레임에서는 경계를 피어 그룹(peer group), 즉 `ORDER BY` 키 값이 같은 행들의 집합 단위로 셉니다. 따라서 `N PRECEDING`/`N FOLLOWING`은 물리적인 행 수(`ROWS`)나 `ORDER BY` 값의 거리(`RANGE`)가 아니라, 현재 행이 속한 피어 그룹의 앞/뒤에 있는 `N`개의 피어 그룹을 의미합니다. [#108653](https://github.com/ClickHouse/ClickHouse/pull/108653) ([nihalzp](https://github.com/nihalzp)).
* 일반 `CREATE MATERIALIZED VIEW ... POPULATE`가 이제 로컬 범위에서 원자적으로 동작합니다. 소스 테이블에 짧은 배타적 잠금을 건 상태에서 뷰의 신규 삽입 구독과 기존 데이터의 스냅샷 생성을 함께 수행하므로, 데이터 채우기(population) 도중 같은 서버를 통해 동시에 삽입된 행이 더 이상 누락되거나 중복되지 않습니다(새로운 설정 `materialized_views_populate_atomically`, 기본적으로 활성화됨). 이 보장은 로컬 삽입 경로에만 적용되며, 다른 레플리카로 들어오거나 분산 쓰기 경로를 거치는 삽입은 대상에서 제외됩니다. 또한 고정된 스냅샷을 제공할 수 있는 소스(MergeTree 엔진 계열 및 `Memory`)가 필요합니다. 그 외의 소스와 `CREATE OR REPLACE` / `REPLACE`, 그리고 `Replicated` 데이터베이스에서 생성된 뷰는 기존의 비원자적 채우기 방식을 그대로 사용합니다. 이제 `POPULATE`를 `TO`와 함께 사용하여 대상 테이블을 백필할 수도 있습니다. [#108715](https://github.com/ClickHouse/ClickHouse/pull/108715) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `ALTER USER`, `ALTER ROLE`, `ALTER SETTINGS PROFILE`에서 이제 `MODIFY SETTING name = value`의 별칭으로 `SET name = value`를 사용할 수 있습니다. 이 구문은 전체 설정 목록을 교체하는 단독 `SETTINGS` 절과 달리 나머지 설정은 유지한 채 개별 설정만 변경합니다. 따라서 사용자의 다른 설정을 실수로 지워버릴 위험이 줄어듭니다. [#108722](https://github.com/ClickHouse/ClickHouse/pull/108722) ([groeneai](https://github.com/groeneai)).
* 기존 제약 조건의 표현식을 즉시 변경할 수 있는 `ALTER TABLE ... MODIFY CONSTRAINT [IF EXISTS] name CHECK expr`를 지원합니다. [#108768](https://github.com/ClickHouse/ClickHouse/pull/108768) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `ON` 절에 조인 대상 테이블 간 부등호 비교(`<`, `<=`, `>`, `>=`)가 두 개 포함된 조인을 위해 정렬 기반 IEJoin 알고리즘을 추가했습니다. `join_algorithm` 설정에 `ie_join`을 추가하면 활성화됩니다. 지원되는 종류는 `ALL INNER/LEFT/RIGHT/FULL JOIN` 및 `SEMI`/`ANTILEFT/RIGHT JOIN`입니다. 이전에는 이러한 쿼리가 필터가 적용된 `CROSS JOIN`(`INNER`만 해당)으로 실행되어 대용량 테이블에서 훨씬 느렸습니다. [#109920](https://github.com/ClickHouse/ClickHouse/pull/109920) ([vdimir](https://github.com/vdimir)).
* 새로운 시스템 테이블 `system.user_query_log`를 추가했습니다. 이 테이블을 사용하면 쿼리 로그 테이블에 대한 접근 권한이 없어도 각 사용자가 자신의 쿼리 로그 레코드를 조회할 수 있습니다. 최초 구현과 아이디어는 Yue Ni(@niyue)가 제공했습니다. [#110156](https://github.com/ClickHouse/ClickHouse/pull/110156) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 새로운 설정 `run_query_in_background`를 추가했습니다. 서버는 쿼리를 수락하면 즉시 빈 결과를 반환하고, 연결 상태와 관계없이 쿼리를 끝까지 실행합니다. 결과는 폐기됩니다. 쿼리는 `system.processes` 및 `system.query_log`에서 `query_id`로 추적하십시오. 연결이 끊어져도 중단되어서는 안 되는 `INSERT ... SELECT`, `CREATE TABLE … AS SELECT`, `CREATE MATERIALIZED VIEW … POPULATE`와 같은 장시간 실행 쿼리용 설정입니다. [#112816](https://github.com/ClickHouse/ClickHouse/pull/112816) ([mstetsyuk](https://github.com/mstetsyuk)).
* ALTER TABLE ... MODIFY PROJECTION을 지원하여 기존 프로젝션(projection)을 재구성하지 않고도 프로젝션 수준 설정(예: index\_granularity)을 변경할 수 있습니다. 새 설정은 머지 과정에서 지연 적용됩니다. [#113343](https://github.com/ClickHouse/ClickHouse/pull/113343) ([diegomestre2](https://github.com/diegomestre2)).
* 데이터 레이크용 S3 테이블 엔진 카탈로그(catalog)가 이제 기존 테이블 쿼리뿐 아니라 `INSERT`도 지원합니다. [#113505](https://github.com/ClickHouse/ClickHouse/pull/113505) ([scanhex12](https://github.com/scanhex12)).
* `Iceberg` 카탈로그가 이제 `catalog_type = 'horizon'`을 통해 Snowflake Horizon Catalog를 지원하므로, Snowflake에서 관리하는 `Iceberg` 테이블을 읽고 쓸 수 있습니다. [#114547](https://github.com/ClickHouse/ClickHouse/pull/114547) ([melvynator](https://github.com/melvynator)).
* `skip_unavailable_shards`가 활성화된 경우 원격 세그먼트(shard)에서 발생한 예외 중 어떤 예외를 별도 알림 없이 무시할지 제어하는 `skip_unavailable_shards_mode` 설정을 추가했습니다(`Distributed` 엔진 설정으로도 사용 가능). 이를 통해 분산 환경에서 쿼리 동작을 더욱 세밀하게 제어할 수 있습니다. [#79091](https://github.com/ClickHouse/ClickHouse/pull/79091) ([byte-sourcerer](https://github.com/byte-sourcerer)).

<h3 id="storage-data-lakes-and-object-storage">
  저장소, 데이터 레이크, 객체 스토리지
</h3>

* Puffin 파일 포맷([https://iceberg.apache.org/puffin-spec/](https://iceberg.apache.org/puffin-spec/)) 지원을 추가했습니다. 이제 `file`, `url`, `s3` 등의 테이블 함수에서 이 포맷을 사용할 수 있습니다. [#103936](https://github.com/ClickHouse/ClickHouse/pull/103936) ([scanhex12](https://github.com/scanhex12)).
* `MergeTree` 테이블에 "패킹" 데이터 파트 저장 방식을 추가했습니다. 이 방식은 스트림마다 파일을 따로 두지 않고 파트의 모든 파일을 단일 아카이브(`data.packed`)에 저장합니다. `min_bytes_for_full_part_storage`, `min_rows_for_full_part_storage`, `min_level_for_full_part_storage` 설정으로 제어하며 기본값은 비활성화입니다. 호환성 참고 사항: 테이블에 패킹 파트가 한 번이라도 기록되면 이전 버전의 서버에서는 이를 읽을 수 없습니다. 따라서 이 포맷을 활성화하면 서버를 다운그레이드할 수 없습니다. [#108118](https://github.com/ClickHouse/ClickHouse/pull/108118) ([Algunenano](https://github.com/Algunenano)).
* NATS 테이블 엔진에 `nats_credentials` 설정을 추가했습니다. 이제 사용자가 NATS 자격 증명을 문자열(`.creds` 파일의 payload와 동일)로 직접 지정할 수 있습니다. [#110733](https://github.com/ClickHouse/ClickHouse/pull/110733) ([addshore](https://github.com/addshore)).

<h3 id="data-formats-and-ingestion">
  데이터 포맷 및 수집
</h3>

* Apache Hive `LazySimpleSerDe` 텍스트 형식으로 데이터를 기록하는 `HiveText` 출력 형식을 추가했습니다. 필드는 `\x01`로 구분하고, 행은 새로운 `format_hive_text_rows_delimiter` 설정(기본값 `\n`)으로 구분하며, 중첩된 `Array`, `Map`, `Tuple` 값에는 Hive의 구분자 목록을 사용합니다. 이 출력은 Hive의 기본 `LazySimpleSerDe`를 대상으로 하므로, 중첩된 값이나 사용자 정의 행 구분 기호에 대해서는 ClickHouse의 `HiveText` 입력과 대칭을 이루지 않습니다. [#107582](https://github.com/ClickHouse/ClickHouse/pull/107582) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 행마다 feature 하나를 담는 GeoJSON `FeatureCollection` 문서를 기록하는 `GeoJSON` 출력 형식을 추가했습니다. 새로운 `format_geojson_validate_geometry` 설정(기본 활성화)은 읽기 및 쓰기 시 GeoJSON 도형을 검사합니다. 또한 `GeoJSON` 입력 형식은 이제 `id`를 `Nullable(String)`으로 추론하므로, 누락되었거나 `null`인 ID와 빈 문자열을 구분할 수 있습니다. [#108065](https://github.com/ClickHouse/ClickHouse/pull/108065) ([nihalzp](https://github.com/nihalzp)).

<h3 id="settings-access-and-observability">
  설정, 액세스 및 관측성
</h3>

* HTTP 인터페이스의 `/docs` 경로에서 사용할 수 있는 내장 문서 검색 페이지를 추가했습니다. 이 페이지에서는 `system.documentation` 테이블을 즉시 검색할 수 있으며, 참고 문서를 구문 강조, 수식, 상호 링크와 함께 렌더링합니다. [#108345](https://github.com/ClickHouse/ClickHouse/pull/108345) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 텍스트 인덱스와 tokens/hasAnyTokens/hasAllTokens 함수에서 사용할 수 있도록 MeCab 형태소 분석기 기반의 일본어 토크나이저를 추가했습니다. 딕셔너리는 서버 구성에 지정된 위치에서 런타임에 로드되며, 사용 전에 SHA-256 체크섬으로 검증됩니다. [#111420](https://github.com/ClickHouse/ClickHouse/pull/111420) ([Ergus](https://github.com/Ergus)).
* `use_split_cache`가 활성화된 경우 시스템 캐시에 저장할 파일을 지정하는 새로운 파일 시스템 캐시 설정 `system_cache_extensions`를 추가했습니다. [#111575](https://github.com/ClickHouse/ClickHouse/pull/111575) ([kirillgarbar](https://github.com/kirillgarbar)).
* 레플리카가 뮤테이션을 로컬에서 직접 실행하지 않고 다른 레플리카로부터 뮤테이션이 적용된 파트를 다운로드할 수 있게 하는 `always_fetch_mutated_part` 설정을 추가했습니다. [#113020](https://github.com/ClickHouse/ClickHouse/pull/113020) ([rorylshanks](https://github.com/rorylshanks)).

<h3 id="other-new-features">
  기타 새 기능
</h3>

* 음수 `LIMIT`에서 `WITH TIES`를 지원합니다. [#100930](https://github.com/ClickHouse/ClickHouse/pull/100930) ([nihalzp](https://github.com/nihalzp)).
* 복원 대상을 세밀하게 제어할 수 있도록 `restore_table_data`, `restore_access_entities`, `restore_functions` 복원 설정을 추가했습니다. 이 설정을 사용하면 범주별로 `structure_only`를 재정의할 수 있습니다. 예를 들어 `structure_only=true, restore_access_entities=true`로 지정하면 테이블 데이터를 제외하고 테이블 정의와 액세스 엔터티만 복원합니다. [#102402](https://github.com/ClickHouse/ClickHouse/pull/102402) ([fm4v](https://github.com/fm4v)).
* 이제 딕셔너리 정의에서 `dictionary_lazy_load`를 사용하여 딕셔너리마다 지연 로딩 여부를 개별적으로 구성할 수 있으며, 이 값은 전역 `dictionaries_lazy_load` 서버 설정보다 우선합니다. 따라서 일부 딕셔너리는 지연 로딩하고 나머지는 즉시 로딩할 수 있습니다. [#108314](https://github.com/ClickHouse/ClickHouse/pull/108314) ([mstetsyuk](https://github.com/mstetsyuk)).
* 배열 첨자 연산자에서 정수 배열을 인덱스로 사용할 수 있습니다. `arr[indexes]`는 지정된 모든 위치의 요소를 반환하며, `arrayMap(i -> arr[i], indexes)`와 동일하게 동작합니다. [#108371](https://github.com/ClickHouse/ClickHouse/pull/108371) ([ucasfl](https://github.com/ucasfl)).
* WGS84 지리 좌표와 UTM 및 MGRS 좌표계 간 변환을 위한 `geoToUTM`, `UTMToGeo`, `geoToMGRS`, `MGRSToGeo` 함수를 추가했습니다. [#108939](https://github.com/ClickHouse/ClickHouse/pull/108939) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 딕셔너리 정의를 삭제하지 않고 딕셔너리가 사용하는 메모리를 해제하는 `SYSTEM UNLOAD DICTIONARY` 및 `SYSTEM UNLOAD DICTIONARIES` 명령을 추가했습니다. 딕셔너리는 다음에 액세스할 때 지연 방식으로 다시 로드됩니다. [#109639](https://github.com/ClickHouse/ClickHouse/pull/109639) ([Manerone](https://github.com/Manerone)).
* 텍스트 인덱스와 `tokens`, `hasAnyTokens`, `hasAllTokens` 함수에서 사용할 수 있는 새로운 `icu` 토크나이저를 추가했습니다. 이 토크나이저는 로케일을 고려한 유니코드 단어 분할(중국어, 일본어, 태국어 등을 위한 딕셔너리 기반 분할 포함)을 제공합니다. [#109940](https://github.com/ClickHouse/ClickHouse/pull/109940) ([Ergus](https://github.com/Ergus)).
* 새로운 코덱 `ZXC`를 추가했습니다. 압축은 느리지만 압축 해제가 매우 빠른 비대칭 LZ 코덱이며, 압축률은 `LZ4`와 `ZSTD`의 중간 수준입니다. [#110620](https://github.com/ClickHouse/ClickHouse/pull/110620) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `s3`, `s3Cluster`, `gcs`, `oss` 테이블 함수와 `S3` 테이블 엔진에서 상대 URL을 S3 기본 URL 기준으로 해석할 수 있도록 `s3_base` 설정을 추가했습니다. 또한 테이블 이름을 선택적 기본 URL 기준의 URL로 해석하여 적절한 백엔드로 전달하는 `URL` 데이터베이스 엔진을 추가했습니다. [#111512](https://github.com/ClickHouse/ClickHouse/pull/111512) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* HTTP 인덱스 페이지(HTML 또는 일반 텍스트 형식의 디렉터리 목록)를 조회하고 일치하는 URL을 추출하는 방식으로 `url()` 및 `URL` 엔진에서 와일드카드 확장을 지원합니다. 와일드카드는 URL 경로 부분을 기준으로 매칭되며, 인덱스 페이지 크기와 읽을 수 있는 디렉터리 수에는 제한이 있습니다. [#95181](https://github.com/ClickHouse/ClickHouse/pull/95181) ([niyue](https://github.com/niyue)).
* `kafka_sasl_mechanism`에 지원 값으로 `AWS_MSK_IAM`을 추가했습니다. 이제 ClickHouse는 SASL/SCRAM 자격 증명을 관리할 필요 없이 IAM 역할을 사용해 Amazon MSK에 인증할 수 있습니다. [#96100](https://github.com/ClickHouse/ClickHouse/pull/96100) ([kalavt](https://github.com/kalavt)).
* 토큰화 후 토큰을 변환하는 후처리기를 텍스트 인덱스에 추가했습니다. [#98939](https://github.com/ClickHouse/ClickHouse/pull/98939) ([Ergus](https://github.com/Ergus)).

<h2 id="experimental-features">
  실험적 기능
</h2>

<h3 id="experimental-query-planning-and-execution">
  쿼리 계획 및 실행
</h3>

* 실행형 사용자 정의 함수를 위한 "드라이버"가 추가되었습니다. `<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` 형태로 보존되므로 서버를 재시작해도 함수가 유지됩니다. 개념 증명(proof-of-concept)용 `c_function_body` 드라이버는 `executable_pool` 모드로 샌드박스화된 Docker 컨테이너 내에서 C 함수 본문을 컴파일하고 실행합니다. [#105131](https://github.com/ClickHouse/ClickHouse/pull/105131) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `/api/v1/query` 및 `/api/v1/query_range`에 대한 Prometheus Query API 요청이 `read_rows` 및 `read_bytes` 메트릭과 함께 `system.query_log`에 기록됩니다. [#106611](https://github.com/ClickHouse/ClickHouse/pull/106611) ([JTCunning](https://github.com/JTCunning)).
* `make_distributed_plan`이 활성화되어 있으면 MergeTree 계열 테이블의 `SELECT ... FINAL`에 대해 분산 쿼리 계획 기반 읽기를 지원합니다. [#108148](https://github.com/ClickHouse/ClickHouse/pull/108148) ([davenger](https://github.com/davenger)).
* MergeTree 쿼리에 Experimental 기능인 계획 기반 병렬 레플리카 실행을 추가했습니다. [#108504](https://github.com/ClickHouse/ClickHouse/pull/108504) ([devcrafter](https://github.com/devcrafter)).
* 상수 표현식을 평가해 쿼리 문자열을 만들고, 그 결과인 단일 `SELECT` 쿼리를 실행하는 Experimental 테이블 함수 `eval`을 추가했습니다. 이 기능은 기본적으로 비활성화되어 있으며 `allow_experimental_eval_table_function` 설정으로 활성화할 수 있습니다. 작성자: Yue Ni [#110132](https://github.com/ClickHouse/ClickHouse/pull/110132) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 계획 기반 병렬 레플리카(`parallel_replicas_plan_based`): 이제 로컬/원격 경계가 일반 쿼리 계획에 대한 계획 수준 최적화를 통해 결정되며, `UNION`이 포함된 뷰에 대한 쿼리는 `parallel_replicas_allow_view_over_mergetree` 없이도 병렬화됩니다. 또한 `IN (subquery)`를 사용하는 쿼리는 이제 실패하지 않고 로컬 계획으로 대체되어 실행됩니다. [#111063](https://github.com/ClickHouse/ClickHouse/pull/111063) ([devcrafter](https://github.com/devcrafter)). [#112443](https://github.com/ClickHouse/ClickHouse/pull/112443) ([devcrafter](https://github.com/devcrafter)).
* Experimental AI 함수의 보안을 강화했습니다. 원격 호스트에 대한 안전하지 않은(`http`) 엔드포인트를 기본적으로 차단하고(새 설정 `ai_function_allow_insecure_endpoint`), 쿼리당 외부 API 호출 수를 기본적으로 제한하며(`ai_function_max_api_calls_per_query`의 기본값이 이제 `1000`), 로그에 기록되는 제공자 오류 응답에서 민감한 내용을 정제합니다. [#111286](https://github.com/ClickHouse/ClickHouse/pull/111286) ([george-larionov](https://github.com/george-larionov)).
* 이제 계획 기반 병렬 레플리카(`parallel_replicas_plan_based`)가 조건을 충족하는 JOIN(`INNER`, `LEFT`, `RIGHT`, `SEMI`/`ANTI` 포함)을 분산 처리합니다. 조인 전체가 하나의 분산 계획 조각에서 실행되며, 한쪽은 레플리카 간에 조정되고 다른 쪽은 브로드캐스트됩니다. [#112268](https://github.com/ClickHouse/ClickHouse/pull/112268) ([devcrafter](https://github.com/devcrafter)).
* 분산 쿼리(`make_distributed_plan = 1`)가 취소되면 단순히 `QUERY_WAS_CANCELLED`를 반환하는 대신 취소를 유발한 오류를 보고합니다. 이전에는 실패한 worker 작업의 실제 오류를 서버 로그에서만 확인할 수 있었습니다. [#112590](https://github.com/ClickHouse/ClickHouse/pull/112590) ([davenger](https://github.com/davenger)).
* `IN (subquery)`를 `JOIN`으로 재작성하지 않고도 이를 포함한 쿼리 계획의 분산 실행을 지원합니다. 집합은 이니시에이터에서 한 번만 생성되며, 그 값은 worker 작업과 함께 전달됩니다. 강제로 적용되던 `rewrite_in_to_join` 재정의는 제거되었으며, 재작성은 명시적 설정을 통해 계속 사용할 수 있습니다. [#113826](https://github.com/ClickHouse/ClickHouse/pull/113826) ([davenger](https://github.com/davenger)).
* 분산 계획 쿼리(`make_distributed_plan`)는 이제 `LIMIT`이 충족되면 전체 결과를 계산한 뒤 버리는 대신 업스트림 스테이지를 중지합니다. [#114806](https://github.com/ClickHouse/ClickHouse/pull/114806) ([davenger](https://github.com/davenger)).
* PromQL 쿼리가 범위 선택자 안에서 `offset`을 사용할 때(예: `rate(m[2m] offset 5m)`) 발생하던 `Illegal type Decimal(18, 0) of argument of function toIntervalNanosecond` 오류를 수정했습니다. [#114997](https://github.com/ClickHouse/ClickHouse/pull/114997) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* Cascades 최적화기(`make_distributed_plan = 1, enable_cascades_optimizer = 1`)로 생성된 분산 계획에서 `GROUPING SETS` 집계를 지원합니다. [#115426](https://github.com/ClickHouse/ClickHouse/pull/115426) ([davenger](https://github.com/davenger)).
* 이제 `TimeSeries` 테이블에서 "최근 샘플" 테이블을 유지할 수 있습니다. 새 엔진 설정 `recent_samples_ttl_seconds`가 0이 아니면 엔진은 TTL이 적용된 samples 테이블 사본(`recent_samples_partition_by` 기준으로 파티션되며 기본값은 일 단위)을 생성하고 삽입할 때마다 이 사본에도 기록합니다. 시간 범위가 TTL 기간 안에 들어오는 PromQL 쿼리는 자동으로 이 테이블에서 읽으므로, 대용량 테이블에서 알림/레코딩 규칙과 짧은 범위의 대시보드가 몇 배 빨라집니다. 이 테이블을 우선 사용하는 동작은 새 쿼리 수준 설정 `time_series_prefer_recent_samples_table`로 비활성화할 수 있습니다. [#115441](https://github.com/ClickHouse/ClickHouse/pull/115441) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* 분산 쿼리 계획(`make_distributed_plan`)은 이제 `LIMIT`이 충족되면 유휴 상태의 업스트림 스테이지를 즉시 중지합니다. 유휴 상태의 exchange 싱크는 `NoMoreDataNeeded`가 도착하는 즉시 이를 읽고, 유휴 상태의 exchange 소스는 출력이 닫힌 것을 감지하여 중지 신호를 업스트림으로 전달합니다. 이전에는 이러한 스테이지가 아무도 사용하지 않는 데이터를 계속 읽고 계산했습니다. [#115690](https://github.com/ClickHouse/ClickHouse/pull/115690) ([davenger](https://github.com/davenger)).
* 이제 `parallel_replicas_plan_based`가 활성화되어 있으면 자동 병렬 레플리카 기능이 런타임 통계를 수집하여 지원되는 쿼리에 병렬 레플리카를 활성화할 수 있습니다. [#115788](https://github.com/ClickHouse/ClickHouse/pull/115788) ([devcrafter](https://github.com/devcrafter)).
* 분산 쿼리 계획을 위한 Experimental Cascades 비용 기반 최적화기를 추가했습니다. `make_distributed_plan = 1`과 함께 `enable_cascades_optimizer = 1`을 설정하면 활성화됩니다. 이 최적화기는 예상 비용을 기준으로 조인 전략(셔플, 브로드캐스트, 복제, 로컬), 집계 방식(2단계, 셔플, 로컬), 2단계 분산 top-N, 읽기 방식(병렬, 복제)을 선택하며, 필요에 따라 exchange 연산자를 삽입합니다. [#86353](https://github.com/ClickHouse/ClickHouse/pull/86353) ([davenger](https://github.com/davenger)).

<h3 id="experimental-storage-data-lakes-and-indexes">
  저장소, 데이터 레이크 및 인덱스
</h3>

* 역직렬화된 Paimon 메타데이터 파일(manifest 목록 및 매니페스트)을 위한 인메모리 SLRU 캐시를 추가했습니다. `use_paimon_metadata_files_cache` 설정으로 활성화하면 동일한 Paimon 테이블에 쿼리를 반복 실행할 때 객체 스토리지에서 메타데이터를 다시 다운로드하거나 다시 파싱하지 않습니다. [#104657](https://github.com/ClickHouse/ClickHouse/pull/104657) ([Binnn-MX](https://github.com/Binnn-MX)).
* 이제 Experimental `ReaderExecutor`(`use_reader_executor`, 기본값은 비활성화)가 원격 소스 연결을 열어 둔 채 순차 읽기에서 재사용할 수 있어, 스캔 시 객체 스토리지 요청 수가 줄어듭니다. [#107735](https://github.com/ClickHouse/ClickHouse/pull/107735) ([CheSema](https://github.com/CheSema)).
* Experimental `ReaderExecutor` 읽기 경로(`use_reader_executor`, 기본값은 비활성화)에 read-through 방식의 파일 시스템 캐시를 추가했습니다. [#110029](https://github.com/ClickHouse/ClickHouse/pull/110029) ([CheSema](https://github.com/CheSema)).
* Experimental `MergeTree` 설정 `allow_experimental_adaptive_codec_selection`을 추가했습니다. 이 설정을 활성화하면 머지 및 뮤테이션 시 기본 코덱을 사용하는 컬럼에 대해 블록마다 출력 크기가 가장 작은 코덱을 선택합니다. [#111834](https://github.com/ClickHouse/ClickHouse/pull/111834) ([rienath](https://github.com/rienath)).
* Experimental `ReaderExecutor` 읽기 경로(`use_reader_executor`, 기본값은 비활성화)에 사용자 공간 페이지 캐시 계층을 추가했습니다. 이제 캐시 미스가 발생하면 실행기가 사용자 공간 페이지 캐시를 채우고, 이후 읽기는 이 캐시에서 zero-copy 방식으로 처리합니다. [#114890](https://github.com/ClickHouse/ClickHouse/pull/114890) ([CheSema](https://github.com/CheSema)).
* 이제 `OPTIMIZE TABLE ... MANIFEST`로 `Iceberg` manifest 파일 컴팩션을 수행하여 메타데이터 파일 수를 줄일 수 있습니다. 이 기능은 `allow_experimental_iceberg_compaction` 설정을 활성화해야 사용할 수 있습니다. [#98178](https://github.com/ClickHouse/ClickHouse/pull/98178) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).

<h3 id="experimental-functions-formats-and-ai">
  함수, 포맷 및 AI
</h3>

* Experimental: 프레디케이트가 컬럼을 기본값과 기본값이 아닌 값으로 정확히 분할하는 경우, `SELECT count(*) FROM t WHERE col <op> default(col)` 쿼리를 데이터 스캔 없이 `serialization.json`에 저장된 컬럼별 희소성 통계만으로 처리합니다. [#105890](https://github.com/ClickHouse/ClickHouse/pull/105890) ([Algunenano](https://github.com/Algunenano)).
* Experimental `Quantize(...)` 벡터 코덱 계열과, 양자화된 보조 스트림을 활용하는 선택적(opt-in) 2단계 근사 벡터 검색 재작성 기능을 추가했습니다. [#108565](https://github.com/ClickHouse/ClickHouse/pull/108565) ([shankar-iyer](https://github.com/shankar-iyer)).
* `Float32`/`Float64` 컬럼(및 이들의 배열)용 Experimental `SZ3` 오차 한정 손실 압축 코덱을 다시 도입했습니다. 이 코덱을 사용하려면 `allow_experimental_codecs`를 활성화해야 합니다. [#108788](https://github.com/ClickHouse/ClickHouse/pull/108788) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Experimental `SZ3('ALGO_LORENZO_REG', ...)` 코덱으로 압축된 데이터를 읽을 때 `CORRUPTED_DATA` 오류가 발생하던 문제를 수정했으며, Experimental `SZ3` 코덱으로 유한하지 않은 부동소수점 값(`NaN` 및 무한대)을 압축할 때 발생하던 정의되지 않은 동작을 방지했습니다. [#110762](https://github.com/ClickHouse/ClickHouse/pull/110762) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* PromQL: 이제 날짜/시간 함수(`hour()`, `minute()`, `month()`, `year()`, `day_of_week()`, `day_of_month()`, `day_of_year()`, `days_in_month()`)를 인수 없이 호출할 수 있으며, 이 경우 Prometheus와 마찬가지로 `vector(time())`이 기본값으로 사용됩니다. [#111869](https://github.com/ClickHouse/ClickHouse/pull/111869) ([valerypetrov](https://github.com/valerypetrov)).
* PromQL: `vector(1) + vector(2)`, `topk(1, vector(1))`, `label_replace(vector(1), ...)`, `on()`을 사용하는 이항 연산자 등 태그가 없는 instant vector에 대한 연산이 타입 오류로 실패하던 문제를 수정했습니다. [#111872](https://github.com/ClickHouse/ClickHouse/pull/111872) ([valerypetrov](https://github.com/valerypetrov)).
* PromQL: `deriv` 함수를 구현하면서, 밀리초 해상도의 타임스탬프에서 이 함수의 기반이 되는 집계 함수가 실제보다 1000배 작은 값을 반환하던 버그를 수정했습니다. [#112360](https://github.com/ClickHouse/ClickHouse/pull/112360) ([valerypetrov](https://github.com/valerypetrov)).
* `parallel_replicas_plan_based`가 활성화된 경우 `ORDER BY` 쿼리에 순서 기반 읽기(read-in-order) 최적화를 적용합니다. 이제 정렬 작업이 레플리카로 전달된 후 initiator에서 병합되므로, 각 레플리카는 정렬 키 순서대로 데이터를 읽습니다. 또한 이 설정이 활성화된 상태에서 기본 키가 아닌 컬럼에 `ORDER BY`를 사용할 때 발생하던 `Unknown function __topKFilter` 오류도 수정했습니다. [#114315](https://github.com/ClickHouse/ClickHouse/pull/114315) ([devcrafter](https://github.com/devcrafter)).
* 데이터 파트를 다시 로드한 후(예: `ATTACH` 또는 서버 재시작 후) 발생하던 벡터 검색 읽기 문제를 수정했습니다. 이제 파트에서 `Quantized` 코덱 서브컬럼이 유실되지 않으므로, 검색 시 전체 정밀도 컬럼으로 폴백하지 않고 양자화된 서브컬럼을 읽습니다. [#114763](https://github.com/ClickHouse/ClickHouse/pull/114763) ([shankar-iyer](https://github.com/shankar-iyer)).
* Experimental `TimeSeries` 테이블 엔진은 더 이상 samples 내부 테이블에서 자동 생성되는 `value` 컬럼에 `Gorilla` 코덱을 적용하지 않으며, 이제 해당 컬럼의 기본 코덱은 `CODEC(ZSTD(1))`입니다. 명시적으로 선언된 컬럼은 사용자가 지정한 코덱을 그대로 유지합니다. `timestamp` 컬럼의 기본값(`CODEC(DoubleDelta, ZSTD(1))`)은 변경되지 않습니다. [#112110](https://github.com/ClickHouse/ClickHouse/pull/112110) ([nikitamikhaylov](https://github.com/nikitamikhaylov)). [#114790](https://github.com/ClickHouse/ClickHouse/pull/114790) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* `make_distributed_plan = 1`로 실행되는 쿼리에서 `ROLLUP`, `CUBE`, `GROUPING SETS` 및 `grouping` 함수를 지원합니다. [#114950](https://github.com/ClickHouse/ClickHouse/pull/114950) ([davenger](https://github.com/davenger)).
* Experimental ALP 코덱에 Real Doubles(RD) 변형과 선택적 인수 `ALP(AUTO|STD|RD)`를 추가했습니다. 이제 인수 없이 ALP를 사용하면 항상 STD를 사용하지 않고, 기존 STD 방식과 RD 중 하나를 자동으로 선택합니다. [#99654](https://github.com/ClickHouse/ClickHouse/pull/99654) ([nazarii-piontko](https://github.com/nazarii-piontko)).

<h3 id="other-experimental-features">
  기타 실험적 기능
</h3>

* kafka\_partition\_shard\_num 및 kafka\_shard\_count 설정을 통해 StorageKafka2에 정적 파티션-세그먼트 선호도(affinity)를 추가했습니다. 이를 통해 여러 ClickHouse 세그먼트가 Kafka 파티션 중 서로 겹치지 않는 부분 집합을 결정적으로 소비할 수 있습니다. [#108886](https://github.com/ClickHouse/ClickHouse/pull/108886) ([JingYanchao](https://github.com/JingYanchao)).
* 이제 `onelake_client_id` 및 `onelake_client_secret` 대신 `onelake_bearer_token` 설정으로 미리 발급받은 bearer 토큰을 사용하여 OneLake에 인증할 수 있습니다. 따라서 수명이 긴 클라이언트 시크릿을 공유할 필요가 없습니다. 토큰은 갱신되지 않으므로 만료되면 데이터베이스를 다시 생성해야 합니다. [#109104](https://github.com/ClickHouse/ClickHouse/pull/109104) ([asya-ch](https://github.com/asya-ch)).
* `packed_skip_index_max_bytes`를 통해 `skp_idx.packed`에 패킹된 스킵 인덱스의 `data_uncompressed_bytes` 값을 수정했습니다. 기존에는 압축되지 않은 크기로 압축된 크기가 보고되었으며, 이로 인해 `distributed_index_analysis`가 활성화되지 않는 경우도 있었습니다. [#109272](https://github.com/ClickHouse/ClickHouse/pull/109272) ([Algunenano](https://github.com/Algunenano)).
* Experimental Prometheus remote-write v1 HTTP 핸들러에 Zstandard 압축 지원을 추가했습니다. [#110907](https://github.com/ClickHouse/ClickHouse/pull/110907) ([JTCunning](https://github.com/JTCunning)).
* PromQL: `clamp`, `clamp_min`, `clamp_max`, `round` 함수를 구현했습니다. [#111870](https://github.com/ClickHouse/ClickHouse/pull/111870) ([valerypetrov](https://github.com/valerypetrov)).
* PromQL: 분위수 수준이 \[0, 1] 범위를 벗어나면 `quantile`이 이제 오류를 발생시키지 않고 Prometheus와 동일하게 -Inf/+Inf/NaN을 반환합니다. 또한 `histogram_quantile`은 Prometheus와 동일하게 `le` 레이블이 없거나 파싱할 수 없는 입력 시리즈를 무시합니다. [#111871](https://github.com/ClickHouse/ClickHouse/pull/111871) ([valerypetrov](https://github.com/valerypetrov)).
* PromQL: `changes()` 및 `resets()` 함수를 구현했습니다. [#112352](https://github.com/ClickHouse/ClickHouse/pull/112352) ([valerypetrov](https://github.com/valerypetrov)).
* Prometheus remote-write 엔드포인트를 통해 들어오는 insert 통계와 쿼리가 올바르게 수집되도록 수정했습니다. [#112825](https://github.com/ClickHouse/ClickHouse/pull/112825) ([JTCunning](https://github.com/JTCunning)).
* PromQL: 제수가 무한대인 나머지 연산에서 유한한 값이 그대로 유지되도록 수정했습니다. [#113746](https://github.com/ClickHouse/ClickHouse/pull/113746) ([fallintoplace](https://github.com/fallintoplace)).
* 일반 따옴표로 묶인 PromQL 문자열에 포함된 리터럴 줄 바꿈을 거부하도록 변경했습니다. [#114381](https://github.com/ClickHouse/ClickHouse/pull/114381) ([fallintoplace](https://github.com/fallintoplace)).
* Experimental 기능인 `make_distributed_plan` 및 `enable_cascades_optimizer`가 활성화된 상태에서 `distributed_plan_workers_num` 값이 매우 크면 서버가 `std::length_error`와 함께 비정상 종료되던 문제를 수정했습니다. 이제 이러한 노드 수는 `INVALID_SETTING_VALUE` 오류와 함께 거부됩니다. [#115398](https://github.com/ClickHouse/ClickHouse/pull/115398) ([groeneai](https://github.com/groeneai)).
* `TimeSeries` 테이블용 Prometheus HTTP API의 `/api/v1/series` 엔드포인트를 구현했습니다. `match[]` 시리즈 셀렉터(값을 반복 지정하면 합집합으로 처리), 선택적 `start`/`end` 시간 범위, 선택적 `limit` 매개변수를 지원합니다. [#115676](https://github.com/ClickHouse/ClickHouse/pull/115676) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).

<h2 id="performance-improvements">
  성능 개선
</h2>

<h3 id="join-and-aggregation-performance">
  JOIN 및 집계 성능
</h3>

* TopK 동적 필터링(`ORDER BY ... LIMIT n`)을 거치는 쿼리에서도 쿼리 조건 캐시를 사용할 수 있도록 했습니다. QCC 엔트리는 TopK 계획 매개변수별로 분할되므로 동일한 쿼리는 캐시된 WHERE 필터 결과를 재사용하고, `LIMIT`, 정렬 컬럼 또는 정렬 방향이 다르면 새 엔트리가 생성됩니다. [#104478](https://github.com/ClickHouse/ClickHouse/pull/104478) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* GROUP BY 키가 ORDER BY 키 및 테이블 정렬 키와 일치하면 LIMIT을 순차 집계(aggregation-in-order)로 푸시하여 조기 종료할 수 있도록 했습니다. 이를 통해 읽는 행 수가 크게 줄어듭니다. [#104859](https://github.com/ClickHouse/ClickHouse/pull/104859) ([thevar1able](https://github.com/thevar1able)).
* `allow_aggregate_partitions_independently`를 기본으로 활성화했습니다. `GROUP BY` 키가 파티션 키에 적합하면 ClickHouse는 각 파티션을 독립적으로 집계하고 전역 병합 단계를 생략할 수 있습니다. 파티션 구성상 이 최적화가 불리한 경우(파티션이 너무 적거나 너무 많거나, 파티션 크기가 크게 편중된 경우)에는 런타임 휴리스틱이 자동으로 최적화를 건너뜁니다. [#105128](https://github.com/ClickHouse/ClickHouse/pull/105128) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `read_in_order_use_virtual_row`를 기본으로 활성화했습니다. 파트가 많은 테이블을 프라이머리 키 순서로 읽을 때(예: `ORDER BY primary_key LIMIT n`) 실제로 결과에 기여할 수 있는 파트만 읽으므로(병렬 읽기를 유지하기 위해 최대 `max_threads`개 파트를 사전 읽기하는 구간 포함) 최대 메모리 활용량이 크게 줄어듭니다. [#106215](https://github.com/ClickHouse/ClickHouse/pull/106215) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `JOIN`의 메모리 사용량을 줄이고 성능을 개선했습니다. 이제 해시 조인의 오른쪽은 8바이트 크기의 간결한 인덱스 기반 행 참조를 사용하므로, 모든 키 타입에서 `ALL` 조인의 해시 테이블 엔트리가 `ANY` 조인만큼 작아집니다. `UInt64` 및 `String` 키(고유 키와 중복 키 모두)로 1억\~3억 행 테이블을 `INNER` 및 `ANY` 조인하는 대규모 `parallel_hash` 조인 쿼리로 벤치마크한 결과, 쿼리 중앙값 기준 약 12% 빨라지고 최대 메모리 사용량이 약 15% 줄었으며 느려진 쿼리는 없었습니다. 가장 크게 개선된 것은 `UInt64` 키에 대한 `INNER` 조인입니다(중앙값 기준 약 21% 빨라지고 메모리 38% 감소). [#107189](https://github.com/ClickHouse/ClickHouse/pull/107189) ([harikrishnan94](https://github.com/harikrishnan94)).
* dpsub 조인 순서 열거 알고리즘을 추가했습니다. dpsize보다 적은 최적화 오버헤드로 최적의 조인 계획을 생성하며, inner 이외의 조인도 지원합니다. [#107351](https://github.com/ClickHouse/ClickHouse/pull/107351) ([fkastrati](https://github.com/fkastrati)).
* 전체 쿼리 메모리 대신 집계 상태 전용 메모리 트래커를 연결하여, 메모리 사용량이 적은 단일 수준 집계가 2단계 집계로 전환되지 않도록 했습니다. [#107490](https://github.com/ClickHouse/ClickHouse/pull/107490) ([m-selmi](https://github.com/m-selmi)).
* 집계 해시 테이블 크기 통계 캐시 키를 AST 대신 쿼리 계획에서 계산하도록 변경하여, 집계 쿼리 분석 시 전체 쿼리 AST를 생성하지 않도록 했습니다. [#107643](https://github.com/ClickHouse/ClickHouse/pull/107643) ([novikd](https://github.com/novikd)).
* 첫 번째 쿼리 실행에서 수집한 런타임 통계를 바탕으로, 첫 실행에서 사용한 `hash` 조인을 이후 실행에서 `parallel_hash`로 전환할 수 있도록 했습니다. [#108125](https://github.com/ClickHouse/ClickHouse/pull/108125) ([m-selmi](https://github.com/m-selmi)).
* 런타임 조인 통계의 해시 테이블 크기를 활용하여 이후 쿼리 실행 시 조인 런타임 필터의 크기를 최적화합니다. 새로운 설정 `join_runtime_filter_size_from_hash_table_stats`로 제어할 수 있습니다. [#108313](https://github.com/ClickHouse/ClickHouse/pull/108313) ([m-selmi](https://github.com/m-selmi)).
* 파티션된 `MergeTree` 테이블에 대한 `DISTINCT` 쿼리에서 각 파티션의 행을 하나의 스트림 안에 유지하도록 하여 속도를 높이고 메모리 사용량을 줄였습니다. 이에 따라 동일한 키 집합이 여러 preliminary `DISTINCT`에 중복으로 나타나지 않고, 각 스트림의 preliminary `DISTINCT`가 서로 겹치지 않는 키 집합을 처리합니다. 이 최적화는 파티션 표현식이 `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](https://github.com/ClickHouse/ClickHouse/pull/108326) ([nihalzp](https://github.com/nihalzp)).
* 이제 `ON` 절에 비동등 조건자가 함께 포함되어 있어도 동등 키를 기반으로 런타임 필터를 생성합니다. 따라서 동등 조인과 비동등 조인이 혼합된 경우 해시 조인에 유입되는 행 수가 줄어듭니다. `LEFT ANTI JOIN`은 영향을 받지 않습니다. [#108579](https://github.com/ClickHouse/ClickHouse/pull/108579) ([29antonioac](https://github.com/29antonioac)).
* 집계 및 조인 해시 테이블의 소프트웨어 프리페치 임계값을 `4 * L2 cache size`에서 `L2 cache size`로 낮추어, 해시 테이블이 L2에 들어가지 않게 되는 시점부터 프리페치가 활성화되도록 했습니다. 이를 통해 보고된 L2 크기가 큰 플랫폼(예: L2가 2 MiB인 aarch64)에서 중간 크기 해시 테이블(\~1-8 MiB)을 사용하는 `GROUP BY` 및 `JOIN`의 성능 저하 문제를 해결했습니다. [#108655](https://github.com/ClickHouse/ClickHouse/pull/108655) ([groeneai](https://github.com/groeneai)).
* 윈도우 함수 성능을 개선했습니다. `SELECT *`를 포함하는, 컬럼이 많은 테이블에 대한 윈도우 쿼리가 이제 훨씬 적은 메모리로 더 빠르게 실행됩니다. `quantile*`, `uniq*`, `groupArray` 등의 윈도우 집계가 `OVER ()` 및 `OVER (ORDER BY ... RANGE ...)`에서 더 빨라졌습니다. `cume_dist` 함수도 더 빨라졌으며, `PARTITION BY` 또는 `ORDER BY`를 사용하는 윈도우는 반복 값이 많은 컬럼에서 성능이 향상되었습니다. [#108688](https://github.com/ClickHouse/ClickHouse/pull/108688) ([nihalzp](https://github.com/nihalzp)).
* 집계 함수가 없는 집계 쿼리는 이제 (지원되는 키 타입에 한해) `HashMap` 대신 `HashSet` 기반 방식을 사용합니다. 최대 1.8배의 속도 향상이 확인되었습니다. [#108862](https://github.com/ClickHouse/ClickHouse/pull/108862) ([nickitat](https://github.com/nickitat)).
* `parallel_hash` 조인 알고리즘에서 잠금 경합으로 발생하는 오버헤드를 줄였습니다. [#108938](https://github.com/ClickHouse/ClickHouse/pull/108938) ([m-selmi](https://github.com/m-selmi)).
* 새로운 `join_algorithm` 값인 `parallel_full_sorting_merge`를 추가했습니다. 해시 호환 동등 조인에서 full sorting merge join을 조인 키의 해시 기준으로 분할하여, 모든 스레드에서 실행되는 독립적인 세그먼트별 merge join으로 처리합니다. merge join의 낮은 스트리밍 방식 메모리 사용량을 유지하면서 병렬 처리가 가능합니다(벤치마크 결과 `parallel_hash` 대비 약 2.4배 빠르고 메모리 사용량은 약 3.3배 적음). `ASOF` 조인은 단일 `full_sorting_merge`로 대체됩니다. 해시 비호환 키 타입(부동 소수점, `JSON`, `Object`, `Dynamic`)은 해시 분산 재작성만 건너뛰며, `query_plan_join_shard_by_pk_ranges`가 활성화된 경우에는 소스 단계에서 기본 키 범위 기준으로 분할될 수 있습니다. 결과는 정렬되지 않습니다. [#109005](https://github.com/ClickHouse/ClickHouse/pull/109005) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 테이블의 현재 활성 크기와 기록되는 블록 크기의 합이 새로운 `materialize_statistics_on_insert_max_table_size` 설정 값(기본값 25 GiB) 이하이면, `INSERT` 시 기본적으로 컬럼 통계(Column Statistics)가 구체화됩니다. 이 검사는 기록되는 블록 단위로 수행되므로, 빈 테이블에 처음 대량 적재하는 경우에도 각 블록마다 통계가 구체화될 수 있습니다. 이를 통해 비용 기반 조인 최적화기는 새로 적재된 차원 테이블에 대해 정확한 추정치를 얻고 비정상적인 조인 순서를 피할 수 있습니다(예: TPC-H Q5와 Q8이 스케일 팩터 40에서 더 이상 시간 초과되지 않습니다). 반면 이미 데이터가 축적된 대규모 팩트 테이블은 기존처럼 머지 중에 통계를 구체화합니다. [#109454](https://github.com/ClickHouse/ClickHouse/pull/109454) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 키 없이 집계하는 경우 집계 함수 `uniqCombined`를 최적화했습니다. [#109794](https://github.com/ClickHouse/ClickHouse/pull/109794) ([CurtizJ](https://github.com/CurtizJ)).
* 집계 함수 `uniqHLL12`와 `uniqCombined`를 최적화했습니다. [#109831](https://github.com/ClickHouse/ClickHouse/pull/109831) ([CurtizJ](https://github.com/CurtizJ)).
* `parallel_hash` 조인 알고리즘에서 조인되지 않은 행의 처리를 병렬화하는 경우를 두 가지 추가했습니다. 잔여 필터가 있는 경우와 조인 키가 작은 경우(단일 수준 해시 맵)입니다. [#110008](https://github.com/ClickHouse/ClickHouse/pull/110008) ([m-selmi](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/110114) ([groeneai](https://github.com/groeneai)).
* `join_use_nulls = 1`인 경우, 외부 조인의 양쪽 컬럼을 모두 참조하는 null 거부 `WHERE`(예: `WHERE l.k = 42 AND r.k = 42`)가 있으면 이제 `join_use_nulls = 0`일 때와 마찬가지로 조인을 `INNER`(또는 `LEFT`/`RIGHT`)로 변환하고 프라이머리 키를 프루닝합니다. 이전에는 이 경우 변환이 생략되어 두 테이블을 모두 전체 스캔했습니다. [#110121](https://github.com/ClickHouse/ClickHouse/pull/110121) ([groeneai](https://github.com/groeneai)).
* 키 없는 집계에서 함수 `uniq`, `uniqExact`, `uniqHLL12`를 최적화했습니다. [#110150](https://github.com/ClickHouse/ClickHouse/pull/110150) ([CurtizJ](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/110234) ([groeneai](https://github.com/groeneai)).
* 단일 수준 집계 해시 테이블의 최종 머지를 병렬화했습니다. 키 공간을 서로 겹치지 않는 해시 파티션으로 분할하고 각 스레드가 이를 독립적으로 머지합니다(`enable_parallel_single_level_merge` 설정, 기본적으로 활성화). 스레드별 해시 테이블이 2단계 임계값 미만으로 유지되지만 머지가 실행 시간의 대부분을 차지하던 `GROUP BY` 쿼리의 속도가 향상됩니다. [#110395](https://github.com/ClickHouse/ClickHouse/pull/110395) ([nihalzp](https://github.com/nihalzp)).
* 단일 `String` 집계 키에 더 작은 해시 테이블 표현을 사용하도록 개선하여 문자열 비중이 높은 `GROUP BY` 워크로드의 성능을 향상했습니다. 새 `enable_packed_string_keys_in_aggregation` 설정은 기본적으로 활성화되어 있습니다. 이 설정을 비활성화하거나 `compatibility`를 `26.8` 미만으로 설정하면 기존 `StringHashTable` 경로로 되돌아가며, 11바이트보다 길고 카디널리티(cardinality)가 매우 낮은 키에서는 이 경로가 더 빠를 수 있습니다. [#110573](https://github.com/ClickHouse/ClickHouse/pull/110573) ([harikrishnan94](https://github.com/harikrishnan94)). [#112089](https://github.com/ClickHouse/ClickHouse/pull/112089) ([harikrishnan94](https://github.com/harikrishnan94)).
* 희소(sparse) 시나리오에서 full sorting merge join 성능을 최대 1.5\~3배 향상했습니다. [#111200](https://github.com/ClickHouse/ClickHouse/pull/111200) ([vdimir](https://github.com/vdimir)).
* probe 측과 build 측의 조인 키 타입이 서로 다른 경우(예: 널 허용(Nullable) probe 키와 널 비허용 build 키)에도 `join_runtime_filter_from_fixed_hash_table`을 활성화합니다. [#111244](https://github.com/ClickHouse/ClickHouse/pull/111244) ([m-selmi](https://github.com/m-selmi)).
* 오른쪽 입력에 `NULL` 조인 키가 있거나 `ON` 표현식으로 필터링된 행이 있을 때 null 맵을 다시 구성하지 않도록 하여, `parallel_hash` 알고리즘을 사용하는 `RIGHT` 및 `FULL` 조인의 성능을 향상했습니다. [#111258](https://github.com/ClickHouse/ClickHouse/pull/111258) ([m-selmi](https://github.com/m-selmi)).
* 병렬 `GROUP BY`를 위한 새로운 적응형 알고리즘을 도입했습니다(`enable_adaptive_aggregator` 설정으로 제어하며 기본적으로 활성화됨). 각 스레드는 자체 해시 테이블에 키가 `adaptive_aggregator_freeze_threshold`개에 도달할 때까지 집계한 후 해당 테이블을 고정합니다. 따라서 자주 등장하는 키는 별도의 조정 없이 캐시에 상주하는 작은 테이블을 계속 갱신하고, 드물게 등장하는 키는 해시에 따라 버킷별 백로그로 라우팅되어 버킷 단위 병렬 머지 과정에서 정확히 한 번만 집계됩니다. [#111459](https://github.com/ClickHouse/ClickHouse/pull/111459) ([nihalzp](https://github.com/nihalzp)).
* 값마다 `ColumnDynamic`을 재구성하지 않도록 하여, 공유 데이터에 저장된 JSON/`Object` 컬럼 값의 행 단위 해싱 속도를 높였습니다(예: JSON 컬럼에 대한 `uniq`/`uniqExact`, 해시 기반 `GROUP BY`/`DISTINCT` 키에서 사용). 해시 값은 변경되지 않습니다. [#111501](https://github.com/ClickHouse/ClickHouse/pull/111501) ([valerypetrov](https://github.com/valerypetrov)).
* ON 절에 여러 개의 `OR` 분리항이 있는 RIGHT 및 FULL 해시 JOIN과, 잔여(부등) 조건이 있는 RIGHT/FULL JOIN의 성능을 향상했습니다. [#111590](https://github.com/ClickHouse/ClickHouse/pull/111590) ([m-selmi](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/111973) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 머지 중 `TTL ... GROUP BY` 집계에 대해 연속 키 최적화를 다시 활성화했습니다. 기존에는 aggregator 생성 시 `min_hit_rate_to_use_consecutive_keys_optimization`(`[0, 1]` 범위의 적중률, 기본값 0.5)가 들어가야 할 자리에 `min_chunk_bytes_for_parallel_parsing`(바이트 임계값, 기본값 10 MiB)이 전달되어, 해당 경로에서 이 최적화가 항상 비활성화되어 있었습니다. 결과에는 영향이 없습니다. [#112314](https://github.com/ClickHouse/ClickHouse/pull/112314) ([groeneai](https://github.com/groeneai)).
* 쿼리 계획(query plan)을 직렬화할 때 `ARRAY JOIN`의 지연 컬럼 복제가 더 이상 누락되지 않습니다. 이전에는 `serialize_query_plan = 1`이면 원격 계획 조각을 실행하는 노드가 `enable_lazy_columns_replication`을 무시하고 복제된 모든 사본을 항상 구체화했습니다. 이 설정은 기본적으로 활성화되어 있는데도 그러했습니다. [#112330](https://github.com/ClickHouse/ClickHouse/pull/112330) ([groeneai](https://github.com/groeneai)).
* `WHERE` 등식 조건의 피연산자 타입이 서로 다르더라도 `Int32`와 `Nullable(Int32)`처럼 공통 상위 타입(common supertype)이 있으면, 이제 해당 조건이 `JOIN` 조건으로 병합됩니다. 이에 따라 CROSS 조인을 INNER 조인으로 변환할 수 있습니다. [#112630](https://github.com/ClickHouse/ClickHouse/pull/112630) ([m-selmi](https://github.com/m-selmi)).
* 요소가 공유 데이터에 `JSON` 값을 담고 있는 `Array`를 복제할 때 재할당이 이차적으로 발생하던 문제를 수정했습니다. 집계 함수에 상수 `Array(JSON)`을 전달하는 경우가 대표적인 예입니다. 이러한 쿼리에서는 복사되는 바이트 수가 행 수의 제곱에 비례하여 증가했습니다. [#112897](https://github.com/ClickHouse/ClickHouse/pull/112897) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/112957) ([groeneai](https://github.com/groeneai)).
* 구조가 서로 다른 여러 테이블을 대상으로 하는 `Merge` 테이블과 JOIN할 때 쿼리 계획 수립에 삼차 복잡도가 발생하던 문제를 수정했습니다. 이전에는 이러한 쿼리가 `max_execution_time`이나 `KILL QUERY`에도 응답하지 않고 쿼리 계획 수립에만 수 분을 소요할 수 있었습니다. [#113140](https://github.com/ClickHouse/ClickHouse/pull/113140) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `GROUP BY` 키가 없는 집계가 실행될 때마다 정작 사용되지도 않는 해시 테이블 크기 캐시 키를 계산하려고, 상수 폴딩된 리터럴의 전체 내용을 포함한 입력 계획 하위 트리 전체를 직렬화하던 성능 회귀를 수정했습니다. `SELECT quantileMerge(arrayJoin(arrayMap(x -> state, range(5000000))))`와 같은 쿼리는 실행할 때마다 쿼리 계획 최적화에 약 63ms가 걸렸으나, 이제는 0.15ms면 충분합니다. [#113333](https://github.com/ClickHouse/ClickHouse/pull/113333) ([groeneai](https://github.com/groeneai)).
* PromQL 집계 연산자 `topk`, `bottomk`, `limitk`를 평가할 때, 모든 시리즈를 단일 행으로 모아 `O(time_steps * series^2)`의 중간 메모리를 사용하는 대신 선택 상태가 `O(time_steps * k)`인 스트리밍 계획을 사용합니다. 이전에 `MEMORY_LIMIT_EXCEEDED`로 실패하던 고카디널리티(high-cardinality) 메트릭 쿼리가 이제 제한된 메모리 안에서 실행되며, 평가도 단일 스레드가 아닌 병렬로 수행됩니다. [#113656](https://github.com/ClickHouse/ClickHouse/pull/113656) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* `timeSeries*ToGrid` 집계 함수 내부의 버킷별 해시 맵을 정렬된 평면 샘플 배열로 대체했습니다. 이에 따라 입력이 순서대로 들어오는 경우(대부분이 이에 해당) 샘플 수집이 O(1) 추가 연산으로 처리되며, 최종 처리 단계의 버킷별 복사 및 정렬 과정이 사라졌습니다. [#113681](https://github.com/ClickHouse/ClickHouse/pull/113681) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* 여러 계획 단계가 공유하는 PromQL 하위 표현식(`topk`/`bottomk`/`limitk` 피연산자, `or`의 좌변)을 두 번이 아닌 한 번만 평가합니다. 이를 위해 PromQL에서 생성되는 SQL이 이제 공유 서브쿼리를 구체화합니다. 그 결과 Samples table을 중복으로 스캔하지 않게 되어, `rate`에 대한 `topk`가 콜드 상태에서 약 2배 빨라지고 kubernetes-mixin 규칙 쿼리의 성능은 10–29% 향상됩니다. [#113772](https://github.com/ClickHouse/ClickHouse/pull/113772) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* 이제 `ORDER BY <column> LIMIT n`(TopK) 최적화를 사용하는 쿼리에서 [쿼리 조건 캐시](/ko/operations/query-condition-cache)가 기본적으로 활성화됩니다. 사용하지 않으려면 `use_query_condition_cache_for_top_k = 0`으로 설정하십시오. [#111492](https://github.com/ClickHouse/ClickHouse/pull/111492) [#114539](https://github.com/ClickHouse/ClickHouse/pull/114539) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 병합 전에 스레드별 집계 상태를 단일 수준에서 2단계 수준으로 변환하는 작업을 병렬화합니다. 이를 통해 코어 수가 매우 많은 머신에서 무거운 집계 상태(예: `COUNT(DISTINCT ...)`, ClickBench Q10/Q11)를 사용하는 짧은 `GROUP BY` 쿼리가 2\~3배 느려지던 성능 저하 문제가 해결됩니다. 이 문제는 26.7 개발 빌드에서 집계 메모리 계산을 정확하게 개선하면서 발생했습니다. [#114691](https://github.com/ClickHouse/ClickHouse/pull/114691) ([alexey-milovidov](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/114783) ([nihalzp](https://github.com/nihalzp)).
* `timeSeries*ToGrid` 집계 함수의 속도를 향상합니다. 이제 샘플별 버킷 계산에서 Int128 나눗셈을 사용하지 않으며, 같은 버킷에 속한 연속 샘플은 해시 맵 조회를 건너뜁니다. [#114889](https://github.com/ClickHouse/ClickHouse/pull/114889) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* `timeSeries*ToGrid` 집계 함수의 샘플을 같은 그리드 버킷에 속하는 연속 샘플 단위로 묶어 처리하여, 정렬된 시계열 데이터에서 `timeSeriesRateToGrid` 및 관련 함수의 샘플 수집 단계 속도를 1.2\~2배 향상합니다. [#115041](https://github.com/ClickHouse/ClickHouse/pull/115041) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* `GROUP BY` 키가 없는 집계는 더 이상 단일 행 출력을 `max_threads`개의 스트림으로 분산하지 않습니다. 따라서 이러한 집계 뒤에 실행 계획이 이어지는 쿼리는 병렬성을 잃지 않으면서도 훨씬 작은 파이프라인(생성, 스케줄링, 프로파일링할 프로세서 수 감소)으로 실행됩니다. [#115170](https://github.com/ClickHouse/ClickHouse/pull/115170) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* PromQL 인스턴트 쿼리의 평가 속도가 향상되었습니다. `timeSeries*ToGrid` 집계 함수는 단일 지점 그리드에 벡터화된 샘플 분류 경로를 사용하며, `timeSeriesIdToGroup`은 결과 컬럼을 직접 채웁니다. [#115267](https://github.com/ClickHouse/ClickHouse/pull/115267) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* `ON` 절에 `OR`로 연결된 여러 등식이 있는 `JOIN`은 더 이상 쿼리에서 선택하지 않는 오른쪽 키 컬럼을 구체화하지 않습니다. [#115465](https://github.com/ClickHouse/ClickHouse/pull/115465) ([nickitat](https://github.com/nickitat)).
* 오른쪽에서 동일한 조인 키가 여러 번 반복될 때 `ANY`, `SEMI`, `ANTI` 조인의 해시 테이블 빌드 속도를 향상합니다. 이제 조인 시 오른쪽의 행마다 메모리에서 `join_any_take_last_row` 설정을 다시 읽지 않습니다. [#115820](https://github.com/ClickHouse/ClickHouse/pull/115820) ([nickitat](https://github.com/nickitat)).
* `String`, `FixedString`, `LowCardinality` 키에 대해 집계 함수 없이 수행하는 `GROUP BY`의 속도를 향상합니다. 이제 사용되지 않는 플레이스홀더를 모든 행마다 해시 테이블에 다시 쓰지 않고, 새 키를 추가하는 행에서만 씁니다. [#115834](https://github.com/ClickHouse/ClickHouse/pull/115834) ([nickitat](https://github.com/nickitat)).
* 상수 폴딩된 대용량 리터럴(literal)에 대한 키 기반 집계에서 메모리 사용량과 쿼리 계획 최적화 시간을 줄였습니다. 집계 해시 테이블 통계 캐시 키를 메모리에 먼저 누적하지 않고 직렬화와 동시에 해시하도록 변경했습니다. 이에 따라 대용량 리터럴이 포함된 계획이 최적화 중에 해당 리터럴의 사본을 더 이상 보유하지 않습니다. 80 MB 리터럴 기준으로 최대 메모리(Peak memory) 사용량은 약 250 MB 줄고 최적화 시간은 약 2.5배 단축됩니다. 계산되는 키 값은 이전과 동일합니다. [#115847](https://github.com/ClickHouse/ClickHouse/pull/115847) ([groeneai](https://github.com/groeneai)).
* 집계 중에 크기가 제한된 힙을 유지하면서 결과에 포함될 수 없는 그룹을 프루닝하도록 하여 `GROUP BY ... ORDER BY ... LIMIT` 및 `GROUP BY ... LIMIT` 쿼리를 최적화했습니다. 이를 통해 고카디널리티(high-cardinality) 그룹화에서 메모리 사용량과 실행 시간이 크게 줄어듭니다. 이 기능은 `enable_group_by_top_k_optimization` 설정으로 제어합니다. Dmitriy Terenichev의 초기 구현을 기반으로 합니다. [#96630](https://github.com/ClickHouse/ClickHouse/pull/96630) ([thevar1able](https://github.com/thevar1able)).

<h3 id="query-optimization-and-execution">
  쿼리 최적화 및 실행
</h3>

* 병렬 레플리카(Parallel Replicas)를 사용한 순차 읽기(in-order reading)에서도 이제 로컬 읽기와 동일하게 테이블을 `max_threads`개의 파트로 분할하는 로직을 사용하므로 병렬성이 향상되었습니다. [#101434](https://github.com/ClickHouse/ClickHouse/pull/101434) ([nickitat](https://github.com/nickitat)).
* Parquet 리더에 row group 및 페이지 수준의 GeoParquet 공간 프루닝을 추가했습니다. row group 프루닝은 경계 상자(bounding box)가 쿼리 지오메트리와 겹치지 않는 row group 전체를 건너뜁니다. 페이지 수준 프루닝은 `covering.bbox` 컬럼 인덱스를 사용하여 row group 내에서 관련 없는 페이지를 건너뜁니다. 또한 `IFunctionBase::isSpatialPredicate()`를 통해 공간 프레디케이트 푸시다운을 일반화하고, Parquet 행을 읽는 동안 공간 프레디케이트를 평가하는 `GeoFilter`를 추가했습니다. [#104435](https://github.com/ClickHouse/ClickHouse/pull/104435) ([bacek](https://github.com/bacek)).
* `use_constant_folding_in_index_analysis` 설정을 추가했습니다(기본값은 비활성화). 이 설정을 활성화하면 `MergeTree` 기본 키(primary key), `MinMax` 및 스킵 인덱스 분석 시 파티션 수준의 상수를 파트별로 필터 프레디케이트에 폴딩하므로, 분기가 파티션 값에 따라 달라지는 필터의 프루닝 효율이 개선됩니다. 예를 들어 `PARTITION BY a`와 함께 사용하는 `(a = 1 AND b >= 1) OR (a = 2 AND b > 10)` 같은 필터가 이에 해당합니다. [#104582](https://github.com/ClickHouse/ClickHouse/pull/104582) ([Michicosun](https://github.com/Michicosun)).
* `vector_search_with_rescoring`을 사용하는 벡터 검색 쿼리에서, 쿼리 파이프라인의 정확한 거리 계산 이전에 정확한 행 위치 지정을 적용합니다. [#105591](https://github.com/ClickHouse/ClickHouse/pull/105591) ([skuznetsov](https://github.com/skuznetsov)).
* 데이터 크기를 줄이는 함수(`length`, `lengthUTF8`, `empty`, `notEmpty`)를 `Sorting` 및 `Filter` 단계 아래로 푸시다운하는 쿼리 계획 최적화를 추가했습니다. 이 최적화는 폭이 넓은 `String` / `FixedString` 인수를 고정 크기의 결과로 대체하므로, 해당 값이 정렬 과정에서 버퍼링되거나 필터 과정에서 복사되지 않습니다. 새 설정 `query_plan_push_down_volume_reducing_functions`로 제어하며, 기본적으로 활성화되어 있습니다. [#106199](https://github.com/ClickHouse/ClickHouse/pull/106199) ([fastio](https://github.com/fastio)).
* 각 캐시 파일의 크기를 파일 이름(`<offset>_<size>`)에 인코딩하여 파일마다 `stat`을 호출하지 않도록 함으로써, 시작 시 파일시스템 캐시 로딩 속도를 높였습니다. 이전 버전에서 작성된 캐시 파일도 계속 로딩할 수 있습니다. [#107415](https://github.com/ClickHouse/ClickHouse/pull/107415) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 기본 키 필터와 함께 사용하는 텍스트 검색 쿼리의 성능을 개선했습니다. [#108114](https://github.com/ClickHouse/ClickHouse/pull/108114) ([CurtizJ](https://github.com/CurtizJ)).
* 상수 폴리곤을 사용하는 `pointInPolygon` 함수의 성능을 개선했습니다. 이제 전처리된 폴리곤 캐시가 원시 상수 인수를 키로 사용하므로, 상수 폴리곤을 입력 블록마다 다시 파싱하지 않고 (캐시 미스 시) 한 번만 파싱합니다. [#108184](https://github.com/ClickHouse/ClickHouse/pull/108184) ([groeneai](https://github.com/groeneai)).
* 해당 기능이 비활성화된 경우(기본값인 `predicate_statistics_sample_rate = 0`) MergeTree 읽기 경로에서 `system.predicate_statistics_log` 선택도 카운터를 유지하지 않도록 했습니다. 이로써 모든 읽기에서 그래뉼별 원자적 업데이트와 `O(rows)` 필터 popcount가 제거되어, 특히 aarch64에서 두드러졌던 성능 저하가 해소되었습니다. [#108190](https://github.com/ClickHouse/ClickHouse/pull/108190) ([groeneai](https://github.com/groeneai)).
* 일반 `MergeTree` 머지에서 배치 정렬 큐를 선택적으로 사용할 수 있도록 `merge_use_batch_sorting_queueMergeTree` 설정을 추가했습니다. 정렬 머지 비용이 큰 머지 워크로드에서 CPU 시간과 실제 소요 시간을 줄여 줍니다. [#108468](https://github.com/ClickHouse/ClickHouse/pull/108468) ([rorylshanks](https://github.com/rorylshanks)).
* 동일한 `WITH` 별칭을 참조하거나 동일한 하위 표현식이 여러 번 반복되는 표현식(예: 깊게 중첩된 `if`/`multiIf` 체인)에 대해, actions DAG를 구성할 때 공유 하위 표현식을 다시 빌드하지 않도록 하여 analyzer의 쿼리 계획 수립 속도를 높였습니다. [#108523](https://github.com/ClickHouse/ClickHouse/pull/108523) ([novikd](https://github.com/novikd)).
* 비교 연산으로 이루어진 `AND` 체인이 많거나 매우 큰 쿼리의 쿼리 분석 속도를 개선했습니다. 이제 `optimize_and_compare_chain` 최적화는 쿼리 트리의 상당 부분을 해시하는 대신 작업 예산(새로운 설정 `optimize_and_compare_chain_max_hash_work`)으로 제한되며, lambda 해석 시 재귀 방지를 위해 lambda 본문 해시를 다시 계산하지 않습니다. [#108757](https://github.com/ClickHouse/ClickHouse/pull/108757) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 필터 전용 후처리기(`if(..., '', token)`)는 이제 원시 토큰으로 그래뉼을 빌드하고 빌드 시점에 빈 값을 제거합니다. 따라서 일반 경로에서 발생하던 항목별 머티리얼라이즈와 `ActionsDAG` 실행이 필요하지 않습니다. [#109049](https://github.com/ClickHouse/ClickHouse/pull/109049) ([ahmadov](https://github.com/ahmadov)).
* 분산 쿼리 계획의 `ShuffleSendStep`에서 단일 스레드 병목을 제거했습니다. 이제 각 업스트림 스트림은 전체 프래그먼트를 하나의 `ScatterByPartitionTransform`으로 모으는 대신, 대상 버킷별로 행을 독립적으로 분배합니다. [#109206](https://github.com/ClickHouse/ClickHouse/pull/109206) ([davenger](https://github.com/davenger)).
* 컬럼 수가 많은 쿼리에서 표현식 평가의 CPU 오버헤드를 줄였습니다(예: stride가 작은 `QBit` 컬럼에 대한 벡터 검색에서 각 벡터가 수백 개의 비트 플레인 서브컬럼으로 확장되어 모두 하나의 `*DistanceTransposed` 호출에 전달되는 경우). [#109380](https://github.com/ClickHouse/ClickHouse/pull/109380) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 프레디케이트가 `LIMIT BY` 키 컬럼만 참조하고, 해당 절이 비어 있지 않은 그룹마다 최소 1개의 행을 유지하는 경우(`n >= 1`이고 `OFFSET 0`인 `LIMIT n BY`) 필터를 `LIMIT BY` 아래로 푸시합니다. 이에 따라 `LIMIT BY` 서브쿼리를 감싸는 외부 `WHERE`로 작성된 프레디케이트가 전체 테이블을 읽고 그룹별 top-N을 먼저 적용하는 대신 스토리지까지 전달되어 프라이머리 키 프루닝, 스킵 인덱스, 프로젝션을 활용할 수 있습니다. `OFFSET`, `LIMIT 0 BY` 또는 음수 `LIMIT BY` 형태의 예외 동작은 변경되지 않습니다. [#110116](https://github.com/ClickHouse/ClickHouse/pull/110116) ([groeneai](https://github.com/groeneai)).
* 프라이머리 키 인덱스 분석에서 하이퍼렉탱글 검사마다 발생하던 힙 할당을 제거하여, 쿼리 형태에 따라 마크 필터링 속도가 5\~26% 향상되었습니다. [#110153](https://github.com/ClickHouse/ClickHouse/pull/110153) ([raimannma](https://github.com/raimannma)).
* Parquet 필터 푸시다운(행 그룹 프루닝 및 컬럼 인덱스)이 이제 `DateTime64` 변형 간, `Decimal` 변형 간, 그리고 `Float32`/`Float64` 간 변환을 지원합니다. [#110457](https://github.com/ClickHouse/ClickHouse/pull/110457) ([al13n321](https://github.com/al13n321)).
* sparseGrams 토크나이저를 사용하는 텍스트 및 블룸 필터 기반 스킵 인덱스의 빌드를 최적화했습니다. [#110541](https://github.com/ClickHouse/ClickHouse/pull/110541) ([UnamedRus](https://github.com/UnamedRus)).
* PREWHERE 조건 순서를 정할 때 I/O 비용과 선택도를 함께 고려합니다. 이를 통해 [https://github.com/ClickHouse/ClickHouse/pull/101275](https://github.com/ClickHouse/ClickHouse/pull/101275) 이후 일부 경우에 발생하던 PREWHERE 실행 성능 저하를 수정했습니다. [https://github.com/ClickHouse/ClickHouse/issues/110462](https://github.com/ClickHouse/ClickHouse/issues/110462) 의 일부입니다. [#110695](https://github.com/ClickHouse/ClickHouse/pull/110695) ([Avogar](https://github.com/Avogar)).
* 후처리기 `IN`/`NOT IN` 필터에 정의된 토큰의 해시 연산을 줄였습니다. [#111690](https://github.com/ClickHouse/ClickHouse/pull/111690) ([ahmadov](https://github.com/ahmadov)).
* enable\_lazy\_columns\_replication이 활성화된 경우, 상수가 아닌 패턴을 사용하는 mapContainsKeyLike, mapContainsValueLike, mapExtractKeyLike, mapExtractValueLike 함수의 메모리 사용량과 실행 시간이 줄었습니다. 이제 캡처 시점에 맵 항목마다 패턴을 미리 복사하지 않고 내부 lambda 실행 시점까지 복사를 미루며, 복사본도 더 빨리 해제됩니다. 따라서 사용량이 최대인 시점에 존재하는 확장된 패턴 복사본이 하나 줄어듭니다. [#111749](https://github.com/ClickHouse/ClickHouse/pull/111749) ([diegomestre2](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/111816) ([Algunenano](https://github.com/Algunenano)).
* 추이적 조건(transitive-conditions) 최적화는 이제 전체 필터를 적용할 수 없는 경우 추가 필터를 인덱스 분석에만 사용합니다. 자세한 내용은 `optimize_and_compare_chain` 설정을 참조하십시오. [#112076](https://github.com/ClickHouse/ClickHouse/pull/112076) ([yariks5s](https://github.com/yariks5s)).
* 실험적 TimeSeries 엔진의 Prometheus 쿼리 API(`/api/v1/query`, `/api/v1/query_range`)가 이제 단일 스레드가 아닌 병렬로 쿼리를 실행합니다. [#112108](https://github.com/ClickHouse/ClickHouse/pull/112108) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* 상수 벡터에 대한 `randomHadamardTransform`을 이제 행마다 평가하지 않고 한 번만 평가합니다. 따라서 `randomHadamardTransform`으로 쿼리 벡터를 회전시킨 후 `QBit` 컬럼과 비교하는 벡터 검색 쿼리의 속도가 향상됩니다. [#112921](https://github.com/ClickHouse/ClickHouse/pull/112921) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 프라이머리 키 컬럼에 대해 `IN (subquery)`로 필터링하는 뮤테이션에서, 같은 뮤테이션의 파트 작업 간 Set 공유 기능을 복원했습니다. `enable_sharing_sets_for_mutations`는 기본으로 활성화되어 있지만, 프라이머리 키 분석용으로 생성된 Set이 공유 캐시에서 제외되면서 파트가 N개인 테이블에서 동일한 Set을 N번 구체화하는 문제가 있었습니다. [#112941](https://github.com/ClickHouse/ClickHouse/pull/112941) ([groeneai](https://github.com/groeneai)).
* 분산 쿼리 계획(`make_distributed_plan`)에서 `ORDER BY ... LIMIT k`가 이제 각 레플리카에서 지연 머티리얼라이즈(lazy materialization)를 사용합니다. 크기가 큰 컬럼은 모든 후보 행이 아니라 해당 레플리카의 로컬 상위 k개 행에 대해서만 읽습니다. [#113111](https://github.com/ClickHouse/ClickHouse/pull/113111) ([shankar-iyer](https://github.com/shankar-iyer)).
* `uniq_v2` 컬럼 통계(column statistics)를 사용할 때 쿼리 계획 수립 속도가 향상되었습니다. 추정 고유값(distinct values) 개수를 이제 캐시하므로, 쿼리 계획 수립 시 쿼리당 여러 번 발생하는 요청마다 매번 다시 계산하지 않습니다. [#113357](https://github.com/ClickHouse/ClickHouse/pull/113357) ([groeneai](https://github.com/groeneai)).
* 이제 Parquet 및 ORC 파일의 `Tuple` 서브컬럼에서도 필터 푸시다운이 동작합니다. `file()`, `s3()`, `url()`에 대해 `WHERE tup.1 = 555555`와 같은 프레디케이트를 사용하면, 이제 파일 전체를 읽지 않고 튜플 요소 자체의 통계를 활용하여 행 그룹과 행 인덱스 스트라이드를 프루닝합니다. [#113383](https://github.com/ClickHouse/ClickHouse/pull/113383) ([groeneai](https://github.com/groeneai)).
* TimeSeries 엔진의 PromQL 쿼리 성능이 향상되었습니다. 내부 셀렉터 SQL이 이제 샘플 테이블의 프라이머리 키 컬럼을 (불필요한 캐스트 없이) 직접 읽고, series-id Set보다 타임스탬프 범위를 먼저 검사합니다. 그 결과 셀렉터 비중이 높은 콜드 쿼리가 30\~44% 빨라졌습니다. [#113768](https://github.com/ClickHouse/ClickHouse/pull/113768) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* 한 메트릭의 모든 시리즈와 일치하는 PromQL 셀렉터는 이제 인덱스 분석 시 큰 `id IN <set>` 조건 대신 `id`에 대한 연속적인 프라이머리 키 범위로 `TimeSeries` 테이블의 samples 테이블을 필터링합니다. 이는 id 레이아웃이 표준 id 생성기를 사용하는 2개 요소의 튜플일 때 적용됩니다. 이를 통해 셀렉터를 많이 사용하는 PromQL 쿼리에서 가장 큰 비중을 차지하던 단일 스레드 인덱스 분석 비용이 제거됩니다. 620억 개의 샘플이 있는 테이블에서 대시보드 및 규칙 쿼리 유형의 콜드 지연 시간이 최대 45% 감소했으며, 전체 테스트 모음의 콜드 기하 평균은 11% 감소했습니다. [#114131](https://github.com/ClickHouse/ClickHouse/pull/114131) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* Prometheus HTTP API 엔드포인트 `/api/v1/query` 및 `/api/v1/query_range`는 이제 `prometheusQuery` 및 `prometheusQueryRange` 테이블 함수와 마찬가지로, 여러 플랜 단계에서 공유하는 PromQL 서브쿼리를 한 번만 평가합니다. 이전에는 `enable_analyzer = 0`으로 요청하거나 프로필에 이 설정이 지정된 사용자가 요청하면, 공유 서브쿼리를 참조하는 단계마다 서브쿼리를 다시 스캔했습니다. [#114261](https://github.com/ClickHouse/ClickHouse/pull/114261) ([groeneai](https://github.com/groeneai)).
* 26.7에서 발생한 회귀 문제를 수정했습니다. `DateTime64` 컬럼에 `toUnixTimestamp`(또는 다른 정수 변환)를 적용한 값으로 정렬된 `MergeTree` 테이블에서, 해당 컬럼에 대한 일반 범위 필터가 프라이머리 키를 사용하지 않아 일치하는 파트의 모든 그래뉼을 읽던 문제입니다. 또한 원본 `DateTime64` 컬럼으로 정렬된 테이블에서 `toInt64(ts) >= c`와 같은 필터도 이제 프라이머리 키를 사용합니다. [#114413](https://github.com/ClickHouse/ClickHouse/pull/114413) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 클러스터링된(예: 프라이머리 키로 정렬된) 컬럼에 대해 `IN`을 실행할 때, 값이 같은 연속된 행에는 이전 행의 결과를 재사용하여 실행 속도를 높였습니다. [#114853](https://github.com/ClickHouse/ClickHouse/pull/114853) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* `h3kRing`, `h3ToChildren`, `h3PolygonToCells`, `h3PolygonToCellsWithContainment` 함수가 많은 행에 대해 결과를 생성할 때 이차 시간이 소요되던 문제를 수정했습니다. CI 스트레스 테스트에서 196,000개 행에 대한 쿼리가 메모리 복사에만 838초를 소비했으나, 이제는 약 5초면 완료됩니다. [#115773](https://github.com/ClickHouse/ClickHouse/pull/115773) ([groeneai](https://github.com/groeneai)).
* 역방향 딕셔너리 조회를 최적화했습니다. `WHERE dictGet(dict, attr, key_expr) = value`와 같은 상수 동등 조건자는 이제 `IN (SELECT ... FROM dictionary(...))` 서브쿼리로 재작성되지 않고 키 필터(`key_expr = const`, `key_expr IN [...]` 또는 `WHERE 0`)로 직접 상수 폴딩되며, `dictGetKeys`의 상수 경로는 이제 병렬로 실행됩니다. [#91164](https://github.com/ClickHouse/ClickHouse/pull/91164) ([nihalzp](https://github.com/nihalzp)).
* 일반 제외 검색 알고리즘이 각 데이터 파트의 프라이머리 키 인덱스를 분석하는 데 사용하는 단계 수를 제한하는 새 설정 `merge_tree_generic_exclusion_search_max_steps`를 추가했습니다. 할당량은 남은 키 범위 중 가장 큰 범위부터 사용되므로 할당량이 작더라도 데이터 대부분을 제외할 수 있습니다. 완전히 분석되지 않은 범위는 통째로 읽으므로 쿼리 결과의 정확성은 유지되지만 더 많은 그래뉼을 읽을 수 있습니다. 이 제한은 느슨하게 적용되어, 최대 `merge_tree_coarse_index_granularity` 단계에 파트가 이미 나뉘어 있는 범위(예: 쿼리 조건 캐시에 의해 나뉜 범위)마다 1단계를 더한 만큼 초과될 수 있습니다. 기본값 0은 단계 수에 제한이 없음을 의미합니다. [#92779](https://github.com/ClickHouse/ClickHouse/pull/92779) ([EmeraldShift](https://github.com/EmeraldShift)).
* 분산 테이블(Distributed Table) 위에 정의된 `VIEW`에 대해 `ORDER BY`와 `LIMIT`를 사용하는 쿼리가 이제 정렬된 스트림 머지 최적화를 사용합니다. 외부 `ORDER BY`/`LIMIT`가 단순 뷰의 내부 쿼리로 푸시되므로, 코디네이터에서 전체 정렬을 수행하지 않고 각 샤드가 로컬에서 데이터를 정렬한 뒤 코디네이터가 미리 정렬된 스트림을 머지합니다. [#94102](https://github.com/ClickHouse/ClickHouse/pull/94102) ([matanper](https://github.com/matanper)).

<h3 id="storage-io-and-data-lake-performance">
  저장소, I/O 및 데이터 레이크 성능
</h3>

* 프라이머리 키 컬럼이 파티션 키의 입력 컬럼이기도 한 경우, `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](https://github.com/ClickHouse/ClickHouse/pull/103480) ([UnamedRus](https://github.com/UnamedRus)).
* 정렬된 스트림에서 동일한 키 값이 이어지는 구간을 스캔하는 연산자의 속도를 개선했습니다. 대상 연산자는 정렬 순서 기반 `DISTINCT`, 정렬 순서 기반 `LIMIT BY`, 정렬 순서 기반 음수 `LIMIT BY`, `full_sorting_merge` 및 `partial_merge` 조인입니다. [#106502](https://github.com/ClickHouse/ClickHouse/pull/106502) ([nihalzp](https://github.com/nihalzp)).
* 이제 Parquet v3 리더는 컬럼 청크 전체가 딕셔너리 인코딩된 경우, 등호 및 `IN` 조건에 대해 min/max 통계와 블룸 필터뿐 아니라 딕셔너리 페이지도 활용하여 행 그룹 전체를 건너뛸 수 있습니다. 이 동작은 새로운 설정 `input_format_parquet_dictionary_filter_push_down`으로 제어됩니다. [#106952](https://github.com/ClickHouse/ClickHouse/pull/106952) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* gzip/zlib/deflate 압축 및 압축 해제에 libdeflate를 사용하도록 변경하여 `.gz`/HTTP/`url`/`s3` 데이터와 Parquet GZIP 코덱의 처리 속도를 개선했습니다(압축은 약 1.15배 빨라지고 압축률도 향상되었으며, 압축 해제는 약 1.4–1.5배 빨라졌습니다). [#108074](https://github.com/ClickHouse/ClickHouse/pull/108074) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 기본 공백 문자를 제거하는 `trimLeft`/`trimRight`/`trimBoth` 함수(및 별칭 `ltrim`/`rtrim`/`trim`)의 속도를 개선했습니다. 공백 제거가 필요 없는 연속된 행은 한 번에 일괄 복사하고, 행별 공백 스캔은 실제로 앞뒤에 공백이 있는 행에 대해서만 수행합니다. [#108177](https://github.com/ClickHouse/ClickHouse/pull/108177) ([groeneai](https://github.com/groeneai)).
* 현재 manifest를 파싱하는 동안 다음 manifest 파일을 미리 가져와 I/O와 CPU 작업이 동시에 진행되도록 하여 Iceberg 테이블 읽기 속도를 개선했습니다. [#108543](https://github.com/ClickHouse/ClickHouse/pull/108543) ([asya-ch](https://github.com/asya-ch)).
* 이제 재채점(rescoring)을 사용하는 벡터 검색 쿼리는 동일한 `MergeTree` 그래뉼의 인접 행까지 무차별 대입 방식으로 재채점하지 않고, 벡터 인덱스 후보 행에 대해서만 정확한 거리를 계산합니다. [#108846](https://github.com/ClickHouse/ClickHouse/pull/108846) ([skuznetsov](https://github.com/skuznetsov)).
* 코어 수가 많은 서버에서 좁은 컬럼을 대상으로 하는 일반적인 로컬 비정렬 `MergeTree` 스캔 시 과도한 읽기 스트림과 파이프라인 오버헤드를 줄이기 위해 `merge_tree_min_bytes_per_read_stream` 설정을 추가했습니다. [#109035](https://github.com/ClickHouse/ClickHouse/pull/109035) ([jiebinn](https://github.com/jiebinn)).
* 공유 데이터에 희소 경로가 많은 `JSON` 컬럼의 직렬화 및 머지 속도를 개선했습니다. 공유 데이터를 경로별 컬럼으로 평탄화할 때 `flattenAndBucketSharedDataPaths`는 더 이상 행마다 누적된 경로 컬럼 전체를 스캔하지 않으며, 기본값을 한 셀씩 삽입하지도 않습니다. 모든 경로에 대한 행별 스캔을 제거하고, 비어 있는 부분은 일괄로 채웁니다. [#109341](https://github.com/ClickHouse/ClickHouse/pull/109341) ([groeneai](https://github.com/groeneai)).
* 이제 양쪽 피어가 모두 protocol revision 54489 이상이면, 네이티브 프로토콜은 `String` 컬럼을 값별 varint 길이 접두사 대신 누적 바이트 오프셋으로 이루어진 별도 스트림(`Array`가 오프셋에 사용하는 것과 동일한 레이아웃)과 그 뒤에 이어지는 연결된 데이터로 전송합니다. 따라서 클라이언트는 버퍼를 정확한 크기로 미리 할당하고 한 번의 대량 복사로 `String` 컬럼을 읽을 수 있으며, 값별 레이아웃보다 약 4배 빠릅니다. 레이아웃은 protocol revision을 통해 협상되므로 기존 클라이언트와 서버에는 영향이 없습니다. 동일한 레이아웃은 새로운 설정 `output_format_native_write_string_with_size_stream` / `input_format_native_read_string_with_size_stream`을 통해 `Native` 및 `Buffers` 포맷에서도 사용할 수 있습니다(포맷의 이식성을 유지하기 위해 기본적으로 비활성화되어 있습니다). [#110320](https://github.com/ClickHouse/ClickHouse/pull/110320) ([vahid-sohrabloo](https://github.com/vahid-sohrabloo)).
* 작은 `LIMIT`과 함께 기본 키 순서(정렬 키의 접두사로 `ORDER BY`)대로 읽는 `FINAL` 쿼리는 더 이상 `split_intersecting_parts_ranges_into_layers_final`을 사용하지 않습니다. [#110431](https://github.com/ClickHouse/ClickHouse/pull/110431) ([KochetovNicolai](https://github.com/KochetovNicolai)).
* Iceberg 테이블을 포함하여 객체 스토리지에서 Parquet 파일을 읽을 때 지연 머티리얼라이즈(lazy materialization, late materialization)를 지원합니다. `ORDER BY ... LIMIT n` 쿼리에서 정렬 및 필터링에 필요하지 않은 컬럼은 `LIMIT` 적용 후 남은 `n`개의 행에 대해서만 읽습니다. S3에 있는 200MB Parquet 파일에서 `SELECT k, s ... ORDER BY k DESC LIMIT 10`은 171MB 대신 3.3MB만 읽습니다(IO 51배 감소, 8배 향상). 새로운 설정 `query_plan_optimize_lazy_materialization_for_object_storage`로 제어하며(기본적으로 활성화됨), `query_plan_optimize_lazy_materialization`도 활성화되어 있어야 합니다. [#110970](https://github.com/ClickHouse/ClickHouse/pull/110970) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 삭제 파일이 많은 Iceberg 테이블에 대한 쿼리가 이제 더 빠르게 시작됩니다. ClickHouse는 삭제 매니페스트 파일을 하나씩 처리하지 않고 동시에 읽고 디코딩하므로 저장소 읽기가 병렬로 수행됩니다. 새로운 설정 `iceberg_delete_manifest_decode_concurrency`(기본값 `4`)로 동시에 디코딩할 파일 수를 제어할 수 있습니다. [#112679](https://github.com/ClickHouse/ClickHouse/pull/112679) ([asya-ch](https://github.com/asya-ch)).
* 행 그룹 및 페이지 프루닝이 가능하도록 UInt128/UInt256/Int128/Int256을 DECIMAL로 Parquet 직렬화하는 선택적 기능을 추가했습니다. [#113347](https://github.com/ClickHouse/ClickHouse/pull/113347) ([bobrik](https://github.com/bobrik)).
* 리더 체인의 단계가 기본 키 또는 스킵 인덱스로 필터링된 범위처럼 조각난 마크 범위를 읽을 때 원격 디스크에서 읽기 요청이 여러 번 중복 발생하던 문제를 수정했습니다. [#113584](https://github.com/ClickHouse/ClickHouse/pull/113584) ([CurtizJ](https://github.com/CurtizJ)).
* 정렬 키가 모두 상수인 `MergeTree` 파트를 쓸 때 불필요한 정렬 여부 검사를 건너뜁니다. [#113899](https://github.com/ClickHouse/ClickHouse/pull/113899) ([perfloop-agent](https://github.com/perfloop-agent)).
* `ORDER BY ... LIMIT n` 쿼리에 대한 지연 머티리얼라이즈가 이제 `file` 테이블 함수와 `File` 테이블 엔진으로 읽는 로컬 Parquet 파일에도 적용됩니다. 정렬 및 필터링에 필요하지 않은 컬럼은 `LIMIT` 적용 후 남은 `n`개의 행에 대해서만 읽습니다. 두 번의 읽기 사이에 파일이 수정되면, 남은 파일에 대한 두 번째 읽기는 새로운 `FILE_CHANGED_DURING_READ` 오류를 반환하며 안전하게 실패합니다. 새로운 설정 `query_plan_optimize_lazy_materialization_for_file`로 제어합니다(기본적으로 활성화됨). 또한 요청된 서브컬럼(예: `JSON` 컬럼의 서브컬럼)이 지연 읽기 대상일 때 객체 스토리지에 대한 지연 머티리얼라이즈가 `Not found column or subcolumn ... in block` 오류로 실패하던 문제도 수정했습니다. [#114262](https://github.com/ClickHouse/ClickHouse/pull/114262) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 파티션된 `MergeTree` 테이블에서 `IN (subquery)`의 집합 생성 속도를 개선했습니다. 각 파티션의 행을 단일 스트림(single stream) 안에 유지하고 스트림별로 독립적으로 중복을 제거하므로, 이전에는 모든 행을 순차적으로 해싱하던 단일 집합 채우기 변환이 이제 고유한 행만 처리합니다. 이 최적화는 파티션 표현식이 서브쿼리 출력 컬럼의 결정론적 함수일 때 적용됩니다. 가장 큰 파티션의 행 수가 평균 파티션 행 수의 2배를 초과하면 이 최적화는 적용되지 않으며, 새로운 설정 `force_creating_set_partitions_independently`(기본값: 비활성화)를 사용하면 이 검사를 건너뛸 수 있습니다. 이 동작은 새로운 설정 `allow_creating_set_partitions_independently`(기본값: 활성화)로 제어합니다. [#114645](https://github.com/ClickHouse/ClickHouse/pull/114645) ([nihalzp](https://github.com/nihalzp)).
* 불필요한 백그라운드 작업을 방지하기 위해 TTL이 없는 로테이션된 비복제 `MergeTree` 시스템 로그 테이블을 `table_readonly`로 표시합니다. 이제 `table_readonlyMergeTree` 설정은 기존에 거부하던 삽입, 뮤테이션, `OPTIMIZE` 외에도 일반 `MergeTree` 테이블의 모든 백그라운드 작업(일반 머지, TTL(`DELETE`/`MOVE`/재압축) 머지 및 재압축 머지, 백그라운드 뮤테이션, 백그라운드 파트 이동)을 중단하며, 데이터를 변경하는 파티션 명령어(`ATTACH`/`MOVE`/`DROP`/`DROP DETACHED`/`FETCH`/`REPLACE PARTITION` 및 해당 테이블을 대상으로 하는 `MOVE PARTITION ... TO TABLE`)도 거부합니다. 따라서 TTL이 설정된 `table_readonly` 테이블은 이 설정이 활성화되어 있는 동안 만료된 데이터를 더 이상 회수하지 않습니다. [#95079](https://github.com/ClickHouse/ClickHouse/pull/95079) ([matt-metivier](https://github.com/matt-metivier)).

<h3 id="memory-and-resource-efficiency">
  메모리 및 리소스 효율성
</h3>

* `UNLOCK SNAPSHOT` 실행 시 잠금 해제 경로에서 사용하지 않는 데이터 파트별 메타데이터를 로드하지 않도록 하여 메모리 사용량을 줄였습니다. 이를 통해 파트 수가 매우 많은 스냅샷에서 메모리 부족(out-of-memory)이 발생하지 않도록 했습니다. [#111849](https://github.com/ClickHouse/ClickHouse/pull/111849) ([jkartseva](https://github.com/jkartseva)).
* 백업 메타데이터를 읽을 때의 메모리 할당을 줄였습니다. 이제 각 파일 엔트리를 복사하지 않고 인메모리 맵으로 이동(move)합니다. [#111718](https://github.com/ClickHouse/ClickHouse/pull/111718) ([jkartseva](https://github.com/jkartseva)).

<h3 id="function-type-and-format-performance">
  함수, 타입, 포맷 성능
</h3>

* `Decimal` 값을 텍스트로 포맷팅하는 속도가 크게 향상되었습니다. 스케일이 큰 `Decimal256`은 최대 190배, `Decimal64`는 약 1.6배 빨라졌습니다. AVX-512 IFMA를 지원하는 프로세서에서는 64비트 정수를 텍스트로 변환하는 속도가 약 1.4배 빨라졌습니다. 또한 소수부에서 발생한 자리올림을 누락하던 `toDecimalString`의 반올림 문제를 수정했습니다. `toDecimalString(toDecimal64('9.995', 3), 2)`는 기존에 `9.00`을 반환했으나 이제 `10.00`을 반환합니다. [#112457](https://github.com/ClickHouse/ClickHouse/pull/112457) ([thevar1able](https://github.com/thevar1able)).
* `FixedString` 키에 대한 `partial_merge` 조인 알고리즘의 성능을 개선했습니다. 값마다 비교 함수를 한 번씩 호출하는 대신 연속된 값 구간을 한 번에 비교합니다. [#105737](https://github.com/ClickHouse/ClickHouse/pull/105737) ([4ertus2](https://github.com/4ertus2)).
* 이제 `HashJoin`에서 단일 컬럼의 non-nullable 문자열 LowCardinality 키를 네이티브로 지원합니다. [#107264](https://github.com/ClickHouse/ClickHouse/pull/107264) ([nickitat](https://github.com/nickitat)).
* 패턴과 대체 문자열이 모두 단일 문자일 때(예: `replaceRegexpAll(s, ' ', '_')`) `replaceAll` 및 `replaceRegexpAll`의 성능을 개선했습니다. 이러한 대체는 더 이상 String 레이아웃을 변경하지 않으므로, 일치 항목마다 검색 루프를 실행하지 않고 컬럼을 한 번만 복사한 뒤 일치하는 바이트를 제자리에서 재작성합니다. [#108178](https://github.com/ClickHouse/ClickHouse/pull/108178) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/108187) ([groeneai](https://github.com/groeneai)).
* 깊게 중첩된 배열 및 튜플 리터럴을 이차 시간이 아닌 선형 시간에 파싱합니다. [#108892](https://github.com/ClickHouse/ClickHouse/pull/108892) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `SECOND`, `MINUTE`, `HOUR` 인터벌에서 `toStartOfInterval` 함수(별칭 `time_bucket`, `date_bin`)의 속도를 최대 5배 향상했습니다. [#109729](https://github.com/ClickHouse/ClickHouse/pull/109729) ([raimannma](https://github.com/raimannma)).
* 람다 없이 호출하면 숫자 배열(`Decimal` 및 `DateTime64` 포함)에 대한 `arraySort` 및 `arrayReverseSort` 함수가 몇 배 더 빠르게 동작합니다. [#109832](https://github.com/ClickHouse/ClickHouse/pull/109832) ([raimannma](https://github.com/raimannma)).
* 고정 오프셋 시간대(예: UTC)의 `DateTime` 및 `DateTime64` 값에 산술 연산 기반 고속 경로를 적용하여 `addDays`, `addWeeks`, `subtractDays`, `subtractWeeks`의 속도를 높였습니다. [#109836](https://github.com/ClickHouse/ClickHouse/pull/109836) ([raimannma](https://github.com/raimannma)).
* `Delta` 코덱의 압축 해제를 벡터화했습니다. 8/16/32비트 데이터 타입의 디코딩이 1.5–5배 빨라져, `Delta`로 압축된 컬럼의 스캔 속도가 최대 20% 향상되었습니다. [#110189](https://github.com/ClickHouse/ClickHouse/pull/110189) ([raimannma](https://github.com/raimannma)).
* 상수 needle을 사용하는 `Enum` 컬럼에 대한 문자열 검색 함수(`like`, `position`, `match`, `countSubstrings`, `hasToken` 등)의 속도를 높였습니다. 모든 행을 검색하지 않고 고유한 enum 이름만 검색한 뒤, 그 결과를 각 행에 다시 매핑합니다. [#110325](https://github.com/ClickHouse/ClickHouse/pull/110325) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 상수가 아닌 needle을 사용하는 부분 문자열 검색 함수(`position`, `countSubstrings`, `multiSearch*`, `replaceAll`/`replaceOne` 및 각각의 대소문자 비구분 변형과 UTF-8 변형)의 성능을 최대 1.5배 향상했습니다. 행 단위 경로에서 단순한 폴백 대신 SIMD 기반 문자열 검색기를 사용하도록 개선했습니다. [#110580](https://github.com/ClickHouse/ClickHouse/pull/110580) ([Algunenano](https://github.com/Algunenano)).
* 동적 변형 또는 JSON 경로가 많은 `Dynamic` 및 `Object` 컬럼의 스쿼싱(squashing)과 머지 성능을 향상했습니다. [#110583](https://github.com/ClickHouse/ClickHouse/pull/110583) ([cv4g](https://github.com/cv4g)).
* `NONE` 코덱 사용 시 `estimateCompressionRatio`의 속도가 빨라졌습니다. [#111107](https://github.com/ClickHouse/ClickHouse/pull/111107) ([rienath](https://github.com/rienath)).
* 경로가 공유 데이터에 저장된 `JSON` 컬럼에 대한 정렬 및 기타 비교 기반 연산의 속도를 개선했습니다. 이전에는 값을 비교할 때마다 임시 `Dynamic` 컬럼을 구체화하고 비교 대상 양쪽 모두에 대해 전체 바이너리 역직렬화를 수행했기 때문에, 이러한 컬럼에 대한 `ORDER BY`가 비정상적으로 느렸습니다. [#111894](https://github.com/ClickHouse/ClickHouse/pull/111894) ([groeneai](https://github.com/groeneai)).
* 256비트 정수(`Int256`, `UInt256`, `Decimal256`)의 나눗셈에서 이제 시프트-뺄셈 방식의 장제법으로 한 번에 1비트씩 계산하는 대신, 몫을 64비트 limb 단위로 계산합니다. 제수가 64비트 이내이면 128 / 64 나눗셈 루프를 사용하고, 그렇지 않으면 Knuth의 Algorithm D를 사용합니다. 이 변경 사항은 `intDiv`, `modulo`, `Decimal256` 산술 연산 및 이러한 타입의 텍스트 변환에 적용됩니다. [#112477](https://github.com/ClickHouse/ClickHouse/pull/112477) ([thevar1able](https://github.com/thevar1able)).
* 바이너리로 인코딩된 타입(`Native`, `input_format_binary_decode_types_in_binary_format`을 사용하는 `RowBinary`)에서 `Nested` 컬럼을 읽을 때 더 이상 타입을 타입 이름으로 다시 변환한 뒤 재파싱하지 않습니다. 또한 잘못된 형식의 중첩 `Tuple` 타입 이름은 이제 중첩 깊이에 따라 지수적으로 시간이 걸린 끝에 `TOO_SLOW_PARSING`으로 실패하는 대신, 구문 오류로 보고됩니다. [#112560](https://github.com/ClickHouse/ClickHouse/pull/112560) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* TimeSeries 테이블에 대한 PromQL 쿼리 속도를 개선했습니다. 연속된 행의 시리즈 id가 동일하면 `timeSeriesIdToGroup`이 이전 행의 그룹을 재사용하므로, 행 단위 id 직렬화와 해시 조회를 건너뜁니다. [#113580](https://github.com/ClickHouse/ClickHouse/pull/113580) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).

<h3 id="other-performance-improvements">
  기타 성능 개선 사항
</h3>

* Apache Arrow 라이브러리를 사용하지 않는 `Arrow` 및 `ArrowStream` 포맷용 네이티브 리더와 writer를 구현하여 불필요한 데이터 복사와 변환을 없앴습니다. 이제 이 구현이 기본값(설정 `input_format_arrow_use_native_reader` 및 `output_format_arrow_use_native_writer`)으로 사용되며, 읽기와 쓰기 모두 더 빨라졌습니다. [#106522](https://github.com/ClickHouse/ClickHouse/pull/106522) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `nullIf(key, sentinel) = const` 프레디케이트를 최적화하여 키 범위를 구성하고, 이를 통해 프라이머리 키, 파티션, 스킵 인덱스 기반 프루닝을 적용할 수 있도록 했습니다. [#107308](https://github.com/ClickHouse/ClickHouse/pull/107308) ([adityaksolves](https://github.com/adityaksolves)).
* 각 행을 SipHash로 해시하는 대신 행 값을 키로 사용하여 멀티셋을 구성함으로써 \`INTERSECT ALL\` 및 \`EXCEPT ALL\`(\`INTERSECT\`와 \`EXCEPT\`의 기본 모드)의 성능을 몇 배 향상했습니다. [#107649](https://github.com/ClickHouse/ClickHouse/pull/107649) ([Algunenano](https://github.com/Algunenano)).
* 단순한 정규식을 LLVM을 사용해 네이티브 코드로 컴파일하여 `match`, `extract`, `extractAll`, `replaceRegexpOne`, `replaceRegexpAll` 함수의 속도를 높였습니다. 이 기능은 새로운 설정 `compile_regular_expressions`(기본적으로 활성화됨)로 제어되며, 지원 범위를 벗어나는 패턴은 자동으로 RE2 엔진을 사용하도록 전환됩니다. [#108004](https://github.com/ClickHouse/ClickHouse/pull/108004) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* NEON으로 짧은 오프셋의 겹치는 복사를 벡터화하여, 고정 폭 정수 컬럼처럼 매치 오프셋이 작은 컬럼에 대한 AArch64(ARM)의 ZSTD 압축 해제 속도를 높였습니다. 예를 들어 AWS Graviton 4에서 `UInt64` 컬럼의 압축 해제가 최대 약 2.3배 빨라졌습니다. [#108049](https://github.com/ClickHouse/ClickHouse/pull/108049) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 고정 크기의 낮은 카디널리티 컬럼에 대한 LZ4 압축 해제 속도를 개선했습니다. [#108175](https://github.com/ClickHouse/ClickHouse/pull/108175) ([nickitat](https://github.com/nickitat)).
* 블록 단위 Myers 코드 경로에서 행마다 발생하던 힙 할당을 제거하여, ARM에서 중간 길이 문자열에 대한 `levenshteinDistance`(및 `editDistance`)의 성능을 개선했습니다. [#108185](https://github.com/ClickHouse/ClickHouse/pull/108185) ([groeneai](https://github.com/groeneai)).
* `precise_float_parsing = 1` 설정 시 텍스트에서 부동소수점 숫자를 파싱하는 속도를 높여, 거의 모든 입력에서 기본 파서와 같거나 더 빠르게 동작하도록 했습니다. 또한 번들된 `fast_float` 라이브러리를 v8.2.10으로 업데이트했습니다. [#108205](https://github.com/ClickHouse/ClickHouse/pull/108205) ([Algunenano](https://github.com/Algunenano)).
* 이제 Base64 인코딩 및 디코딩 함수가 `simdutf`를 사용하므로 성능이 향상되었습니다. [#108333](https://github.com/ClickHouse/ClickHouse/pull/108333) ([thevar1able](https://github.com/thevar1able)).
* 처리 비용이 큰 높은 카디널리티 키에 대해 `DISTINCT`를 최적화했습니다. [#108366](https://github.com/ClickHouse/ClickHouse/pull/108366) ([nihalzp](https://github.com/nihalzp)).
* `errno`를 보존하지 않는 컴파일러 최적화를 활성화하여 수학 함수의 성능을 개선했습니다. [#108628](https://github.com/ClickHouse/ClickHouse/pull/108628) ([nickitat](https://github.com/nickitat)).
* 실제로 압축하지 않고 압축된 크기를 분석적으로 계산하도록 하여, `T64`로 인코딩된 컬럼에 대한 `estimateCompressionRatio`의 속도를 높였습니다. [#109054](https://github.com/ClickHouse/ClickHouse/pull/109054) ([rienath](https://github.com/rienath)).
* 이제 JOIN에서 왼쪽 테이블의 프라이머리 키 인덱스 또는 스킵 인덱스를 사용하여 그래뉼을 프루닝할 수 있습니다. [#109085](https://github.com/ClickHouse/ClickHouse/pull/109085) ([shankar-iyer](https://github.com/shankar-iyer)).
* 좌표 변환에서 사인/코사인 쌍을 함께 계산하고 중복된 삼각 함수 호출을 제거하여 H3 지리 함수(`h3ToGeoBoundary`, `h3ToGeo`, `h3CellAreaM2`/`h3CellAreaRads2`, `geoToH3`)의 성능을 개선했습니다. 결과는 이전과 비트 단위까지 동일합니다. [#109399](https://github.com/ClickHouse/ClickHouse/pull/109399) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 비교 및 부호 확장 코드를 분기 없는(branchless) 방식으로 변경하여, 큰 정수 타입(`Int128`, `UInt128`, `Int256`, `UInt256` 및 `Decimal128`과 같이 이를 기반으로 하는 타입)의 비교(`<`, `>`, `<=`, `>=`) 성능을 최대 7배, 부호 있는 정수를 `Int256`으로 변환하는 성능을 최대 7배(부호가 혼합된 데이터 기준) 개선했습니다. [#109474](https://github.com/ClickHouse/ClickHouse/pull/109474) ([raimannma](https://github.com/raimannma)).
* 상수가 아닌 `Nullable` 인수가 하나뿐인 함수는 이제 null map을 새로 할당하고 머지하는 대신 인수의 null map을 결과와 공유합니다. [#110151](https://github.com/ClickHouse/ClickHouse/pull/110151) ([raimannma](https://github.com/raimannma)).
* 원소별 비교 루프 대신 벡터화된 축약(reduction)을 사용하여 숫자 배열에 대한 `arrayMin` 및 `arrayMax` 함수의 성능을 약 1.3\~1.5배 개선했습니다. [#110163](https://github.com/ClickHouse/ClickHouse/pull/110163) ([raimannma](https://github.com/raimannma)).
* 입력 스트림이 distinct 컬럼의 접두사 기준으로 정렬되어 있을 때(예: `SELECT DISTINCT a, b FROM table ORDER BY a`) `DISTINCT`의 성능을 개선했습니다. 이러한 쿼리는 최대 2.4배 빠르게 실행됩니다. [#110170](https://github.com/ClickHouse/ClickHouse/pull/110170) ([nihalzp](https://github.com/nihalzp)).
* `groupBitOr`/`groupBitAnd`/`groupBitXor` 및 분산 계열 함수(`varPop`, `varSamp`, `stddevPop`, `stddevSamp`, `skewPop`, `skewSamp`, `kurtPop`, `kurtSamp`, `covarPop`, `covarSamp`, `corr`)에 벡터화된 배치 경로를 도입했습니다. 조건을 예측하기 어려운 경우 `-If` 콤비네이터 사용 시 최대 4배, 콤비네이터 없이 분산 계열 함수를 사용할 때는 최대 3배 빨라집니다. [#110461](https://github.com/ClickHouse/ClickHouse/pull/110461) ([raimannma](https://github.com/raimannma)).
* 텍스트 인덱스 분석을 최적화했습니다. [#110530](https://github.com/ClickHouse/ClickHouse/pull/110530) ([CurtizJ](https://github.com/CurtizJ)).
* 16진수 자릿값의 검증과 변환을 두 번이 아닌 한 번에 처리하여 텍스트에서 `UUID` 값을 파싱하는 속도를 높였습니다(예: `LowCardinality(UUID)`로의 `JSONExtract`, `toUUID`, `CAST AS UUID`). [#110625](https://github.com/ClickHouse/ClickHouse/pull/110625) ([groeneai](https://github.com/groeneai)).
* SSSE3 `pshufb`로 짧은 오프셋의 중첩 복사를 벡터화하여, 고정 폭 정수 컬럼처럼 매치 오프셋이 작은 컬럼에 대한 x86\_64 환경의 ZSTD 압축 해제 속도를 높였습니다([#108049](https://github.com/ClickHouse/ClickHouse/pull/108049)의 AArch64 NEON 최적화에 대응하는 x86\_64 버전). [#110909](https://github.com/ClickHouse/ClickHouse/pull/110909) ([thevar1able](https://github.com/thevar1able)).
* `uniqExact`와 같이 CRC32 해싱을 사용하고 행별 삽입을 인라인 처리하여 숫자 타입에 대한 `groupUniqArray`의 속도를 최대 3배 높였습니다. [#110917](https://github.com/ClickHouse/ClickHouse/pull/110917) ([raimannma](https://github.com/raimannma)).
* 부동 소수점 컬럼에 대한 minmax 및 기본 컬럼 통계의 효율성을 개선했습니다. [#111221](https://github.com/ClickHouse/ClickHouse/pull/111221) ([cv4g](https://github.com/cv4g)).
* `COUNT()` 쿼리 결과를 텍스트 인덱스의 카디널리티 메타데이터에서 직접 반환합니다. [#111494](https://github.com/ClickHouse/ClickHouse/pull/111494) ([ahmadov](https://github.com/ahmadov)).
* 128비트 및 256비트 유형(`Int128`, `UInt128`, `Int256`, `UInt256`, `Decimal128`, `Decimal256`)에 대한 `min` 및 `max` 연산 속도를 개선했습니다. 큰 정수형은 최대 1.8배, 큰 Decimal 유형은 최대 3.4배 빨라졌습니다. [#111965](https://github.com/ClickHouse/ClickHouse/pull/111965) ([raimannma](https://github.com/raimannma)).
* `system.query_log` 수집 과정의 성능 저하를 수정했습니다. `Settings` 및 `asynchronous_read_counters` 맵 컬럼을 생성하는 작업이 이전보다 약 6배 느려져, 변경된 설정이 많은 쿼리를 다수 기록하는 서버에서 `SYSTEM FLUSH LOGS query_log`가 180초 타임아웃을 초과할 수 있었습니다. [#112210](https://github.com/ClickHouse/ClickHouse/pull/112210) ([groeneai](https://github.com/groeneai)).
* 텍스트 인덱스에 없는 토큰을 선택적으로 캐싱하는 기능을 추가했습니다. [#112742](https://github.com/ClickHouse/ClickHouse/pull/112742) ([rorylshanks](https://github.com/rorylshanks)).
* 이제 비동기 로깅에서 크기가 제한된 락프리(lock-free) 큐를 사용합니다. 로그 메시지를 기록하는 스레드는 뮤텍스에서 블로킹되지 않으며 로깅 스레드를 깨우지도 않습니다. [#112803](https://github.com/ClickHouse/ClickHouse/pull/112803) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* point 인수가 `Point` 유형(또는 숫자 요소 2개로 구성된 다른 `Tuple`)의 키 컬럼 전체인 경우에도 `pointInPolygon`에 프라이머리 키 인덱스를 사용합니다. 예를 들어 `coord`로 정렬된 테이블에 대한 `pointInPolygon(coord, [...])`이 이에 해당합니다. 이전에는 스칼라 키 컬럼 2개를 사용하는 `pointInPolygon((x, y), [...])` 형식만 분석했습니다. [#112956](https://github.com/ClickHouse/ClickHouse/pull/112956) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `text_index_posting_list_apply_mode`의 기본값이 `lazy`입니다. 따라서 `posting_list_codec`이 설정된 텍스트 인덱스에서는 텍스트 인덱스 쿼리가 포스팅 리스트를 비트맵으로 미리 구체화하지 않고, 커서를 사용해 패킹된 블록 세분화 수준에서 필요할 때마다 디코딩합니다. [#113521](https://github.com/ClickHouse/ClickHouse/pull/113521) ([CurtizJ](https://github.com/CurtizJ)).
* 태그 그룹 ID가 조밀한 범위에 분포하는 경우 해시 기반 재매핑 대신 직접 인덱싱을 사용하여 벡터화된 TimeSeries 태그 변환 속도를 개선했습니다. [#114244](https://github.com/ClickHouse/ClickHouse/pull/114244) ([fallintoplace](https://github.com/fallintoplace)).
* 텍스트 인덱스 병합 성능을 개선했습니다. [#114525](https://github.com/ClickHouse/ClickHouse/pull/114525) ([CurtizJ](https://github.com/CurtizJ)).
* PromQL 집합 연산자에 압축된 존재 마스크를 사용합니다. [#115224](https://github.com/ClickHouse/ClickHouse/pull/115224) ([fallintoplace](https://github.com/fallintoplace)).
* 시스템 테이블을 연결(attach)할 때 테이블 주석을 설정하려고 전체 컬럼 정의를 포함한 각 테이블의 메타데이터를 두 번씩 복사하지 않습니다. [#115490](https://github.com/ClickHouse/ClickHouse/pull/115490) ([thevar1able](https://github.com/thevar1able)).
* 모든 값이 0인 PromQL 조건 벡터에 대한 중복 시리즈 검사 속도를 개선했습니다. [#115822](https://github.com/ClickHouse/ClickHouse/pull/115822) ([fallintoplace](https://github.com/fallintoplace)).
* `DateTime64` 인수에 대한 `toUTCTimestamp`/`to_utc_timestamp` 및 `fromUTCTimestamp`/`from_utc_timestamp`의 속도를 개선하여, 이전 오버플로 수정 이후 저하되었던 처리량을 회복했습니다. 결과는 동일합니다. [#115838](https://github.com/ClickHouse/ClickHouse/pull/115838) ([groeneai](https://github.com/groeneai)).
* x86-64에서 무작위 데이터 생성(`rand`, `rand64`, `randomString`, `randomFixedString`, `generateUUIDv4`, `generateUUIDv7`)에 드는 고정 초기 설정 비용을 줄였습니다. 블록이 작을 때 효과가 두드러지며, 생성되는 값은 달라지지 않습니다. [#116158](https://github.com/ClickHouse/ClickHouse/pull/116158) ([Algunenano](https://github.com/Algunenano)).
* 이제 `enable_function_early_short_circuit` 설정으로 분석 단계에서 내장 `and` 및 `or`에 대한 조기 단락(short-circuit) 폴딩을 활성화할 수 있습니다. 이를 통해 일반적인 타입 추론과 의미론적 유효성 검사는 그대로 유지하면서, 결과에 영향을 주지 않는 단일 행 `count()` 스칼라 서브쿼리의 실행을 건너뛸 수 있습니다. [#83505](https://github.com/ClickHouse/ClickHouse/pull/83505) ([fhw12345](https://github.com/fhw12345)).
* 단순 직렬화가 가능한 벡터에 대해 단일 버퍼 IO 호출을 사용하도록 했습니다. [#89842](https://github.com/ClickHouse/ClickHouse/pull/89842) ([Ergus](https://github.com/Ergus)).
* `optimize_or_like_chain`을 기본으로 활성화했습니다. [#94517](https://github.com/ClickHouse/ClickHouse/pull/94517) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 서버에 사용자가 많을 때 system.users에서 단일 사용자 레코드를 조회하는 성능을 개선했습니다. [#96699](https://github.com/ClickHouse/ClickHouse/pull/96699) ([alistairjevans](https://github.com/alistairjevans)).

<h2 id="improvements">
  개선 사항
</h2>

<h3 id="query-and-sql-improvements">
  쿼리 및 SQL 개선 사항
</h3>

* `UNION` 쿼리의 여러 분기에서 참조되는 Materialized CTE가 이제 한 번만 구체화되어 모든 분기에서 공유됩니다. 이전에는 각 분기가 CTE의 개별 복사본을 받아 인라인으로 처리하고 별도로 평가했습니다. [#102107](https://github.com/ClickHouse/ClickHouse/pull/102107) ([novikd](https://github.com/novikd)).
* probe 측이 작을 것으로 추정되면 JOIN runtime filter를 건너뜁니다. 새 설정 `join_runtime_filter_min_probe_rows`(기본값 `1000`)로 임계값을 제어할 수 있습니다 [#104860](https://github.com/ClickHouse/ClickHouse/pull/104860) ([vdimir](https://github.com/vdimir)).
* `EXPLAIN [PLAN] actions=1, compact=1, pretty=1`이 기본값이 되었습니다. [#105036](https://github.com/ClickHouse/ClickHouse/pull/105036) ([Fgrtue](https://github.com/Fgrtue)).
* LIMIT BY의 양수 형태(LimitByTransform, LimitBySortedStreamTransform)에서 취소 지연 시간을 줄였습니다. 이제 KILL QUERY와 Ctrl+C를 실행하면 전체 단계가 끝날 때까지 기다리지 않고 단일 청크 내에서 처리가 중단됩니다. [#106070](https://github.com/ClickHouse/ClickHouse/pull/106070) ([rvasin](https://github.com/rvasin)).
* 자동 병렬 레플리카에서 JOIN 쿼리를 지원합니다. [#106073](https://github.com/ClickHouse/ClickHouse/pull/106073) ([nickitat](https://github.com/nickitat)).
* 스레드가 이미 할당했지만 아직 전역 메모리 추적 카운터에 반영되지 않은 메모리 양을 보고하는 새 비동기 메트릭 UntrackedMemory(`system.asynchronous_metrics`에서 확인 가능)를 추가했습니다. 각 스레드는 작은 할당을 로컬에 누적한 뒤 한꺼번에 보고합니다. 이를 통해 `MemoryTracking`과 프로세스의 실제 메모리 사용량 사이의 차이를 설명할 수 있습니다. 또한 `MEMORY_LIMIT_EXCEEDED` 오류 메시지에 추적되지 않은 메모리 양도 함께 표시되므로, 쿼리나 서버가 메모리 한도에 도달한 원인을 더 쉽게 파악할 수 있습니다. [#106386](https://github.com/ClickHouse/ClickHouse/pull/106386) ([mstetsyuk](https://github.com/mstetsyuk)).
* 삽입 파이프라인을 구성하는 중에 materialized view의 `TO` target table이 쓰기를 거부하여 `INSERT`가 실패하는 경우(예: 대상이 `View`이거나 트랜잭션을 지원하지 않는 경우), 이제 오류 메시지에 스토리지 오류만 표시하는 대신 materialized view와 해당 target table의 이름을 함께 표시합니다. [#107234](https://github.com/ClickHouse/ClickHouse/pull/107234) ([groeneai](https://github.com/groeneai)).
* 이름이 지정된 `Tuple`에 대한 `ALTER TABLE ... MODIFY COLUMN <col> Tuple(...)`은 하위 필드만 추가하는 경우 이제 메타데이터만 변경하므로, 최상위 `ADD COLUMN`과 같은 속도로 수행됩니다. `SET allow_metadata_only_named_tuple_alter = 1`로 활성화할 수 있습니다. [#107305](https://github.com/ClickHouse/ClickHouse/pull/107305) ([amosbird](https://github.com/amosbird)).
* `MaterializedPostgreSQL` 데이터베이스 엔진에 생성 시점 설정인 `materialized_postgresql_use_extended_date_and_time_types`를 추가했습니다. 기본값(활성화)에서는 PostgreSQL `date`/`timestamp` 컬럼이 `Date32`/`DateTime64`로 추론되며, `CREATE DATABASE` 시점에 이 설정을 `0`으로 지정하면 범위가 더 좁은 `Date`/`DateTime` 타입으로 추론됩니다. 이 설정은 `MaterializedPostgreSQL` 테이블 엔진에는 적용되지 않습니다. [#107428](https://github.com/ClickHouse/ClickHouse/pull/107428) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `EXPLAIN PLAN`은 조인의 예상 결과 행 수가 테이블 통계가 아닌 힌트나 무작위 대체값에서 산출된 경우 이를 근사값(`~~...`)으로 표시합니다. 이를 통해 JOIN 재정렬에 필요한 신뢰할 수 있는 통계가 없는 계획을 쉽게 식별할 수 있습니다. [#107666](https://github.com/ClickHouse/ClickHouse/pull/107666) ([vdimir](https://github.com/vdimir)).
* 이제 `MergeTree` 테이블에 대한 `INSERT`가 많은 파트를 쓰는 중에도 쿼리 취소와 `max_execution_time`을 준수하므로, kill된 후에도 오랫동안 계속 실행되는 문제가 더 이상 발생하지 않습니다. [#107929](https://github.com/ClickHouse/ClickHouse/pull/107929) ([al13n321](https://github.com/al13n321)).
* 이제 `arrayFold`가 쿼리 취소와 `max_execution_time`을 준수합니다. 이전에는 매우 긴 배열에 대한 fold(예: `arrayFold(acc, x -> arrayPushFront(acc, x), range(number), emptyArrayUInt64())`)가 단일 함수 호출 안에서 전체 fold를 실행하여 중단할 수 없었기 때문에, fold가 끝날 때까지 `KILL QUERY`와 시간 제한이 무시되었습니다. [#108192](https://github.com/ClickHouse/ClickHouse/pull/108192) ([groeneai](https://github.com/groeneai)).
* 쿼리 실행 전 단계별 `ProfileEvents`인 `QueryParseMicroseconds`, `QueryAnalysisMicroseconds`, `QueryPlanBuildMicroseconds`, `QueryPipelineBuildMicroseconds`를 추가했습니다. 이 이벤트로 쿼리 실행 전 각 단계(파싱, 분석, 쿼리 계획 빌드, 파이프라인 빌드)에서 소요되는 시간을 확인할 수 있으며, `system.query_log`와 `system.events`에서 조회할 수 있습니다. [#108282](https://github.com/ClickHouse/ClickHouse/pull/108282) ([jrdi](https://github.com/jrdi)).
* 테이블 메타데이터가 `max_query_size`를 초과하게 되는 `ALTER TABLE` 작업은 이제 사전에 거부됩니다. 이를 통해 DDL 배포, 레플리카 복구 등의 구성 요소에서 테이블을 로드할 수 없게 되는 문제를 방지합니다. [#108283](https://github.com/ClickHouse/ClickHouse/pull/108283) ([lockie](https://github.com/lockie)).
* 카티션 조인과 분석기가 계획한 상수 조건 조인을 위한 `ConstantJoin`을 추가했습니다. 이에 따라 분석기를 사용할 때 이러한 쿼리가 호환되지 않는 `join_algorithm` 설정 때문에 실패하는 문제가 더 이상 발생하지 않습니다. [#108289](https://github.com/ClickHouse/ClickHouse/pull/108289) ([antaljanosbenjamin](https://github.com/antaljanosbenjamin)).
* 각 엔터티의 문서가 정의된 소스 파일의 경로를 담은 `source` 컬럼을 `system.documentation`에 추가했습니다. 이제 이 테이블에는 압축 코덱, 프로파일 이벤트, 현재 메트릭, 비동기 메트릭, 시스템 테이블 자체(컬럼 포함)에 대한 문서도 포함되며, 설정 문서에는 유형과 기본값도 표시됩니다. [#108346](https://github.com/ClickHouse/ClickHouse/pull/108346) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* WHERE에 `table` 및 `database` 필터를 지정하면 `system.iceberg_history`는 일치하는 데이터베이스만 나열합니다. 서버에 관련 없는 원격 데이터베이스가 많을 때 시간을 절약할 수 있습니다. [#108492](https://github.com/ClickHouse/ClickHouse/pull/108492) ([Diskein](https://github.com/Diskein)).
* 이제 쿼리 매개변수(`{name:Type}` 치환)를 설정 값으로 사용할 수 있습니다. 쿼리(예: `SELECT`, `INSERT`)의 `SETTINGS` 절과 독립된 `SET` 쿼리 모두에서 사용할 수 있습니다. 예: `SELECT ... SETTINGS max_threads = {threads:UInt64}`, `SET max_threads = {threads:UInt64}`. [#108760](https://github.com/ClickHouse/ClickHouse/pull/108760) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* EXPLAIN WHATIF에서 스킵 인덱스의 결합 효과를 계산할 수 있습니다. 적합한 모든 가상 인덱스 성능의 교집합에 해당하는 데이터 비율을 보여 줍니다. [#108934](https://github.com/ClickHouse/ClickHouse/pull/108934) ([yariks5s](https://github.com/yariks5s)).
* 이제 CTE가 하나인 쿼리도 여러 CTE가 있는 쿼리와 동일한 줄바꿈 및 들여쓰기로 포맷됩니다. 이전에는 `WITH a AS (...)`의 경우 CTE가 `WITH`와 같은 줄에 놓였지만, CTE가 2개 이상이면 `WITH`가 별도 줄에 놓이고 각 CTE가 들여쓰기되었습니다. [#109092](https://github.com/ClickHouse/ClickHouse/pull/109092) ([groeneai](https://github.com/groeneai)).
* `File` 테이블 엔진으로 읽는 로컬 Parquet 파일에서도 쿼리 조건 캐시(Query Condition Cache)를 지원합니다(이전에는 객체 스토리지와 데이터 레이크에서만 지원). [#109247](https://github.com/ClickHouse/ClickHouse/pull/109247) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 원격(객체 스토리지) Parquet 파일의 쿼리 조건 캐시 키로 경로와 함께 ETag도 사용합니다. 따라서 객체를 같은 위치에 덮어쓰더라도 더 이상 오래된 캐시 결과가 반환되지 않습니다. [#109310](https://github.com/ClickHouse/ClickHouse/pull/109310) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `ON` 조건에서 동등 비교되는 `INNER JOIN` 키를 한정자 없이 참조하더라도(예: `SELECT id FROM a INNER JOIN b ON a.id = b.id`) 양쪽이 동일한 값을 가지는 것이 보장되므로 더 이상 모호한 식별자로 보고되지 않습니다. [#109366](https://github.com/ClickHouse/ClickHouse/pull/109366) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `QBit`에 대한 전치 거리 함수(`L2DistanceTransposed`, `cosineDistanceTransposed`, `dotProductTransposed` 및 양자화 버전인 `L2DistanceTransposedQuantized`, `cosineDistanceTransposedQuantized`, `dotProductTransposedQuantized`)가 이제 검색 대상 차원 수보다 긴 기준 벡터를 허용하며, 추가로 뒤에 오는 원소는 무시합니다. 따라서 축소 차원(Matryoshka) 검색 시 전체 크기의 쿼리 벡터를 미리 잘라낼 필요 없이 그대로 재사용할 수 있습니다. [#109388](https://github.com/ClickHouse/ClickHouse/pull/109388) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 분산 쿼리에 항상 알려진 클라이언트 버전이 포함되는지 확인하는 정합성 검사를 추가했습니다. 이제 원격 샤드(shard)에 버전 0을 조용히 전달하는 대신 논리 오류를 발생시킵니다. 서버가 시작하는 쿼리(백그라운드 플러시, 스트리밍 컨슈머, 딕셔너리 리로드, 비동기 insert 플러시)는 이제 서버 자체 버전을 개시자(initiator) 버전으로 보고합니다. [#109408](https://github.com/ClickHouse/ClickHouse/pull/109408) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* MergeTree 계열 테이블 엔진에 대한 뮤테이션(mutation) 작업의 where 절에서 한정된 컬럼 이름을 사용할 때 발생하던 문제를 수정했습니다. [#109491](https://github.com/ClickHouse/ClickHouse/pull/109491) ([Michicosun](https://github.com/Michicosun)).
* 분산 쿼리 계획(`make_distributed_plan`)에서 파티션을 지정하지 않은 윈도우 함수(`OVER (ORDER BY ...)`)를 지원합니다. 이전에는 `WindowStep`을 원격 실행용으로 직렬화할 수 없어 윈도우 함수가 포함된 쿼리는 모두 실패했습니다. `PARTITION BY`가 있는 윈도우는 당분간 계속 거부됩니다. [#109802](https://github.com/ClickHouse/ClickHouse/pull/109802) ([VighneshPath](https://github.com/VighneshPath)).
* 이제 `ALTER DATABASE ... MODIFY SETTING = 'xxx'`를 사용하여 one-lake 카탈로그의 일부 인증 설정을 변경할 수 있습니다. [#110019](https://github.com/ClickHouse/ClickHouse/pull/110019) ([alesapin](https://github.com/alesapin)).
* `IN`의 오른쪽 서브쿼리가 왼쪽 인수보다 한 차원 더 깊은 배열 컬럼 하나만 반환하는 경우, 이제 혼란스러운 타입 불일치 오류로 실패하지 않고 (배열 리터럴이나 배열을 반환하는 함수와 마찬가지로) 해당 배열 원소의 집합으로 해석됩니다. 예를 들어 `x IN (SELECT groupArray(x) FROM ...)`이 이제 정상적으로 동작합니다. [#110169](https://github.com/ClickHouse/ClickHouse/pull/110169) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* TopK 동적 필터링(`ORDER BY ... LIMIT k`)으로 가속되는 쿼리가 이제 쿼리 조건 캐시를 더욱 폭넓게 활용합니다. 지연 머티리얼라이즈가 적용된 경우에도 캐시가 채워지며, 이러한 쿼리는 동일한 `WHERE` 조건을 가진 일반 쿼리가 이전에 기록한 항목을 재사용할 수 있습니다. [#110507](https://github.com/ClickHouse/ClickHouse/pull/110507) ([shankar-iyer](https://github.com/shankar-iyer)).
* 이제 `SHOW CREATE TABLE`(및 `SHOW CREATE VIEW` / `SHOW CREATE DICTIONARY`)은 요청한 테이블이 존재하지 않으면 `SELECT` 쿼리와 마찬가지로 오류 메시지에서 이름이 비슷한 테이블을 제안합니다. [#110633](https://github.com/ClickHouse/ClickHouse/pull/110633) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 스트리밍 쿼리의 첫 번째 스냅샷만 읽은 뒤 업데이트를 구독하지 않고 종료하는 STREAM BOUNDED 수정자를 추가했습니다. [#110653](https://github.com/ClickHouse/ClickHouse/pull/110653) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
* PromQL 쿼리의 쿼리 결과 캐시 문제를 수정했습니다. `promql` 방언은 비결정적 함수 검사를 우회하여 `now()` 시점에 고정된 오래된 결과를 반환할 수 있었으며, Prometheus HTTP API(`/api/v1/query`, `/api/v1/query_range`)는 캐시 엔트리를 전혀 저장하지 않았습니다. [#110887](https://github.com/ClickHouse/ClickHouse/pull/110887) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).
* 이제 `EXPLAIN ANALYZE`는 조인 양쪽의 행 수, 매칭 비율, 팬아웃(fanout)과 함께 해시 테이블 메모리, 스필링(spilling) 등 알고리즘별 상태를 보고합니다. 추가 기록 작업이 필요한 매칭 메트릭을 수집하려면 `matches = 1`을 사용하십시오. [#110892](https://github.com/ClickHouse/ClickHouse/pull/110892) ([Fgrtue](https://github.com/Fgrtue)).
* 쿼리가 런타임에 프로세서를 제거할 때(예: 지연 읽기를 사용하는 `FINAL` 또는 외부 정렬) 서버가 비정상 종료될 수 있던 파이프라인 실행기의 heap-use-after-free 문제를 수정했습니다. 이 문제는 AST fuzzer를 통해 발견되었습니다. [#111017](https://github.com/ClickHouse/ClickHouse/pull/111017) ([groeneai](https://github.com/groeneai)).
* 공유 스토리지 스냅샷(`enable_shared_storage_snapshot_in_query` 설정)을 사용하는 쿼리가 스냅샷에서 데이터 파트를 제거할 때 발생하던 use-after-free(세그멘테이션 폴트) 문제를 수정했습니다. 예를 들어 쿼리의 다른 부분이 동시에 읽고 있는 `MergeTree` 테이블을 스트리밍 서브쿼리가 함께 읽는 경우가 이에 해당합니다. [#111192](https://github.com/ClickHouse/ClickHouse/pull/111192) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 비어 있는 `MergeTree` 테이블 읽기처럼 계획 단계에서 소스가 행을 생성하지 않는다는 것이 확실한 쿼리에 대해서도 분산 쿼리 계획(`make_distributed_plan`)을 지원합니다. 이전에는 이러한 쿼리가 `SUPPORT_IS_DISABLED` 오류로 실패했습니다. [#111941](https://github.com/ClickHouse/ClickHouse/pull/111941) ([groeneai](https://github.com/groeneai)).
* 여러 `AND` 조건으로 구성된 `WHERE` 절에서 마지막 조건이 아닌 다른 조건에 의해 제외된 그래뉼(granule)이 *쿼리 조건 캐시*에 기록되지 않던 문제를 수정했습니다. [#112083](https://github.com/ClickHouse/ClickHouse/pull/112083) ([shankar-iyer](https://github.com/shankar-iyer)).
* 버킷 기반 공유 데이터 직렬화(map\_with\_buckets 및 advanced)를 사용하는 JSON 컬럼을 쓸 때, 모든 버킷을 동시에 구체화하지 않고 쓰기 시 공유 데이터를 버킷 하나씩 분할하도록 하여 최대 메모리 사용량을 줄였습니다. 이 개선은 주로 Array(JSON) 컬럼에 효과적입니다. 스칼라 JSON은 공유 데이터가 그래뉼 단위로(index\_granularity\_bytes로 제한됨) 분할되므로 절감 효과가 작지만, Array(JSON)는 그래뉼 하나에 많은 중첩 행과 그만큼 많은 공유 데이터가 담길 수 있어 버킷을 하나씩 분할하는 방식으로 최대 메모리 사용량을 크게 낮출 수 있습니다 [#112172](https://github.com/ClickHouse/ClickHouse/pull/112172) ([Avogar](https://github.com/Avogar)).
* 메모리 예약 스케줄링(Experimental)은 한도를 초과한 예약 증가에 필요한 공간을 대기 중인 메모리 해제로 확보할 수 있는 경우 더 이상 할당을 축출하지 않습니다. 이제 진행 중인 감소가 적용될 때까지 기다린 후 축출 여부를 결정하므로, 메모리 압력 상황에서 불필요하게 쿼리가 강제 종료되는 일을 방지합니다. [#112299](https://github.com/ClickHouse/ClickHouse/pull/112299) ([serxa](https://github.com/serxa)).
* 이제 `SYSTEM DROP FILESYSTEM CACHE`는 캐시 메타데이터 키를 병렬로 삭제하므로 대용량 파일 시스템 캐시를 더 빠르게 정리할 수 있습니다. 새로운 파일 캐시 설정 `drop_cache_threads`로 삭제 작업자 수를 지정할 수 있으며 기본값은 16입니다. 값을 1로 지정하면 쿼리 스레드에서 직접 삭제를 수행합니다. [#112532](https://github.com/ClickHouse/ClickHouse/pull/112532) ([kssenii](https://github.com/kssenii)).
* 컬럼 선언의 수정자인 `COMMENT`, `CODEC`, `STATISTICS`, `TTL`, `COLLATE`, `PRIMARY KEY` 및 컬럼별 `SETTINGS`를 이제 `CREATE TABLE`에서 임의의 순서로 작성할 수 있으며, 각 수정자는 최대 한 번만 사용할 수 있습니다. 이전에는 정해진 순서 하나만 허용되었기 때문에, 예를 들어 `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](https://github.com/ClickHouse/ClickHouse/pull/112788) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 많은 테이블과 일치하는 `Merge` 테이블(또는 `merge` 테이블 함수)에 대한 쿼리가 이제 모든 하위 테이블의 계획 수립이 끝난 뒤에야 반응하는 것이 아니라, 테이블별 쿼리 계획을 생성하는 도중에도 `KILL QUERY`와 `max_execution_time`에 반응합니다. [#113415](https://github.com/ClickHouse/ClickHouse/pull/113415) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `timeout_overflow_mode = 'break'` 설정에서 `max_execution_time`을 초과한 `Merge` 테이블의 `SELECT`는 이제 중단 전에 일치하는 모든 테이블에 대해 전체 쿼리 분석을 실행하지 않고, 나머지 일치 테이블에 대한 쿼리 계획 생성을 바로 중단합니다. 해당 모드의 문서에 설명된 대로 쿼리는 여전히 오류 없이 완료됩니다. [#113642](https://github.com/ClickHouse/ClickHouse/pull/113642) ([groeneai](https://github.com/groeneai)).
* `MergeTree` 읽기 중 컬럼의 선언된 타입과 실제 데이터가 일치하지 않는 경우(타입 출처가 혼재된 경우, 예: 뮤테이션이 완료되지 않은 `ALTER TABLE ... MODIFY COLUMN` 이후), 서버는 이제 검사 없이 캐스트를 수행하는 대신 해당 컬럼과 두 구조를 명시한 명확한 예외를 보고합니다. 이전에는 디버그 및 새니타이저 빌드에서 컬럼 이름 없이 `Bad cast from type A to B`만 출력하고 비정상 종료되었으며, 릴리스 빌드에서는 일치하지 않는 메모리를 아무 알림 없이 탐색했습니다. [#114087](https://github.com/ClickHouse/ClickHouse/pull/114087) ([alexey-milovidov](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/114327) ([vdimir](https://github.com/vdimir)).
* 비동기 연결 수립 및 원격 쿼리 실행(헤지 요청, `async_socket_for_remote`, `async_query_sending_for_remote`)에 사용되는 파이버로 OpenTelemetry 추적 컨텍스트를 전파합니다. 이제 분산 쿼리에서 원격 쿼리의 스팬은 클라이언트가 제공한 추적 컨텍스트에 직접 연결되지 않고 시작 노드의 `Connection::sendQuery` 스팬의 하위 스팬으로 올바르게 연결되며, 각 비동기 작업 실행마다 별도의 스팬이 생성됩니다. [#114813](https://github.com/ClickHouse/ClickHouse/pull/114813) ([diegomestre2](https://github.com/diegomestre2)).
* `DROP DATABASE`는 이제 로딩 의존성과 참조 의존성을 모두 고려한 역위상 순서로 테이블을 삭제합니다(이전에는 로딩 의존성만 고려). 따라서 `DROP DATABASE` 도중 크래시가 발생하더라도 의존 대상이 이미 삭제된 테이블이 남지 않습니다. [#114952](https://github.com/ClickHouse/ClickHouse/pull/114952) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* PostgreSQL 스타일의 정규식 매칭 연산자를 지원합니다: `~`(`match` 함수의 별칭), `~*`(대소문자를 구분하지 않는 매칭), `!~` 및 `!~*`(부정). 이제 PostgreSQL 호환 프로토콜로 ClickHouse에 연결했을 때 `psql`의 `\d`, `\dt`, `\dv` 명령이 동작하며, 쿼리가 실패해도 더 이상 연결이 끊어지지 않습니다. [#115066](https://github.com/ClickHouse/ClickHouse/pull/115066) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `EXPLAIN WHATIF`는 `empirical_status`가 `unsupported`일 때 새로 표시되는 `empirical_reason` 줄을 통해 경험적 추정을 건너뛴 이유를 알려 줍니다. [#115140](https://github.com/ClickHouse/ClickHouse/pull/115140) ([yariks5s](https://github.com/yariks5s)).
* `join_algorithm` 설정으로 활성화된 조인 알고리즘 중 어느 것도 `JOIN`을 실행할 수 없을 때, 이제 오류 메시지가 단순히 모두 동작하지 않았다고만 알리는 대신 시도한 알고리즘과 실패한 JOIN의 엄격성(strictness) 및 종류를 명시합니다. [#115226](https://github.com/ClickHouse/ClickHouse/pull/115226) ([elkinal](https://github.com/elkinal)).
* 이제 기준 벡터가 정수 배열 리터럴인 경우(예: `ORDER BY L2Distance(vec, [1, 2])`)에도 벡터 검색 쿼리에서 벡터 유사성 인덱스를 사용할 수 있습니다. 이전에는 이러한 쿼리가 아무런 알림 없이 전수 스캔(brute-force scan)으로 대체되었습니다. [#115255](https://github.com/ClickHouse/ClickHouse/pull/115255) ([rschu1ze](https://github.com/rschu1ze)).
* 잠금 파일을 생성한 `BACKUP` 시도가 아무것도 기록하기 전에 실패하면, 대상을 점유하는 도중이든 아카이브를 여는 도중이든 더 이상 대상에 잠금 파일이 남지 않습니다. 이전에는 이후의 어떤 백업도 이러한 잠금과 일치할 수 없었기 때문에, 파일을 수동으로 삭제하기 전까지 같은 대상에 대한 재시도가 모두 실패했습니다. 또한 `S3` 및 `Azure` 대상으로의 백업에서도 잠금을 배타적으로 생성하며, 다른 백업이 소유한 잠금은 스토리지가 반환한 임의의 오류 대신 동시 백업으로 보고됩니다. [#115387](https://github.com/ClickHouse/ClickHouse/pull/115387) ([jkartseva](https://github.com/jkartseva)).
* 샘플링(`opentelemetry_start_trace_probability`)으로 시작된 트레이스가 이제 쿼리의 클라이언트 정보에 다시 기록됩니다. 따라서 원격 및 분산 보조 쿼리와 DDL 항목이 별개의 트레이스를 새로 시작하지 않고 동일한 트레이스에 합류합니다. [#115619](https://github.com/ClickHouse/ClickHouse/pull/115619) ([diegomestre2](https://github.com/diegomestre2)).
* 테이블 위치를 자체적으로 관리하는 Amazon S3 Tables 기반 Iceberg 테이블에서 `CREATE TABLE`이 동작하도록 수정했습니다. [#115652](https://github.com/ClickHouse/ClickHouse/pull/115652) ([scanhex12](https://github.com/scanhex12)).
* 적응형 `GROUP BY` 집계(`enable_adaptive_aggregator`)는 이제 드문 키의 처리를 지연하는 것이 실제로 효과가 있는지 측정하고, 해당 키나 집계 인수가 너무 커서 복사하는 이점이 없으면 일반 알고리즘으로 되돌아갑니다. 따라서 큰 문자열 컬럼에 대한 집계(예: 사용자별 `min(URL)`)도 일반 알고리즘과 같은 속도와 메모리 사용량으로 실행됩니다. 각 스레드의 고정(frozen) 테이블 크기를 바이트 단위로 제한하는 `adaptive_aggregator_freeze_threshold_bytes`를 추가했습니다(이 값과 키 개수 임계값 중 먼저 도달하는 쪽에서 테이블이 고정됩니다). [#115755](https://github.com/ClickHouse/ClickHouse/pull/115755) ([nihalzp](https://github.com/nihalzp)).
* 최종 집계 결과가 `LIMIT n`이 포함된 `ORDER BY`로 전달될 때 각 2단계 버킷에서 상위 `n`개 그룹만 구체화하는 계획 최적화를 켜고 끌 수 있는 `query_plan_aggregation_bucket_top_k` 설정(기본적으로 활성화됨)을 추가했습니다. 이제 이 최적화는 `EXPLAIN` 출력에도 표시됩니다. [#116124](https://github.com/ClickHouse/ClickHouse/pull/116124) ([nihalzp](https://github.com/nihalzp)).
* 매개변수화된 뷰(parameterized view)에 대한 `DESCRIBE` 쿼리 지원을 개선했습니다. 새 분석기에서 스칼라 표현식 내의 매개변수화된 뷰를 지원합니다. [#68978](https://github.com/ClickHouse/ClickHouse/pull/68978) ([novikd](https://github.com/novikd)).
* 이제 `SELECT * FROM t WHERE id`와 같은 쿼리에서 `id` 컬럼에 대해 인덱스 스키핑이 사용됩니다. [#89603](https://github.com/ClickHouse/ClickHouse/pull/89603) ([adityachopra29](https://github.com/adityachopra29)).
* JOIN 재정렬 최적화 과정에서 Expression 단계를 JOIN 단계로 머지할 수 있도록 `query_plan_merge_expression_into_join` 설정을 추가했습니다. 이를 통해 조인을 감싸는 서브쿼리(예: 계산된 컬럼이 있는 서브쿼리 안에 JOIN이 있는 경우)에 걸쳐서도 JOIN 재정렬을 수행할 수 있으므로, 복잡한 조인 트리를 더 효과적으로 최적화할 수 있습니다. [#98533](https://github.com/ClickHouse/ClickHouse/pull/98533) ([vdimir](https://github.com/vdimir)).
* `system.grants` 테이블에 권한 부여가 와일드카드 접두사 매칭(예: `GRANT SELECT ON db*.*`)을 사용하는지 여부를 나타내는 `is_wildcard` 컬럼을 추가했습니다. 기존에는 `system.grants`에서 같은 이름에 대한 와일드카드 권한 부여와 정확히 일치하는 권한 부여를 구분할 수 없었습니다. [#98577](https://github.com/ClickHouse/ClickHouse/pull/98577) ([il9ue](https://github.com/il9ue)).

<h3 id="functions-and-data-types-improvements">
  함수 및 데이터 타입
</h3>

* 새로운 설정 `allow_lossy_numeric_supertype`(기본값: 비활성화)을 추가했습니다. 이 설정을 활성화하면 손실 없는 공통 타입이 없는 숫자 인수(예: `Decimal`과 `Float64`, 또는 `Int64`와 `Float64`)에 대해 `if`, `multiIf`, `coalesce`, `ifNull`, `array`, `map`의 결과 타입이 `Variant` 대신 숫자 상위 타입인 `Float64`로 결정되므로, 그 결과를 `sum`, `avg`, `min`, `max` 등의 집계 함수에 사용할 수 있습니다. 또한 관련 집계 함수 오류 메시지에 이 설정 이름이 함께 표시됩니다. [#107236](https://github.com/ClickHouse/ClickHouse/pull/107236) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/107454) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 파싱 시 JSON 객체 크기를 제한하는 `input_format_json_max_object_size` 설정을 추가했습니다. [#107669](https://github.com/ClickHouse/ClickHouse/pull/107669) ([Avogar](https://github.com/Avogar)).
* SQLite 데이터베이스 열기에 실패할 때(예: `sqlite` 테이블 함수나 `SQLite` 데이터베이스 엔진에 열 수 없는 경로를 지정한 경우) 발생하던 메모리 누수를 수정했습니다. [#107807](https://github.com/ClickHouse/ClickHouse/pull/107807) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `QBit` 데이터 타입에서 `length` 함수를 지원합니다. 이 함수는 벡터의 차원을 상수로 반환합니다. [#108071](https://github.com/ClickHouse/ClickHouse/pull/108071) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `QBit`을 `Array`로 `CAST`하여 원래 벡터를 복원하는 기능을 지원합니다. 이는 기존의 `Array`에서 `QBit`으로의 변환과 반대 방향의 변환입니다. [#108072](https://github.com/ClickHouse/ClickHouse/pull/108072) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `MySQL` 데이터베이스 엔진, 테이블 엔진, 테이블 함수가 MySQL의 공간 컬럼 타입(`LINESTRING`, `POLYGON`, `MULTILINESTRING`, `MULTIPOLYGON` 및 범용 `GEOMETRY`)을 `String` 대신 이에 대응하는 ClickHouse 기하 타입으로 매핑합니다. 이 동작은 `mysql_datatypes_support_level` 설정의 새로운 `geometry` 플래그로 제어하며, 기본적으로 활성화되어 있습니다. `POINT`는 기존과 같이 항상 `Point`로 변환됩니다. 범용 `GEOMETRY` 컬럼은 포괄 타입인 `Geometry`로 매핑되며, ClickHouse에 대응 타입이 없는 하위 타입(`MULTIPOINT`, `GEOMETRYCOLLECTION`)의 값을 읽으면 읽기 시점에 예외가 발생합니다. [#108944](https://github.com/ClickHouse/ClickHouse/pull/108944) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 정밀한(가장 가까운 표현 가능 값을 찾는) 부동소수점 파싱 알고리즘을 기본으로 사용하며, `precise_float_parsing` 설정이 `toFloat*`/`CAST`뿐 아니라 입력 형식(CSV, TSV, JSON, VALUES 등)과 숫자 리터럴에도 적용됩니다. 경우에 따라 더 빠르지만 정확도가 낮은 이전 동작을 사용하려면 `precise_float_parsing = 0`으로 설정하십시오. [#109086](https://github.com/ClickHouse/ClickHouse/pull/109086) ([Algunenano](https://github.com/Algunenano)).
* 고정 크기 요소로 이루어진 `Array`를 `String`으로 `reinterpret`하는 기능을 지원합니다. 이는 기존의 `String`/`FixedString`을 `Array`로 `reinterpret`하는 기능과 반대 방향의 변환입니다. [#109383](https://github.com/ClickHouse/ClickHouse/pull/109383) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 차원이 동일하게 유지된다면 원소 타입 및/또는 stride가 서로 다른 `QBit` 타입 간의 `CAST`를 허용합니다(예: `QBit(Float32, N)`에서 `CAST(x AS QBit(Float64, N))`로 변환). stride만 변경하는 경우에는 손실이 없으며, 원소 타입을 변경하는 경우에는 해당 `Array` 변환 의미 체계를 따릅니다(예: `Float32`에서 `BFloat16`으로 변환하면 정밀도가 손실될 수 있으며, `accurateCast` / `accurateCastOrNull`은 정확하게 표현할 수 없는 행을 거부합니다). [#109387](https://github.com/ClickHouse/ClickHouse/pull/109387) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `quantizeBFloat16ToInt8` 및 `dequantizeInt8ToBFloat16` 함수가 기존 스칼라 오버로드에 더해 이제 `Array` 및 `QBit` 인수도 받으며, 전체 벡터에 Lloyd-Max 코덱을 적용합니다(해당 원소 타입의 `Array`/`QBit`를 반환). [#109398](https://github.com/ClickHouse/ClickHouse/pull/109398) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `parseDateTime` / `parseDateTime64`(및 `OrZero` / `OrNull` 변형)의 MySQL 스타일 형식 지정자 `%f`가 이제 정확히 6자리를 요구하지 않고 1\~6자리의 소수 자릿수를 허용하며, MySQL의 `STR_TO_DATE`처럼 왼쪽 정렬된 마이크로초로 해석합니다. 또한 내장 함수 문서 예시에서 `PrettyCompact` 테이블이 잘못 정렬되던 문제를 수정했습니다. [#109421](https://github.com/ClickHouse/ClickHouse/pull/109421) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `basic` 통계의 `NullCount` 하위 통계 이름이 `DefaultCount`로 변경되었습니다. 이제 `build`는 `Nullable` 컬럼의 `NULL` 행을 세는 대신 `IColumn::getNumberOfDefaultRows`를 통해 컬럼 타입 고유의 기본값과 같은 행을 셉니다. [#109977](https://github.com/ClickHouse/ClickHouse/pull/109977) ([hanfei1991](https://github.com/hanfei1991)).
* 거의 사용되지 않는 혼합 타입 쌍(`Decimal`과 너비가 다른 정수, 그리고 `Int128`/`UInt128`/`Int256`/`UInt256`이 포함된 쌍)의 비교 및 산술 연산을 타입 조합마다 전용 컴파일 커널을 두는 대신 공통 타입으로 변환하여 실행하도록 변경해 바이너리 크기를 약 10.5MB 줄였습니다. 동일 타입 쌍, 자주 사용되는 쌍, 메모리 바운드 연산인 `plus`/`minus`/`multiply`는 전용 커널을 그대로 유지하며, 결과, 결과 타입 및 예외 상황은 변경되지 않습니다. [#110131](https://github.com/ClickHouse/ClickHouse/pull/110131) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `SQLite` 테이블 엔진 또는 `sqlite` 테이블 함수에서 읽을 때 SQLite 데이터베이스가 다른 연결에 의해 잠겨 있어도 더 이상 바쁜 대기(busy-spin)로 CPU 코어 하나를 완전히 점유하지 않습니다. 이제 읽기는 잠금을 기다리는 동안 유휴 상태로 대기하며, 취소도 가능합니다. [#110248](https://github.com/ClickHouse/ClickHouse/pull/110248) ([groeneai](https://github.com/groeneai)).
* 로그 및 예외 메시지의 경과 시간, 속도, 비율 값을 세 자리로 반올림하여 `1.345844286 sec.`와 같은 숫자가 더 이상 전체 정밀도로 출력되지 않도록 했습니다. [#110277](https://github.com/ClickHouse/ClickHouse/pull/110277) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 선행 행을 건너뛴 후 별도의 크기 스트림이 있는 `String` 컬럼을 `MergeTree`에서 읽으면 잘못된 데이터를 반환하거나 서브스트림 캐시에서 경계를 넘어 읽을 수 있던 문제를 수정했습니다. 또한 map shared data 직렬화로 저장된 `JSON` 하위 객체에 동시 읽기 또는 반복 읽기가 접근할 때 잘못된 데이터가 반환될 수 있던 문제를 수정했습니다. [#110471](https://github.com/ClickHouse/ClickHouse/pull/110471) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `PostgreSQL` 테이블 엔진과 `postgresql` 테이블 함수에서 `SETTINGS` 절을 지원하여(예: `SETTINGS postgresql_connection_pool_size = 50`) `MySQL` 엔진과 동등한 기능을 제공합니다. [#110614](https://github.com/ClickHouse/ClickHouse/pull/110614) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `bitmaskToArray` 및 `bitmaskToList` 함수가 `(U)Int128` 및 `(U)Int256` 인수를 지원합니다. 또한 큰 정수 인수에 대해 `bitPositionsToArray` 함수의 실행 시간이 가장 높은 설정 비트의 위치가 아니라 설정된 비트 수에 비례하도록 개선되었습니다. [#110743](https://github.com/ClickHouse/ClickHouse/pull/110743) ([raimannma](https://github.com/raimannma)).
* 음수가 포함된 부호 있는 고정 폭 값을 GCD 코덱이 처리하는 방식을 수정했습니다. 이전에는 부호 있는 값으로 제수를 직접 계산했기 때문에 공약수를 찾지 못할 수 있었고, 그 결과 부호 있는 정수 및 decimal 컬럼의 압축 효율이 크게 떨어질 수 있었습니다. 이제 부호 있는 타입은 절댓값을 기준으로 제수를 계산하며, 부호 없는 타입과 압축 해제는 기존 동작을 그대로 유지합니다. [#113798](https://github.com/ClickHouse/ClickHouse/pull/113798) ([kshcherbatov](https://github.com/kshcherbatov)).
* 이제 `PARTITION BY`를 포함한 윈도 함수가 `make_distributed_plan`에서도 동작합니다. 계획 구조가 허용하는 경우, 윈도우는 각각 완전한 파티션을 할당받는 여러 버킷에서 병렬로 실행됩니다. [#114111](https://github.com/ClickHouse/ClickHouse/pull/114111) ([VighneshPath](https://github.com/VighneshPath)).
* 이제 외부 집계의 널 허용 고정 폭 집계 방식에 64비트 해시 함수를 사용합니다(카디널리티가 매우 높은 집계에서 심각한 해시 충돌을 방지합니다). [#114210](https://github.com/ClickHouse/ClickHouse/pull/114210) ([nickitat](https://github.com/nickitat)).
* 이제 `LowCardinality` 컬럼에 대한 `x IN (subquery)`가 `x IN (literal list)`와 동일한 타입인 `LowCardinality(UInt8)`를 반환합니다. 이전에는 두 형식이 서로 다른 타입을 반환했기 때문에, 이러한 `IN`이 포함된 분산 계획은 계획 타입 검사에서 별도의 예외 처리가 필요했습니다. [#114229](https://github.com/ClickHouse/ClickHouse/pull/114229) ([davenger](https://github.com/davenger)).
* `JSON` 데이터 타입, `JSONExtract`, `isValidJSON`에서 64비트 범위를 초과하는 정수를 파싱할 수 있습니다. 이러한 값이 있어도 전체 문서가 거부되지 않고, `Int128`/`UInt256` 등의 넓은 정수 타입으로 읽힙니다. [#114379](https://github.com/ClickHouse/ClickHouse/pull/114379) ([Avogar](https://github.com/Avogar)).
* OpenSearch, Elasticsearch, SolR, Lucene과의 호환성을 높이기 위해 텍스트 인덱스 토크나이저 `array`의 별칭으로 `keyword`를 추가했습니다. [#115507](https://github.com/ClickHouse/ClickHouse/pull/115507) ([rschu1ze](https://github.com/rschu1ze)).
* 이제 `toDateOrNull`, `toDateTimeOrNull`, `toDateTime64OrNull` 함수가 모든 기본 정수 타입의 정수 인수를 받을 수 있으며(`toDate`, `toDateTime`, `toDateTime64`와 동일한 방식으로 해석되고 시간대 인수를 선택적으로 지정할 수 있음), 결과 타입의 범위를 벗어나는 값에는 `NULL`을 반환합니다. 예를 들어 `toDateTimeOrNull(1583851242, 'Asia/Shanghai')`는 `2020-03-10 22:40:42`를 반환하고, `toDateTimeOrNull(4294967296)`은 `NULL`을 반환합니다. [#79791](https://github.com/ClickHouse/ClickHouse/pull/79791) ([jitendra1411](https://github.com/jitendra1411)).

<h3 id="storage-data-lakes-and-object-storage-improvements">
  저장소, 데이터 레이크 및 객체 저장소
</h3>

* 파일 시스템 캐시 eviction 활동에 대한 선택적(opt-in) 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](https://github.com/ClickHouse/ClickHouse/pull/105020) ([sacheendra](https://github.com/sacheendra)).
* 이제 대상 테이블이 `MergeTree` 엔진 계열인 경우 `Alias` 엔진에서 병렬 레플리카 읽기를 지원합니다. [#107830](https://github.com/ClickHouse/ClickHouse/pull/107830) ([nauu](https://github.com/nauu)).
* Azure Blob Storage의 읽기 후 쓰기 방식 복사(네이티브 복사를 사용할 수 없을 때 백업에서 사용)에서 동시에 스테이징되는 파트 수를 max\_inflight\_parts\_for\_one\_file로 제한하여, 여러 대용량 파일을 병렬로 복사할 때 메모리가 과도하게 사용되지 않도록 했습니다. [#108232](https://github.com/ClickHouse/ClickHouse/pull/108232) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
* HDFS 저장소에서 `_etag` 가상 컬럼을 지원합니다. [#108255](https://github.com/ClickHouse/ClickHouse/pull/108255) ([zhangyifan27](https://github.com/zhangyifan27)).
* `system.backups` 및 `system.backup_log`에 `settings` 및 `engine_settings` 컬럼을 추가했습니다. `settings`는 작업 시 요청된 백업/복원 관련 설정(예: `allow_s3_native_copy`, `deduplicate_files`, `structure_only`)을 보여 주고, `engine_settings`는 백업 엔진의 reader/writer가 실제로 사용한 설정(예: `allow_native_copy`와 같은 S3 요청 설정으로, 엔드포인트 구성과 머지된 후에는 요청된 값과 다를 수 있음)을 보여 줍니다. 이를 통해 `BACKUP`/`RESTORE` 작업이 실제로 어떤 설정으로 실행되었는지 확인할 수 있습니다. [#108334](https://github.com/ClickHouse/ClickHouse/pull/108334) ([jkartseva](https://github.com/jkartseva)).
* 등록된 `S3Queue` 및 `AzureQueue` 테이블의 Keeper 상태(처리 완료, 처리 중, 실패한 파일 수 포함)를 조회할 수 있는 `system.s3_queue_metadata` 및 `system.azure_queue_metadata`를 추가했습니다. [#108522](https://github.com/ClickHouse/ClickHouse/pull/108522) ([kssenii](https://github.com/kssenii)).
* 텍스트 인덱스 헤더 캐시의 메모리 사용량을 2\~2.5배 줄였습니다. 캐시(`text_index_header_cache_size` 설정)에 더 많은 데이터 파트의 헤더를 담을 수 있어 텍스트 검색 쿼리의 디스크 읽기가 줄어듭니다. [#109332](https://github.com/ClickHouse/ClickHouse/pull/109332) ([CurtizJ](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/109351) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 스키마에서 파생된 파트별 메타데이터(컬럼 목록, 컬럼 정의, 직렬화, 컬럼 하위 스트림)를 모든 파트에 복사하지 않고 테이블의 파트 간에 공유하도록 변경하여, 데이터 파트가 많은 `MergeTree` 테이블의 메모리 사용량을 줄였습니다. 작은 파트가 많은 넓은 테이블에서 효과가 가장 큽니다. [#109816](https://github.com/ClickHouse/ClickHouse/pull/109816) ([Algunenano](https://github.com/Algunenano)).
* 새로운 설정 `use_projection_index_in_read_pools`를 추가했습니다(기본값은 비활성화). 이 설정을 활성화하면 프로젝션 인덱스로 완전히 필터링된 마크 범위를 읽기 중에 그래뉼 단위로 건너뛰는 대신, 해당 범위에 대한 읽기 작업을 생성하기 전에 `MergeTree` 읽기 풀 내부에서 제거합니다. 따라서 읽지 않을 데이터에 대해 읽기 작업을 생성하거나 리더를 설정하지 않으며, 읽기 작업 크기도 남은 마크를 기준으로 유지됩니다. [#110291](https://github.com/ClickHouse/ClickHouse/pull/110291) ([KochetovNicolai](https://github.com/KochetovNicolai)).
* `MergeTree`에서 파트별 기본 키 이진 탐색 진단 정보의 로깅 수준을 trace에서 test로 낮추어 출력량을 줄였습니다. [#110324](https://github.com/ClickHouse/ClickHouse/pull/110324) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* TLS(HTTPS, S3) 기반의 풀링된 HTTP keep-alive 연결이 불필요하게 재연결되는 문제를 수정했습니다. 기존에는 오래된 연결을 검사할 때 소켓에 `poll`을 사용했는데, 이 방식은 아직 읽지 않은 TLS 핸드셰이크 이후 레코드(세션 티켓 또는 `KeyUpdate`)가 남아 있는 활성 보안 연결을 닫힌 것으로 잘못 판단합니다. 이제 일반 소켓에서는 논블로킹 `MSG_PEEK`를, TLS 소켓에서는 `SSL_peek`/`SSL_has_pending`을 사용하므로 정상적인 TLS 종료와 일부만 도착한 TLS 레코드도 올바르게 감지합니다. [#110402](https://github.com/ClickHouse/ClickHouse/pull/110402) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 OneLake catalog에서 OAuth 리프레시 토큰을 사용해 액세스 토큰을 갱신할 수 있습니다. [#110413](https://github.com/ClickHouse/ClickHouse/pull/110413) ([alesapin](https://github.com/alesapin)).
* `*MergeTree` 테이블에 INSERT된 블록의 중복을 제거하는 과정에서 수행되는 컬럼 단위 데이터 해시 계산 횟수를 집계하는 `DuplicationDataHashComputations` ProfileEvent를 추가했습니다. [#111173](https://github.com/ClickHouse/ClickHouse/pull/111173) ([valerypetrov](https://github.com/valerypetrov)).
* UNIQUE KEY 인덱스 SST를 로컬 임시 파일에 먼저 기록하지 않고, 저장소 추상화 계층을 통해 파트에 직접 기록하도록 변경했습니다. [#111189](https://github.com/ClickHouse/ClickHouse/pull/111189) ([JingYanchao](https://github.com/JingYanchao)).
* 로컬 디스크의 Iceberg 테이블에 대한 동시 쓰기를 지원합니다. 이제 `LocalObjectStorage`가 조건부 쓰기를 구현하므로 `version-hint.text`를 통해 새 스냅샷을 게시하는 compare-and-swap이 로컬 디스크에서도 동작하며, 동시에 쓰는 여러 작성자가 서로의 업데이트를 덮어써 잃어버리는 일이 없습니다. [#112556](https://github.com/ClickHouse/ClickHouse/pull/112556) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `S3` 클라이언트의 버킷 리전 캐시가 데이터 레이크 카탈로그에서도 동작합니다. 이전에는 데이터 레이크 카탈로그로 요청을 보낼 때마다 리전을 다시 조회했습니다. [#113330](https://github.com/ClickHouse/ClickHouse/pull/113330) ([scanhex12](https://github.com/scanhex12)).
* 이제 Azure 클라이언트 측 네트워크 장애(연결 재설정/거부, DNS 및 TLS 오류)가 인위적인 `500` 오류로 표시되지 않고 전송 오류로 처리되어 재시도됩니다. 이는 S3 클라이언트와 동일한 동작입니다. [#115269](https://github.com/ClickHouse/ClickHouse/pull/115269) ([arsenmuk](https://github.com/arsenmuk)).

<h3 id="formats-and-ingestion-improvements">
  포맷 및 수집
</h3>

* HTTP 인터페이스에서 snappy 압축(`Accept-Encoding: snappy`)을 허용하고, 일반 `file`/`url` snappy I/O에서 Hadoop snappy 블록 포맷과 snappy 프레이밍 포맷 중 하나를 선택할 수 있도록 `snappy_mode` 설정을 추가했습니다. [#100752](https://github.com/ClickHouse/ClickHouse/pull/100752) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `input_format_csv_missing_nullable_as_empty_string` 설정을 추가했습니다(기본값은 비활성화). 이 설정을 활성화하면 `input_format_csv_empty_as_default` 설정과 관계없이 CSV 입력에서 누락된 `Nullable(String)` 값을 `NULL` 대신 빈 `String`으로 읽습니다. [#107577](https://github.com/ClickHouse/ClickHouse/pull/107577) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `input_format_protobuf_oneof_presence`를 사용해 protobuf 메시지를 처리할 때 스키마 변경을 허용할 수 있도록 태그가 정확히 일치하지 않아도 되도록 변경했습니다. [#109174](https://github.com/ClickHouse/ClickHouse/pull/109174) ([ilejn](https://github.com/ilejn)).
* 레거시 Apache Arrow 기반 ORC 리더를 제거했습니다. 이제 ORC 입력 형식은 항상 ClickHouse 네이티브 디코더(기존 기본값)를 사용합니다. `input_format_orc_use_fast_decoder` 설정은 더 이상 사용되지 않습니다(설정은 가능하지만 아무런 효과가 없습니다). [#110074](https://github.com/ClickHouse/ClickHouse/pull/110074) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 Hive 엔진은 Apache Arrow ORC 어댑터 대신 ClickHouse 네이티브 ORC 리더를 사용해 ORC 파일 메타데이터(min/max 인덱스, 행 수)를 읽습니다. [#110086](https://github.com/ClickHouse/ClickHouse/pull/110086) ([alexey-milovidov](https://github.com/alexey-milovidov)).

<h3 id="security-access-and-observability-improvements">
  보안, 액세스 및 관측성
</h3>

* `system.tables` 테이블에 새 컬럼 `skipping_indices_types`가 추가되었습니다. 이 컬럼에는 각 테이블에 정의된 데이터 스킵 인덱스의 고유한 타입 목록이 포함됩니다. [#106388](https://github.com/ClickHouse/ClickHouse/pull/106388) ([CurtizJ](https://github.com/CurtizJ)).
* 이제 `max_threads` 등 유사한 설정의 자동 값이 `system.settings`에서 `'auto(8)'`가 아닌 `auto(8)`로 표시됩니다. 값을 감싸던 작은따옴표는 오래전부터 값에 고착되어 있던 잔재였습니다. 버전 간 호환성은 그대로 유지되며, 이전 버전 서버에서 받은 설정을 파싱할 때는 기존의 따옴표 형식도 계속 허용됩니다. [#108657](https://github.com/ClickHouse/ClickHouse/pull/108657) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `system.documentation`에서 설정 기본값이 비어 있으면 빈 백틱 대신 *빈 문자열*로 표시합니다. [#108708](https://github.com/ClickHouse/ClickHouse/pull/108708) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 내장 `/docs` 페이지와 `help` 명령에서 보여 주는 `system.documentation`의 설정 문서에 이제 기본값 변경 이력이 포함됩니다. 설정이 도입된 버전과 이후의 모든 기본값 변경 내역이 이전 값, 새 값, 변경 사유와 함께 표시됩니다. [#112177](https://github.com/ClickHouse/ClickHouse/pull/112177) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 모든 SQL 문의 문서(예: 이름, 구문, 설명, 예시)를 시스템 테이블 `system.statements`에서 조회할 수 있습니다. [#115341](https://github.com/ClickHouse/ClickHouse/pull/115341) ([rschu1ze](https://github.com/rschu1ze)).

<h3 id="settings-and-configuration-improvements">
  설정 및 구성
</h3>

* 새로운 서버 설정 `memory_worker_rss_speculative_reserve_ratio`(기본값 `1.0`, 새니타이저 빌드에서는 `0`)를 추가했습니다. 이 설정을 사용하면 전역 메모리 트래커가 `MemoryWorker`의 각 주기마다 관측된 RSS에 더해 `ratio * min(resident - previous_resident, resident - tracked)`만큼을 추정적으로 예약합니다. 샘플 사이에 RSS 증가 속도가 트래커의 집계 속도를 앞지르면 트래커 값을 높게 잡으므로, 할당 시 `MEMORY_LIMIT_EXCEEDED`가 더 일찍 발생하고 커널 OOM-killer가 먼저 작동할 가능성이 줄어듭니다. 추정 예약을 비활성화하려면 ratio를 `0`으로 설정하십시오. 새니타이저 빌드에서는 `resident - tracked` 차이의 대부분을 새니타이저 섀도 메모리가 차지하므로 기본값이 `0`입니다. [#104976](https://github.com/ClickHouse/ClickHouse/pull/104976) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 텍스트 인덱스의 지연(lazy) 포스팅 리스트 적용 모드가 더 이상 Experimental 기능이 아니므로, `allow_experimental_text_index_lazy_apply` 없이도 `text_index_posting_list_apply_mode = 'lazy'`로 선택할 수 있습니다. 밀도 임계값 설정의 이름이 `text_index_density_threshold`에서 `text_index_lazy_intersection_density_threshold`로 변경되었습니다. [#108814](https://github.com/ClickHouse/ClickHouse/pull/108814) ([CurtizJ](https://github.com/CurtizJ)).
* `merge_selector_enable_heuristic_to_lower_max_parts_to_merge_at_once` 설정이 이제 기본적으로 활성화됩니다. 이에 따라 머지 선택기가 파티션이 얼마나 차 있는지에 따라 한 번에 머지할 최대 파트 수를 자동으로 낮춥니다. [#110726](https://github.com/ClickHouse/ClickHouse/pull/110726) ([Michicosun](https://github.com/Michicosun)).
* PostgreSQL wire protocol에서 PostgreSQL 정리 명령인 `RESET`, `UNLISTEN`, `DISCARD`를 구문 오류로 처리하지 않고, 아무 작업도 수행하지 않는(no-op) 명령으로 허용합니다. 이를 통해 연결 설정 및 정리 과정에서 `RESET ALL`과 `UNLISTEN *`를 전송하는 Skunk 등의 드라이버와의 호환성이 향상됩니다. [#110780](https://github.com/ClickHouse/ClickHouse/pull/110780) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* AI 텍스트 함수(`aiGenerate`, `aiClassify`, `aiExtract`, `aiTranslate`)는 이제 잘렸거나 불완전한 제공자 응답(예: 모델이 `max_tokens` 한도에 도달한 경우)을 받으면 부분 출력을 별도 알림 없이 반환하지 않고 거부합니다. 이때의 동작은 `ai_function_throw_on_error` 설정을 따릅니다. [#111830](https://github.com/ClickHouse/ClickHouse/pull/111830) ([george-larionov](https://github.com/george-larionov)).
* 가우스 조건부 평균 접두사 중심점(centroid)으로 `p < 8QBit(Int8)` 코드를 재구성하여 축소 정밀도 `L2DistanceTransposedQuantized`, `cosineDistanceTransposedQuantized`, `dotProductTransposedQuantized`를 개선했습니다. 전체 정밀도(`p = 8`)에서는 계속 비트 단위까지 동일한 결과를 반환합니다. 축소 정밀도의 근사 거리는 달라질 수 있으며, 재현율/지연 시간 개선 효과는 워크로드에 따라 다릅니다. [#111867](https://github.com/ClickHouse/ClickHouse/pull/111867) ([skuznetsov](https://github.com/skuznetsov)).
* `write_snapshot_version` 설정을 재시작 없이 다시 로드할 수 있도록 했습니다. [#112150](https://github.com/ClickHouse/ClickHouse/pull/112150) ([alesapin](https://github.com/alesapin)).
* 원격 레플리카와의 비동기 통신에 사용되는 파이버(fiber) 스택의 관측성을 추가했습니다. 프로파일 이벤트 `FiberStackAllocs`, `FiberStackAllocBytes`, `FiberStackAllocNanoseconds`, `FiberStackFreeNanoseconds`와 메트릭 `FiberStacks`, `FiberStackBytes`가 제공됩니다. [#114541](https://github.com/ClickHouse/ClickHouse/pull/114541) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Prometheus remote-write 프로토콜이 이제 비동기 삽입(asynchronous insert)을 지원합니다. `async_insert` 설정에 따라 동시에 들어오는 여러 remote-write 요청의 데이터를 일괄 처리한 후 파트를 생성합니다(기본적으로 활성화되어 있으며, 동기 방식을 유지하려면 핸들러 URL에 `async_insert=0`을 추가하십시오). 요청은 데이터가 대상 `TimeSeries` 테이블의 모든 내부 테이블에 플러시된 후에만 승인됩니다. [#115688](https://github.com/ClickHouse/ClickHouse/pull/115688) ([nikitamikhaylov](https://github.com/nikitamikhaylov)).

<h3 id="other-improvements">
  기타 개선 사항
</h3>

* `shrink_over_allocated_columns_min_waste_ratio`와 `shrink_over_allocated_columns_min_waste_bytes` 설정 2개를 추가했습니다. 이 설정을 사용하면 INSERT 시 과다 할당된 컬럼(가변 길이 컬럼이 2의 거듭제곱 단위로 증가하여 예약된 메모리가 실제 사용 메모리보다 큰 컬럼)을 머티리얼라이즈 및 파트 쓰기 전에 실제 크기에 맞게 축소하므로 최대 메모리 사용량이 줄어듭니다. 기본적으로 비활성화되어 있습니다. [#112161](https://github.com/ClickHouse/ClickHouse/pull/112161) ([Avogar](https://github.com/Avogar)).
* `TTLDrop` 머지에서는 데이터 읽기 단계를 완전히 건너뛰어 과도한 메모리 사용, 특히 읽기/프리페치 버퍼 할당으로 인한 메모리 사용을 방지합니다. [#105859](https://github.com/ClickHouse/ClickHouse/pull/105859) ([Avogar](https://github.com/Avogar)).
* `dotProduct`에서 `BFloat16`을 지원하도록 했으며, SIMD 경로를 배치 처리하여 내적 성능을 개선했습니다. [#106569](https://github.com/ClickHouse/ClickHouse/pull/106569) ([nickitat](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/106821) ([UberDever](https://github.com/UberDever)).
* `allow_experimental_delta_lake_writes`로 제어되는 `DeltaLake` 테이블 쓰기 기능이 Beta로 승격되었습니다. [#107034](https://github.com/ClickHouse/ClickHouse/pull/107034) ([kssenii](https://github.com/kssenii)).
* `uniqCombined64` 스케치 기반의 `uniq` 경량 대안인 `uniq_v2` 컬럼 통계 유형을 추가했습니다. [#107863](https://github.com/ClickHouse/ClickHouse/pull/107863) ([hanfei1991](https://github.com/hanfei1991)).
* make\_distributed\_plan 실행을 관찰할 수 있도록 ProfileEvents `DistributedPlanRemoteTasks`, `DistributedPlanLocalExecution`, `DistributedPlanHostsUsed`를 추가했습니다. [#107985](https://github.com/ClickHouse/ClickHouse/pull/107985) ([shankar-iyer](https://github.com/shankar-iyer)).
* 이제 OneLake 등 REST 데이터 레이크 카탈로그로 보내는 요청에 ClickHouse `User-Agent` 헤더가 포함됩니다. [#108117](https://github.com/ClickHouse/ClickHouse/pull/108117) ([scanhex12](https://github.com/scanhex12)).
* 이제 `MVTEncodeGeom`은 클리핑 전에 지오메트리를 정수 픽셀 그리드에 스냅하고 `wagyu`로 폴리곤을 클리핑합니다. 따라서 클리핑된 출력이 유효하고(자기 교차 링이 복구됨) 경계에 정렬되어 PostGIS `ST_AsMVTGeom`의 결과와 일치합니다. [#108248](https://github.com/ClickHouse/ClickHouse/pull/108248) ([saarthak2002](https://github.com/saarthak2002)).
* 텍스트 인덱스 캐시 3개를 모두 전역으로 활성화했습니다. 이전에는 쿼리 내에서만 활성화되었습니다. 또한 포스팅 리스트 캐시 크기가 이제 0으로 설정되어 사실상 이 캐시는 다시 비활성화됩니다. 포스팅 리스트는 크기가 커서 캐싱 비용이 지나치게 높기 때문입니다. [#108274](https://github.com/ClickHouse/ClickHouse/pull/108274) ([rschu1ze](https://github.com/rschu1ze)).
* 테이블을 로드하기 전에 Prometheus 엔드포인트(메트릭 전용 구성인 경우)와 비동기 메트릭 수집을 시작하도록 하여, 오래 걸릴 수 있는 메타데이터 로딩 단계에서도 메트릭을 관찰할 수 있습니다. [#108402](https://github.com/ClickHouse/ClickHouse/pull/108402) ([cwurm](https://github.com/cwurm)).
* 이항 수학 함수에서 BFloat16을 지원합니다. [#108442](https://github.com/ClickHouse/ClickHouse/pull/108442) ([zhangyifan27](https://github.com/zhangyifan27)).
* 이제 전치 벡터 거리 함수 `L2DistanceTransposed`, `cosineDistanceTransposed`, `dotProductTransposed`는 `Nullable(QBit)` 컬럼에도 부분 비트 평면 읽기 최적화를 적용하여, 컬럼 전체가 아닌 요청된 비트 평면만 읽습니다. [#109358](https://github.com/ClickHouse/ClickHouse/pull/109358) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `BFloat16` 배열에 대해 `arraySum`, `arrayAvg`, `arrayProduct`를 지원합니다. [#109420](https://github.com/ClickHouse/ClickHouse/pull/109420) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `L1Normalize`, `L2Normalize`, `LinfNormalize`, `LpNormalize` 함수(및 해당 별칭)가 이제 튜플뿐만 아니라 배열에서도 동작합니다. 이는 `L2Norm` 및 거리 함수의 동작과 일관됩니다. [#110052](https://github.com/ClickHouse/ClickHouse/pull/110052) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 풀링된 연결(pooled connection)에 대해 더 이상 사용할 때마다 ping을 보내지 않습니다. 이에 따라 재사용되는 모든 연결에 추가되던 `Ping`-`Pong` 왕복이 제거되어 분산 쿼리와 `clickhouse-benchmark`의 지연 시간이 줄어듭니다. 오래된(stale) 풀링 연결은 타임아웃이 0인 poll(왕복이 추가되지 않는 논블로킹 검사)로 감지하고 재연결하여 복구합니다. [#110068](https://github.com/ClickHouse/ClickHouse/pull/110068) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 분산 인덱스 분석(distributed index analysis)에 사용되는 큰 파트 목록을 스칼라로 전송합니다(max\_ast\_elements/max\_query\_size로 인해 발생할 수 있는 실패를 방지하고 AST 파싱 오버헤드를 제거합니다). [#110419](https://github.com/ClickHouse/ClickHouse/pull/110419) ([azat](https://github.com/azat)).
* 이제 Playground에서 클라우드 로고를 클릭하면 ClickHouse 웹사이트가 새 탭에서 열리므로, 쿼리 실행 중에 진행 상황을 잃지 않습니다. [#110422](https://github.com/ClickHouse/ClickHouse/pull/110422) ([williamhatcher](https://github.com/williamhatcher)).
* `auto_statistics_types`의 기본값을 `basic, uniq`에서 `basic, uniq_v2`로 변경했습니다. [#110878](https://github.com/ClickHouse/ClickHouse/pull/110878) ([hanfei1991](https://github.com/hanfei1991)).
* `RWLockImpl::getLock()` 재진입 어설션(`RWLock is already locked in exclusive mode` / `Cannot acquire exclusive lock while RWLock is already locked`)이 발생하면, 이제 오류 메시지에 현재 잠금을 보유한 다른 `query_id`와 요청한 `query_id`가 이미 보유한 잠금 개수가 표시되므로 이러한 잠금 순서 오류를 진단할 수 있습니다. [#110971](https://github.com/ClickHouse/ClickHouse/pull/110971) ([groeneai](https://github.com/groeneai)).
* `randomHadamardTransform`은 이제 가장 큰 홀수 인수가 64 이하인 모든 벡터 길이(예: 임베딩 모델에서 흔히 쓰이는 `3584 = 512 * 7`)에 대해 길이를 보존하는 정확한 변환을 계산합니다. 이로써 기존에 지원하던 `2^N`, `2^k * {12, 20}`, `2^k * 9` 계열이 확장됩니다. 정확히 표현할 수 없는 길이에 대해 전체 변환을 수행하면, 이제 더 긴 벡터로 조용히 0을 채우는 대신 예외가 발생합니다. 임의 길이의 잘린 프로젝션을 계산하려면 `output_dims`를 전달하십시오. [#111006](https://github.com/ClickHouse/ClickHouse/pull/111006) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* HTTP 인터페이스에서 `ACCESS_DENIED` 예외가 발생하면 `500 Internal Server Error` 대신 HTTP 코드 `403 Forbidden`을 반환합니다. [#111043](https://github.com/ClickHouse/ClickHouse/pull/111043) ([Schum-io](https://github.com/Schum-io)).
* `UTMToGeo`는 이제 네 번째 인수로 정수 반구 플래그뿐만 아니라 `geoToUTM`이 반환하는 MGRS 위도 밴드 문자도 받습니다. 따라서 `geoToUTM` 결과를 `UTMToGeo`에 그대로 전달하여 왕복 변환할 수 있습니다. [#111521](https://github.com/ClickHouse/ClickHouse/pull/111521) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `MaterializedPostgreSQL`은 이제 업데이트 시 변경되지 않은 PostgreSQL `TOAST` 값을 기본값으로 대체하지 않고 그대로 보존합니다. [#111552](https://github.com/ClickHouse/ClickHouse/pull/111552) ([OrpheusAgent](https://github.com/OrpheusAgent)).
* 텍스트 인덱스 빌더가 임시 세그먼트를 플러시하는 시점을 제어하는 `text_index_max_processed_tokens_before_flush` 및 `text_index_max_memory_usage_before_flush` 설정을 추가했습니다. [#111573](https://github.com/ClickHouse/ClickHouse/pull/111573) ([rorylshanks](https://github.com/rorylshanks)).
* 스냅샷별 커밋 순서 정렬을 건너뛰는 STREAM UNORDERED 수정자를 추가했습니다. [#111794](https://github.com/ClickHouse/ClickHouse/pull/111794) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
* 이제 `make_distributed_plan=1`을 설정하면 아직 지원되지 않는 기능이 비활성화됩니다. [#112463](https://github.com/ClickHouse/ClickHouse/pull/112463) ([alesapin](https://github.com/alesapin)).
* stdout이 tty인 경우 INTO OUTFILE 출력에 ANSI 이스케이프 시퀀스를 기록하지 않습니다. [#113252](https://github.com/ClickHouse/ClickHouse/pull/113252) ([azat](https://github.com/azat)).
* `allow_experimental_delta_kernel_rs`의 이름을 `allow_delta_kernel_rs`로 변경했습니다. 기존 이름은 별칭으로 계속 사용할 수 있습니다. [#113476](https://github.com/ClickHouse/ClickHouse/pull/113476) ([kssenii](https://github.com/kssenii)).
* Experimental 압축 코덱을 각각 개별적으로 활성화할 수 있도록 `enable_alp_codec`, `enable_sz3_codec`, `enable_zxc_codec`, `enable_quantized_codec` 설정을 추가했습니다. [#113824](https://github.com/ClickHouse/ClickHouse/pull/113824) ([rienath](https://github.com/rienath)).
* 스택 오버플로우가 발생하면 아무 보고 없이 종료되는 대신 이를 보고합니다. 이제 치명적 시그널 핸들러가 대체 시그널 스택에서 실행되므로, 오류가 발생한 스레드가 스택을 모두 소진한 경우에도 `SIGSEGV`, `SIGABRT`, `SIGILL`, `SIGBUS`, `SIGSYS`, `SIGFPE`, `SIGTRAP`에 대한 스택 트레이스가 생성됩니다. [#113927](https://github.com/ClickHouse/ClickHouse/pull/113927) ([groeneai](https://github.com/groeneai)).
* 인스턴트 쿼리와 범위 쿼리에서 Prometheus HTTP API의 lookback\_delta 매개변수를 지원합니다. [#113971](https://github.com/ClickHouse/ClickHouse/pull/113971) ([fallintoplace](https://github.com/fallintoplace)).
* 이제 QueryRunner 테이블은 테이블 수명 내내 스레드를 점유하지 않고, 필요할 때 워커 스레드를 시작했다가 유휴 상태가 되면 해제합니다. [#114522](https://github.com/ClickHouse/ClickHouse/pull/114522) ([mstetsyuk](https://github.com/mstetsyuk)).
* 이번 변경으로 WHATIF 인덱스를 사용할 때 프로젝션 기반 기준값이 SQL 문을 실패 처리하는 대신 후보별로 `not_applicable`을 보고합니다. [#114846](https://github.com/ClickHouse/ClickHouse/pull/114846) ([yariks5s](https://github.com/yariks5s)).
* 동일한 표현식에 대한 여러 비교 조건으로 구성된 AND 체인을 최적화합니다. 모순되는 조건을 감지하고(예: `a < 3 AND a > 5` → `false`), 중복 조건을 제거합니다(예: `a = 3 AND a < 5` → `a = 3`). [#99736](https://github.com/ClickHouse/ClickHouse/pull/99736) ([wudidapaopao](https://github.com/wudidapaopao)).

<h2 id="bug-fixes">
  버그 수정
</h2>

<h3 id="mergetree-replication-and-storage-fixes">
  MergeTree, 복제 및 저장소 관련 수정 사항
</h3>

* `MergeTree`에서 `ALTER TABLE ... RENAME COLUMN`과 동시에 실행되는 `OPTIMIZE TABLE ... FINAL`(또는 임의의 백그라운드 머지) 간의 경쟁 조건으로 인해, 이름이 변경된 컬럼의 데이터가 아무런 경고 없이 기본값으로 대체될 수 있던 문제를 수정했습니다. 이제 두 작업이 진행되는 동안 `currently_processing_in_background_mutex`를 계속 보유하도록 하여, 새로운 인메모리 메타데이터를 게시하는 시점과 `current_mutations_by_version`에 이름 변경 뮤테이션을 등록하는 시점 사이의 경쟁 구간을 제거했습니다. [#104822](https://github.com/ClickHouse/ClickHouse/pull/104822) ([groeneai](https://github.com/groeneai)).
* 프로젝션에서 GROUP BY, ORDER BY와 `arrayJoin`을 함께 사용할 때 잘못된 쿼리 결과가 반환되던 문제를 수정했습니다. [#101775](https://github.com/ClickHouse/ClickHouse/pull/101775) ([Onyx2406](https://github.com/Onyx2406)).
* 잘못된 Azure 업로드 크기 설정(예: `azure_min_upload_part_size = 0` 또는 `azure_max_blocks_in_multipart_upload = 0`)은 이제 쓰기 경로 깊숙한 곳에서 내부 예외(`second_size > 0`)를 일으키는 대신, 초기 단계에서 명확한 오류와 함께 거부됩니다. 이는 쿼리 설정과 Azure 디스크 구성 모두에 적용됩니다. [#103394](https://github.com/ClickHouse/ClickHouse/pull/103394) ([statxc](https://github.com/statxc)).
* 그래뉼래리티 설정이 서로 호환되지 않는(하나는 적응형, 다른 하나는 비적응형) 두 `MergeTree` 테이블 간에 `ALTER TABLE ... MOVE/REPLACE/ATTACH PARTITION`을 실행하면 이제 `LOGICAL_ERROR` 대신 `BAD_ARGUMENTS`가 발생합니다. [#103881](https://github.com/ClickHouse/ClickHouse/pull/103881) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/104927) ([groeneai](https://github.com/groeneai)).
* 갱신 가능 구체화 뷰(`MATERIALIZED VIEW ... REFRESH ...`)에서 갱신 작업이 `EXCHANGE TABLES`를 통해 교체한 임시 내부 테이블이 서버의 `max_table_size_to_drop`보다 크면 삭제되지 않던 누수 문제를 수정했습니다. 그 결과 갱신할 때마다 이전 임시 내부 테이블은 정리되지 않은 채 새 임시 내부 테이블이 계속 생성되어, 디스크가 가득 찰 때까지 뷰의 데이터 디렉터리가 커졌습니다. 이제 갱신 작업의 내부 삭제는 `max_table_size_to_drop` 및 `max_partition_size_to_drop`을 우회합니다. 단, 사용자가 뷰 자체에 대해 직접 실행하는 `DROP TABLE`에는 이러한 안전장치가 그대로 적용됩니다. [#105106](https://github.com/ClickHouse/ClickHouse/pull/105106) ([groeneai](https://github.com/groeneai)).
* 정렬 키에 `SimpleAggregateFunction`(또는 `allow_suspicious_primary_key = 1`에서만 허용되는 다른 타입)이 포함된 `MergeTree` 테이블에서, 정렬 키를 변경할 수 없는 `ALTER` 쿼리(설정, 주석, 코덱 변경, 키가 아닌 컬럼 추가 등)를 실행하면 예기치 않은 `DATA_TYPE_CANNOT_BE_USED_IN_KEY` 오류가 발생하던 문제를 수정했습니다. [#105111](https://github.com/ClickHouse/ClickHouse/pull/105111) ([groeneai](https://github.com/groeneai)).
* 쿼리 타임아웃(`timeout_overflow_mode = 'break'`가 설정된 `max_execution_time`)으로 중단된 `OPTIMIZE ... DRY RUN`은 이제 `rows_sources` 관련 논리 오류(디버그 및 새니타이저 빌드에서는 서버가 비정상 종료됨) 대신 `TIMEOUT_EXCEEDED`를 반환합니다. [#107114](https://github.com/ClickHouse/ClickHouse/pull/107114) ([groeneai](https://github.com/groeneai)).
* `use_hive_partitioning=1`로 Hive 파티셔닝된 파일을 읽을 때, Hive 파티션 컬럼을 함께 선택한 상태에서 `WHERE`/`PREWHERE` 절로 실제(가상이 아닌) 컬럼을 필터링하면 `NOT_FOUND_COLUMN_IN_BLOCK`이 발생하던 문제를 수정했습니다. [#107505](https://github.com/ClickHouse/ClickHouse/pull/107505) ([groeneai](https://github.com/groeneai)).
* `toStartOfDay`, `toStartOfISOYear`, `toDaysSinceYearZero`, `toRelativeSecondNum`, `toRelativeMinuteNum`, `toRelativeHourNum`, `toRelativeWeekNum`, `toRelativeDayNum`, `toMonthNumSinceEpoch`, `toYearNumSinceEpoch`를 함수가 표현할 수 있는 범위를 벗어난 날짜(특히 `1970-01-01` 이전 날짜)가 포함된 `Date32` 키 컬럼에 적용하면, 프라이머리 키 및 파티션 프루닝이 잘못 수행되어 쿼리 결과가 틀리게 반환되던 문제를 수정했습니다. 이 함수들은 프라이머리 인덱스에 단조(monotonic) 함수로 보고되지만, 이전에는 이러한 인수에 대해 값이 순환(wrap around)되어 인덱스가 실제로 일치하는 행이 있는 그래뉼까지 프루닝할 수 있었습니다. 이제 이 함수들은 결과 타입의 경계값에서 포화(saturate)되어 `Date32` 전체 범위에서 단조성을 유지하므로 프루닝이 올바르게 동작합니다. [#108018](https://github.com/ClickHouse/ClickHouse/pull/108018) ([nihalzp](https://github.com/nihalzp)).
* `CREATE TABLE dst AS src SETTINGS ...`(및 명시적인 `ENGINE` 없이 `ORDER BY`/`PARTITION BY`를 사용하는 유사한 형태)가 원본 테이블의 엔진, 저장소 절(테이블 `TTL` 및 키 등), 설정을 아무런 경고 없이 누락하던 문제를 수정했습니다. 이제 엔진과 재정의되지 않은 저장소 절은 원본 테이블에서 상속되며, 지정한 설정은 원본 테이블의 설정에 덮어쓰는 방식으로 병합됩니다. [#108085](https://github.com/ClickHouse/ClickHouse/pull/108085) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Windows 기반 파일 시스템(WSL, CIFS/SMB, Docker Desktop 바인드 마운트)에서 `MergeTree` 테이블에 대한 `INSERT`가 `filesystem error: in rename: Permission denied` 오류로 실패하던 문제를 수정했습니다. 이 문제는 파트 작성기(part writer)가 파트 디렉터리 이름을 변경하는 동안에도 파일 디스크립터를 열어 두어 발생했습니다. [#108089](https://github.com/ClickHouse/ClickHouse/pull/108089) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 레거시 `hypothesis` 스킵 인덱스(`ATTACH` 호환성을 위해서만 남아 있는, 제거된 인덱스 유형)를 가진 채 ATTACH된 MergeTree 테이블이 작업 불능 상태에 빠지던 문제를 수정했습니다. 이전에는 이러한 테이블에서 경량 `DELETE`, `OPTIMIZE`, 일반 `INSERT`, 필터가 적용된 `SELECT`가 `ILLEGAL_INDEX`("Index of type 'hypothesis' is no longer supported") 오류로 실패했으며, `DELETE` 뮤테이션은 끝없이 재시도되었습니다. 이제 더 이상 쓰이지 않는 이 인덱스는 비활성 상태로 취급됩니다. 즉, 머지/뮤테이션 시에는 변경 없이 그대로 유지되고, 삽입 및 쿼리 계획 수립 시에는 무시되며, `ALTER TABLE ... DROP INDEX`로 여전히 삭제할 수 있습니다. [#108217](https://github.com/ClickHouse/ClickHouse/pull/108217) ([groeneai](https://github.com/groeneai)).
* 병렬 레플리카 환경에서 `MergeTree` 테이블의 가상 컬럼을 조회할 때(`asterisk_include_virtual_columns = 1`로 `SELECT *`를 실행하는 경우 포함) `NOT_FOUND_COLUMN_IN_BLOCK` 오류(예: `Column _part not found`)가 발생하던 문제를 수정했습니다. [#108451](https://github.com/ClickHouse/ClickHouse/pull/108451) ([groeneai](https://github.com/groeneai)).
* 프라이머리 키가 동일하지만 선언 방식이 다른 테이블(한쪽은 명시적 `PRIMARY KEY`, 다른 쪽은 `ORDER BY`로부터 암시적으로 지정)을 `ATTACH PARTITION ... FROM`이 거부하던 문제를 수정했습니다. [#108590](https://github.com/ClickHouse/ClickHouse/pull/108590) ([jordiori](https://github.com/jordiori)).
* 이제 디스크로의 자동 스필링을 사용하는 조인을 포함해 지원되는 모든 해시 기반 조인 경로에서 `join_any_take_last_row`가 적용됩니다. [#108936](https://github.com/ClickHouse/ClickHouse/pull/108936) ([antaljanosbenjamin](https://github.com/antaljanosbenjamin)).
* `query_plan_optimize_lazy_final`이 활성화된 상태에서 `WHERE` 필터의 일부가 (`optimize_move_to_prewhere_if_final`에 의해) `PREWHERE`로 이동될 때 `NOT_FOUND_COLUMN_IN_BLOCK` 오류가 발생하던 문제를 수정했습니다. 이제 지연 실행 FINAL 최적화는 prewhere에서 계산된 조건 컬럼을 저장소에 요청하지 않습니다. [#109073](https://github.com/ClickHouse/ClickHouse/pull/109073) ([groeneai](https://github.com/groeneai)).
* 세션에 `optimize_respect_aliases = 0`이 설정된 상태에서 테이블 수준 `ALIAS` 컬럼에 대해 `ALTER TABLE ... ADD PROJECTION`을 실행하면 테이블을 사용할 수 없게 되던 문제(이후 `INSERT`가 `UNKNOWN_IDENTIFIER`, "Missing columns" 오류로 실패)를 수정했습니다. [#109091](https://github.com/ClickHouse/ClickHouse/pull/109091) ([groeneai](https://github.com/groeneai)).
* 이전 분석기(`allow_experimental_analyzer = 0`)에서 다른 테이블과 조인된 `Merge` 엔진 테이블에 대해 `ORDER BY ALL`(또는 `GROUP BY ALL`)을 실행할 때 발생하던 널 포인터 assertion 실패(`TreeRewriter::analyzeSelect`의 `px != 0`, 디버그 및 sanitizer 빌드에서 서버가 중단됨)를 수정했습니다. [#109139](https://github.com/ClickHouse/ClickHouse/pull/109139) ([groeneai](https://github.com/groeneai)).
* 상관관계가 서브쿼리 프로젝션에만 나타나고 상관관계가 없는 `WHERE` 절이 함께 사용될 때 상관 `EXISTS` 서브쿼리와 스칼라 서브쿼리가 잘못된 결과를 반환하던 문제(서브쿼리가 모든 행에서 false / `NULL`로 평가될 수 있음)를 수정했습니다. [https://github.com/ClickHouse/ClickHouse/issues/105760](https://github.com/ClickHouse/ClickHouse/issues/105760) 문제를 해결합니다. [#109186](https://github.com/ClickHouse/ClickHouse/pull/109186) ([novikd](https://github.com/novikd)).
* `enable_block_number_column` 또는 `enable_block_offset_column` 설정이 활성화된 상태에서 프로젝션이 있는 `MergeTree` 테이블을 머지하면 불필요한 `_block_number`/`_block_offset` 컬럼이 포함된 프로젝션 파트가 생성되던 버그를 수정했습니다. 이로 인해 머지된 프로젝션 파트가 프로젝션 정의 및 삽입으로 생성된 프로젝션 파트와 일치하지 않게 되어, `CHECK TABLE`과 `OPTIMIZE ... DRY RUN`이 해당 파트를 손상된 것(`CORRUPTED_DATA`)으로 보고했습니다. [#109284](https://github.com/ClickHouse/ClickHouse/pull/109284) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/109428) ([groeneai](https://github.com/groeneai)).
* `Wide` 파트에서 `MATERIALIZED` 컬럼에 대한 `ALTER TABLE ... DROP COLUMN`처럼 파트 전체를 재작성하는 뮤테이션을 실행한 후 데이터 파트에서 스킵 인덱스가 삭제되던 문제(또는 `CHECK TABLE`이 `UNEXPECTED_FILE_IN_DATA_PART`로 실패하던 문제)를 수정했습니다. [#109616](https://github.com/ClickHouse/ClickHouse/pull/109616) ([groeneai](https://github.com/groeneai)).
* `ALTER TABLE ... APPLY PATCHES`로 경량 업데이트를 구체화한 후 스킵 인덱스(`text`, `bloom_filter` 등)와 프로젝션이 오래된 상태로 남던 문제를 수정했습니다. 이전에는 패치로 업데이트된 컬럼에 의존하는 인덱스 및 프로젝션 파일이 갱신되지 않아, 이를 사용하는 쿼리가 잘못된 결과를 반환할 수 있었습니다(예: `hasToken`이 업데이트된 행을 찾지 못하거나, 적용이 끝난 패치 파트가 제거된 후 프로젝션이 오래된 집계 결과를 반환). [#109709](https://github.com/ClickHouse/ClickHouse/pull/109709) ([groeneai](https://github.com/groeneai)).
* `_sample_factor` 가상 컬럼을 참조하는 뮤테이션이 실행 도중 `Unexpected const virtual column: _sample_factor` 오류로 실패하여 뮤테이션이 멈춘 상태로 남던 문제를 수정했습니다. 이제 뮤테이션은 이 컬럼을 `SAMPLE`이 없는 쿼리가 반환하는 값과 동일한 `1`로 읽습니다. [#109813](https://github.com/ClickHouse/ClickHouse/pull/109813) ([groeneai](https://github.com/groeneai)).
* `GROUP BY GROUPING SETS`가 포함된 쿼리(또는 이를 포함하는 스칼라 서브쿼리나 뮤테이션 서브쿼리)를 `force_aggregation_in_order = 1`로 실행할 때 발생하던 두 가지 오류를 수정했습니다. 하나는 이전 분석기(`enable_analyzer = 0`)에서 발생하던 `Trying to get name of not a column: ExpressionList` 오류이고, 다른 하나는 분석기 사용 시 `enable_memory_bound_merging_of_aggregation_results = 1`로 분산 쿼리를 실행할 때 발생하던 `Memory bound merging of aggregated results is not supported for grouping sets.` 오류입니다. [#109862](https://github.com/ClickHouse/ClickHouse/pull/109862) ([groeneai](https://github.com/groeneai)).
* `use_constant_folding_in_index_analysis`와 관련된 세 가지 문제를 수정했습니다. 첫째, 테이블에 `part_minmax_index_columns = 'with_block_number_offset'`가 설정된 경우 일반 프로젝션을 사용하는 `SELECT`가 논리 오류 `Invalid partition key size`로 중단될 수 있던 문제, 둘째, `PARTITION BY id % 200`과 같은 모듈로 파티션 키에 대한 필터에서 잘못된 결과가 반환되던(행이 경고 없이 누락되던) 문제, 셋째, `max_threads > 1` 설정에서 `sparseGrams` 토크나이저를 사용하는 `text` 인덱스를 여러 파티션에 걸쳐 `LIKE` 프레디케이트로 쿼리할 때 크래시(데이터 레이스)가 발생하던 문제입니다. [#109896](https://github.com/ClickHouse/ClickHouse/pull/109896) ([groeneai](https://github.com/groeneai)).
* `LowCardinality(Nullable(...))` 컬럼에 `minmax` 스킵 인덱스를 생성한 경우 잘못된 결과가 반환되던 문제를 수정했습니다. 이전에는 저장소로 푸시다운된 `WHERE`/`PREWHERE`/`HAVING ... IS NULL` 프레디케이트가 모든 그래뉼을 프루닝하여, 컬럼에 NULL이 있는데도 0개의 행을 반환했습니다. [#110061](https://github.com/ClickHouse/ClickHouse/pull/110061) ([groeneai](https://github.com/groeneai)).
* `prefer_localhost_replica`에 의해 로컬 레플리카가 선택될 때 Distributed 테이블에서 `ORDER BY ... LIMIT` 쿼리가 느리게 실행되던 문제를 수정했습니다. [#110136](https://github.com/ClickHouse/ClickHouse/pull/110136) ([EmeraldShift](https://github.com/EmeraldShift)).
* `DELETE` 또는 `ALTER UPDATE` 뮤테이션의 `WHERE` 조건 내 서브쿼리나 `UPDATE` 할당에서 집합 연산(`UNION`/`UNION ALL`/`UNION DISTINCT`/`EXCEPT`/`INTERSECT`)을 사용하면 예외(`UNION mode UNION_DEFAULT must be normalized`)가 발생하던 문제를 수정했습니다. [#110196](https://github.com/ClickHouse/ClickHouse/pull/110196) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `x IN (subquery)`를 포함한 뮤테이션이 기본 키 분석 중 서브쿼리 집합을 생성하는 동안 서버 종료가 지연되고 `KILL MUTATION`이 응답하지 않던 문제를 수정했습니다. 이제 집합 생성이 즉시 취소됩니다. [#110198](https://github.com/ClickHouse/ClickHouse/pull/110198) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `KILL TRANSACTION`과 트랜잭션 내에서 실행되는 `ALTER TABLE ... UPDATE/DELETE` 간의 레이스 컨디션을 수정했습니다. 뮤테이션이 트랜잭션에 등록된 후 테이블에 등록되기 전에 롤백이 발생하면 고아 뮤테이션 항목이 남았고, 이로 인해 백그라운드 작업에서 논리 오류(`Cannot find transaction ... that has started mutation ...`)가 발생하며 서버를 재시작할 때까지 해당 파트에 대한 이후의 모든 뮤테이션이 차단되었습니다. [#110226](https://github.com/ClickHouse/ClickHouse/pull/110226) ([tiandiwonder](https://github.com/tiandiwonder)).
* `DataLakeCatalog`(Iceberg/Glue) 데이터베이스에서 테이블 하나의 메타데이터라도 확인할 수 없으면 `system.tables` 쿼리 전체가 중단되거나 테이블이 경고 없이 누락되던 문제를 수정했습니다. 이제 `database_datalake_require_metadata_access` 설정과 관계없이 해당 테이블은 이름으로 계속 표시되며, 저장소 객체를 열어야 하는 컬럼(`engine`, `total_rows` 등)에는 기본값 또는 NULL이 표시됩니다. 손상된 테이블에 직접 액세스하면 이전과 같이 오류가 보고됩니다. [#110242](https://github.com/ClickHouse/ClickHouse/pull/110242) ([groeneai](https://github.com/groeneai)).
* 조인 순서 카디널리티 추정 시 이제 모든 활성 파트가 아니라 파티션/기본 키 프루닝 후 남은 파트만을 기준으로 컬럼 통계를 조합합니다. 이전에는 작은 파티션으로 프루닝된 쿼리도 테이블 전체 통계를 기준으로 계획이 수립되어(행 수를 2500배 과대 추정해 해시 조인의 빌드 측이 뒤바뀌는 사례가 관찰됨), 오히려 통계를 비활성화해야 더 나은 계획이 생성되는 역설적인 상황이 발생했습니다. 또한 조인 순서 최적화기가 메모이제이션한 인덱스 분석 결과를 적용된 프로젝션으로 오인하여, JOIN 하위의 MergeTree 릴레이션에서 지연 FINAL이 경고 없이 비활성화되던 문제도 수정했습니다. [#110283](https://github.com/ClickHouse/ClickHouse/pull/110283) ([skuznetsov-clickhouse](https://github.com/skuznetsov-clickhouse)).
* 그래뉼리티가 호환되지 않는(하나는 적응형, 다른 하나는 비적응형) 두 MergeTree 테이블 간에 `ALTER TABLE ... MOVE/REPLACE PARTITION`을 실행하면 이제 `LOGICAL_ERROR` 대신 `BAD_ARGUMENTS`가 발생합니다. 이는 사용자가 충분히 유발할 수 있는 상황이므로 내부 오류(디버그/새니타이저 빌드에서는 서버를 중단시킴)로 처리되어서는 안 됩니다. [#110535](https://github.com/ClickHouse/ClickHouse/pull/110535) ([groeneai](https://github.com/groeneai)).
* `WHERE`에서 참조하는 컬럼에 `ALTER TABLE ... UPDATE`가 적용되어 `<cond>`와 일치하게 된 행을 `TTL ... DELETE WHERE <cond>`가 삭제하지 않던 문제를 수정했습니다. 이제 뮤테이션이 행 TTL을 다시 계산하므로, 새로 조건과 일치하게 된 만료 행이 아무 알림 없이 남아 있지 않고 삭제됩니다. [#110648](https://github.com/ClickHouse/ClickHouse/pull/110648) ([groeneai](https://github.com/groeneai)).
* `non_replicated_deduplication_window`가 활성화된 파티션된 `MergeTree` 테이블에 `INSERT`할 때, 비동기 삽입 배치가 부분적으로만 중복 제거되면(일부 `insert_deduplication_token`은 중복이고 일부는 새로운 경우) `LOGICAL_ERROR` "Invalid partition key size: 0"가 발생하여 작업이 중단될 수 있던 문제를 수정했습니다. [#110651](https://github.com/ClickHouse/ClickHouse/pull/110651) ([groeneai](https://github.com/groeneai)).
* 새 분석기에서 constant folding이 상수 `Geometry` 값의 타입을 아무 알림 없이 변경하던 문제를 수정했습니다. `Geometry`는 이름이 지정된 `Variant`로, 각 대안이 동일한 저장 레이아웃을 공유할 수 있습니다(`LineString`/`Ring`, `MultiLineString`/`Polygon`, 빈 값). 이 때문에 대안만 다른 두 폴딩된 상수가 하나로 합쳐져, 예를 들어 상수 `MULTIPOLYGON EMPTY`가 `LINESTRING()`으로 반환되었습니다. [#110709](https://github.com/ClickHouse/ClickHouse/pull/110709) ([groeneai](https://github.com/groeneai)).
* read-in-order 쿼리에서 `distinct-in-order` 또는 `aggregation-in-order`가 `ORDER BY`로 read-in-order virtual row를 설정한 정렬 키 접두사보다 더 긴 접두사까지 읽기를 확장할 때 잘못된 결과(머지 순서 오류)가 발생하던 문제를 수정했습니다. virtual row의 추가 정렬 컬럼이 기본값으로 채워져 `MergingSortedTransform`의 순서가 어긋날 수 있었습니다(debug/sanitizer 빌드에서는 `LOGICAL_ERROR`로 중단됨). [#110725](https://github.com/ClickHouse/ClickHouse/pull/110725) ([groeneai](https://github.com/groeneai)).
* interserver-secret 클러스터에서 병렬 레플리카 읽기 및 분산 읽기를 수행할 때 쿼리의 활성 역할(SET ROLE / role=)이 원격 노드로 전달되도록 했습니다. 이전에는 사용자의 기본 역할이 대신 사용되어 row policy가 initiator와 다르게 평가되었습니다. [#110867](https://github.com/ClickHouse/ClickHouse/pull/110867) ([evillique](https://github.com/evillique)).
* `ReplicatedMergeTree` 테이블에 대한 주석 전용 또는 설정 전용 `ALTER`가 동시에 실행된 `ALTER ... ADD COLUMN`으로 추가된 컬럼을 아무 알림 없이 누락시켜, 레플리카가 오래된 테이블 structure에 머무를 수 있던 드문 경쟁 조건을 수정했습니다. [#111029](https://github.com/ClickHouse/ClickHouse/pull/111029) ([tiandiwonder](https://github.com/tiandiwonder)).
* `Distributed` 테이블을 감싸는 `Merge` 테이블에서 집계가 포함된 `GROUP BY`를 실행할 때, 그룹화 키가 컬럼에 대한 함수이고 집계 함수가 같은 컬럼을 읽으면(예: `SELECT toString(g), min(g) FROM merge_over_distributed GROUP BY toString(g)`) `NUMBER_OF_COLUMNS_DOESNT_MATCH` 오류가 발생하던 문제를 수정했습니다. [#111334](https://github.com/ClickHouse/ClickHouse/pull/111334) ([groeneai](https://github.com/groeneai)).
* 왼쪽 키는 `Nullable`이지만 저장소 키는 그렇지 않을 때, `Join` 엔진 테이블(`StorageJoin`)에 `USING`을 사용한 `FULL JOIN`이 잘못된 결과를 반환하던 문제를 수정했습니다. 키가 `NULL`이고 일치하는 행이 없는 왼쪽 행에서 `NULL` 대신 `0`이 반환되었습니다. [#111371](https://github.com/ClickHouse/ClickHouse/pull/111371) ([groeneai](https://github.com/groeneai)).
* 이제 테이블의 `fsync_part_directory` 설정이 활성화되어 있으면 `ALTER TABLE ... DETACH PARTITION/PART`가 `detached/` 아래에 생성하는 복제본(파트 하위 트리 및 디스크 루트까지 이어지는 디렉터리 체인)을 fsync합니다. 이는 Full(디렉터리) 및 Packed 파트 저장 방식 모두에 적용됩니다. 이전에는 활성 집합에서 행을 제거하는 빈 커버링 파트는 fsync되었지만 복제본은 전혀 fsync되지 않았기 때문에, 확인 응답 직후 전원이 끊기면 btrfs에서 분리된 데이터가 손실될 수 있었습니다(동기화되지 않은 복제본 디렉터리 엔트리가 롤백되어 `detached/`가 비게 되고 `ATTACH`할 대상이 남지 않음). 이 동작은 기존 `fsync_part_directory` 설정으로 제어되며, 기본 동작은 변경되지 않습니다. [#111426](https://github.com/ClickHouse/ClickHouse/pull/111426) ([groeneai](https://github.com/groeneai)).
* 스키마를 저장소에서 추론하는 경우(예: `SELECT NULL`을 수행하는 뷰를 기반으로 컬럼 없이 정의한 `remote()`/`Remote`/`Distributed` 테이블) 이제 `Nullable(Nothing)` 컬럼(또는 테이블에서 허용되지 않는 다른 유형의 컬럼)을 `CREATE TABLE` 시점에 거부합니다. 이전에는 이러한 메타데이터가 그대로 저장되어, 다음 서버 재시작 시 로드에 실패하고 관련 없는 테이블의 로드까지 막았습니다. [#111487](https://github.com/ClickHouse/ClickHouse/pull/111487) ([groeneai](https://github.com/groeneai)).
* 병렬 레플리카로 읽을 때 이니시에이터에서 프로젝션 최적화(정확한 개수 계산, minmax-count, 또는 범위를 선택하지 않는 저장된 집계/일반 프로젝션)만으로 쿼리 결과가 모두 산출되는 경우, 서버를 중단시킬 수 있던 `LOGICAL_ERROR`(`Got read request from replica N for unknown stream ...`)를 수정했습니다. [#111689](https://github.com/ClickHouse/ClickHouse/pull/111689) ([groeneai](https://github.com/groeneai)).
* DeltaLake 파티션 `INSERT`(`allow_experimental_delta_lake_writes=1`)가 경로 문자를 포함한 파티션 값을 손상시키고 `NULL`을 거부하던 문제를 수정했습니다. `a/b` 같은 값은 아무 경고 없이 `a`로 커밋되었고, `%`가 포함된 값은 다시 읽을 수 없는 데이터 파일을 생성했으며, `NULL` 파티션 값은 `NOT_IMPLEMENTED` 오류로 실패했습니다. 이제 파티션 값은 퍼센트 인코딩되어 하나의 경로 세그먼트로 기록되고, 실제 값은 경로에서 다시 파싱하지 않고 `partitionValues`에 저장되며, `NULL`(또는 빈 문자열) 파티션 값은 `partitionValues` 항목을 null로 하여 `__HIVE_DEFAULT_PARTITION__`으로 기록됩니다. [#111793](https://github.com/ClickHouse/ClickHouse/pull/111793) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/111997) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/112009) ([groeneai](https://github.com/groeneai)).
* 쿼리가 `intDiv(constant, key)` 또는 `divide(constant, key)`로 필터링할 때 오류 없이 행이 누락되는 문제를 수정했습니다. 상수를 키 컬럼으로 나누면 기본 키(primary key) 및 파티션 분석이 단조성(monotonicity)의 방향을 잘못 판단하여, 조건에 맞는 그래뉼이 제외되고 쿼리가 오류 없이 더 적은 행을 반환했습니다. 또한 최상위 비트가 설정된 부호 없는 상수를 피제수로 사용하는 `intDiv`를 수정했고, `Decimal` 피연산자 때문에 나눗셈이 decimal의 고유 너비로 계산되는 경우에는 단조성을 보장하지 않도록 했으며, `IPv4`/`IPv6` 상수를 키 컬럼으로 나누는 유효한 쿼리에서 키 분석이 `Cannot compare DB::IPv4 with long` 오류를 발생시키지 않도록 했습니다. [#112156](https://github.com/ClickHouse/ClickHouse/pull/112156) ([groeneai](https://github.com/groeneai)).
* `SELECT` 본문에서 `INTERSECT`/`EXCEPT`를 사용하거나 `UNION DISTINCT`와 `UNION ALL`을 혼합한 `UNION` 체인을 사용하는 매개변수화된 뷰(parameterized view)가 일반 뷰로 분류되는 문제를 수정했습니다. 이러한 뷰는 정상적으로 생성되지만 메타데이터를 다시 읽을 수 없었습니다. 로드 시 `Invalid storage definition in metadata file` 오류가 발생하여 뷰를 영구적으로 로드할 수 없었고, 디버그 또는 sanitizer 빌드 서버는 시작 중에 중단되었습니다. 또한 `system.tables.parameterized_view_parameters`에도 해당 뷰의 매개변수가 표시되지 않았습니다. [#112211](https://github.com/ClickHouse/ClickHouse/pull/112211) ([groeneai](https://github.com/groeneai)).
* 쿼리가 `geohashesInBox`를 평가하는 동안 `max_execution_time`과 `KILL QUERY`가 무시되는 문제를 수정했습니다. 이러한 쿼리는 블록의 모든 행을 확장한 뒤에야 중단될 수 있었기 때문에 취소가 몇 분이 지나서야 적용되었습니다. 이제 함수가 행을 순회하면서 쿼리의 시간 제한을 확인합니다. 정렬 키, 스킵 인덱스, `PARTITION BY`처럼 영구 저장되는 테이블 표현식 내부의 평가는 이번 수정에 포함되지 않으며 별도로 추적됩니다. [#112273](https://github.com/ClickHouse/ClickHouse/pull/112273) ([groeneai](https://github.com/groeneai)).
* 다른 Merge 테이블 또는 컬럼 유형이 다른 materialized view를 기반으로 하는 Merge 테이블에서 PREWHERE를 사용할 때 발생하던 논리 오류(logical error)를 수정했습니다. 또한 원격 서버에서 데이터를 읽는 테이블(분산 테이블 또는 이를 감싸는 테이블)에서 행 정책(row policy)이 경고 없이 무시되어, 정책으로 숨겨야 할 행이 노출될 수 있던 문제를 수정했습니다. 이제 이러한 쿼리는 ILLEGAL\_PREWHERE 오류와 함께 거부됩니다. 이 경우 각 원격 서버의 기본 로컬 테이블에 정책을 정의하십시오. 단, `serialize_query_plan = 1`로 전송되는 읽기에는 여전히 이 정책이 적용되지 않으며, 이는 기존부터 있던 별도의 버그입니다. [#112326](https://github.com/ClickHouse/ClickHouse/pull/112326) ([PedroTadim](https://github.com/PedroTadim)).
* `ALTER TABLE ... MODIFY COLUMN`으로 유형을 변경했으나 뮤테이션이 실행되지 않은 경우(예: `KILL MUTATION`으로 제거된 경우) 오래된 보조(스킵) 인덱스를 읽는 문제를 수정했습니다. 디스크의 그래뉼은 이전 유형으로 기록되었는데 새 유형으로 디코딩되어 `LOGICAL_ERROR`가 발생하거나, 수 엑사바이트 규모의 메모리 할당을 요청하거나, 오류 없이 잘못된 결과를 반환했습니다. 또한 저장된 바이트는 모두 그대로이지만 의미가 바뀌어 뮤테이션이 아예 생성되지 않는 표현식의 인덱스가 잘못된 결과를 반환하는 문제도 수정했습니다. `DateTime` 시간대만 변경하거나 `UInt8`에서 `Bool`로 바꾸는 것처럼 사용자 정의 유형 이름만 변경하는 `MODIFY COLUMN`이 이에 해당합니다. 이제 영향을 받는 파트에서는 이러한 인덱스를 건너뜁니다. [#112484](https://github.com/ClickHouse/ClickHouse/pull/112484) ([groeneai](https://github.com/groeneai)).
* 클러스터 전체를 대상으로 집계하는 쿼리를 `serialize_query_plan = 1` 및 계획 기반 병렬 레플리카(plan-based parallel replicas)로 실행할 때, 머지 단계가 파이프라인을 0개의 스트림으로 재조정하여 발생하던 `LOGICAL_ERROR`(`Cannot add transform Resize to Pipes because it has no outputs`)를 수정했습니다. [#112506](https://github.com/ClickHouse/ClickHouse/pull/112506) ([groeneai](https://github.com/groeneai)).
* `ReplicatedMergeTree` 레플리카가 자신의 대기 중인 `ALTER ... ADD COLUMN`을 적용하기 전에 다른 레플리카에서 가져온 파트를 뮤테이션할 때 발생하던 `LOGICAL_ERROR`("Part ... contains column ... that is absent in table ...")를 수정했습니다. 이제 이러한 뮤테이션은 메타데이터 변경이 적용될 때까지 연기됩니다. [#112510](https://github.com/ClickHouse/ClickHouse/pull/112510) ([groeneai](https://github.com/groeneai)).
* `ORDER BY`가 디스크로 스필되는 쿼리에서 읽기 카운터(`read_rows`, `read_bytes`, `ProfileEvents['SelectedRows']`, `ProfileEvents['SelectedBytes']`)와 `READ_ROWS` 및 `READ_BYTES` 쿼터가 과다 집계되던 문제를 수정했습니다. 외부 정렬 임시 파일에서 다시 읽은 행이 소스 읽기로 중복 집계되어, 스필이 발생한 쿼리는 실제보다 많이 읽은 것으로 보고되었고 쿼터를 초과하지 않았는데도 `QUOTA_EXCEEDED`로 거부될 수 있었습니다. [#112645](https://github.com/ClickHouse/ClickHouse/pull/112645) ([groeneai](https://github.com/groeneai)).
* 디스크로 스필되는 `JOIN`의 결과 크기를 `ProfileEvents['JoinResultRowCount']`가 실제보다 적게 보고하던 문제를 수정했습니다. 지연된 버킷에서 출력된 행이 `JoinDelayedJoinedTransformRowCount`에만 집계되고 전체 합계에서는 누락되었습니다. 쿼리 결과 자체는 항상 정확했으며, 프로필 이벤트 값만 잘못되었습니다. [#112673](https://github.com/ClickHouse/ClickHouse/pull/112673) ([groeneai](https://github.com/groeneai)).
* 레플리카와 연결을 수립하는 중인 분산 쿼리에서 `max_execution_time`과 `KILL QUERY`가 아무런 알림 없이 적용되지 않던 문제를 수정했습니다. 이제 이러한 쿼리는 남은 레플리카와 재시도를 모두 거치지 않고 다음 연결 시도 시점에 중지됩니다. [#112689](https://github.com/ClickHouse/ClickHouse/pull/112689) ([groeneai](https://github.com/groeneai)).
* 완료되지 않은 `RENAME COLUMN` alter-뮤테이션이 진행 중인데도 `MergeTree` 테이블에 `ALTER`가 적용되던 문제를 수정했습니다. 이로 인해 저장소 메타데이터가 호환되지 않는 방식으로 갱신되어 이후 뮤테이션이 완전히 막힐 수 있었습니다. [#112783](https://github.com/ClickHouse/ClickHouse/pull/112783) ([Michicosun](https://github.com/Michicosun)).
* `Distributed` 테이블을 기반으로 하는 `Merge` 테이블에서 읽을 때 `ORDER BY` 결과가 잘못되던 문제를 수정했습니다. 행이 올바른 순서로 반환되지 않을 수 있었고, `LIMIT`을 사용하면 결과에 포함되어야 할 행이 누락될 수 있었습니다. [#112931](https://github.com/ClickHouse/ClickHouse/pull/112931) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `share_nested_offsets`가 활성화된(기본값) 테이블에서 파일 시스템 읽기 프리페치가 활성화되어 있고, 삭제 후 다시 추가된 서브컬럼과 함께 `Nested` 컬럼을 읽을 때 잘못된 결과가 반환되던 문제를 수정했습니다. 이러한 쿼리는 `ALTER`의 영향을 전혀 받지 않았고 물리적으로도 존재하는 컬럼에 대해 기본값을 반환할 수 있었습니다. 객체 스토리지에서는 `remote_filesystem_read_prefetch`의 기본값이 `1`이므로 별도의 설정 변경 없이도 발생하며, 로컬 디스크에서는 `local_filesystem_read_prefetch = 1`일 때 발생합니다. 읽기 범위가 여러 블록에 걸쳐 있을 때 이러한 읽기 결과를 손상시키는, 프리페치와 무관한 별도의 결함은 여전히 남아 있으며 이번 수정에서는 다루지 않습니다. [#112997](https://github.com/ClickHouse/ClickHouse/pull/112997) ([groeneai](https://github.com/groeneai)).
* `PARTITION BY`를 사용하는 윈도 함수나 `join_algorithm = 'parallel_full_sorting_merge'`를 사용하는 조인처럼 데이터를 파티션별로 분산하는 쿼리에서, 블록이 일부만 분배된 상태에서 한 샤드의 다운스트림이 종료되면 `Pipeline stuck` 논리 오류가 발생하던 문제를 수정했습니다. [#113190](https://github.com/ClickHouse/ClickHouse/pull/113190) ([groeneai](https://github.com/groeneai)).
* `ReplicatedMergeTree`에서 `alter_sync = 2`로 실행한 `ALTER`, `OPTIMIZE`, `TRUNCATE` 및 파티션 조작 SQL 문이 다른 레플리카를 기다리는 동안 테이블 종료가 시작되면(예: 동시에 실행된 `DROP DATABASE ... SYNC`로 인해) 응답 없이 멈추던 문제를 수정했습니다. 이제 이러한 SQL 문은 `UNFINISHED`로 실패하며, `max_execution_time`과 `KILL QUERY`도 정상적으로 적용됩니다. [#113228](https://github.com/ClickHouse/ClickHouse/pull/113228) ([groeneai](https://github.com/groeneai)).
* `read_in_order_use_virtual_row`가 활성화된 상태에서 `MergeTree` 순차 읽기(read-in-order) 쿼리가 `WITH FILL ... INTERPOLATE`와 `IN` 또는 `has` 필터를 함께 사용하면 `Cannot insert element into Set`(`NOT_IMPLEMENTED`) 오류가 발생하던 문제를 수정했습니다. [#113264](https://github.com/ClickHouse/ClickHouse/pull/113264) ([groeneai](https://github.com/groeneai)).
* `inject_random_order_for_select_without_order_by` 설정이 활성화된 상태에서 집계 쿼리가 `Distributed` 자식 테이블을 포함하는 `Merge` 테이블을 읽을 때 발생하던 논리 오류(예외) `Chunk info was not set for chunk in MergingAggregatedTransform`를 수정했습니다. 이제 중간 단계까지만 계획되는 쿼리에는 무작위 `ORDER BY rand()` 래퍼가 주입되지 않습니다. [#113266](https://github.com/ClickHouse/ClickHouse/pull/113266) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `MergeTree` 테이블에 시간 표현식이 동일하고 `WHERE` 조건만 다른 `TTL ... DELETE WHERE` 규칙이 2개 이상 있을 때 행이 전혀 삭제되지 않던 문제를 수정했습니다. TTL 삭제 머지 후 파트의 `rows_where_ttl_info`가 0으로 초기화되어 해당 파트에 대한 TTL 머지가 더 이상 예약되지 않았고, 그 결과 만료된 행이 오류나 로그 메시지 없이 무기한 남아 있었습니다. [#113384](https://github.com/ClickHouse/ClickHouse/pull/113384) ([groeneai](https://github.com/groeneai)).
* 정렬 키, 스킵 인덱스, `PARTITION BY` 키 등 테이블 메타데이터에 저장된 표현식 안에서 쿼리가 `geohashesInBox`, `arrayFold`, `sleep`, `base58Decode`, `h3PolygonToCells` 또는 `h3PolygonToCellsWithContainment`를 평가하는 동안 `max_execution_time`과 `KILL QUERY`가 무시되던 문제를 수정했습니다. [#113456](https://github.com/ClickHouse/ClickHouse/pull/113456) ([groeneai](https://github.com/groeneai)).
* 자식 테이블이 2개 이상인 `Merge` 테이블이 외부 쿼리에서 참조하는 머티리얼라이즈된 CTE를 읽을 때 발생하던 `LOGICAL_ERROR`(`Reading from materialized CTE '...' before its materialization completed - DelayedPortsProcessor gate is missing in the query plan`)를 수정했습니다. [#113558](https://github.com/ClickHouse/ClickHouse/pull/113558) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 자식 테이블이 여러 개인 `Merge` 테이블에 대해 단일 컬럼 `PREWHERE`와 별도의 `WHERE`를 함께 사용한 `EXPLAIN ANALYZE`에서 발생하던 `Logical error: 'Required output position N is out of range for pass-through inputs'`를 수정했습니다. [#113725](https://github.com/ClickHouse/ClickHouse/pull/113725) ([groeneai](https://github.com/groeneai)).
* 컬럼 타입이 기반 저장소와 다른 뷰(예: `engine`이 `Nullable(String)`인 `information_schema.tables`와, 기반이 되며 해당 컬럼이 `String`인 `system.tables`)에 대한 필터가 저장소로 푸시다운될 때 발생하던 논리 오류(`Unexpected return type`)를 수정했습니다. [#113984](https://github.com/ClickHouse/ClickHouse/pull/113984) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 조건절에 `IN (subquery)`가 포함된 뮤테이션이 서브쿼리의 Set이 아직 생성되는 도중에 `KILL MUTATION`이나 `DETACH DATABASE` 등으로 취소될 때 발생하던 `Not-ready Set is passed as the second argument for function 'in'` 오류를 수정했습니다. [#114463](https://github.com/ClickHouse/ClickHouse/pull/114463) ([groeneai](https://github.com/groeneai)).
* 정렬 키, 기본 키 또는 파티션 키에 사용되는 컬럼에 대해 `ALTER TABLE ... DROP COLUMN`을 실행하면 이제 `ALTER TABLE ... CLEAR COLUMN`과 마찬가지로 설명과 함께 `ALTER_OF_COLUMN_IS_FORBIDDEN` 오류로 실패합니다. 이전에는 키 표현식을 다시 계산하는 과정에서 발생한, 원인을 파악하기 어려운 `UNKNOWN_IDENTIFIER: Missing columns` 오류로 실패했습니다. 그룹의 컬럼이 키에 사용되는 상태에서 공통 접두사로 `Nested` 그룹 전체를 삭제하거나 초기화하는 경우에도 동일하게 적용됩니다. 이전에는 이로 인해 그룹의 데이터가 아무 알림 없이 손상되거나 끝나지 않는 뮤테이션이 남을 수 있었습니다. 또한 `TTL` 표현식에서만 사용되는 컬럼을 삭제하면 이제 어떤 TTL 표현식이 영향을 받는지 알려 줍니다. [#114468](https://github.com/ClickHouse/ClickHouse/pull/114468) ([m7kss1](https://github.com/m7kss1)).
* 하나의 `ALTER`에서 이름 변경, 삭제 후 다시 추가된 컬럼이 뮤테이션이 아직 대기 중인 동안 자체 기본값 대신 삭제된 컬럼의 값을 반환하던 문제를 수정했습니다. [#114601](https://github.com/ClickHouse/ClickHouse/pull/114601) ([tiandiwonder](https://github.com/tiandiwonder)).
* 기본 테이블(underlying table)이 상위 컬럼을 `ALIAS`로 선언한 경우 `Merge` 테이블을 통해 서브컬럼(`.size0`, `.null`, 튜플 요소, `String.size`)을 읽을 때 발생하던 문제를 수정했습니다. 이러한 읽기는 해당 타입의 기본값을 반환했으며, 같은 쿼리에서 상위 컬럼도 함께 선택하면 관련 없는 컬럼의 값이 반환될 수 있었습니다. [#114673](https://github.com/ClickHouse/ClickHouse/pull/114673) ([groeneai](https://github.com/groeneai)).
* 폴리곤 인수가 유효하지 않은 상수 리터럴이고 `validate_polygons = 0`인 경우, MergeTree 프라이머리 키에 대해 `pointInPolygon`으로 필터링한 `SELECT` 결과에서 행이 누락되던 문제를 수정했습니다. 프라이머리 키 분석이 검사하지 않은 폴리곤을 기반으로 그래뉼 프루닝(granule pruning)을 수행하면서, 조건에 맞는 행이 포함된 그래뉼까지 제외했습니다. [#114710](https://github.com/ClickHouse/ClickHouse/pull/114710) ([groeneai](https://github.com/groeneai)).
* `ALTER TABLE ... MATERIALIZE INDEX`, `MATERIALIZE STATISTICS`, `MATERIALIZE PROJECTION`을 포맷팅할 때 `IF EXISTS` 절이 누락되어, 포맷팅된 쿼리가 파싱된 쿼리와 달라지던 문제를 수정했습니다. 또한 SQL 파서가 생성할 수 없고 포맷팅하면 다른 명령으로 바뀌던 4가지 `ALTER ... STATISTICS` AST JSON 페이로드를 거부하도록 했습니다. [#115099](https://github.com/ClickHouse/ClickHouse/pull/115099) ([groeneai](https://github.com/groeneai)).
* 집계 도중 딕셔너리가 커지는 `LowCardinality(String)` 키로 집계하거나 조인할 때 캐시된 딕셔너리 해시를 범위 밖에서 읽던 문제를 수정했습니다. 이 문제는 `TTL ... GROUP BY`에서 발생할 수 있었으며, 잘못된 해시가 산출되거나 새니타이저 빌드에서 heap-buffer-overflow가 보고될 수 있었습니다. [#115604](https://github.com/ClickHouse/ClickHouse/pull/115604) ([groeneai](https://github.com/groeneai)).
* 이제 `CREATE TABLE` 및 `ALTER TABLE`에서 파티션 키에 사용되는 컬럼에 `SZ3`와 같은 손실 압축 코덱을 지정하면 거부됩니다. [#115626](https://github.com/ClickHouse/ClickHouse/pull/115626) ([groeneai](https://github.com/groeneai)).
* 대상이 매개변수화된 뷰(parameterized view)인 `Alias` 테이블과 일치하는 `Merge` 테이블을 통해 읽을 때 더 이상 `LOGICAL_ERROR: Table has no columns.`(디버그 및 새니타이저 빌드에서는 서버가 중단됨)가 발생하지 않습니다. 이러한 테이블은 이제 매개변수화된 뷰 자체와 동일한 `STORAGE_REQUIRES_PARAMETER` 오류를 보고합니다. 컬럼을 제공할 수 없는 그 밖의 일치 테이블은 이제 내부 오류 대신 `UNSUPPORTED_METHOD`를 보고합니다. [#115896](https://github.com/ClickHouse/ClickHouse/pull/115896) ([groeneai](https://github.com/groeneai)).
* 표현식이 `_sample_factor`를 참조하는 대기 중인 뮤테이션의 즉석 프리뷰 문제를 수정했습니다. `apply_mutations_on_fly = 1`이고 `SAMPLE` 절이 있으면, 표현식이 백그라운드 머티리얼라이즈 시 저장되는 값 대신 읽기 쿼리의 샘플 계수로 평가되었습니다. 이로 인해 프리뷰된 행이 최종 구체화 결과와 일치하지 않았으며, 대기 중인 `ALTER TABLE t DELETE WHERE _sample_factor > 1` 때문에 `SAMPLE` 읽기가 행을 전혀 반환하지 않을 수도 있었습니다. 쿼리 자체의 `_sample_factor` 컬럼은 변경되지 않습니다. [#115906](https://github.com/ClickHouse/ClickHouse/pull/115906) ([groeneai](https://github.com/groeneai)).
* 형식 버전 `V3`의 통계 파일을 이제 `ILLEGAL_STATISTICS`로 거부하지 않고 읽습니다. 이러한 파일은 특정 짧은 기간의 `master` 빌드에서만 생성되었지만, 이를 포함한 파트는 전혀 읽을 수 없었고, 읽기 전용 디스크에서는 `ALTER TABLE ... MATERIALIZE STATISTICS`로 다시 생성할 수도 없었습니다. [#116030](https://github.com/ClickHouse/ClickHouse/pull/116030) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `SELECT ... FROM t STREAM ... ORDER BY ... LIMIT n` 쿼리가 `PROJECTION`이 있는 테이블을 읽을 때 `Invalid number of columns in chunk pushed to OutputPort`(`LOGICAL_ERROR`)가 발생하던 문제를 수정했습니다. 이제 `STREAM` 읽기에는 지연 머티리얼라이즈(lazy materialization)가 적용되지 않습니다. [#116187](https://github.com/ClickHouse/ClickHouse/pull/116187) ([groeneai](https://github.com/groeneai)).
* 복제 데이터베이스에서는 `ALTER TABLE ATTACH PARTITION FROM`을 복제하지 않습니다. [#94835](https://github.com/ClickHouse/ClickHouse/pull/94835) ([MikhailBurdukov](https://github.com/MikhailBurdukov)).
* 롤백된 트랜잭션 MergeTree 파트가 커밋된 파트와 교차하는 경우, 테이블 시작 과정에서 서버가 중단되거나(새니타이저 빌드) 데이터가 아무런 알림 없이 손실되던 문제를 수정했습니다. 이제 `PartLoadingTree::add`는 교차하는 두 파트 중 롤백된 파트를 올바르게 식별하여 제거하고, 부모를 잃은 하위 파트를 커밋된 파트 아래에 올바른 순서로 다시 연결합니다. [#100992](https://github.com/ClickHouse/ClickHouse/pull/100992) ([tuanpach](https://github.com/tuanpach)).
* MergeTree 테이블의 `Array(LowCardinality(String))` 컬럼에서 `indexOfAssumeSorted`가 잘못된 결과를 반환하던 문제를 수정했습니다. [#101771](https://github.com/ClickHouse/ClickHouse/pull/101771) ([Onyx2406](https://github.com/Onyx2406)).
* `Iceberg` 메타데이터의 동시 업데이트나 `DeltaLake` 테이블에 대한 `merge` 읽기처럼, 고정된 `datalake_table_state` 없이 읽기 파이프라인에 도달할 수 있는 경로로 `Iceberg` 또는 `DeltaLake` 데이터 레이크 테이블을 읽을 때 발생하던 `LOGICAL_ERROR` 예외를 수정했습니다. [#102033](https://github.com/ClickHouse/ClickHouse/pull/102033) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/106202) ([groeneai](https://github.com/groeneai)).
* 경량한 삭제 이후 프로젝션 파트가 남지 않는 경우(프로젝션이 출력 행 0개로 재구성되거나 삭제되는 경우, `lightweight_mutation_projection_mode = 'rebuild'`/`'drop'`) 데이터 파트에 손상된 프로젝션이 있는 것으로 잘못 표시되던 문제를 수정했습니다. 기존에는 이 손상 상태 때문에 해당 파트에 대한 쿼리에서 프로젝션 최적화가 비활성화되었습니다. [#106273](https://github.com/ClickHouse/ClickHouse/pull/106273) ([tiandiwonder](https://github.com/tiandiwonder)).
* `system.warnings`의 메모리/CPU/뮤테이션 과부하 경고가 비동기 메트릭 사이클보다 한 사이클씩 늦게 반영되고 첫 번째 사이클에서는 아예 표시되지 않던 문제를 수정했습니다. [#108035](https://github.com/ClickHouse/ClickHouse/pull/108035) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 실험적 설정 `make_distributed_plan = 1`을 사용한 상태에서 `Distributed` 테이블이나 뷰를 기반으로 하는 `Merge` 테이블을 쿼리할 때 발생하던 `LOGICAL_ERROR` 예외(`ScatterExchangeStep should have one source shard, got 8`)와 행 중복 문제를 수정했습니다. [#108401](https://github.com/ClickHouse/ClickHouse/pull/108401) ([groeneai](https://github.com/groeneai)).
* `Nullable(Tuple(...))` 컬럼 내 널을 허용하지 않는 `LowCardinality` 요소를 서브컬럼으로(예: 정렬 키로) 사용할 때, 머지 도중 서버가 중단되거나(`Sort order of blocks violated`) 잘못된 읽기가 발생하던 문제를 수정했습니다. [#108679](https://github.com/ClickHouse/ClickHouse/pull/108679) ([groeneai](https://github.com/groeneai)).
* 계정 키가 유효한 Base64가 아닐 때 `azureBlobStorage()`(및 관련 Azure 테이블 함수/저장소)를 통해 벤더링된 Azure SDK의 `Base64Decode`에서 크래시가 발생하던 문제를 수정했습니다. `>= 0x80`인 바이트는 디코드 테이블의 범위를 벗어난 읽기를 일으켰고, 유효하지 않은 바이트는 모두 음수 값에 대한 정의되지 않은 왼쪽 시프트(새니타이저 환경에서 중단)를 일으켰습니다. 이제 유효하지 않은 키는 정상적으로 거부됩니다. [#108716](https://github.com/ClickHouse/ClickHouse/pull/108716) ([groeneai](https://github.com/groeneai)).
* 이전에 수행된 동일한 작업이 중단되어(예: 트랜잭션 롤백 또는 크래시) 오래된 `tmp_empty_<part>` 디렉터리가 남아 있는 상태에서 MergeTree 테이블에 `DROP`/`DETACH`/`MOVE`/`REPLACE PARTITION`을 실행하면, 디버그 및 새니타이저 빌드에서 서버가 중단될 수 있는 `LOGICAL_ERROR`("New empty part is about to materialize but the directory already exist")가 발생하던 문제를 수정했습니다. 이제 실패하는 대신 오래된 디렉터리를 회수합니다. [#108879](https://github.com/ClickHouse/ClickHouse/pull/108879) ([groeneai](https://github.com/groeneai)).
* 와이드 파트(wide part)에서 컬럼의 `TTL`이 만료된 후 프로젝션이 컬럼의 DDL `DEFAULT`(예: `-1`) 대신 타입 기본값(예: `0`)을 반환하던 문제를 수정했습니다. [#109013](https://github.com/ClickHouse/ClickHouse/pull/109013) ([tiandiwonder](https://github.com/tiandiwonder)).
* 사용자 정의 `disk` 설정(`SETTINGS disk = disk(...)`)으로 생성된 `MergeTree` 테이블에서 `ALTER` 쿼리가 실패하던 문제를 수정했습니다. [#109199](https://github.com/ClickHouse/ClickHouse/pull/109199) ([Michicosun](https://github.com/Michicosun)).
* `Merge` 테이블을 통해 `MaterializedPostgreSQL` 데이터베이스의 테이블을 읽을 때 오래된 행과 삭제된 행이 나타나던 문제를 수정했습니다. [#109339](https://github.com/ClickHouse/ClickHouse/pull/109339) ([vdimir](https://github.com/vdimir)).
* 값이 `Int32` 범위를 벗어나는 `BIGINT` 컬럼으로 파티셔닝된 Paimon 테이블을 읽지 못하던 문제를 수정했습니다. 이러한 파티션 값이 잘리면서(예: `9223372036854775807`이 `-1`로 변환됨) 잘못된 파티션 경로가 생성되어 파일 시스템 오류가 발생했습니다. [#109510](https://github.com/ClickHouse/ClickHouse/pull/109510) ([groeneai](https://github.com/groeneai)).
* 하위 테이블에 기존 컬럼 하나만으로 필터를 구성한 row policy(예: `CREATE ROW POLICY ... USING flag`)가 있는 `Merge` 테이블을 읽을 때 발생하던 논리 오류("Cannot determine row level filter; 0 columns deleted, 0 columns added")를 수정했습니다. [#109843](https://github.com/ClickHouse/ClickHouse/pull/109843) ([groeneai](https://github.com/groeneai)).
* IcebergLocal이 저장소 유형을 Azure로 보고하던 문제를 수정했습니다. [#109872](https://github.com/ClickHouse/ClickHouse/pull/109872) ([PedroTadim](https://github.com/PedroTadim)).
* 이제 `CHECK TABLE`은 메타데이터 로드에 실패한 프로젝션 파트에 대해 오해를 일으키는 `Columns doesn't match ... Expected: 0 columns` 오류 대신 실제 손상 내용을 보고합니다. [#110262](https://github.com/ClickHouse/ClickHouse/pull/110262) ([Algunenano](https://github.com/Algunenano)).
* 남아 있는 `txn_version.txt.tmp` 파일의 디스크 수준 메타데이터가 손상된 경우 객체 스토리지 디스크의 `MergeTree` 테이블 때문에 서버 시작이 실패하던 문제를 수정했습니다. [#110519](https://github.com/ClickHouse/ClickHouse/pull/110519) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `_part_offset` 또는 커밋 순서 프로젝션이 있는 MergeTree 테이블에서 `allow_part_offset_column_in_projections` 또는 `allow_commit_order_projection`을 비활성화한 뒤 테이블을 분리(detach)하거나 서버를 재시작하면 테이블을 영구적으로 ATTACH할 수 없게 되던 문제를 수정했습니다. 이 두 설정은 CREATE 시점에만 확인하는 조건이므로 이제 ATTACH 시에는 다시 검사하지 않습니다. [#110570](https://github.com/ClickHouse/ClickHouse/pull/110570) ([groeneai](https://github.com/groeneai)).
* `ReplicatedMergeTree`에서 두 개의 파티션 작업(예: 두 개의 `MOVE PARTITION` / `REPLACE PARTITION` 쿼리, 또는 백그라운드 `DROP_RANGE`와 경합하는 쿼리 하나)이 겹치는 범위에 대한 백그라운드 파트 검사를 동시에 취소할 때 서버를 중단시킬 수 있던 드문 `LOGICAL_ERROR`("Unexpected number of parts to remove from parts\_queue")를 수정했습니다. [#110738](https://github.com/ClickHouse/ClickHouse/pull/110738) ([groeneai](https://github.com/groeneai)).
* `Quantized(...)` 코덱을 사용하는 컬럼이 풀링 가능한 직렬화 내부에 중첩된 경우(예: 이름이 같은 컬럼의 타입이 소스마다 달라 `Variant`로 병합되는 `Merge` 테이블) 발생할 수 있던 `Hash is not set for serialization` 논리 오류를 수정했습니다. [#110776](https://github.com/ClickHouse/ClickHouse/pull/110776) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/110936) ([groeneai](https://github.com/groeneai)).
* 단일 컬럼 `MergeTree` 테이블의 유일한 컬럼에 완전히 만료되는 컬럼 `TTL`이 설정된 경우(`min_bytes_for_wide_part = 1`) 머지 중에 발생하던 논리 오류 `Cannot calculate columns sizes when columns or checksums are not initialized`를 수정했습니다. [#111169](https://github.com/ClickHouse/ClickHouse/pull/111169) ([groeneai](https://github.com/groeneai)).
* `min_rows_to_fsync_after_merge` / `min_compressed_bytes_to_fsync_after_merge` / `fsync_part_directory`가 설정된 경우, 머지되었거나 구체화된 파트의 텍스트 인덱스 파일도 fsync하도록 했습니다. 이전에는 파트 내에서 이 파일들만 동기화되지 않았기 때문에, 머지 직후 전원이 차단되면 커밋은 되었지만 손상된 파트가 남아 데이터 손실이 발생할 수 있었습니다. [#111335](https://github.com/ClickHouse/ClickHouse/pull/111335) ([groeneai](https://github.com/groeneai)).
* 매니페스트 파티션 튜플이 파티션 스펙과 일치하지 않을 때 `Iceberg` 테이블에서 `OPTIMIZE TABLE ... MANIFEST`가 올바르게 동작하지 않던 문제를 수정했습니다. [#111368](https://github.com/ClickHouse/ClickHouse/pull/111368) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
* 여러 개의 `text` 인덱스가 있는 `MergeTree` 테이블에서 텍스트 인덱스 직접 읽기 최적화가 읽기 헤더에 사용되지 않는 인덱스 가상 컬럼을 남기는 경우, 지연 머티리얼라이즈 최적화에서 발생하던 범위 밖 읽기(릴리스 빌드) / 논리 오류(debug 빌드)와 `Merge` 테이블의 `Pipe::unitePipes`에서 발생하던 논리 오류를 수정했습니다. [#111467](https://github.com/ClickHouse/ClickHouse/pull/111467) ([groeneai](https://github.com/groeneai)).
* `part_minmax_index_columns`를 낮춘 후(예: `with_block_number_offset`에서 `partition_key_only`로 되돌린 경우) debug/새니타이저 빌드에서 백그라운드 머지를 중단시킬 수 있던 `LOGICAL_ERROR`("Part level Min-Max index was constructed from unexpected columns set")를 수정했습니다. [#111511](https://github.com/ClickHouse/ClickHouse/pull/111511) ([groeneai](https://github.com/groeneai)).
* 파티션이 2개 이상이고 행 정책(row policy)이 정의된 테이블에서 `STREAM` 읽기(`enable_streaming_queries = 1`)를 실행할 때 발생하던 크래시를 수정했습니다. debug 및 새니타이저 빌드에서는 `Filter column ... not found in DAG outputs` 논리 오류로 실패했고, 릴리스 빌드에서는 세그폴트가 발생할 수 있었습니다. [#111572](https://github.com/ClickHouse/ClickHouse/pull/111572) ([groeneai](https://github.com/groeneai)).
* 현재 설정에서 다형성 파트가 비활성화된 상태(비적응형 세분화 수준)에서 `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 및 새니타이저 빌드에서는 이 예외로 인해 서버가 중단됩니다. [#111626](https://github.com/ClickHouse/ClickHouse/pull/111626) ([groeneai](https://github.com/groeneai)).
* `fsync_part_directory = 1`인 경우, 이제 상위 디렉터리(상위 디렉터리 간 이동 시에는 원본 상위 디렉터리까지)를 fsync하여 파트 디렉터리 이름을 임시 이름에서 최종 이름으로 변경하는 작업 자체의 영속성도 보장합니다. 이전에는 이동된 디렉터리만 fsync되었기 때문에, 파트가 커밋된 직후 전원이 차단되면 파일이 이미 기록되었는데도 디스크에서 파트가 누락될 수 있었고, 그 결과 해당 설정을 활성화했더라도 행이 손실될 수 있었습니다. [#111861](https://github.com/ClickHouse/ClickHouse/pull/111861) ([groeneai](https://github.com/groeneai)).
* `MergeTree` 테이블에서 `Nullable(Tuple(...))` 컬럼을 NULL 정보를 담는 요소 하위 컬럼(`Variant`, `Dynamic` 또는 `LowCardinality`) 중 하나와 함께 조회할 때 잘못된 결과와 `LOGICAL_ERROR`가 발생하던 문제를 수정했습니다. 하위 컬럼을 읽는 과정에서 상위 튜플에서 `NULL`인 행을 서브스트림 캐시를 통해 이미 공유된 컬럼에 `NULL`로 표시했기 때문에, 전체 컬럼을 읽을 때 값이 밀린 상태로 읽혔습니다. [#111949](https://github.com/ClickHouse/ClickHouse/pull/111949) ([groeneai](https://github.com/groeneai)).
* 자동 디스크 스필(spill-to-disk) 임계값이 설정된 경우(26.5부터 기본값) 해시 조인에서 빌드 이후 최적화(고정 해시 테이블로의 변환, 공유 런타임 필터, 오른쪽 테이블 범위 재조정)가 적용되지 않던 문제를 수정했습니다. [#111972](https://github.com/ClickHouse/ClickHouse/pull/111972) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `text_index_posting_list_apply_mode = 'lazy'`일 때 `simdcomp`를 사용하지 않는 빌드(x86\_64 Linux를 제외한 모든 대상, 예: aarch64)에서 `hasAllTokens` 및 기타 다중 토큰 `text` 인덱스 검색이 잘못된 결과(행이 경고 없이 누락됨)를 반환하던 문제를 수정했습니다. 이식 가능한(portable) 비트 패킹 디코더가 비트 폭이 0인 블록에 대해 디코딩된 0 값을 기록하지 않아, 단일 포스팅 세그먼트에 있는 포스팅이 누락되었습니다. 디스크 저장 형식은 변경되지 않았으며, 수정 후에는 기존 데이터도 올바르게 읽힙니다. [#112178](https://github.com/ClickHouse/ClickHouse/pull/112178) ([groeneai](https://github.com/groeneai)).
* 이제 손상된 MergeTree 통계가 로드되면 오류를 무시하지 않고 작업이 실패합니다. [#112201](https://github.com/ClickHouse/ClickHouse/pull/112201) ([skuznetsov-clickhouse](https://github.com/skuznetsov-clickhouse)).
* HDFS에서 확인 응답된 Iceberg 쓰기가 경고 없이 손실되던 문제를 수정했습니다. Iceberg 커밋은 새 메타데이터 파일마다 조건부 쓰기로 게시하지만, `HDFSObjectStorage`가 조건을 무시하고 단순 덮어쓰기를 수행했습니다. 이 때문에 동시에 쓰는 writer가 모두 확인 응답을 받았음에도 그중 한 writer의 스냅샷에는 접근할 수 없게 되었습니다. 이제 HDFS는 조건부 쓰기를 거부하므로, 명시적 컬럼 목록이 포함된 `CREATE TABLE ... ENGINE = IcebergHDFS(...)`를 비롯하여 HDFS에서 저장소가 관리하는 Iceberg 쓰기는 실패합니다. 읽기에는 영향이 없습니다. [#112437](https://github.com/ClickHouse/ClickHouse/pull/112437) ([groeneai](https://github.com/groeneai)).
* `KeeperMap` 테이블에 대한 `DELETE`가 일치하는 행 중 처음 `max_block_size`개만 삭제하면서도 뮤테이션이 성공적으로 완료되었다고 보고하던 문제를 수정했습니다. 또한 `keeper_map_strict_mode = 1`인 `DELETE`가 원자적으로 동작하지 않던 문제도 수정했습니다. 기존에는 버전 없는 삭제로 대체되어 동시에 업데이트된 행이 삭제될 수 있었고, 일치하는 행을 블록 단위로 적용했기 때문에 충돌이 발생하면 삭제가 일부만 적용될 수 있었습니다. [#112777](https://github.com/ClickHouse/ClickHouse/pull/112777) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 읽기 또는 머지 경로에서 발생한 일시적인 Azure blob storage 오류(RBAC 권한 전파 중 발생한 `403 Forbidden`, 자격 증명 인증 실패, `408`로 나타나는 연결 시간 초과)가 재시도 불가능한 오류로 잘못 분류되어 `POTENTIALLY_BROKEN_DATA_PART`(Code 740)로 보고되고, 정상 파트에 대해 잘못된 심각 경보가 발생하던 문제를 수정했습니다. 이제 이러한 일시적 실패는 재시도 가능한 오류로 처리되며, 실제로 지속되는 실패는 존재하지 않는 손상 데이터 파트가 아닌 일반 Azure 오류로 표시됩니다. [#112871](https://github.com/ClickHouse/ClickHouse/pull/112871) ([arsenmuk](https://github.com/arsenmuk)).
* 접두사가 붙은 엔드포인트를 사용하는 Azure blob storage 디스크에서 `listObjects`가 첫 페이지 이후의 모든 페이지에서 잘못된 blob 이름을 반환하던 문제를 수정했습니다. 페이지네이션 과정에서 엔드포인트 접두사를 제거하는 클라이언트 래퍼를 우회한 것이 원인이었습니다. 이제 페이지네이션은 연속 토큰(continuation token)을 통해 래퍼를 다시 거치므로 모든 페이지에서 올바른 blob 이름이 반환됩니다. [#112872](https://github.com/ClickHouse/ClickHouse/pull/112872) ([arsenmuk](https://github.com/arsenmuk)).
* 파트 전체를 다시 쓰지 않는 뮤테이션으로 생성된 파트에서, 테이블을 다시 로드한 후 `_block_number` 및 `_block_offset`에 대한 파트별 MinMax 인덱스가 손실되던 문제를 수정했습니다. [#112878](https://github.com/ClickHouse/ClickHouse/pull/112878) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 뮤테이션 조건식에서 명시적 데이터베이스 이름 없이 `merge` 테이블 함수를 사용하면 예외(릴리스 빌드에서는 서버 시작을 막는 오류)가 발생하던 문제를 수정했습니다. 이제 테이블 이름과 마찬가지로 뮤테이션이 적용된 테이블의 데이터베이스가 사용됩니다. [#113185](https://github.com/ClickHouse/ClickHouse/pull/113185) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `share_nested_offsets = 1`인 `MergeTree` 테이블에서 삭제 후 다시 추가된 `Nested` 멤버의 서브컬럼을 같은 그룹의 기존 멤버와 함께 읽을 때 잘못된 결과가 반환되거나 `LOGICAL_ERROR`가 발생하던 문제를 수정했습니다. 읽기 범위가 2개 이상의 블록에 걸치면 기존 멤버가 이후 블록의 값을 반환했습니다. [#113225](https://github.com/ClickHouse/ClickHouse/pull/113225) ([groeneai](https://github.com/groeneai)).
* `max_streams_to_max_threads_ratio`가 매우 큰 상태에서 `Merge` 테이블을 읽을 때 디버그 및 새니타이저 빌드에서 산술 예외가 발생하던 문제를 수정했습니다. 스트림 수가 32비트로 잘려 `2^32`의 배수가 0이 되는 것이 원인이었습니다. 또한 `Merge` 테이블의 스트림 수를 곱한 값이 `size_t`를 초과하면 정의되지 않은 동작 대신 `PARAMETER_OUT_OF_BOUND`를 발생시키고, `MergeTree` 스트림 수를 데이터 양에 맞게 제한할 때 오버플로가 발생하지 않도록 했으며, 전체 소스 수가 65536을 초과하는 `Merge` 테이블 읽기는 거부하도록 했습니다. [#113382](https://github.com/ClickHouse/ClickHouse/pull/113382) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `hdfs` 디스크에 쓰기가 실패하던 문제를 수정했습니다. 생성된 객체 키에 중첩된 디렉터리 접두사가 포함되는데, 블롭 저장소와 달리 HDFS는 실제 디렉터리를 사용하며 파일 생성 시 누락된 상위 디렉터리를 자동으로 만들지 않기 때문에 `Parent directory doesn't exist` 오류가 발생했습니다. [#113396](https://github.com/ClickHouse/ClickHouse/pull/113396) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `remote`/`remoteSecure` 테이블 함수 또는 `Remote`/`RemoteSecure` 테이블 엔진에 존재하지 않는 명명된 컬렉션을 `key = value` 재정의와 함께 지정했을 때 엉뚱한 오류가 보고되던 문제를 수정했습니다. 이러한 호출은 별도의 알림 없이 위치 기반 호출로 다시 파싱되어 재정의가 데이터 표현식으로 분석되었고, 그 결과 관련 없는 대상을 가리키는 오류가 보고되었습니다(예: `remote(collection, database = merge(...))`에 대해 Function with name `merge` does not exist). 이제는 명명된 컬렉션이 없다는 오류가 보고됩니다. [#113510](https://github.com/ClickHouse/ClickHouse/pull/113510) ([groeneai](https://github.com/groeneai)).
* `merge_max_block_size_bytes`가 빈 컬럼의 `byteSize()`보다 작게 설정되었을 때 백그라운드 머지와 `OPTIMIZE`에서 무한 루프가 발생하던 문제를 수정했습니다. 빈 `LowCardinality` 컬럼에도 딕셔너리가 포함되어 있어 단 하나의 행도 머지되기 전에 바이트 제한에 도달할 수 있었고, 이 경우 머지가 빈 블록을 끝없이 생성하면서 CPU 코어 하나를 100% 점유하고 백그라운드 풀 슬롯을 해제하지 않았습니다. [#113585](https://github.com/ClickHouse/ClickHouse/pull/113585) ([groeneai](https://github.com/groeneai)).
* 테이블이 `serialization_info_version = 'basic'`을 사용할 때 Compact 파트의 뮤테이션 결과가 파트의 직렬화 정보가 메모리에 남아 있는지, 아니면 `serialization.json`에서 다시 로드되었는지에 따라 달라지던 문제를 수정했습니다. 이로 인해 `ReplicatedMergeTree`에서는 바이트 수준에서 동일한 원본 파트를 가진 두 레플리카가 서로 다른 뮤테이션 결과 파트를 기록했고, 뮤테이션이 `CHECKSUM_DOESNT_MATCH`로 실패했습니다. [#113588](https://github.com/ClickHouse/ClickHouse/pull/113588) ([groeneai](https://github.com/groeneai)).
* 대상 저장소에서 .lock 파일을 읽을 수 없을 때 Backup이 동시 백업이 진행 중이라고 잘못 보고하는 대신 실제 잠금 파일 접근 오류를 보고하도록 개선했습니다. [#113637](https://github.com/ClickHouse/ClickHouse/pull/113637) ([kirillshokhin](https://github.com/kirillshokhin)).
* `MergeTree` 테이블의 백그라운드 작업(통계 갱신, 파트 갱신, 오래된/예상치 못한 파트 로딩)과 테이블 소멸 간의 데이터 경쟁을 수정했습니다. [#113722](https://github.com/ClickHouse/ClickHouse/pull/113722) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 업데이트 대상 테이블의 데이터베이스가 세션의 데이터베이스와 다를 때 `UPDATE`와 경량 `DELETE`가 잘못된 테이블을 읽던 문제를 수정했습니다. 이제 뮤테이션의 표현식은 현재 데이터베이스를 암묵적으로 사용하는 `merge` 테이블 함수와 한정되지 않은 테이블 식별자 모두에 대해 업데이트 대상 테이블의 데이터베이스를 기준으로 정규화됩니다. 이전에는 이러한 이름이 세션의 데이터베이스를 기준으로 해석되어, 다른 테이블에서 선택된 행이 아무런 경고 없이 업데이트되거나 삭제되었습니다. [#113748](https://github.com/ClickHouse/ClickHouse/pull/113748) ([groeneai](https://github.com/groeneai)).
* 기본 키 범위 레이어 단위로 `MergeTree` 테이블을 읽을 때 특정 레이어가 빈 파이프를 생성하면 예외가 발생하던 문제를 수정했습니다. [#114177](https://github.com/ClickHouse/ClickHouse/pull/114177) ([alexey-milovidov](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/114405) ([groeneai](https://github.com/groeneai)).
* 뮤테이션 진행 중 테이블을 읽을 때 발생하던 문제를 수정했습니다. 이전에는 `MATERIALIZED` 컬럼이 오래된 값을 반환할 수 있었고, 이 컬럼을 업데이트된 컬럼과 함께 조회하면 오류가 발생할 수 있었습니다. [#114561](https://github.com/ClickHouse/ClickHouse/pull/114561) ([tiandiwonder](https://github.com/tiandiwonder)).
* `make_distributed_plan`을 활성화한 상태에서 내부에 집합 연산이 포함된 하위 테이블을 가진 `Merge` 테이블을 읽을 때 발생하던 논리 오류(`Block structure mismatch`)를 수정했습니다. [#114753](https://github.com/ClickHouse/ClickHouse/pull/114753) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 컴팩션을 구현하지 않은 엔진을 사용하는 객체 스토리지 테이블에서 `OPTIMIZE TABLE`을 실행하면 실제로는 아무 작업도 하지 않으면서 성공으로 보고되었습니다. 이제는 해당 구문을 지원하지 않는 다른 모든 엔진과 마찬가지로 오류를 발생시킵니다. 이 변경은 `DeltaLake`, `Paimon`, `Hudi` 및 일반 객체 스토리지 엔진(`S3`, `GCS`, `COSN`, `OSS`, `AzureBlobStorage`, `HDFS`, 객체 스토리지 기반 `URL`)에 적용되며, 컴팩션을 구현한 `Iceberg`는 영향을 받지 않습니다. [#114805](https://github.com/ClickHouse/ClickHouse/pull/114805) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/114980) ([groeneai](https://github.com/groeneai)).
* 경량 업데이트를 사용하는 테이블에서 발생하던 `Found patch part ... that intersects mutation with version ...`(`LOGICAL_ERROR`) 오류를 수정했습니다. 패치 파트를 머지하면 데이터 버전 범위가 기존 파트의 데이터 버전에 걸치는 패치가 생성될 수 있었습니다. 이러한 패치는 적용할 수도 건너뛸 수도 없어 해당 파티션에 대한 이후의 모든 작업이 실패하고 복제 큐가 멈췄습니다. 이제 이러한 머지는 할당되지 않습니다. [#115064](https://github.com/ClickHouse/ClickHouse/pull/115064) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Backup` 데이터베이스 엔진이 사용할 수 없게 된 백업(예: 파일이 삭제되었거나 기반 스토리지에 접근할 수 없는 경우)을 참조할 때 서버가 시작되지 않던 문제를 수정했습니다. 이제 서버 전체의 시작을 막는 대신 해당 데이터베이스를 테이블 없이 로드합니다. [#83188](https://github.com/ClickHouse/ClickHouse/pull/83188) ([orloffv](https://github.com/orloffv)).
* 디스크 용량 부족 오류 이후 로깅이 복구되지 않던 문제를 수정했습니다. 이전에는 로그 디스크가 가득 차면 ClickHouse가 실패 상태에 빠져 syslog에 오류 메시지를 끊임없이 쏟아냈으며(시간당 100GB 이상 기록될 수 있음), 디스크 공간이 확보된 후에도 복구되지 않았습니다. 이제 디스크 공간이 확보되면 서버를 재시작하지 않아도 로깅 시스템이 자동으로 복구됩니다. [#93127](https://github.com/ClickHouse/ClickHouse/pull/93127) ([jaehanbyun](https://github.com/jaehanbyun)).
* DeltaLake 스토리지의 스키마 방문자(schema visitor)에서 발생하던 크래시를 수정했습니다. [#97112](https://github.com/ClickHouse/ClickHouse/pull/97112) ([kssenii](https://github.com/kssenii)).

<h3 id="data-lake-and-external-storage-fixes">
  데이터 레이크 및 외부 저장소 관련 수정 사항
</h3>

* S3 멀티파트 업로드(예: `INSERT INTO ... hits_s3`)에서 일시적으로 발생하던 `Code: 499 ... InvalidPart` (`S3_ERROR`) 실패를 수정했습니다. MinIO는 `CompleteMultipartUpload` 시 방금 업로드된 파트를 잠시 누락된 것으로 보고할 수 있습니다. 이제 이 오류도 기존에 처리되던 `NoSuchKey`와 마찬가지로 `s3_max_unexpected_write_error_retries` 한도 내에서 재시도됩니다. [#109364](https://github.com/ClickHouse/ClickHouse/pull/109364) ([groeneai](https://github.com/groeneai)).
* 데이터 파일 형식이 `Parquet`가 아닌 Iceberg 테이블에서 `ALTER TABLE ... DELETE` 및 `ALTER TABLE ... UPDATE`를 실행하면, 서버가 비정상 종료되거나 테이블이 아무런 경고 없이 손상되는 대신 명확한 `NOT_IMPLEMENTED` 오류와 함께 거부됩니다. [#105893](https://github.com/ClickHouse/ClickHouse/pull/105893) ([groeneai](https://github.com/groeneai)).
* `file`, `s3`, `input` 등의 테이블 함수에서 `INSERT SELECT`를 수행할 때 동일한 소스 컬럼을 두 번 이상 선택하면 `Cannot add column ...: column with this name already exists` 오류가 발생하던 문제를 수정했습니다. [#105982](https://github.com/ClickHouse/ClickHouse/pull/105982) ([crakjie](https://github.com/crakjie)).
* HTTP 쿼리 문자열 매개변수로 전달된 민감한 값(예: `param_secret_key`/`param_aws_secret_access_key`와 같은 `param_*` 쿼리 매개변수 바인딩, `password` 매개변수, S3 방식의 `signature` 매개변수)이 더 이상 `system.text_log`나 OpenTelemetry 스팬에 그대로 기록되지 않습니다. 이제 `Request URI` 로그 줄에서는 민감한 정보로 보이는 이름을 가진 매개변수의 값을 `[HIDDEN]`으로 가립니다. [#108475](https://github.com/ClickHouse/ClickHouse/pull/108475) ([groeneai](https://github.com/groeneai)).
* `S3Queue` 및 `AzureQueue` 테이블 엔진의 `_etag` 가상 컬럼을 수정했습니다. 이 컬럼은 선언만 되어 있고 값이 채워지지 않아 `SELECT _etag`가 항상 빈 문자열을 반환했습니다. 이제 `S3` 엔진 및 `s3()` 테이블 함수와 마찬가지로 객체의 ETag를 반환합니다. [#108625](https://github.com/ClickHouse/ClickHouse/pull/108625) ([groeneai](https://github.com/groeneai)).
* S3 요청이 진행 중일 때 S3에서 읽거나 S3에 쓰는 쿼리가 취소되면(예: `KILL QUERY`), 이제 오해를 일으키는 네트워크/S3 오류 대신 취소로 보고됩니다. 특히 S3로의 백업 또는 복원이 취소되면 이제 `system.backups`에 `BACKUP_CANCELLED`/`RESTORE_CANCELLED`가 기록됩니다. [#108673](https://github.com/ClickHouse/ClickHouse/pull/108673) ([jkartseva](https://github.com/jkartseva)).
* `S3Queue` 테이블 엔진의 `_tags` 가상 컬럼을 수정했습니다. 이 컬럼은 선언만 되어 있고 값이 채워지지 않아 `SELECT _tags`가 항상 빈 맵을 반환했습니다. 이제 `S3` 엔진 및 `s3()` 테이블 함수와 마찬가지로 객체의 태그를 반환합니다. [#108676](https://github.com/ClickHouse/ClickHouse/pull/108676) ([groeneai](https://github.com/groeneai)).
* 데이터 레이크 카탈로그 데이터베이스에서 SHOW TABLES와 SELECT ... FROM system.tables가 서로 다른 결과를 반환하던 문제를 수정했습니다. 이제 ClickHouse가 읽을 수 없는 테이블은 양쪽 모두에서 일관되게 숨겨집니다. [#109273](https://github.com/ClickHouse/ClickHouse/pull/109273) ([SmitaRKulkarni](https://github.com/SmitaRKulkarni)).
* Delta Lake 테이블(`DeltaLakeLocal` / `deltaLake`)에 대한 `INSERT`가 싱크의 쓰기 시작 이후에 실패하면(예: 소스 쿼리가 삽입 도중 예외를 발생시키거나 쿼리가 취소된 경우) 서버가 중단되던 문제(릴리스 빌드에서는 데이터 파일이 경고 없이 마무리되지 않던 문제)를 수정했습니다. [#109328](https://github.com/ClickHouse/ClickHouse/pull/109328) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/109515) ([groeneai](https://github.com/groeneai)).
* `CREATE TABLE ... AS SELECT` 쿼리에서 스칼라 서브쿼리를 `s3` 테이블 함수의 URL 인수(또는 다른 테이블 함수의 인수)로 사용할 때 발생하던 `Host is empty in S3 URI` 오류를 수정했습니다. 이제 테이블 함수 인수에 포함된 스칼라 서브쿼리는 쿼리 분석 단계에서 평가됩니다. [#110254](https://github.com/ClickHouse/ClickHouse/pull/110254) ([CheSema](https://github.com/CheSema)).
* Iceberg 테이블에 `UPDATE ..., DELETE ...`와 같은 다중 명령 `ALTER`를 실행할 때 발생하던 논리 오류(debug/sanitizer 빌드에서는 서버 중단)를 수정했습니다. 이제 이러한 뮤테이션은 명확한 `NOT_IMPLEMENTED` 오류와 함께 거부됩니다. [#110347](https://github.com/ClickHouse/ClickHouse/pull/110347) ([groeneai](https://github.com/groeneai)).
* 초기 스키마에 중첩 필드(`Tuple`/`Array`/`Map`)가 포함된 Iceberg 테이블에서 `ALTER TABLE ... ADD COLUMN` 실행 후 중복된 필드 ID가 생성되던 문제를 수정했습니다. 이제 `last-column-id`에 중첩된 하위 필드까지 포함하여 할당된 최대 필드 ID가 기록되므로, 이후 추가되는 컬럼이 중첩 필드 ID를 재사용하지 않으며 읽기 작업도 더 이상 `ICEBERG_SPECIFICATION_VIOLATION`(`Duplicate field id`) 오류로 실패하지 않습니다. [#110884](https://github.com/ClickHouse/ClickHouse/pull/110884) ([groeneai](https://github.com/groeneai)).
* 테이블에 `ALTER TABLE ... ADD COLUMN` 실행 전후에 기록된 데이터 파일이 함께 존재하고 `optimize_move_to_prewhere`가 활성화되어 있을 때, Iceberg 테이블에 대한 `DELETE`/`UPDATE`가 엉뚱한 행을 경고 없이 삭제하던(또는 `NOT_FOUND_COLUMN_IN_BLOCK` 오류를 발생시키던) 문제를 수정했습니다. [#111693](https://github.com/ClickHouse/ClickHouse/pull/111693) ([groeneai](https://github.com/groeneai)).
* Iceberg 테이블에서 `ALTER TABLE ... EXECUTE expire_snapshots`를 실행한 후 보존된 스냅샷의 `system.iceberg_history` 내 `made_current_at` 값이 `1970-01-01`로 표시되던 문제를 수정했습니다. 또한 메타데이터에 `snapshot-log`가 없는 테이블에 대해 `system.iceberg_history`가 행을 반환하지 않던 문제도 수정했습니다. [#111781](https://github.com/ClickHouse/ClickHouse/pull/111781) ([groeneai](https://github.com/groeneai)).
* `MATERIALIZED VIEW`를 통해 Iceberg 테이블에 삽입할 때 발생하던 데이터 손상 문제를 수정했습니다. 데이터 파일이 대상 테이블의 현재 Iceberg 스키마가 아닌 `CREATE` 시점의 컬럼 타입을 기준으로 기록되었기 때문에, `DateTime` 값이 단순 Avro `int`로 저장되어 마이크로초 단위로 읽혔고, `DateTime64(0)` 또는 `DateTime64(9)`는 파일을 아예 다시 읽을 수 없었습니다. 이에 따라 대상 테이블의 Iceberg 스키마가 뷰에 선언된 컬럼보다 넓으면, 이제 `INSERT INTO <materialized view>`는 손상된 행을 기록하는 대신 `TYPE_MISMATCH` 오류를 발생시킵니다. [#112359](https://github.com/ClickHouse/ClickHouse/pull/112359) ([groeneai](https://github.com/groeneai)).
* 튜플 안에 튜플이 중첩된 스키마를 가진 Iceberg 테이블에 쓰기 작업을 할 때 발생하던 문제를 수정했습니다. 게시된 테이블 메타데이터에서 내부 튜플의 필드 이름이 위치 기반 이름 `1`, `2`, ...로 대체되어, 기본 `Parquet` 포맷에서는 `INSERT`가 `INCORRECT_DATA` 오류로 실패했고 `Avro` 포맷에서는 해당 컬럼을 다시 읽을 수 없었습니다. [#112480](https://github.com/ClickHouse/ClickHouse/pull/112480) ([groeneai](https://github.com/groeneai)).
* 두 쿼리가 동시에 같은 테이블 이름을 조회할 때 `Filesystem` 또는 `HDFS` 데이터베이스가 영구적으로 멈추는 교착 상태(deadlock)를 수정했습니다. 이 문제가 발생하면 해당 데이터베이스에 대한 이후의 모든 쿼리가 무기한 대기 상태가 되고 중단할 수도 없어, 복구하려면 서버를 재시작해야 했습니다. [#112495](https://github.com/ClickHouse/ClickHouse/pull/112495) ([groeneai](https://github.com/groeneai)).
* `WHERE` 프레디케이트의 `NOT` 아래에 delta-kernel 프레디케이트 변환기가 처리할 수 없는 하위 표현식이 있을 때 `DeltaLake` 테이블이 실제보다 적은 행을 반환하던 문제를 수정했습니다. 이제 이러한 하위 표현식은 하위 반복자(iterator)의 끝으로 처리되지 않고, 명시적인 알 수 없는 프레디케이트로 delta-kernel에 전달됩니다. 기존에는 이 때문에 상위 논리곱(conjunction)이 경고 없이 잘려 나갔습니다. [#112652](https://github.com/ClickHouse/ClickHouse/pull/112652) ([groeneai](https://github.com/groeneai)).
* `ALTER TABLE ... EXECUTE remove_orphan_files`가 Iceberg 테이블에서 사용 중인 `metadata/version-hint.text`를 삭제하던 문제를 수정했습니다. 연결 가능한 집합(reachable set)의 항목을 문자열 연결로 생성할 때 값 끝에 슬래시가 있다고 가정했지만 실제로는 슬래시가 붙지 않는 값이었기 때문에, 실제 힌트 파일이 연결 가능한 파일로 인식되지 않아 `older_than` 임계값보다 오래되면 삭제되었습니다. 그 결과 `iceberg_use_version_hint = 1`로 설정된 테이블은 아예 읽을 수 없게 되었습니다. [#113548](https://github.com/ClickHouse/ClickHouse/pull/113548) ([groeneai](https://github.com/groeneai)).
* `ALTER TABLE ... MODIFY COLUMN`으로 `Nullable`이 된 Iceberg 컬럼을 필터링할 때 발생하던 `LOGICAL_ERROR`를 수정했습니다. [#114521](https://github.com/ClickHouse/ClickHouse/pull/114521) ([groeneai](https://github.com/groeneai)).
* `ENGINE = URL(...)` 정의를 포함한 `ATTACH TABLE`이 URL 스킴에 따라 실제로 사용되는 엔진의 `TABLE ENGINE` 권한을 확인하지 않던 문제를 수정했습니다. 이로 인해 `TABLE ENGINE ON URL` 권한만 가진 사용자도 `File`, `S3`, `AzureBlobStorage` 또는 `HDFS` 기반 테이블을 ATTACH한 후 읽을 수 있었습니다. `CREATE TABLE`에서는 이러한 동작이 올바르게 거부됩니다. [#115914](https://github.com/ClickHouse/ClickHouse/pull/115914) ([groeneai](https://github.com/groeneai)).
* IPv4와 IPv6 주소를 모두 제공하지만 그중 한 가지 주소 체계만 라우팅 가능한 호스트에서 외부로 나가는 HTTP 요청(예: \`aiGenerate\`, \`url\` 테이블 함수, S3)이 \`No route to host\`로 실패하던 문제를 수정했습니다. 이제 HTTP 연결 풀은 첫 번째 주소가 네트워크 오류로 실패하면 첫 요청에서 곧바로 오류를 전파하지 않고, 확인된 다음 주소로 폴백합니다. [#103786](https://github.com/ClickHouse/ClickHouse/pull/103786) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `{key, value}` 두 필드로 구성된 레코드의 Avro `array`를 ClickHouse `Map` 컬럼으로 읽을 수 있도록 개선했습니다. 이는 Iceberg와 Spark가 문자열이 아닌 키를 가진 `MAP<K, V>`를 표현할 때 사용하는 인코딩입니다(Avro 네이티브 맵은 문자열 키만 지원합니다). 이전에는 이러한 파일을 `Array(Tuple(key, value))`로는 읽을 수 있었지만 `Map(K, V)`로 읽으면 `Type Map(...) is not compatible with Avro array` 오류가 발생했습니다. [#109289](https://github.com/ClickHouse/ClickHouse/pull/109289) ([groeneai](https://github.com/groeneai)).
* 버전 번호가 숫자로만 이루어져 있지만 32비트 정수 범위를 초과하는 메타데이터 파일(예: `v99999999999999999999.metadata.json`)이 있는 Iceberg 테이블을 읽을 때 발생하던 문제를 수정했습니다. 이전에는 이러한 이름에 대해 명확한 `BAD_ARGUMENTS` 오류 대신 원인을 파악하기 어려운 `std::out_of_range`(`STD_EXCEPTION`)가 발생했습니다. [#109619](https://github.com/ClickHouse/ClickHouse/pull/109619) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/109812) ([groeneai](https://github.com/groeneai)).
* 쓰기 형식이 `Avro`인 Iceberg 테이블에서 `"required": false`로 선언된 `list`, `map` 또는 `struct` 유형의 필드가 `["null", T]` union 없이 필수 필드로 직렬화되던 문제를 수정했습니다. 이로 인해 데이터 파일 자체의 스키마가 테이블 메타데이터와 일치하지 않았고, 다른 Iceberg 리더에서는 해당 필드를 필수 필드로 인식했습니다. 이제 이러한 필드는 Iceberg 사양에서 선택적 필드에 사용하는 `["null", T]` union으로 기록됩니다. [#112648](https://github.com/ClickHouse/ClickHouse/pull/112648) ([groeneai](https://github.com/groeneai)).
* Iceberg `snapshot-log`에 동일한 `snapshot-id`가 두 번 이상 나타날 때(롤백 후 이러한 상태가 됨) `system.iceberg_history`의 `made_current_at`이 스냅샷이 현재 스냅샷이 된 가장 최근 시각 대신 가장 이른 시각을 보고하던 문제를 수정했습니다. [#113598](https://github.com/ClickHouse/ClickHouse/pull/113598) ([groeneai](https://github.com/groeneai)).
* 명명된 컬렉션에 `http_client = 'gcp_oauth'`가 설정되어 있고 Google OAuth2 토큰 엔드포인트가 연결은 수락하지만 끝내 응답하지 않을 때, `BACKUP`/`RESTORE ... TO S3`, GCS 디스크 및 `s3` 테이블 함수가 최대 1시간 동안 멈추던 문제를 수정했습니다. 이제 Bearer 토큰 요청은 호출자의 데이터 전송 요청 타임아웃을 상속하지 않으며, STS `AssumeRole` 요청 상한과 마찬가지로 응답 대기 시간이 최대 10초로 제한됩니다. [#115531](https://github.com/ClickHouse/ClickHouse/pull/115531) ([groeneai](https://github.com/groeneai)).
* 백그라운드 캐시 다운로드가 `ErrnoException` 이외의 예외로 실패하면(예: Iceberg 테이블에 `OPTIMIZE`를 수행하는 중) 비어 있는 고아 캐시 파일이 남아, 파일 시스템 캐시에서 논리 오류(`Expected file ... not to exist`)가 발생할 수 있던 문제를 수정했습니다. [#110549](https://github.com/ClickHouse/ClickHouse/pull/110549) ([groeneai](https://github.com/groeneai)).
* 최대 엔트리 수 기준으로 설정된 캐시(`SLRU` 정책)가 그 개수만큼의 엔트리가 두 번 이상 접근된 이후로 새 엔트리를 아무런 경고 없이 더 이상 받아들이지 않던 문제를 수정했습니다. 영향을 받는 캐시는 Iceberg 및 Paimon 메타데이터 파일 캐시, Parquet 메타데이터 캐시, 텍스트 인덱스 캐시, 벡터 유사성 인덱스 캐시, 컴파일된 표현식 캐시, ObjectStorageQueue 파일 상태 캐시입니다. [#115517](https://github.com/ClickHouse/ClickHouse/pull/115517) ([groeneai](https://github.com/groeneai)).
* 변경 가능한 `snapshot/LATEST` 힌트가 동시에 교체되는 도중 Paimon 테이블 읽기가 실패할 수 있던 문제를 수정했습니다. 이제 유효하지 않거나 오래된 힌트가 있으면 안전하게 스냅샷 목록 조회로 폴백됩니다. [#112010](https://github.com/ClickHouse/ClickHouse/pull/112010) ([JiaQiTang98](https://github.com/JiaQiTang98)).
* 입력 버퍼(예: `restricted_seek = true`인 S3 읽기 버퍼)가 minizip이 요청한 seek 또는 읽기를 거부하여 zip 아카이브의 압축을 풀 수 없을 때, 근본 원인이 되는 실제 예외를 표시하도록 개선했습니다. 이전에는 실제 오류가 일반적인 `Couldn't unpack zip archive: Code = -100` / `Couldn't open zip archive` 메시지에 가려져 있었습니다. [#105103](https://github.com/ClickHouse/ClickHouse/pull/105103) ([groeneai](https://github.com/groeneai)).
* refs가 없는 메타데이터에서 Iceberg 쓰기가 제대로 동작하지 않던 문제를 수정했습니다 [#106896](https://github.com/ClickHouse/ClickHouse/pull/106896) ([AVMusorin](https://github.com/AVMusorin)).
* 외부 엔진이 생성한 메타데이터에 선택 항목인 `snapshots`, `metadata-log` 또는 `snapshot-log` 배열이 없는 Iceberg 테이블에 데이터를 삽입할 때 예외가 발생하던 문제를 수정했습니다. 이제 이러한 삽입이 실패하지 않고 정상적으로 완료됩니다. [#107473](https://github.com/ClickHouse/ClickHouse/pull/107473) ([tiandiwonder](https://github.com/tiandiwonder)).
* 일시적인 읽기 오류 후 S3 업로드(예: 백업)를 재시도할 때 발생할 수 있던 `ReadBuffer is canceled. Can't read from it.` 오류를 수정했습니다. [#108573](https://github.com/ClickHouse/ClickHouse/pull/108573) ([groeneai](https://github.com/groeneai)).
* 최종 비동기 S3/Azure 멀티파트 업로드 완료 작업의 스케줄링이 실패하면(예: 스레드 풀 고갈 시) `std::future_error`("The associated promise has been destructed prior to the associated state becoming ready")가 발생하고, debug/새니타이저 빌드에서는 서버가 비정상 종료될 수 있던 문제를 수정했습니다. 이제 실제 스케줄링 오류가 보고됩니다. [#108730](https://github.com/ClickHouse/ClickHouse/pull/108730) ([groeneai](https://github.com/groeneai)).
* 스케일이 9보다 작은 `DateTime64` 컬럼으로 약 2262년 이후의 ORC 타임스탬프를 읽을 때 발생하던 문제를 수정했습니다. 기존 네이티브 ORC 리더는 모든 타임스탬프를 고정된 `DateTime64(9)` 중간값을 거쳐 변환했는데, 이 방식은 나노초 스케일에서 `Int64` 오버플로우를 일으킵니다. 그 결과 요청된 `DateTime64` 스케일(예: Iceberg가 생성하는 `DateTime64(6)`)로 표현할 수 있는 값조차 `VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE` 오류와 함께 거부되었습니다. 이제 타임스탬프를 요청된 스케일로 직접 읽으며, 대상 스케일로도 값을 담을 수 없으면 `date_time_overflow_behavior` 설정을 따릅니다. [#109302](https://github.com/ClickHouse/ClickHouse/pull/109302) ([groeneai](https://github.com/groeneai)).
* 스키마에 지원되지 않는 중첩 유형(예: `ROW` 필드)이 포함된 Paimon 테이블을 읽으면, 이제 오류 코드 0에 메시지도 없는 `DB::Exception. (OK)` 대신 지원되지 않는 유형을 명시한 `BAD_ARGUMENTS` 오류를 명확하게 보고합니다. [#109762](https://github.com/ClickHouse/ClickHouse/pull/109762) ([groeneai](https://github.com/groeneai)).
* 동일한 원본 컬럼으로 두 번 이상 파티셔닝된 Iceberg 테이블(예: `PARTITIONED BY (hours(ts), ts)`)을 읽을 때 발생하던 문제를 수정했습니다. 이전에는 이러한 테이블을 읽으면 `Cannot add column ...: column with this name already exists (ILLEGAL_COLUMN)` 오류가 발생했습니다. [#109895](https://github.com/ClickHouse/ClickHouse/pull/109895) ([groeneai](https://github.com/groeneai)).
* 이제 ClickHouse가 Iceberg 테이블에 기록하는 데이터 파일은 Avro(`field-id`) 및 ORC(`iceberg.id`/`iceberg.required` 유형 속성) 포맷에서도 Iceberg 필드 ID를 포함하며, ORC `String` 컬럼은 바이너리가 아닌 ORC `string`으로 기록됩니다. 이전에는 Parquet만 필드 ID를 포함했기 때문에, 사양을 준수하는 리더(예: Spark/iceberg-java)는 컬럼 이름 변경 후 ClickHouse가 기록한 Avro 행에 대해 아무 경고 없이 NULL을 반환했고, ClickHouse가 기록한 ORC 파일은 아예 읽지 못했습니다. [#109994](https://github.com/ClickHouse/ClickHouse/pull/109994) ([groeneai](https://github.com/groeneai)).
* 모든 포지션 삭제 파일보다 최신인 Parquet 이외 포맷(예: `ORC`)의 데이터 파일이 포함된 Iceberg 테이블에서 `OPTIMIZE TABLE`을 실행할 때 발생하던 논리 오류 `ChunkInfoRowNumbers does not exist`를 수정했습니다. [#110107](https://github.com/ClickHouse/ClickHouse/pull/110107) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `s3` 및 `file`을 통해 압축되지 않은 `STORED` zip 항목에서 대용량 `Parquet` 파일을 읽을 때 발생하던 문제를 수정했습니다. [#110495](https://github.com/ClickHouse/ClickHouse/pull/110495) ([Gudauu](https://github.com/Gudauu)).
* 백그라운드 스케줄 풀(예: Global Thread 풀이 고갈된 상황에서의 `iceberg` 풀)을 시작하지 못하더라도 더 이상 서버가 중단되지 않으며, 해당 오류는 이제 복구 가능한 예외로 처리됩니다. 또한 `system.background_schedule_pool`을 조회해도 더 이상 부수 효과로 해당 풀이 생성되지 않습니다. [#111209](https://github.com/ClickHouse/ClickHouse/pull/111209) ([groeneai](https://github.com/groeneai)).
* Paimon REST 카탈로그의 DLF 인증 문제를 수정했습니다. 요청 서명을 한 번만 계산한 뒤 재사용했기 때문에 첫 요청 이후의 모든 카탈로그 요청이 HTTP 401로 실패했고, SHOW TABLES는 빈 목록을 반환했습니다. 테이블 존재 여부를 확인할 때 HTTP 404를 제대로 감지하지 못하던 문제도 함께 수정했습니다. [#112015](https://github.com/ClickHouse/ClickHouse/pull/112015) ([JiaQiTang98](https://github.com/JiaQiTang98)).
* 포지션 삭제로 인해 비어 버린 `Iceberg` 데이터 청크를 파티셔닝할 때(예: 데이터 파일이 완전히 삭제된 파티션 `Iceberg` 테이블을 컴팩션하는 경우) 발생하던 `LOGICAL_ERROR`(`partitions_count > 0`)를 수정했습니다. [#112432](https://github.com/ClickHouse/ClickHouse/pull/112432) ([PedroTadim](https://github.com/PedroTadim)).
* Azure 배치 객체 삭제 시 배치 요청 자체가 실패하면 `system.blob_storage_log`에 Delete 이벤트가 전혀 기록되지 않아 배치 전체가 로그에서 누락되던 문제를 수정했습니다. 이제 배치 수준에서 실패하면 각 객체마다 Delete 이벤트가 기록됩니다. [#112873](https://github.com/ClickHouse/ClickHouse/pull/112873) ([arsenmuk](https://github.com/arsenmuk)).
* 밀리초보다 높은 정밀도의 `TIMESTAMP` 컬럼으로 파티션된 `Paimon` 테이블을 읽을 때 `scale 6 is not supported, only support scale <= 3` 오류와 함께 실패하던 문제를 수정했습니다. [#113401](https://github.com/ClickHouse/ClickHouse/pull/113401) ([JiaQiTang98](https://github.com/JiaQiTang98)).
* 스키마에 이름이 비어 있는 컬럼이 선언된 데이터 레이크 테이블을 읽을 때 발생하던 크래시를 수정했습니다. 형식이 잘못된 Iceberg 메타데이터는 `ICEBERG_SPECIFICATION_VIOLATION`으로 거부되며, 카탈로그, Delta Lake 또는 Paimon에서 제공한 스키마는 `AMBIGUOUS_COLUMN_NAME`으로 거부됩니다. 이 검사는 조건 없이 항상 수행되므로, 필드 이름이 비어 있는 과거 스키마를 사용하지 않고 보유만 하고 있는 Iceberg 테이블도 해당 스키마를 읽는 시점에 비정상 종료되는 대신 읽을 수 없는 상태가 됩니다. [#114394](https://github.com/ClickHouse/ClickHouse/pull/114394) ([groeneai](https://github.com/groeneai)).
* Iceberg 사양에서 금지하는 스키마 진화(schema evolution)가 메타데이터에 기술된 Iceberg 테이블을 읽어도 더 이상 서버가 비정상 종료되지 않습니다. 기존에는 `IcebergSchemaProcessor`에서 발생하는 4가지 사양 위반이 실패한 어서션으로 취급되는 `LOGICAL_ERROR`로 보고되거나, 검사 없이 치명적인 어서션에 도달했습니다. 이제는 `ICEBERG_SPECIFICATION_VIOLATION`이 발생합니다. [#114518](https://github.com/ClickHouse/ClickHouse/pull/114518) ([groeneai](https://github.com/groeneai)).
* HTTP `Last-Modified` 헤더를 이식성 없는 방식으로 파싱하는 바람에 musl 기반 빌드에서 `url`/`urlCluster` 테이블 함수의 `_time` 가상 컬럼이 항상 `NULL`이 되던 문제를 수정했습니다. [#111619](https://github.com/ClickHouse/ClickHouse/pull/111619) ([thevar1able](https://github.com/thevar1able)).
* `allow_experimental_url_wildcard_from_index_pages`가 활성화된 상태에서 `CREATE TABLE ... AS url('http://host/**/', ...)`로 테이블을 생성하면 이후 서버가 시작되지 않던 문제를 수정했습니다. 이러한 테이블의 메타데이터를 로드할 때 Experimental 기능 검사가 다시 수행되어 `SUPPORT_IS_DISABLED`로 실패하면서 서버 시작이 중단되었습니다. [#115095](https://github.com/ClickHouse/ClickHouse/pull/115095) ([groeneai](https://github.com/groeneai)).
* `URL` 데이터베이스 엔진의 테이블이 더 이상 소스 읽기 권한이 없는 사용자에게 로컬 파일의 존재 여부를 노출하지 않습니다. `SHOW TABLES` 권한만 있으면 실행할 수 있는 `EXISTS TABLE`과 테이블 해석 과정 모두 이제 권한을 확인하기 전에는 파일 시스템을 조회하지 않습니다. [#113029](https://github.com/ClickHouse/ClickHouse/pull/113029) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Exception::addMessage`를 통해 추가되는 메시지에도 `query_masking_rules`를 적용하여, 마스킹 규칙이 구성된 경우 `jdbc()`/`odbc()` 오류의 `(in file/uri ...)` 접미사에 포함된 URL 인코딩된 자격 증명이 유출되지 않도록 했습니다. [#106916](https://github.com/ClickHouse/ClickHouse/pull/106916) ([gaurav0107](https://github.com/gaurav0107)).

<h3 id="formats-and-ingestion-fixes">
  포맷 및 수집 관련 수정 사항
</h3>

* Arrow `time32`/`time64`를 스키마 없이 읽을 때(예: `SELECT * FROM file(..., 'Arrow')`) 이제 `DateTime64` 대신 `Time64`로 추론합니다. 이전에는 `DateTime64`로 추론했습니다. 따라서 이전 추론 타입을 전제로 하는 다운스트림 작업은 업그레이드 후 정상적으로 동작하지 않습니다. 또한 `Time`/`Time64`를 Arrow로 내보내는 기능을 추가했으며, 정밀도에 따라 적절한 Apache Arrow 시간 타입이 선택됩니다. [#104316](https://github.com/ClickHouse/ClickHouse/pull/104316) ([Maoyao233](https://github.com/Maoyao233)).
* 지연 컬럼 복제(`enable_lazy_columns_replication`)가 적용된 상태에서 배치 처리 도중 발생한 오류로 `INSERT`가 롤백될 때(예: `Buffer` 테이블, 비동기 삽입(asynchronous inserts), `Kafka`/`RabbitMQ`/`FileLog` 엔진) 잘못된 결과가 반환되거나 범위를 벗어난 읽기가 발생할 수 있던 문제를 수정했습니다. [#108935](https://github.com/ClickHouse/ClickHouse/pull/108935) ([groeneai](https://github.com/groeneai)).
* `INSERT` 컬럼 목록에서 `t.* LIKE '<pattern>'` / `t.* ILIKE '<pattern>'` 형태의 한정 컬럼 매처는 허용하면서, 이와 동일한 정규 형태인 `t.COLUMNS('<regexp>')`는 거부하던 파서 불일치 문제를 수정했습니다. 이 문제로 쿼리 포맷 왕복 변환이 깨졌으며, debug/sanitizer 빌드에서는 서버가 비정상 종료되었습니다. [#109176](https://github.com/ClickHouse/ClickHouse/pull/109176) ([groeneai](https://github.com/groeneai)).
* ADLS Gen2(DFS) 쓰기를 `.blob` 호스트 대신 `.dfs` 엔드포인트 호스트로 라우팅하도록 변경하여, Microsoft Fabric / OneLake `DataLakeCatalog` 테이블에 대한 `INSERT`가 `IncorrectEndpointError`(HTTP 400)로 실패하던 문제를 수정했습니다. 참고: `remote_url_allow_hosts`를 사용하는 경우 `INSERT`를 수행하려면 `.blob`(읽기) 및 `.dfs`(쓰기) Fabric 호스트를 모두 허용 목록에 추가해야 합니다. [#110290](https://github.com/ClickHouse/ClickHouse/pull/110290) ([zlareb1](https://github.com/zlareb1)).
* 데이터 레이크 테이블 함수를 통해 쓰기를 수행할 때(예: `INSERT INTO FUNCTION icebergS3(...)`) 생성된 parquet 파일의 문자열 컬럼에서 `String` 타입 어노테이션이 누락되어, Spark 같은 외부 리더가 기록된 데이터를 읽지 못하던 문제를 수정했습니다. 이제 이러한 쓰기에도 테이블 엔진을 통한 쓰기와 동일한 포맷 설정이 적용됩니다. [#110465](https://github.com/ClickHouse/ClickHouse/pull/110465) ([tiandiwonder](https://github.com/tiandiwonder)).
* Arrow Flight로 로그인한 후 `system.session_log`를 읽을 수 없게 되던 문제를 수정했습니다. `interface` 컬럼은 `Enum8` 타입이지만 열거값에 `ArrowFlight`가 빠져 있어, Arrow Flight 프로토콜로 로그인하면 원시 값 `10`이 기록되었고 해당 행을 읽는 모든 `SELECT`에서 `Unexpected value 10 in enum` 예외가 발생했습니다. [#110758](https://github.com/ClickHouse/ClickHouse/pull/110758) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `TSV` 계열 포맷의 스키마 추론에서 `0.0`이나 `0.5`처럼 앞에 0이 붙은 소수 값을 `String`으로 추론하던 문제를 수정했습니다(`CSV`는 올바르게 `Float64`로 추론합니다). 또한 첫 번째 행이 이러한 값으로만 이루어진 경우 `TSV` 헤더 자동 감지가 해당 행을 헤더로 간주하여 결과에서 누락되는 문제도 있었습니다. 아울러 `TSKV`에서 `x=1\x2E5`처럼 이스케이프 시퀀스로 작성된 값을 숫자 유형으로 추론한 뒤 파싱에 실패하던 문제도 수정했습니다. 단, `007`처럼 앞의 0이 정수 패딩인 값은 `TSV` 값 파서가 다시 읽을 수 없으므로 계속 `String`으로 추론됩니다. [#112226](https://github.com/ClickHouse/ClickHouse/pull/112226) ([groeneai](https://github.com/groeneai)).
* 값 파서가 다시 읽을 수 없는 텍스트 값에 대해 스키마 추론이 숫자 타입을 제안하던 문제를 수정했습니다. 추론 과정에서는 불완전한 지수(`1e+`), 가수가 없는 값(`.`), 반복된 부호(`++inf`)를 허용했지만, 추론된 스키마로 데이터를 읽을 때 `readFloatTextPrecise`가 이를 `CANNOT_PARSE_NUMBER`로 거부했습니다. `Dynamic` 컬럼에서는 이 문제가 INSERT 시점의 오류로 나타났습니다. 이제 추론 시 리더가 실제로 사용하는 파서로 숫자를 검증합니다. 이에 따라 추론된 타입이 `max_read_buffer_size`에 따라 달라지던 경우도 없어졌으며, `0e5`처럼 앞자리가 0인 유효한 지수 형식이 CSV와 마찬가지로 TSV에서도 `Float64`로 추론됩니다. 잘못된 지수 형식 처리 문제도 함께 수정했습니다. [#112453](https://github.com/ClickHouse/ClickHouse/pull/112453) ([groeneai](https://github.com/groeneai)).
* 행 기반 입력 형식이 블록 하나를 파싱하는 동안 `KILL QUERY`와 `max_execution_time`이 수 분간 무시되던 문제를 수정했습니다. 이제 행 기반 입력 형식은 8192행마다 쿼리 취소 여부를 확인하므로, 종료된 삽입 작업(특히 블록당 최대 `max_insert_block_size`개의 행을 파싱하는 백그라운드 비동기 삽입 플러시)이 블록 끝까지 실행되지 않고 즉시 중단됩니다. [#112646](https://github.com/ClickHouse/ClickHouse/pull/112646) ([groeneai](https://github.com/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`에 누락되어 있던 캐시 키 getter를 등록하고, `Template` getter가 자체 행 포맷의 이스케이프 규칙을 사용하도록 수정했습니다. [#113533](https://github.com/ClickHouse/ClickHouse/pull/113533) ([groeneai](https://github.com/groeneai)).
* 상위 쿼리 끝에 `SETTINGS` 절이 있을 때 `view` 및 `viewIfPermitted` 테이블 함수의 서브쿼리 인수가 잘못 포맷되던 문제를 수정했습니다. 이러한 쿼리는 다시 파싱할 수 없는 `view((SELECT ...))` 형태로 포맷되어 내부 포맷-파싱-포맷 검사를 통과하지 못하고 `Inconsistent AST formatting` 오류가 발생했습니다. [#114658](https://github.com/ClickHouse/ClickHouse/pull/114658) ([groeneai](https://github.com/groeneai)).
* 포맷 자동 감지 시 JSON 데이터가 TSKV로 잘못 감지되던 문제를 수정했습니다. [#106009](https://github.com/ClickHouse/ClickHouse/pull/106009) ([Avogar](https://github.com/Avogar)).
* 유효한 시각 범위를 벗어난(음수 또는 `>= 24h`) `Time`/`Time64` 값을 `Arrow` 포맷으로 내보내면, 이제 잘못된 Arrow `time32`/`time64` 데이터를 기록하지 않고 명확한 오류를 반환합니다. [#107179](https://github.com/ClickHouse/ClickHouse/pull/107179) ([tiandiwonder](https://github.com/tiandiwonder)).
* 타임스탬프 컬럼의 시간대가 고정 숫자형 UTC 오프셋(예: `+05:30`, `-08:00`, `00:00`)이거나 IANA 형식이 아닌 마커 `fixed`로 지정된 `Arrow`, `ArrowStream` 및 Arrow 기반 `ORC` 파일을 읽을 때 `Cannot load time zone ...`(`BAD_ARGUMENTS`) 오류로 실패하던 문제를 수정했습니다. [#108633](https://github.com/ClickHouse/ClickHouse/pull/108633) ([groeneai](https://github.com/groeneai)).
* 이제 `Nullable(Tuple(...))` 컬럼을 여러 컬럼으로 평탄화하지 않고 단일 CSV 필드로 직렬화합니다. 이전에는 null이 아닌 값은 여러 CSV 필드로, `NULL`은 단일 `\N`으로 기록되어 행마다 컬럼 수가 달라졌고, 그 결과 `CSVWithNames`/`CSVWithNamesAndTypes` 헤더와 왕복 변환이 깨졌습니다. [#108959](https://github.com/ClickHouse/ClickHouse/pull/108959) ([groeneai](https://github.com/groeneai)).
* `MsgPack` 포맷의 스키마 추론 중 과도한 메모리 할당이 발생하던 문제를 수정했습니다. 배열/맵/문자열/바이너리 헤더에 매우 큰 원소 개수가 선언된, 손상되었거나 퍼징된 입력으로 인해 수 기가바이트에 달하는 단일 할당이 더 이상 발생하지 않으며, 이러한 입력은 이제 잘못된 형식의 입력으로 거부됩니다. 이로써 새니타이저 환경에서 발생하던 `allocation-size-too-big` 중단과 릴리스 빌드에서 발생하던 메모리 부족 문제가 해결되었습니다. [#109019](https://github.com/ClickHouse/ClickHouse/pull/109019) ([groeneai](https://github.com/groeneai)).
* `output_format_arrow_low_cardinality_as_dictionary = 1` 설정으로 `LowCardinality(Time)` 컬럼을 `Arrow` 포맷으로 쓸 때 발생하던 `LOGICAL_ERROR`를 수정했습니다. [#109730](https://github.com/ClickHouse/ClickHouse/pull/109730) ([groeneai](https://github.com/groeneai)).
* `Dynamic` 타입 개수 또는 `JSON`/`Object` 경로 개수가 `SIZE_MAX`에 가까운 손상된 `Native` 포맷 스트림을 읽을 때 발생하던 문제를 수정했습니다. 이러한 잘못된 형식의 입력은 이제 처리되지 않은 `std::length_error` 대신 명확한 `INCORRECT_DATA` 오류와 함께 거부됩니다. [#110590](https://github.com/ClickHouse/ClickHouse/pull/110590) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이전(버전 0) 상태 포맷으로 직렬화된 `Bool` 값을 가진 `sumMap`/`sumMapWithOverflow`/`sumMapFiltered` 집계 상태를 병합할 때 발생하던 `LOGICAL_ERROR: Cannot sum Bools`(디버그/새니타이저 빌드에서는 서버 중단)를 수정했습니다. 이번 수정으로 버전 0 `Bool` 상태에서 오류 없이 잘못된 결과가 반환되던 두 가지 문제도 함께 해결되었습니다. `Bool` 타입의 맵 키가 상태 간에 중복 제거되지 않던 문제와, 0 값 압축 과정에서 엉뚱한 항목이 삭제되던 문제입니다. [#110922](https://github.com/ClickHouse/ClickHouse/pull/110922) ([groeneai](https://github.com/groeneai)).
* 입력 데이터를 파싱한 결과 행이 0개일 때(예: 빈 JSON 또는 피처가 없는 GeoJSON `FeatureCollection`) `format` 테이블 함수에서 `NOT_FOUND_COLUMN_IN_BLOCK`이 발생하던 문제를 수정했습니다. 이제 올바른 컬럼으로 구성된 빈 결과를 반환합니다. [#111428](https://github.com/ClickHouse/ClickHouse/pull/111428) ([groeneai](https://github.com/groeneai)).
* 이제 WKT로 인코딩된 지오메트리 컬럼에 대문자가 아닌 타입 키워드(`point(1 2)`)나 빈 컨테이너(`LINESTRING EMPTY`, `POLYGON()`, `POLYGON(())`)가 사용된 GeoParquet, Arrow, ArrowStream 파일도 읽을 수 있습니다. 이전에는 동일한 문자열을 `readWKT` 함수로는 파싱할 수 있었음에도 이러한 파일을 가져올 때 `BAD_ARGUMENTS` 또는 `CANNOT_PARSE_NUMBER` 오류가 발생했습니다. 또한 빈 지오메트리에 대한 `wkt` 출력(`LINESTRING()`으로 표기됨)을 저장한 파일을 다시 읽지 못하던 문제도 함께 수정되었습니다. [#112020](https://github.com/ClickHouse/ClickHouse/pull/112020) ([groeneai](https://github.com/groeneai)).
* `auto` 및 `none` 압축 힌트를 전부 소문자가 아닌 형태로 작성하면(예: `file('data.csv.gz', 'CSV', 'x String', 'AUTO')`) `Unknown compression method`가 발생하던 문제를 수정했습니다. `GZIP` 등의 코덱 이름은 이미 대소문자 구분 없이 허용되었으며, 이제 이 두 특수 힌트도 동일하게 동작합니다. [#113631](https://github.com/ClickHouse/ClickHouse/pull/113631) ([groeneai](https://github.com/groeneai)).
* `CSV` 이스케이프 규칙을 사용하는 `CustomSeparated`, `Regexp`, `Template` 포맷에서 첫 번째 원소가 `NULL`인 `Tuple` 컬럼을 읽을 때 발생하던 문제를 수정했습니다. 이러한 포맷에서 단독 `Tuple`은 원소마다 필드 하나를 차지하므로, 맨 앞의 `\N` 필드는 컬럼 전체가 아니라 해당 원소를 나타냅니다. 이전에는 이 필드가 컬럼 전체로 처리되어 나머지 원소 필드가 뒤따르는 컬럼으로 밀려났고, 그 결과 `CustomSeparated`가 자신의 출력을 다시 읽지 못했습니다. [#114471](https://github.com/ClickHouse/ClickHouse/pull/114471) ([groeneai](https://github.com/groeneai)).
* `Regexp` 입력 형식이 일치한 필드에서 파싱되지 않은 나머지 부분을 아무런 알림 없이 버려, 오류를 보고하는 대신 잘리거나 엉뚱한 값을 저장하던 문제를 수정했습니다. 예를 들어 `JSON` 규칙에서 `v=-1`을 `UInt64`로 읽으면 `0`이, `v=2020-01-01junk`를 `Date`로 읽으면 `1975-07-14`가 저장되었습니다. 이제 `Escaped`, `CSV`, `JSON` 규칙에서는 잘못된 형식의 필드를 거부하며, 이는 각 규칙의 기준으로 문서화된 포맷의 동작과 일치합니다. `Raw` 규칙에서는 탭이 포함된 일치 필드를 탭 위치에서 자르지 않고 전체를 읽습니다. [#114520](https://github.com/ClickHouse/ClickHouse/pull/114520) ([groeneai](https://github.com/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` 논리 오류(디버그 및 새니타이저 빌드에서 서버 중단)를 수정했습니다. [#109175](https://github.com/ClickHouse/ClickHouse/pull/109175) ([groeneai](https://github.com/groeneai)).
* 포맷 수준의 키 조건이 Parquet 파일에서 읽지 않는 컬럼을 참조할 때 Parquet v3 리더에서 발생하던 논리 오류(`Logical error: 'KeyCondition uses PREWHERE output'`)를 수정했습니다. [#109267](https://github.com/ClickHouse/ClickHouse/pull/109267) ([groeneai](https://github.com/groeneai)).
* 헤더가 없을 때 사전 정의된 HTTP 핸들러에서 발생하던 예외를 수정했습니다. [#108324](https://github.com/ClickHouse/ClickHouse/pull/108324) ([vitlibar](https://github.com/vitlibar)).
* 행 기반 입력 형식(예: `TSV`/`CSV`)이 입력 파싱에 실패했는데 하위 읽기 작업이 이미 취소된 경우(예: 잘못된 HTTP 청크 또는 잘린 본문) 발생할 수 있던 `Logical error: 'ReadBuffer is canceled. Can't read from it.'`를 수정했습니다. 이제 상세 파싱 진단 정보를 생성할 때 취소된 버퍼에서 읽지 않습니다. [#109708](https://github.com/ClickHouse/ClickHouse/pull/109708) ([groeneai](https://github.com/groeneai)).
* 스트리밍 파싱이 SQL 표현식 파싱으로 정상 폴백되는 경우, `Values` 포맷이 더 이상 `system.errors` 및 `system.error_log`에 파싱 오류를 기록하지 않습니다. [#111141](https://github.com/ClickHouse/ClickHouse/pull/111141) ([pamarcos](https://github.com/pamarcos)).
* 중지된 `RabbitMQ` 테이블에서 `SYSTEM REFRESH`가 대기 중인 백로그를 간헐적으로 소비하지 못하던 문제를 수정했습니다. REFRESH는 순서와 무관한 스트리밍 사이클을 정확히 한 번만 허용하는데, AMQP 전달 루프가 막 비동기로 시작된 상태여서 해당 사이클이 0개의 행으로 즉시 반환될 수 있었습니다. 그 결과 단 한 번의 기회가 낭비되어 다음 `SYSTEM START`까지 메시지가 소비되지 않은 채 남았습니다. [#111480](https://github.com/ClickHouse/ClickHouse/pull/111480) ([groeneai](https://github.com/groeneai)).
* `nats_stream`이 설정된 `NATS` 테이블이 NATS 서버 재시작 후 아무런 알림 없이 메시지를 전혀 소비하지 않던 문제를 수정했습니다. 이제 `DETACH TABLE` 및 `ATTACH TABLE`을 실행하지 않아도 `JetStream` subscription이 자동으로 다시 설정됩니다. [#112828](https://github.com/ClickHouse/ClickHouse/pull/112828) ([groeneai](https://github.com/groeneai)).
* 지나치게 큰 `kafka_num_consumers` 값을 지정하면 `Kafka` 테이블 엔진 내부에서 메모리 할당에 실패하는 대신 명확한 오류와 함께 거부합니다. 이전에는 `kafka_disable_num_consumers_limit`이 활성화된 상태에서 이러한 값을 지정하면 `std::length_error` 예외가 발생했습니다. [#114764](https://github.com/ClickHouse/ClickHouse/pull/114764) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Arrow Flight 서버: ADBC Flight SQL 드라이버 등 Go 기반 Flight 클라이언트가 전송하는, 패딩 없이 Base64로 인코딩된 `Basic` 인증 자격 증명을 허용합니다. 또한 `authorization` 헤더 형식이 잘못된 경우 일반적인 `Unexpected error in RPC handling` 대신 적절한 인증 오류를 반환합니다. [#115085](https://github.com/ClickHouse/ClickHouse/pull/115085) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Arrow Flight 서버: 사용자 이름/비밀번호 구분자가 누락된 잘못된 형식의 기본 인증 자격 증명을 거부하도록 수정했습니다. [#115347](https://github.com/ClickHouse/ClickHouse/pull/115347) ([alexey-milovidov](https://github.com/alexey-milovidov)).

<h3 id="data-type-function-and-serialization-fixes">
  데이터 타입, 함수 및 직렬화 관련 수정 사항
</h3>

* Wide 파트가 있는 테이블에서 `ALTER TABLE ... MODIFY COLUMN`으로 컬럼을 동적 서브컬럼을 갖는 타입으로 변경(예: `Variant`에서 `Dynamic`으로)한 후 해당 파트를 읽거나 병합할 때 발생하던 논리적 오류 `Stream <col>.variant_discr ... is not found`(디버그 및 새니타이저 빌드에서는 서버 중단)를 수정했습니다. [#110204](https://github.com/ClickHouse/ClickHouse/pull/110204) ([groeneai](https://github.com/groeneai)).
* 요소가 널을 허용하지 않는 `LowCardinality(T)`인 `Nullable(Tuple(...))` 컬럼의 서브컬럼을 읽으면서 같은 쿼리에서 상위 서브컬럼도 함께 읽을 때 발생하던 문제를 수정했습니다. Compact 파트에서는 추출된 서브컬럼이 `LowCardinality(Nullable(T))` 버퍼로 역직렬화된 뒤 그 하위 스트림이 상위 서브컬럼의 읽기와 공유되었기 때문에, 상위 서브컬럼이 잘못된 값을 반환하거나, 쿼리가 `Unexpected return type from assumeNotNull` 오류로 실패하거나, `string_view` 강화 어설션에 의해 서버가 종료되었습니다. [#112232](https://github.com/ClickHouse/ClickHouse/pull/112232) ([groeneai](https://github.com/groeneai)).
* 통계 기반 파트 프루닝이 인덱스 분석 중에 `IN`/`GLOBAL IN` 서브쿼리를 추측 실행하다가 해당 서브쿼리가 실패하면 `LOGICAL_ERROR` "Not-ready Set is passed as the second argument for function `globalNullIn`" 오류가 발생하고 쿼리의 실제 오류 메시지가 손실되던 문제를 수정했습니다. [#114121](https://github.com/ClickHouse/ClickHouse/pull/114121) ([groeneai](https://github.com/groeneai)).
* `Quantized('product', ...)` 코덱을 사용하는 컬럼의 `product_quantization_codebook` 서브컬럼을 읽을 때 발생하던 `Cannot read all data of type FixedString` 오류를 수정했습니다. 파트별 코드북은 모든 그래뉼의 데이터 뒤에 기록되므로 마크로 구분되지 않으며, 이 때문에 마크 범위가 파트의 마지막 마크보다 앞에서 끝나는 읽기에서는 코드북을 끝까지 읽지 못할 수 있었습니다. [#112818](https://github.com/ClickHouse/ClickHouse/pull/112818) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Dynamic` 컬럼 내부의 `Map` 값에서 `Map` 레이아웃이 파트 자체의 메타데이터와 맞지 않는 파트가 기록되지 않도록 했습니다. `map_serialization_version`만 다른 테이블들이 캐시된 직렬화 객체 하나를 공유했기 때문에, 메타데이터에는 `with_buckets`로 선언되어 있는데도 파트에는 `basic` Map 레이아웃이 적용될 수 있었고, 이후 해당 파트를 읽으면 `LOGICAL_ERROR: Stream ...buckets_info ... is not found` 오류로 실패했습니다. 이전 버전에서 이미 이렇게 기록된 파트는 여전히 읽을 수 없으므로 삭제해야 합니다. [#113514](https://github.com/ClickHouse/ClickHouse/pull/113514) ([groeneai](https://github.com/groeneai)).
* `ALP`, `FPC`, `GCD`가 타입에서 파생된 파라미터를 코덱 해시에 포함하지 않던 문제를 수정했습니다. Compact 파트에서 writer는 서로 다른 코덱 해시마다 압축 스트림 하나를 공유하므로, 같은 코덱을 사용하지만 값 너비가 다른 두 컬럼이 충돌하여 잘못된 너비를 가진 코덱 객체 하나를 공유하게 되었습니다. 이로 인해 너비가 맞지 않으면 유효한 삽입이 `CANNOT_COMPRESS` 오류로 거부되었고, 그렇지 않더라도 두 컬럼 중 하나가 본래보다 비효율적으로 압축되었습니다. [#114189](https://github.com/ClickHouse/ClickHouse/pull/114189) ([groeneai](https://github.com/groeneai)).
* 테이블의 정렬 키가 `Date` 컬럼을 `toDateTime`으로 감싸고(예: `ORDER BY toDateTime(date_column)`) 쿼리가 `WHERE date_column >= '...'`와 같은 비교 조건으로 원래 컬럼을 필터링할 때 발생하던 잘못된 인덱스 프루닝을 수정했습니다. `toDateTime(Date)`는 `DateTime` 범위를 벗어나는(`2106-02-07` 이후) `Date` 값에서 오버플로가 발생하므로 저장된 키가 단조적이지 않습니다. 이 상태에서 프라이머리 키 프루닝을 사용하면 일치하는 행이 포함된 그래뉼이 제외될 수 있으므로, ClickHouse는 이 키/조건 조합에 더 이상 프라이머리 키 프루닝을 적용하지 않습니다. [#101814](https://github.com/ClickHouse/ClickHouse/pull/101814) ([nihalzp](https://github.com/nihalzp)).
* `DEFAULT`가 지정된 `Nullable` 컬럼을 다른 타입(예: `Nullable(UInt8)` → `String`,`LowCardinality(String)` 또는 `Array(UInt8)`)으로 변환할 때 `ALTER MODIFY COLUMN`이 실패하던 문제를 수정했습니다. [#102156](https://github.com/ClickHouse/ClickHouse/pull/102156) ([il9ue](https://github.com/il9ue)).
* SQLite로 `WHERE` 프레디케이트를 푸시할 때 `StorageSQLite` 및 `sqlite()` 테이블 함수에서 SQL 리터럴 이스케이프가 잘못 수행되던 문제를 수정했습니다. 작은따옴표와 제어 문자(`\n`, `\r`, `\t`, `\`)가 백슬래시로 이스케이프되었는데, SQLite는 이를 해석하지 않아 구문 오류가 발생하거나 잘못된 쿼리 결과가 반환되었습니다. 또한 PostgreSQL로 푸시다운되는 문자열 리터럴의 이스케이프도 수정했습니다. 기존에는 `IN` 목록 내부에 중첩된 문자열에 ClickHouse 방식의 이스케이프가 그대로 남아 있었고, 제어 문자가 백슬래시 시퀀스로 전송되어 PostgreSQL에서 다른 바이트로 해석되었습니다. [#104217](https://github.com/ClickHouse/ClickHouse/pull/104217) ([tiandiwonder](https://github.com/tiandiwonder)).
* `query_plan_convert_join_to_in`이 활성화되어 있고 SELECT가 소스 배열 컬럼을 참조할 때 `INNER JOIN ... ON arrayJoin(...) = ...` 쿼리에서 `NOT_FOUND_COLUMN_IN_BLOCK` 예외가 발생하던 문제를 수정했습니다. [#104809](https://github.com/ClickHouse/ClickHouse/pull/104809) ([tiandiwonder](https://github.com/tiandiwonder)).
* 상수가 아닌 우변 피연산자가 현재 행의 컬럼을 참조하는 IN 및 NOT IN 표현식의 문제를 수정하고, 새 분석기의 튜플 우변 처리를 기존 ClickHouse IN 의미 체계에 맞게 조정했습니다. 이전 분석기에서는 우변에 원본 컬럼만 단독으로 사용하면(`x IN (arr)`) 여전히 테이블 이름으로 해석되어 범위에서 제외됩니다. [#104993](https://github.com/ClickHouse/ClickHouse/pull/104993) ([niyue](https://github.com/niyue)).
* `String` 또는 `Nullable(String)` 키로 `DirectKeyValueJoin`을 사용할 때 `EmbeddedRocksDB`, `Redis`, `KeeperMap` 테이블에 대한 `JOIN`이 아무런 오류 없이 0개의 행을 반환할 수 있던 문제를 수정했습니다. [#105253](https://github.com/ClickHouse/ClickHouse/pull/105253) ([vdimir](https://github.com/vdimir)).
* 비등가 `JOIN ... ON` 프레디케이트가 `ARRAY JOIN []`으로 생성된 컬럼처럼 `Nothing` 유형의 컬럼을 참조할 때 발생하던 `LOGICAL_ERROR`("Unexpected expression in JOIN ON section. Expected boolean (UInt8), got 'Nothing'")를 수정했습니다. [#106981](https://github.com/ClickHouse/ClickHouse/pull/106981) ([groeneai](https://github.com/groeneai)).
* 별칭이 지정된 람다가 표현식 목록의 첫 번째가 아닌 위치에서 접근 연산자(`.N` 튜플 원소 또는 `[]` 배열 원소)의 피연산자로 사용될 때(예: `SELECT 1, ((p0, p1) -> p0 AS a7).4[3] FROM t`) 디버그 및 sanitizer 빌드에서 서버가 비정상 종료될 수 있던 `Inconsistent AST formatting` 논리 오류를 수정했습니다. [#107092](https://github.com/ClickHouse/ClickHouse/pull/107092) ([groeneai](https://github.com/groeneai)).
* `clusterAllReplicas(..., urlCluster(...))`처럼 다른 분산 쿼리 내부에 중첩된 클러스터 테이블 함수(`urlCluster`, `fileCluster`, `s3Cluster` 등)는 이제 논리 오류(`Distributed task iterator is not initialized`)로 실패하지 않고 `BAD_ARGUMENTS` 오류와 함께 거부됩니다. [#107107](https://github.com/ClickHouse/ClickHouse/pull/107107) ([groeneai](https://github.com/groeneai)).
* 정밀도가 낮은 부동소수점 컬럼에서 정확히 표현할 수 없는 십진 리터럴(예: `Float32` 컬럼의 `0.1`)을 사용하면(예: `SELECT * FROM values('x Float32', 0.1)`) `values` 테이블 함수가 `ARGUMENT_OUT_OF_BOUND`로 실패하던 문제를 수정했습니다. 이제 이러한 값은 `CAST` 및 `INSERT ... VALUES`와 마찬가지로 허용되며, 표현 가능한 가장 가까운 값으로 변환됩니다. [#108055](https://github.com/ClickHouse/ClickHouse/pull/108055) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `mapFilter`, `mapSort`(및 그 변형), `mapConcat`이 `Map`의 키 및 값 유형에서 `LowCardinality`를 제거하던 문제를 수정했습니다. 이전에는 `Map(LowCardinality(String), String)` 컬럼에 `mapFilter`를 적용하면 `Map(String, String)`이 반환되어, `CREATE TABLE ... AS SELECT`로 생성된 테이블의 메타데이터가 손상되고 `CHECK TABLE`이 실패할 수 있었습니다. [#108057](https://github.com/ClickHouse/ClickHouse/pull/108057) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 스킵 인덱스(예: 카디널리티가 높은 컬럼에 대한 무제한 `set(0)` 인덱스)를 빌드하는 동안 취소되었거나 `KILL`된 `INSERT`가 오랫동안 계속 실행되던 문제를 수정했습니다. 이제 쿼리가 취소되면 인덱스 빌드가 즉시 중단됩니다. [#108351](https://github.com/ClickHouse/ClickHouse/pull/108351) ([tiandiwonder](https://github.com/tiandiwonder)).
* `primes` 테이블 함수에 대한 `SELECT`가 취소 요청에 응답하지 않던 문제를 수정했습니다. `step`(또는 `limit`) 값이 크면 `KILL QUERY`나 타임아웃 이후에도 쿼리가 오랫동안 계속 실행될 수 있었습니다. 이제 즉시 중단됩니다. [#108353](https://github.com/ClickHouse/ClickHouse/pull/108353) ([tiandiwonder](https://github.com/tiandiwonder)).
* 이름에 부분 문자열 `INT`가 포함된 데이터 타입 이름(예: 데이터 타입 위치에 사용된 `quantileInterpolatedWeighted`와 같은 함수 형태의 이름)의 파싱 문제를 수정했습니다. 이러한 이름이 MySQL 정수 타입으로 잘못 인식되어 첫 번째 `(...)` 인수 그룹이 표시 너비 수정자로 간주되어 경고 없이 제거되었으며, 이로 인해 쿼리 포맷팅 왕복 변환(round-trip)이 깨질 수 있었습니다. [#108354](https://github.com/ClickHouse/ClickHouse/pull/108354) ([groeneai](https://github.com/groeneai)).
* 잘못된 형식의 `ARRAY JOIN` 뒤에 쉼표와 괄호로 묶인 테이블 목록이 오면 거부되지 않고 크로스 조인으로 잘못 파싱되던 불일치 문제를 수정했습니다. [#108365](https://github.com/ClickHouse/ClickHouse/pull/108365) ([Algunenano](https://github.com/Algunenano)).
* 분산 쿼리가 구조적으로 동일한 중복 `ALIAS` 컬럼을 중복 제거하는 동시에 `key = value` 형식의 named collection 인수를 사용하는 테이블 함수(예: `oss(s3_conn, filename = '...')`)를 참조할 때 발생하던 `LOGICAL_ERROR`("Invalid action query tree node ...") 예외를 수정했습니다. [#108435](https://github.com/ClickHouse/ClickHouse/pull/108435) ([groeneai](https://github.com/groeneai)).
* 분산 테이블에서 둘 이상의 `LowCardinality` 인수를 사용하는 함수 호출(예: `remote()`와 함께 `GROUP BY` 키로 사용된 `concatAssumeInjective((SELECT toLowCardinality('p')), s)`) 시 발생할 수 있던 논리 오류(릴리스 빌드에서는 예외 발생, 디버그 및 새니타이저 빌드에서는 서버 중단)를 수정했습니다. 오류 메시지는 `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](https://github.com/ClickHouse/ClickHouse/pull/108871) ([groeneai](https://github.com/groeneai)).
* 서버에서 해석되는 `DateTime`/`DateTime64` 문자열 리터럴(비동기 `INSERT`, `SELECT` 리터럴)에 `use_client_time_zone`이 적용되지 않던 문제를 수정했습니다. 이제 `use_client_time_zone`이 활성화되면 클라이언트가 로컬 시간대를 `session_timezone`으로 전달하므로, 서버 측 파싱 결과가 동기 `INSERT` 경로와 일치합니다. [#109051](https://github.com/ClickHouse/ClickHouse/pull/109051) ([groeneai](https://github.com/groeneai)).
* `max_execution_time`(`timeout_overflow_mode = 'throw'` 설정 시)이 쿼리를 취소하지 못하는 경우가 있던 문제를 수정했습니다. 내부 타임아웃 감시자가 이미 기한이 더 늦은 쿼리를 기다리고 있을 때 나중에 등록된 기한이 더 이른 쿼리를 완전히 놓칠 수 있었고, 이 경우 해당 쿼리가 제한 시간을 한참 넘겨 실행되었습니다. [#109792](https://github.com/ClickHouse/ClickHouse/pull/109792) ([tiandiwonder](https://github.com/tiandiwonder)).
* 분석기가 활성화된 상태에서 `Distributed` 테이블에 대한 쿼리가 `Nullable`로 바뀐 `_shard_num`(또는 `shardNum()`)을 `ORDER BY`와 함께 사용할 때(예: `join_use_nulls = 1`인 `FULL JOIN`) 발생하던 `NOT_FOUND_COLUMN_IN_BLOCK` 오류를 수정했습니다. [#109798](https://github.com/ClickHouse/ClickHouse/pull/109798) ([groeneai](https://github.com/groeneai)).
* `enable_join_runtime_filters = 1`(26.2부터 기본적으로 활성화됨)이 설정된 조인에서 빌드 측 조인 키가 NULL을 포함하는 `LowCardinality(Nullable(...))`이고 런타임 필터(runtime filter)가 블룸 필터로 대체될 때 발생할 수 있던 `NOT_IMPLEMENTED` 오류("Method getDataAt is not supported for Nullable(String)")를 수정했습니다. [#109824](https://github.com/ClickHouse/ClickHouse/pull/109824) ([groeneai](https://github.com/groeneai)).
* 고차 함수(higher-order function)가 구체적인 값을 받아야 하는 위치(예: `arrayFold(lambda, arr, another_lambda)`와 같이 `arrayFold`의 누산기(accumulator) 위치)에 람다 표현식이 전달되면 서버 크래시가 발생하던 문제를 수정했습니다. 이제 `enable_analyzer = 0`일 때 이러한 쿼리는 크래시를 일으키지 않고 `ILLEGAL_TYPE_OF_ARGUMENT` 오류와 함께 거부됩니다. [#109840](https://github.com/ClickHouse/ClickHouse/pull/109840) ([groeneai](https://github.com/groeneai)).
* 행 정책(row policy) 필터에서 `arrayJoin`의 별칭인 `unnest`를 사용할 수 없도록 하여, 이러한 정책이 읽기 시점에 `column->size() == num_rows` 논리 오류(logical error)를 일으킬 수 있던 허점을 해결했습니다. [#109973](https://github.com/ClickHouse/ClickHouse/pull/109973) ([Algunenano](https://github.com/Algunenano)).
* 같은 쿼리에서 전체 튜플도 함께 읽는 경우(예: `SELECT *`) 필드를 `tupleElement(t, 'name')`, `tupleElement(t, N)` 또는 `t.N`으로 액세스하면 `Tuple` 서브컬럼에 정의된 스킵 인덱스가 사용되지 않던 문제를 수정했습니다. 이제 이 모든 형식에서도 이름 기반 서브컬럼 액세스 `t.name`과 동일한 방식으로 그래뉼을 제외합니다. [#110056](https://github.com/ClickHouse/ClickHouse/pull/110056) ([groeneai](https://github.com/groeneai)).
* `text`, `tokenbf_v1` 또는 `ngrambf_v1` 스킵 인덱스가 있는 `Array(String)` 컬럼을 배열 리터럴(`arr = ['x']`)과 비교할 때 발생하던 `BAD_GET` 오류를 수정했습니다. 이제 이러한 비교는 쿼리 전체를 실패시키지 않고, 인덱스에서 전체 스캔으로 처리됩니다. [#110057](https://github.com/ClickHouse/ClickHouse/pull/110057) ([groeneai](https://github.com/groeneai)).
* 적용 시점에 컬럼이 이미 존재하면 `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`에서 불필요하게 `ILLEGAL_COLUMN` 오류가 발생하던 문제를 수정했습니다. 이 문제는 하나의 구문에서 `IF NOT EXISTS`로 같은 컬럼을 두 번 추가하거나, 준비 단계와 적용 단계 사이에 동시 실행된 다른 `ALTER`가 해당 컬럼을 추가한 경우에 발생했습니다. [#110080](https://github.com/ClickHouse/ClickHouse/pull/110080) ([groeneai](https://github.com/groeneai)).
* `identity()`(또는 스칼라 서브쿼리 결과)가 중첩된 `LowCardinality`를 포함하는 값을 감싸고, 쿼리에서 `WITH TOTALS`/`WITH ROLLUP`을 사용할 때 발생하던 `LOGICAL_ERROR`(`Bad cast from type ColumnLowCardinality to ColumnString`)를 수정했습니다. [#110138](https://github.com/ClickHouse/ClickHouse/pull/110138) ([groeneai](https://github.com/groeneai)).
* 튜플 표현식에 `GROUP BY ALL`을 `ORDER BY`와 함께 사용할 때 발생하던 `NOT_FOUND_COLUMN_IN_BLOCK` 오류를 수정했습니다. [#110206](https://github.com/ClickHouse/ClickHouse/pull/110206) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 서브컬럼(예: `Nullable` 컬럼의 `x.null` 또는 `Array`의 `arr.size0`)을 참조하는 `CHECK` 제약 조건이 있는 테이블에 `INSERT`할 때 발생하던 `NOT_FOUND_COLUMN_IN_BLOCK` 오류를 수정했습니다. [#110208](https://github.com/ClickHouse/ClickHouse/pull/110208) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 기본적으로 활성화되어 있는 optimize\_and\_compare\_chain 최적화로 인해 잘못된 쿼리 결과가 반환되던 문제를 수정했습니다. 체인에 쌍별 변환 규칙이 다른 타입이 섞여 있으면(예: Enum과 String, Decimal과 Float64, 너비가 다른 FixedString) a \< b AND b \< c에서 추이성으로 도출된 조건이 원래 조건과 다른 비교 의미를 사용할 수 있었습니다. 이제 추이적 조건은 단일 비교 순서를 공유하는 타입 그룹 내에서만 도출됩니다. [#110621](https://github.com/ClickHouse/ClickHouse/pull/110621) ([yariks5s](https://github.com/yariks5s)).
* `optimize_injective_functions_in_group_by`가 `GROUP BY GROUPING SETS` 및 `GROUP BY ... WITH TOTALS`의 쿼리 결과를 변경하던 문제를 수정했습니다. 이 설정은 결과를 변경하지 않는 것으로 문서화되어 있지만, 그룹화 키에 적용된 단사(injective) 함수를 제거하면 해당 키가 집계 집합에 포함되지 않은 행(`GROUPING SETS`에서 해당 키를 포함하지 않는 집합) 또는 `WITH TOTALS` 행에서 잘못된 값이 생성되거나 행이 누락되었습니다. 이 잘못된 값이 실제 키 값과 우연히 같아질 수 있었기 때문에, 동일한 결과 집합 안에서 상위 집계 행과 실제 그룹을 구분할 수 없었습니다. [#110721](https://github.com/ClickHouse/ClickHouse/pull/110721) ([groeneai](https://github.com/groeneai)).
* `median`/`quantile`(ReservoirSampler 기반) 집계 함수 상태에 매우 큰 정수 상수를 곱할 때(예: `medianState(x) * 18446744073709551615`) 서버가 멈추는 문제를 수정했습니다. 이 경우 쿼리가 취소 요청에 응답하지 않고 무기한 실행될 수 있었습니다. [#110779](https://github.com/ClickHouse/ClickHouse/pull/110779) ([groeneai](https://github.com/groeneai)).
* `JSON` 인수에 내부 유형 힌트 서브컬럼 이름(백틱 유형 표식으로 시작하는 이름)을 지정하여 `getSubcolumn`을 호출할 때 발생하던 크래시(쿼리 분석 중 널 포인터 역참조)를 수정했습니다. [#110940](https://github.com/ClickHouse/ClickHouse/pull/110940) ([groeneai](https://github.com/groeneai)).
* `map[key]`가 첫 번째 키가 아닌 뒤에 나오는 중복 키의 값을 반환하던 문제를 수정했습니다. `Map` 컬럼에 중복 키가 있으면 `map[key]`의 결과가 같은 블록의 앞선 행과 `optimize_functions_to_subcolumns` 설정에 따라 달라질 수 있었으며, 그 결과 같은 행에 대한 `SELECT`와 `WHERE`의 결과가 서로 다를 수 있었습니다. [#111246](https://github.com/ClickHouse/ClickHouse/pull/111246) ([groeneai](https://github.com/groeneai)).
* `use_variant_default_implementation_for_comparisons = 0`일 때 `AND` 체인에서 컬럼을 `Nullable`이 아닌 유형의 NULL 값 상수(예: NULL 값을 가진 `Variant`)와 비교하면 논리 표현식 최적화기에서 논리 오류 `!rhs_literal->getValue().isNull()`이 발생하던 문제를 수정했습니다. [#111292](https://github.com/ClickHouse/ClickHouse/pull/111292) ([groeneai](https://github.com/groeneai)).
* 쿼리에 `set` 스킵 인덱스가 있고 `(x AND <null-value>) OR y` 형태의 조건식에서 NULL이 함수로 생성되는 경우(예: `toInt64OrNull('x')`, `nullIf(1, 1)`, `CAST(NULL AS Nullable(Int64))`) 잘못된 결과가 반환되던 문제를 수정했습니다. 이러한 값이 `__bitWrapperFunc`로 래핑되면서 "unknown" 마스크 대신 `NULL`이 전파되었고, 이로 인해 set 인덱스가 실제로 조건에 맞는 그래뉼까지 제외하여 쿼리가 반환해야 할 행보다 적은 행을 반환했습니다. [#111604](https://github.com/ClickHouse/ClickHouse/pull/111604) ([groeneai](https://github.com/groeneai)).
* 분석기를 사용할 때 `CREATE TABLE`/`ALTER TABLE`에서 `_table`이나 `_database` 같은 가상 컬럼을 참조하는 컬럼 `DEFAULT`/`MATERIALIZED` 표현식이 허용되던 문제를 수정했습니다. 이런 테이블에 삽입하면 `NOT_FOUND_COLUMN_IN_BLOCK` 오류가 발생했고, `MATERIALIZED` 컬럼(값을 명시적으로 지정할 수 없음)이 있으면 테이블에 영구적으로 삽입할 수 없었습니다. 이제 이러한 표현식은 정의 시점에 거부되며, 이는 분석기를 사용하지 않을 때의 동작과 같습니다. 가상 컬럼을 참조하는 `ALIAS` 컬럼(읽기 시점에 계산)과 `EPHEMERAL` 컬럼(저장되지 않는 삽입 입력)은 계속 정상적으로 동작합니다. [#111776](https://github.com/ClickHouse/ClickHouse/pull/111776) ([groeneai](https://github.com/groeneai)).
* 매개변수화된 뷰(parameterized view)를 `Array`, `Tuple` 또는 `LowCardinality` 유형의 값을 반환하는 서브쿼리 인수로 호출할 때(예: `SELECT * FROM v(param = (SELECT groupArray(x) FROM t))`) `UNKNOWN_QUERY_PARAMETER` 오류가 발생하던 문제를 수정했습니다. [#111790](https://github.com/ClickHouse/ClickHouse/pull/111790) ([groeneai](https://github.com/groeneai)).
* 비교 연산의 연쇄(`x = c1 OR x = c2 OR ...`, `x != c1 AND x != c2 AND ...`, `has(const_array, x)`)를 `IN`/`NOT IN`으로 변환하는 분석기 재작성에서 발생하던 버그 3개를 수정했습니다. `use_variant_default_implementation_for_comparisons = 0`인 `Variant` 표현식에서는 재작성으로 인해 표현식 결과 유형이 `UInt8`에서 `Nullable(UInt8)`로 바뀌었고, 그 결과 디버그 및 새니타이저 빌드의 쿼리 트리 검증 단계에서 `LOGICAL_ERROR`가 발생했습니다. 동적 구조를 가진 표현식(`Dynamic`, `Array(Dynamic)`, `JSON`)에서는 `IN`이 이러한 인수를 허용하지 않기 때문에, 재작성 후 정상적으로 동작하던 쿼리가 `Illegal type ... of argument of function in` 오류와 함께 실패했습니다. 또한 상수가 표현식의 유형으로 손실 없이 변환되지 않을 때(예: 시각 정보가 포함된 `DateTime` 상수를 `Date` 컬럼과 비교하는 경우) 두 방향 모두 잘못된 결과를 반환했습니다. [#111924](https://github.com/ClickHouse/ClickHouse/pull/111924) ([groeneai](https://github.com/groeneai)).
* 쿼리가 병렬 레플리카, 분산 테이블 또는 외부 집계를 사용하거나 상태가 테이블에 저장된 경우(`Dynamic` 값 내부 포함), `quantileDeterministic`, `quantilesDeterministic`, `medianDeterministic`이 동일한 데이터에 대해 실행할 때마다 다른 결과를 반환하던 문제를 수정했습니다. 이 버전 이전에 버전 정보가 없는 유형 표기로 기록된 상태는 레이아웃을 변경할 수 없으므로 기존 동작을 유지합니다. [#112052](https://github.com/ClickHouse/ClickHouse/pull/112052) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 벡터 검색 쿼리가 쿼리 조건 캐시를 오염시켜 잘못된 결과가 반환되던 문제를 수정했습니다. `vector_similarity` 인덱스가 있는 테이블에 대한 `SELECT ... WHERE <condition> ORDER BY <distance function> LIMIT n` 쿼리가 그래뉼을 `<condition>`과 일치하지 않는 것으로 기록할 수 있었고, 이 때문에 이후 같은 테이블에 대해 실행한 일반 `SELECT ... WHERE <condition>` 쿼리가 별다른 경고 없이 더 적은 행을 반환했습니다. 이제 벡터 검색 읽기는 쿼리 조건 캐시에 기록하지 않습니다. [#112086](https://github.com/ClickHouse/ClickHouse/pull/112086) ([groeneai](https://github.com/groeneai)).
* 직렬화된 쿼리 계획에서 `serialize_string_in_memory_with_zero_byte`가 누락되던 문제를 수정했습니다. `serialize_query_plan = 1`일 때 이 설정을 비활성화한 클러스터에서는 개시 노드와 역직렬화된 계획을 실행하는 노드 간에 메모리 내 문자열 표현이 서로 달라질 수 있었습니다. 해당 설정이 역직렬화 시에는 읽히지만 직렬화 시에는 기록되지 않아, 실행 노드에서는 항상 기본값이 적용되었기 때문입니다. [#112131](https://github.com/ClickHouse/ClickHouse/pull/112131) ([groeneai](https://github.com/groeneai)).
* `ON l.id = r.id AND CAST(NULL AS Nullable(UInt8))`처럼 `ON` 표현식에 상수 논리곱 항이 포함된 `JOIN`에서 잘못된 결과가 반환되던 문제를 수정했습니다. 쿼리 계획 최적화 과정에서 해당 상수가 별다른 경고 없이 제거되어, 조인이 마치 상수가 없는 것처럼 실행되었습니다. 그 결과 `INNER`, `LEFT SEMI`, `RIGHT SEMI` 조인은 항상 거짓인 조건이므로 아무 행도 반환하지 않아야 하는데도 일치하는 행을 반환했고, `RIGHT ANTI`는 모든 행을 반환해야 하는데도 아무 행도 반환하지 않았습니다. [#112155](https://github.com/ClickHouse/ClickHouse/pull/112155) ([vdimir](https://github.com/vdimir)).
* 매개변수화된 뷰(parameterized view)를 `parameter = value` 형식의 할당이 아닌 인수로 호출하면 잘못된 결과가 반환되던 문제를 수정했습니다. `enable_analyzer = 0`인 경우와 기본 설정의 `EXPLAIN SYNTAX`에서 `pv(concat(name, '!'))`, `pv(name, 'a')`, `pv(name != 'a')`, `pv(tuple(name = 'a'))` 같은 호출은 분석기처럼 `UNKNOWN_QUERY_PARAMETER`를 보고하지 않고, 별다른 경고 없이 뷰 매개변수를 관련 없는 표현식에 바인딩했습니다. 이제 이러한 호출은 두 실행 경로 모두에서 동일하게 거부됩니다. [#112194](https://github.com/ClickHouse/ClickHouse/pull/112194) ([groeneai](https://github.com/groeneai)).
* 정의에서 `substring` 문법으로 다시 파싱할 수 없는 형태로 `substr`, `mid` 또는 `byteSlice`를 호출하는 `CREATE VIEW` 또는 `CREATE FUNCTION`은 생성은 허용되지만, ClickHouse가 기록하는 메타데이터가 유효한 SQL이 아니던 버그를 수정했습니다. 이후 해당 정의를 읽으면 `SYNTAX_ERROR`로 실패했고, 서버 시작 시에는 메타데이터 로딩이 중단되어 서버가 아예 시작되지 않았습니다. 이제 이러한 정의도 왕복이 가능하며, `substring(x, a, b, c)` 형태의 기존 메타데이터 파일도 다시 읽을 수 있으므로 영향을 받은 서버가 수동 조치 없이 시작됩니다. [#112195](https://github.com/ClickHouse/ClickHouse/pull/112195) ([groeneai](https://github.com/groeneai)).
* 프라이머리 키가 `Array` 또는 `Tuple`이고 쿼리에서 여기에 `plus`, `minus`, `multiply`, `divide` 또는 `intDiv`를 적용하면 잘못된 결과, 잘못 정렬된 `ORDER BY` 출력, `BAD_TYPE_OF_FIELD` 예외가 발생하던 문제를 수정했습니다. 복합 값에 대한 산술 연산은 요소별로 평가되지만 복합 값의 비교는 사전식으로 이루어지므로, 이제 프라이머리 키 분석에서 이러한 표현식을 단조(monotonic)로 간주하지 않습니다. [#112339](https://github.com/ClickHouse/ClickHouse/pull/112339) ([groeneai](https://github.com/groeneai)).
* 왼쪽 테이블이 `Distributed` 테이블이거나 `*Cluster` 테이블 함수인 경우처럼 `PASTE JOIN`을 포함한 쿼리가 다른 서버로 전송될 때, 원격 서버에서 `Code: 62 ... You must not specify ANY or ALL for PASTE JOIN. (SYNTAX_ERROR)`가 발생하던 문제를 수정했습니다. 포매터가 파서에서 허용하지 않는 표기인 `ALL PASTE JOIN`을 출력했기 때문에 수신 서버가 전달받은 쿼리를 파싱할 수 없었습니다. [#112404](https://github.com/ClickHouse/ClickHouse/pull/112404) ([groeneai](https://github.com/groeneai)).
* `(SELECT 1) AS t(x)` 또는 `WITH t(x) AS (SELECT 1)`과 같은 컬럼 별칭 목록이 `view` 테이블 함수 내부에서 인식되지 않아, `view` 외부에서는 동일한 구문이 정상 동작하는데도 `t.x` 참조가 `UNKNOWN_IDENTIFIER`로 실패하던 문제를 수정했습니다. [#112690](https://github.com/ClickHouse/ClickHouse/pull/112690) ([groeneai](https://github.com/groeneai)).
* `ARRAY JOIN` 절에 표현식이 없을 때 쿼리 포맷팅 중 논리 오류가 발생하던 문제를 수정했습니다. 이제 이러한 절은 허용된 후 다시 파싱할 수 없는 텍스트로 포맷팅되지 않고, 빈 `USING`과 마찬가지로 파싱 단계에서 `SYNTAX_ERROR`로 거부됩니다. [#112699](https://github.com/ClickHouse/ClickHouse/pull/112699) ([groeneai](https://github.com/groeneai)).
* 서브쿼리용으로 준비된 표현식 액션이 빌드 시 사용된 Context가 해제된 뒤에 실행되면 `connectionId`에서 `Context has expired` 예외가 발생하던 문제를 수정했습니다. [#112870](https://github.com/ClickHouse/ClickHouse/pull/112870) ([clickgapai](https://github.com/clickgapai)).
* 조인 중에 평가되는 비등가(non-equi) `JOIN ON` 조건에 `arrayJoin`이 포함되면 논리 오류와 잘못된 결과가 발생하던 문제를 수정했습니다. 이제 `hash`, `parallel_hash` 또는 `grace_hash` 조인은 이러한 조건을 `INVALID_JOIN_ON_EXPRESSION`으로 거부합니다. 확장이 한쪽에만 의존한다면 조인 전에 서브쿼리 내 `ARRAY JOIN`으로 옮기십시오. `arrayJoin` 인수가 양쪽 컬럼을 모두 읽는 조건은 구조를 재작성해야 합니다. [#112889](https://github.com/ClickHouse/ClickHouse/pull/112889) ([groeneai](https://github.com/groeneai)).
* `geohashesInBox(0., 0., 180., 0., 12)`처럼 면적이 0인 박스에 대해 `geohashesInBox`가 제한 없이 시간을 소모하던 문제를 수정했습니다. 이러한 쿼리는 올바른 단일 geohash를 반환하기는 했지만 행마다 약 5e8회의 무의미한 루프를 반복했으며, `max_execution_time`과 `KILL QUERY`도 모두 무시했습니다. [#112976](https://github.com/ClickHouse/ClickHouse/pull/112976) ([groeneai](https://github.com/groeneai)).
* 값 없이 작성된 것으로 표시된 `SETTINGS` 변경에 `true`가 아닌 값이 포함된 경우 이를 거부하고, 쿼리를 포맷할 때 이러한 변경의 값을 생략하지 않도록 수정했습니다. 이전에는 조작된 AST JSON 페이로드로 `Bool` 설정을 `false`로 실행하면서도 `system.query_log`와 `formatQueryFromJSON`에는 값이 없는 형태로 표시되게 할 수 있었습니다. [#113025](https://github.com/ClickHouse/ClickHouse/pull/113025) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 선언된 컬럼 타입이 내부 쿼리가 생성하는 타입과 다른 `VIEW`에서 조회할 때 발생하던 `UNKNOWN_IDENTIFIER`를 수정했습니다. 예를 들어 `v`가 `String` 컬럼에 대해 `arr Array(UInt8)`를 선언한 상태에서 `SELECT sum(length(arr)) FROM v`를 실행하는 경우입니다. 기본값인 `optimize_functions_to_subcolumns = 1`에서는 옵티마이저가 `length(arr)`를 `arr.size0` 서브컬럼 읽기로 재작성한 뒤 그 이름을 내부 쿼리로 전달했지만, 내부 쿼리에는 해당 서브컬럼이 존재하지 않았습니다. [#113057](https://github.com/ClickHouse/ClickHouse/pull/113057) ([groeneai](https://github.com/groeneai)).
* `postgresql` 테이블 함수 및 PostgreSQL 엔진 읽기의 취소 처리를 수정했습니다. 읽기가 시작되는 도중에 취소하면 트랜잭션 포인터에서 경쟁 상태가 발생할 수 있었고, 취소 요청이 아예 유실되어 PostgreSQL이 쿼리를 끝낼 때까지 쿼리가 계속 실행될 수 있었습니다. 단, `COPY` SQL 문이 실행되기 전에 PostgreSQL에 도달한 취소 요청은 여전히 무시될 수 있습니다. [#113150](https://github.com/ClickHouse/ClickHouse/pull/113150) ([groeneai](https://github.com/groeneai)).
* 클러스터 테이블 함수(`s3Cluster`, `urlCluster`, `fileCluster`) 기반의 `SQL SECURITY DEFINER` 또는 `SQL SECURITY NONE` 뷰를 `remote`나 `clusterAllReplicas` 등을 통해 보조 쿼리로 읽을 때 발생하던 `LOGICAL_ERROR`(`Next task callback is not set for query`)를 수정했습니다. 이제 지원되지 않는 중첩은 debug 및 새니타이저 빌드에서 서버를 중단시키지 않고 일반 쿼리 오류로 거부됩니다. [#113371](https://github.com/ClickHouse/ClickHouse/pull/113371) ([groeneai](https://github.com/groeneai)).
* `analyzer_compatibility_join_using_top_level_identifier = 1` 설정에서 `view(...)` 인수를 사용하는 remote 계열 테이블 함수를 `SELECT` 목록 별칭을 키로 하는 `JOIN ... USING`의 왼쪽에 사용할 때 발생하던 논리 오류 `IDENTIFIER is not a table expression`을 수정했습니다. [#113400](https://github.com/ClickHouse/ClickHouse/pull/113400) ([groeneai](https://github.com/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 및 새니타이저 빌드에서는 서버를 중단시켰습니다. [#113556](https://github.com/ClickHouse/ClickHouse/pull/113556) ([groeneai](https://github.com/groeneai)).
* `Variant` 컬럼에 대한 쿼리가 `max_execution_time` 및 `KILL QUERY`를 무시하던 문제를 수정했습니다. 여러 `Variant` 인수로 함수를 호출하면 각 인수의 모든 대안마다 함수를 한 번씩 해석했는데, 이 작업을 수행하는 두 루프 모두 취소 여부를 확인하지 않아 해당 쿼리가 끝날 때까지 중지할 수 없었습니다. [#113612](https://github.com/ClickHouse/ClickHouse/pull/113612) ([groeneai](https://github.com/groeneai)).
* 하나의 SQL 문에서 `ALIAS` 컬럼을 물리 컬럼(`DEFAULT` 또는 `MATERIALIZED`)으로 변경하면서 `CODEC`도 함께 지정하면 `ALTER TABLE ... MODIFY COLUMN`이 `Cannot specify codec for column type ALIAS` 오류로 실패하던 문제를 수정했습니다. [#113853](https://github.com/ClickHouse/ClickHouse/pull/113853) ([groeneai](https://github.com/groeneai)).
* 상수 `ON` 표현식으로 `ARRAY JOIN`이 포함된 오른쪽 테이블과 조인할 때 발생하던 서버 크래시를 수정했습니다. 지연 복제된 오른쪽 컬럼을 읽을 때 이미 해제된 `ColumnReplicated`에 접근하는 문제가 있었습니다. [#113901](https://github.com/ClickHouse/ClickHouse/pull/113901) ([groeneai](https://github.com/groeneai)).
* 테이블의 정렬 키가 `GROUP BY` 키의 진부분 접두사(strict prefix)이고 `quantileDD`처럼 상태가 힙 메모리를 소유하는 집계 함수를 사용할 때 `optimize_aggregation_in_order = 1`에서 발생하던 메모리 누수를 수정했습니다. 이러한 쿼리가 실행될 때마다 서버를 재시작하기 전까지 메모리 사용량이 계속 증가했습니다. [#114010](https://github.com/ClickHouse/ClickHouse/pull/114010) ([groeneai](https://github.com/groeneai)).
* `UInt128`/`UInt256`에 대한 `isProbablePrime`이 `max_execution_time` 및 `KILL QUERY`를 무시하던 문제를 수정했습니다. 큰 값으로 이루어진 블록이 취소 지점 없이 단일 함수 호출 안에서 끝까지 실행되었기 때문에, 쿼리가 제한 시간을 넘겨 수 분 동안 계속 실행될 수 있었습니다. [#114032](https://github.com/ClickHouse/ClickHouse/pull/114032) ([groeneai](https://github.com/groeneai)).
* `PREWHERE` 절에 `IN (subquery)` 프레디케이트가 포함되어 있고 `rewrite_in_to_join = 1`(또는 이를 강제로 활성화하는 `make_distributed_plan = 1`)이 설정된 경우 `Code: 46. DB::Exception: Unknown function exists. (UNKNOWN_FUNCTION)` 오류가 발생하던 문제를 수정했습니다. 동일한 쿼리를 `WHERE`로 작성하면 정상적으로 동작했습니다. [#114067](https://github.com/ClickHouse/ClickHouse/pull/114067) ([RohithPariki](https://github.com/RohithPariki)).
* 인수가 원소 타입이 `Nothing`인 비어 있지 않은 배열일 때(예: `SELECT arrayAutocorrelation([arrayMax([])])`) `arrayAutocorrelation`에서 발생하던 `LOGICAL_ERROR`를 수정했습니다. 이제 이러한 인수는 `ILLEGAL_COLUMN` 오류와 함께 거부됩니다. 빈 배열 리터럴 `[]`는 기존과 같이 `[]`를 반환합니다. [#114249](https://github.com/ClickHouse/ClickHouse/pull/114249) ([groeneai](https://github.com/groeneai)).
* 이제 `CREATE TABLE` 및 `ALTER TABLE`에서 정렬 키에 사용되는 컬럼에 `SZ3`와 같은 손실 코덱을 지정하면 거부됩니다. [#114531](https://github.com/ClickHouse/ClickHouse/pull/114531) ([groeneai](https://github.com/groeneai)).
* 인터벌 인수의 초 단위 길이가 2^32의 배수일 때(예: `toIntervalDay(2147483648)`) `hop` 및 `windowID` 함수에서 발생하던 취소 불가능한 무한 루프를 수정했습니다. 오버플로된 뺄셈이 시간 오버플로 검사를 우회했고, 인수가 상수이면 루프가 분석 단계에서 실행되어 쿼리를 kill할 수조차 없었습니다. 같은 인터벌로 인해 `WINDOW VIEW`의 백그라운드 스레드가 무한히 반복 실행될 수도 있었으며, 이제 이러한 윈도우 뷰는 생성 시점에 거부됩니다. [#114607](https://github.com/ClickHouse/ClickHouse/pull/114607) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 원격 클러스터에서 데이터를 읽는 `IN` 서브쿼리가 포함된 쿼리에서 발생하던 논리 오류 `Not-ready Set is passed as the second argument for function 'in'`를 수정했습니다. 이제 쿼리는 연결 실패 등 서브쿼리에서 발생한 실제 오류를 반환하며 실패합니다. [#114983](https://github.com/ClickHouse/ClickHouse/pull/114983) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Log`, `TinyLog` 또는 `StripeLog` 테이블에 대한 `INSERT`가 기록된 파일 크기를 커밋하는 중에 실패하는 문제를 수정했습니다. 이러한 삽입은 오류를 보고했음에도 행이 테이블에 남아 있거나, 배열 컬럼의 데이터 파일 간 정합성이 깨질 수 있었습니다. 이제 오프셋상으로는 원소가 있다고 표시되지만 실제로는 원소가 없는 배열 컬럼을 가진 `Log` 또는 `TinyLog` 테이블을 읽으면, 원소의 끝을 넘어 읽는 대신 해당 컬럼 이름을 명시한 오류가 발생합니다. 부분적으로 기록된 원소 컬럼은 이전부터 거부되었습니다. [#115027](https://github.com/ClickHouse/ClickHouse/pull/115027) ([groeneai](https://github.com/groeneai)).
* `has([map('k', 'v')], m)`처럼 `Array(Map(...))` 타입의 상수를 포함한 쿼리를 `Distributed` 테이블에서 실행하거나 병렬 레플리카로 실행할 때 발생하던 `TYPE_MISMATCH`("CAST AS Array can only be performed between same-dimensional array types") 오류를 수정했습니다. [#115883](https://github.com/ClickHouse/ClickHouse/pull/115883) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 투영된 컬럼의 이름이 자신의 내부 관계 중 하나에 속한 컬럼 이름과 같은 뷰 또는 `view()`와 조인할 때 잘못된 결과가 반환되던 문제를 수정했습니다. 예: `SELECT expr(x.c0) AS c0 FROM a AS x, b AS y`. 조인 순서 최적화기가 이러한 표현식을 평탄화된 조인 그래프에 병합한 뒤 두 번 적용하는 바람에, 쿼리가 오류 없이 왜곡된 값을 반환했습니다. 표현식이 컬럼 타입까지 변경하는 경우에는 같은 원인으로 플랜 생성 시점에 `AMBIGUOUS_COLUMN_NAME`이 대신 발생했습니다. [#116152](https://github.com/ClickHouse/ClickHouse/pull/116152) ([groeneai](https://github.com/groeneai)).
* ROLLUP/CUBE와 함께 `group_by_use_nulls`를 사용할 때 외부 컬럼이 `Nullable`이 되면서 상관 서브쿼리(correlated subquery)에서 예외가 발생하던 문제를 수정했습니다. [#100365](https://github.com/ClickHouse/ClickHouse/pull/100365) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 이제 `Replicated` 데이터베이스에서 `max_replication_lag_to_enqueue = 0`을 허용하지 않습니다. 이 값을 사용하면 복구 후 미동기화 검사가 항상 참이 되어, 디버그 및 새니타이저 빌드에서 `LOGICAL_ERROR`로 서버가 중단되었습니다. 이제 `0`은 모든 경로(`CREATE DATABASE ... SETTINGS`, `<database_replicated>` 서버 설정 블록, `ATTACH` 재실행, 업그레이드 시 기존 메타데이터 재실행)에서 파싱 시점에 `BAD_ARGUMENTS`로 거부됩니다. 허용되는 최솟값은 `1`입니다. [#106006](https://github.com/ClickHouse/ClickHouse/pull/106006) ([groeneai](https://github.com/groeneai)).
* 서로 다른 타입이 섞인 배열을 삽입할 때 NO\_COMMON\_TYPE 예외가 발생하지 않도록 JSON(Object) 컬럼에 minmax 스킵 인덱스를 생성할 수 없게 했습니다. 대신 타입이 지정된 서브컬럼을 사용하십시오(예: `INDEX idx json.field TYPE minmax`). [#106094](https://github.com/ClickHouse/ClickHouse/pull/106094) ([linhaojie](https://github.com/linhaojie)).
* Dynamic 인수가 주어졌을 때 `JSON_QUERY`/`JSON_VALUE`/`JSON_EXISTS`가 String/UInt8 대신 Dynamic을 반환하던 문제를 수정했습니다. [#106877](https://github.com/ClickHouse/ClickHouse/pull/106877) ([Avogar](https://github.com/Avogar)).
* `interactive_delay`와 같은 대기 타임아웃 설정을 매우 큰 값으로 지정했을 때 발생하던 부호 있는 정수 오버플로를 수정했습니다. 이 문제로 인해 대기 없이 즉시 타임아웃되거나, Undefined Behavior Sanitizer 환경에서 서버가 중단될 수 있었습니다. [#106961](https://github.com/ClickHouse/ClickHouse/pull/106961) ([groeneai](https://github.com/groeneai)).
* `geohashesInBox` 함수의 좌표 인수에 상수와 비상수 값이 섞여 있거나 좌표가 `BFloat16`일 때 발생하던 `LOGICAL_ERROR`("Unsupported argument types")를 수정했습니다. 이제 상수/비상수가 섞인 `Float32` 인수가 정상적으로 동작하며, `BFloat16` 인수는 명확한 오류 메시지와 함께 거부됩니다. [#107063](https://github.com/ClickHouse/ClickHouse/pull/107063) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/107371) ([groeneai](https://github.com/groeneai)).
* MongoDB에서 데이터를 읽을 때(예: MongoDB 딕셔너리 또는 `mongodb` 테이블 함수 사용 시) 재시도 가능한 읽기 오류 이후 재시도용 서버 선택까지 실패하면, 번들된 `mongo-c-driver`에서 메모리 누수가 발생할 수 있던 문제를 수정했습니다. [#107448](https://github.com/ClickHouse/ClickHouse/pull/107448) ([groeneai](https://github.com/groeneai)).
* `pointInPolygon`이 `Variant` 또는 `Dynamic`과 같은 래퍼 타입의 상수 폴리곤 인수로 호출될 때(예: `pointInPolygon((x, y), if(c, [(0, 0), ...], NULL))`) 기본 키 분석 중에 발생하던 논리 오류(`WhichDataType(const_type).isArray()`) 및 서버 비정상 종료를 수정했습니다. [#107589](https://github.com/ClickHouse/ClickHouse/pull/107589) ([groeneai](https://github.com/groeneai)).
* `Variant` 및 `Dynamic` 컬럼 내부에 중첩된 `LowCardinality`가 일관성 없이 제거되어 `concat`, `format`, 기본 키 분석 등에서 발생하던 논리 오류(`Bad cast`)를 수정했습니다. [#107773](https://github.com/ClickHouse/ClickHouse/pull/107773) ([Avogar](https://github.com/Avogar)).
* 실행형 사용자 정의 함수의 명령 매개변수 파싱을 수정하여, 이름이 비어 있거나 유효하지 않은 플레이스홀더가 매개변수로 허용되지 않도록 했습니다. [#107983](https://github.com/ClickHouse/ClickHouse/pull/107983) ([goutamadwant](https://github.com/goutamadwant)).
* 원소가 `Dynamic`/`Variant`인 `Tuple`에 `accurateCastOrNull`을 적용할 때 원본의 실제 `NULL`이 변환 실패로 처리되던 문제를 수정했습니다. 이제 대상 원소가 `Nullable`이면 원본 `NULL`은 원소 `NULL`로 유지되며(일반 `Tuple(Nullable(...))` 원본과 동일), 대상 원소가 `Nullable`이 아니면 원소 기본값을 생성하는 대신 튜플 전체가 null이 됩니다(`Dynamic`이 아닌 경우의 동작과 동일). 파싱/오버플로 실패 시에는 이전과 같이 튜플 전체가 null이 됩니다. [#108023](https://github.com/ClickHouse/ClickHouse/pull/108023) ([groeneai](https://github.com/groeneai)).
* 이제 `mongodb` 테이블 함수는 명명된 인수로 전달된 `oid_columns`(예: `oid_columns='_id'`)를 `BAD_ARGUMENTS`로 거부하지 않고 허용합니다. [#108039](https://github.com/ClickHouse/ClickHouse/pull/108039) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `DateTime64`, `Decimal` 또는 부동소수점 범위를 사용하는 `range_hashed` 또는 `complex_key_range_hashed` 딕셔너리를 타입이 일치하는 인수와 함께 `dictGet`/`dictHas`로 조회할 수 있도록 했습니다. 이전에는 이러한 쿼리가 `must be convertible to Int64` 오류로 실패했으며, `Decimal`/`DateTime64` 범위에서 한쪽 끝이 열린 구간은 기본값을 잘못 반환했습니다. [#108052](https://github.com/ClickHouse/ClickHouse/pull/108052) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `accurateCastOrNull`로 `Array(Dynamic)` 또는 `Array(Variant)`를 `QBit`로 캐스팅할 때(예: `accurateCastOrNull(CAST(range(114), 'Array(Dynamic)'), 'QBit(Float32, 114)')`) 발생하던 서버 비정상 종료(`IColumn::insertFrom`의 `Logical error`)를 수정했습니다. [#108288](https://github.com/ClickHouse/ClickHouse/pull/108288) ([groeneai](https://github.com/groeneai)).
* 형식이 잘못되었거나 동기화가 어긋난 네이티브 TCP 프로토콜 스트림으로 인해 발생할 수 있던 서버 크래시(`Received signal 4`, 잘못된 명령어)를 수정했습니다. 이제 `ClientInfo`의 `initial_address` 필드가 파싱 전에 숫자 형식의 `host:port`인지 검증하므로, 숫자가 아닌 포트가 트랩 처리된 libc 함수 `getservbyname`에 전달되지 않습니다. [#108410](https://github.com/ClickHouse/ClickHouse/pull/108410) ([groeneai](https://github.com/groeneai)).
* `mannWhitneyUTest`, `rankCorr`, `largestTriangleThreeBuckets`, `quantileGK`, `sequenceMatch`/`sequenceCount`, `groupArrayIntersect`의 조작된 집계 함수 상태를 역직렬화할 때 발생하던 과도한 메모리 할당 문제를 수정했습니다. 잘못된 형식의 상태가 매우 큰 원소 개수를 선언하면 서버가 단 몇 바이트의 입력만으로 수십 기가바이트를 할당하려 할 수 있었습니다. 이제 이러한 상태는 `TOO_LARGE_ARRAY_SIZE` 오류로 거부됩니다. [#108465](https://github.com/ClickHouse/ClickHouse/pull/108465) ([groeneai](https://github.com/groeneai)).
* `GROUPING SETS`/`ROLLUP`/`CUBE`에서 `LowCardinality` 상수 그룹화 키와 함께 `group_by_use_nulls`를 사용할 때 발생하던 논리 오류(`Bad cast from type DB::ColumnNullable to DB::ColumnString`)와 잘못된 결과가 반환될 수 있던 문제를 수정했습니다. [#108771](https://github.com/ClickHouse/ClickHouse/pull/108771) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Map` 값에 `LowCardinality`를 포함하는 중첩 `Map`이 있을 때 `mapFilter`, `mapSort`, `mapReverseSort`, `mapPartialSort`, `mapConcat`에서 발생하던 `TYPE_MISMATCH`를 수정했습니다. 예: `mapFilter((k, v) -> 1, map('a'::LowCardinality(String), map('x'::LowCardinality(String), 'y')))`. [#108798](https://github.com/ClickHouse/ClickHouse/pull/108798) ([groeneai](https://github.com/groeneai)).
* 이름이 있는 원소와 이름이 없는 원소가 섞인 `Tuple` 데이터 타입(예: `Tuple(a UInt8, UInt16)`)을 포맷할 때 debug 및 새니타이저 빌드에서 서버가 중단되던 `LOGICAL_ERROR`("Inconsistent AST formatting")를 수정했습니다. [#108915](https://github.com/ClickHouse/ClickHouse/pull/108915) ([groeneai](https://github.com/groeneai)).
* 이제 `JSONExtract`는 문자열 JSON 값을 `DateTime`/`DateTime64`로 변환할 때 `CAST`와 마찬가지로 `cast_string_to_date_time_mode` 설정을 따릅니다. [#109252](https://github.com/ClickHouse/ClickHouse/pull/109252) ([Utkal059](https://github.com/Utkal059)).
* 오른쪽 인수에 배열 컬럼만 단독으로 지정한 `IN`이 아무런 경고 없이 잘못된(항상 false인) 결과를 반환하거나 예외를 발생시키던 문제를 수정했습니다. 이제 `x IN arr`는 `has(arr, x)`와 동일하게 동작합니다. [#109416](https://github.com/ClickHouse/ClickHouse/pull/109416) ([alexey-milovidov](https://github.com/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" 오류와 함께 실패하던(debug 및 새니타이저 빌드에서는 서버 중단) `LOGICAL_ERROR`를 수정했습니다. [#109462](https://github.com/ClickHouse/ClickHouse/pull/109462) ([groeneai](https://github.com/groeneai)).
* `FixedString` 인수를 `String`으로 올바르게 캐스팅하도록 개선하여 `conv`에서 발생하던 `ILLEGAL_COLUMN` 예외를 수정했습니다. [#109771](https://github.com/ClickHouse/ClickHouse/pull/109771) ([hp77-creator](https://github.com/hp77-creator)).
* `serialize_query_plan = 1` 설정에서 `FINAL` / `SAMPLE`을 사용한 테이블 함수 읽기가 잘못된 결과를 반환하던 문제를 수정하고, 테이블 함수의 집계 해시 테이블 통계 캐시 키도 수정했습니다(이전에는 모든 테이블 함수가 사전 할당 항목 하나를 공유했습니다). [#109847](https://github.com/ClickHouse/ClickHouse/pull/109847) ([azat](https://github.com/azat)).
* 컨테이너 타입(예: `Array(Bool)`, `Tuple(Bool, ...)`) 안에서 숫자 `1`/`0`을 `Bool` 값으로 파싱하지 못하던 문제를 수정했습니다. 이전에는 `[true,false]`는 정상 동작했지만 `[1,0]`은 `CANNOT_READ_ARRAY_FROM_TEXT` 오류와 함께 실패했습니다. [#109976](https://github.com/ClickHouse/ClickHouse/pull/109976) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/110055) ([groeneai](https://github.com/groeneai)).
* 아직 작은 표현(small representation)으로 유지되고 있는 비트맵에서 `subBitmap`, `bitmapSubsetInRange`, `bitmapSubsetLimit`이 잘못된 결과를 반환하던 문제를 수정했습니다. 여기에는 `2^32`보다 큰 `UInt64` 및 `Int64` 원소 값이 32비트로 잘리던 문제도 포함됩니다. 이제 부호 있는(signed) 원소 타입에 대한 비트맵 함수의 비교는 일관되게 해당 원소 타입의 부호 없는 값을 사용합니다. 따라서 `Int8` 비트맵에서 원소 `-1`은 부호 확장된 `4294967295`가 아니라 `255`로 비교됩니다. 이 변경으로 작은 표현을 넘어 커진 비트맵에서 `bitmapMin`, `bitmapMax`, `bitmapContains`, `bitmapTransform`이 잘못 동작하던 문제도 함께 수정되었습니다. 부호 확장된 임계값을 전달하던 쿼리는 수정해야 합니다. 예를 들어 `Int8` 비트맵에서 `bitmapSubsetInRange(bm, 4294967168, 4294967296)`은 `bitmapSubsetInRange(bm, 128, 256)`으로 바꿔야 합니다. 또한 `groupNumericIndexedVector`가 `Int8` 및 `Int16` 인덱스 컬럼에 대해 더 넓은 인덱스 유형과 다른 결과를 반환하던 문제와, `numericIndexedVectorGetValue`가 음수 인덱스에 대해 `0`을 반환하던 문제도 수정했습니다. 아울러 1부터 시작하는 인덱싱을 사용한다고 잘못 설명되어 있던 부분 집합 함수와 부호 있는 타입에 대한 `bitmapBuild` / `bitmapToArray` 지원 내용을 포함하여 비트맵 함수 문서를 바로잡았습니다. [#110072](https://github.com/ClickHouse/ClickHouse/pull/110072) ([RamiDarwiche](https://github.com/RamiDarwiche)).
* 인터벌 종류의 `WITH FILL STEP`과 극단적인 델타를 사용하는 `add*` / `subtract*` 날짜/시간 인터벌 함수에서, 인터벌 연산 중 정의되지 않은 동작인 부호 있는 오버플로우가 발생할 수 있던 경로를 수정했습니다. 이제 극단적인 인터벌 값도 부호 있는 오버플로우에 의존하지 않고 결정적으로 동작합니다. 또한 매우 큰 `YEAR` 간격을 사용하는 인터벌 종류의 `WITH FILL`이 달력을 거꾸로 진행시키며 멈추던 문제도 수정했습니다. [#110158](https://github.com/ClickHouse/ClickHouse/pull/110158) ([groeneai](https://github.com/groeneai)).
* 정렬 순서가 그룹화 키의 접두사에 불과한 상태에서 여러 키로 그룹화할 때, 순서 기반 집계(aggregation in order)의 처리 시간이 이차 시간 복잡도로 급증하던 문제(및 `max_execution_time`에 응답하지 않던 문제)를 수정했습니다. [#110159](https://github.com/ClickHouse/ClickHouse/pull/110159) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 피연산자에 최소 공통 상위 타입(least common supertype)이 없을 때 `ILLEGAL_TYPE_OF_ARGUMENT` 오류가 발생하던 비교 문제를 수정했습니다. 이제 `Array(Int64)`와 `Array(UInt64)`, `Array(Int256)`와 `Array(UInt256)` 같은 배열을 `=`, `!=`, `<`, `<=`, `>`, `>=`, `IS DISTINCT FROM`, `IS NOT DISTINCT FROM`으로 사전식 비교할 수 있습니다. 또한 `isDistinctFrom` / `isNotDistinctFrom` 같은 NULL-안전 비교에서도 지원되는 배열 외의 숫자 또는 decimal 쌍을 예외 없이 값으로 비교합니다. 중첩된 `Tuple(Nullable(...))` 원소를 가진 배열에 대해서도 동등 비교가 가능합니다. [#110245](https://github.com/ClickHouse/ClickHouse/pull/110245) ([diegomestre2](https://github.com/diegomestre2)).
* 음수 오프셋을 가진 시간대에서 극단적인 `DateTime64` 값(예: `INT64_MIN`)을 `Time`/`Time64`로 변환할 때 발생하던 부호 있는 정수 오버플로우(UBSan)를 수정했습니다. [#110451](https://github.com/ClickHouse/ClickHouse/pull/110451) ([groeneai](https://github.com/groeneai)).
* 범위를 벗어난 부동소수점 값(`BFloat16`, `Float32`, `Float64`)과 `Int64::max()`보다 큰 `UInt64` 값을 `DateTime` 및 `Time`으로 변환할 때, 이제 모든 아키텍처에서 일관되게 범위 경계값으로 포화(saturate)됩니다(이전에는 범위를 벗어난 변환 결과가 아키텍처마다 달랐으며, x86-64에서는 값이 순환(wrap around)될 수 있었습니다). 또한 유한하지 않은 값(`NaN`, `inf`)은 이제 임의의 결과를 생성하지 않고 예외를 발생시킵니다. 같은 수정 사항이 `toDate`의 부동소수점→`Date` 변환 경로에도 적용되었으며, 포화되지 않고 epoch 이전 날짜를 반환할 수 있었던 `UInt64` 및 wide 정수(`(U)Int128`, `(U)Int256`)의 `Date`, `Date32` 변환에도 적용되었습니다. 숫자를 `Time`으로 변환할 때도 이제 모든 숫자 소스 타입에 대해 해당 타입의 범위로 포화됩니다(이전에는 좁은 부호 없는 정수나 wide 정수 소스의 값이 제한되지 않은 채 저장되었다가 출력할 때만 제한되었습니다). 또한 `Time`으로의 정확한 캐스트(accurate cast)는 더 이상 `Time`이 지원하는 음수 값을 거부하지 않으며, 범위에 맞지 않는 값을 조용히 포화시키지도 않습니다. 숫자를 `Date32`로 정확하게 캐스트할 때(`accurateCast`, `accurateCastOrNull`) 범위를 벗어나거나 유한하지 않은 값을 더 이상 조용히 포화시키지 않고, 기존 `Date` 및 `DateTime`과 마찬가지로 예외를 발생시키거나 `NULL`을 반환합니다. `OrDefault` 변형은 이러한 입력에 대해 `Date32`의 기본값을 반환합니다. 정수가 아닌 부동소수점 숫자를 `Date`, `Date32`, `DateTime` 또는 `Time`으로 정확하게 캐스트하면 이제 조용히 잘라내지 않고 거부합니다. 아울러 `toDateTime64` 예시를 잘못 보여 주고 `DateTime64` 값 범위를 설명하던 `toDateTime32` 함수 문서도 수정했습니다. [#110459](https://github.com/ClickHouse/ClickHouse/pull/110459) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 맵 키가 딕셔너리 인코딩된 ORC 파일을 읽을 때 `Map cannot have a key of type LowCardinality(Nullable(String))` 오류와 함께 스키마 추론이 실패하는 문제를 수정했습니다. Spark로 작성한 ORC 파일과 `output_format_orc_dictionary_key_size_threshold`를 활성화한 상태에서 ClickHouse 자체로 작성한 파일도 이에 해당합니다. [#110492](https://github.com/ClickHouse/ClickHouse/pull/110492) ([tiandiwonder](https://github.com/tiandiwonder)).
* `optimize_or_like_chain`이 활성화된 상태에서 `OR` 체인 내 `LIKE`/`ILIKE`/`match`의 좌변에 집계 함수나 윈도 함수가 있을 때 발생할 수 있던 논리 오류(`Function node with name '...' is not resolved as ordinary function`)를 수정했습니다. [#110641](https://github.com/ClickHouse/ClickHouse/pull/110641) ([groeneai](https://github.com/groeneai)).
* `Date`/`Date32`/`DateTime64` 값에 극단적인 `MONTH`, `WEEK`, `DAY` 인터벌 개수를 사용할 때 `toStartOfInterval`에서 발생하던 부호 있는 정수 오버플로우를 수정했습니다. [#110688](https://github.com/ClickHouse/ClickHouse/pull/110688) ([groeneai](https://github.com/groeneai)).
* `readWKT`와 `readWKTPoint`가 `POINT EMPTY`에 대해 초기화되지 않은 좌표(스칼라) 또는 이전 행의 오래된 좌표(벡터화)를 반환하던 문제를 수정했습니다. ClickHouse의 `Point`는 빈 표현이 없는 고정된 `Tuple(Float64, Float64)`이므로, 이제 `POINT EMPTY`는 `CANNOT_PARSE_TEXT` 오류와 함께 거부됩니다. [#110692](https://github.com/ClickHouse/ClickHouse/pull/110692) ([groeneai](https://github.com/groeneai)).
* `flipCoordinates`에서 `Geometry` 타입이 유실되던 문제를 수정했습니다. 이제 `Geometry` 인수를 전달하면 내부의 `Variant(...)`가 아닌 `Geometry` 타입으로 결과가 반환되므로, `areaCartesian` 같은 함수에 바로 전달할 수 있습니다. [#110694](https://github.com/ClickHouse/ClickHouse/pull/110694) ([groeneai](https://github.com/groeneai)).
* 빈 폴리곤의 WKB 직렬화가 정규 형식이 아니던 문제를 수정했습니다. 이제 `wkb(POLYGON EMPTY)`는 불필요한 점 0개짜리 단일 링 대신 `numRings = 0`을 출력하므로, 표준 빈 폴리곤을 WKB로 왕복 변환해도 아이덴티티가 보존됩니다. [#110796](https://github.com/ClickHouse/ClickHouse/pull/110796) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/110835) ([groeneai](https://github.com/groeneai)).
* `col`이 `LowCardinality`일 때 `throwIf(notLike(col, pattern))`(및 함수를 인자로 받는 다른 `throwIf`)가 무조건 예외를 발생시키던 문제를 수정했습니다. 기본 `LowCardinality` 구현은 딕셔너리 전체에 대해 `throwIf`를 실행했는데, 이 딕셔너리에는 이를 참조하는 행이 없더라도 예약된 기본값이 항상 포함되어 있습니다. 따라서 사용되지 않는 이 슬롯의 값이 0이 아니면 조건을 만족하지 않는 데이터에 대해서도 `throwIf`가 예외를 발생시켰습니다. [#110864](https://github.com/ClickHouse/ClickHouse/pull/110864) ([groeneai](https://github.com/groeneai)).
* `-Tuple` 컴비네이터를 적용한 집계 함수를 `RESPECT NULLS`와 함께 사용하여 중간 상태(`-State`, 분산 집계, `WITH ROLLUP`/`WITH CUBE`)를 생성할 때 발생하던 크래시를 수정했습니다. 결합된 함수의 이름이 잘못된 상태 변형을 기준으로 지정되어, 직렬화된 `AggregateFunction` 타입을 다시 읽어 들일 때 호환되지 않는 메모리 내 레이아웃으로 재해석되었습니다. [#110930](https://github.com/ClickHouse/ClickHouse/pull/110930) ([groeneai](https://github.com/groeneai)).
* `mysql` 테이블 함수 또는 `MySQL` 테이블/데이터베이스 엔진을 통해 널 허용 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](https://github.com/ClickHouse/ClickHouse/pull/110943) ([groeneai](https://github.com/groeneai)).
* 버전이 지정된 집계 상태를 포함하는 `SimpleAggregateFunction` 래퍼를 이전 버전의 피어로 보낼 때의 `Native` 직렬화 문제를 수정했습니다. [#110997](https://github.com/ClickHouse/ClickHouse/pull/110997) ([groeneai](https://github.com/groeneai)).
* 분산 쿼리 및 병렬 레플리카를 사용하는 쿼리에서 `Variant` 타입(`Geometry` 포함) 상수에 대해 발생하던 `CANNOT_CONVERT_TYPE` 오류를 수정했습니다. [#111136](https://github.com/ClickHouse/ClickHouse/pull/111136) ([fm4v](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/111245) ([groeneai](https://github.com/groeneai)).
* 1초 미만 인터벌을 사용하는 `toStartOfInterval`에서 발생하던 부호 있는 정수 오버플로우를 수정했습니다. `Int64` 하한에서 한 인터벌 이내에 있는 `DateTime64` 값은 내림한 결과가 경고 없이 양수 쓰레기 값으로 래핑되었으나, 이제는 함수가 `DECIMAL_OVERFLOW` 예외를 발생시킵니다. [#111370](https://github.com/ClickHouse/ClickHouse/pull/111370) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 중첩된 컴비네이터 하에서 `-Tuple` 컴비네이터를 `RESPECT NULLS` / `IGNORE NULLS` 수정자와 함께 사용하는 분산 쿼리(예: `anyRespectNullsStateTuple(...) IGNORE NULLS`)에서 발생하던 예외(`CANNOT_CONVERT_TYPE` 또는 논리 오류)를 수정했습니다. [#111570](https://github.com/ClickHouse/ClickHouse/pull/111570) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 파싱이 실패했을 때 일부만 추가된 바이트가 컬럼에 남는 `FixedString` 텍스트 try-parse 문제를 수정했습니다. 이 문제로 인해 `Variant`/`Array`/`Nullable` 컬럼을 직렬화하는 과정에서 `Sizes of nested column and null map of Nullable column are not equal` 논리 오류가 발생하거나, 결과 바이트가 아무런 경고 없이 밀릴 수 있었습니다. [#111908](https://github.com/ClickHouse/ClickHouse/pull/111908) ([groeneai](https://github.com/groeneai)).
* `Buffer` 테이블을 통해 동적 서브컬럼(`JSON` 또는 `Dynamic` 컬럼 내부의 경로)을 읽을 때 예외가 발생하고 데이터가 아무런 경고 없이 누락되던 문제를 수정했습니다. [#111948](https://github.com/ClickHouse/ClickHouse/pull/111948) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `countSubstringsCaseInsensitiveUTF8`의 이차 복잡도 문제를 수정했습니다. 이 문제로 인해 일치 항목이 많은 수 메가바이트 크기의 haystack에서는 함수 실행에 수 분이 걸렸습니다. 이제 각 일치 항목의 문자 오프셋을 매번 행의 시작부터 다시 계산하지 않고 점진적으로 갱신합니다. [#112003](https://github.com/ClickHouse/ClickHouse/pull/112003) ([groeneai](https://github.com/groeneai)).
* 인수 3개를 받는 `toStartOfInterval` 오버로드에서 발생하던 부호 있는 정수 오버플로를 수정했습니다. `origin` 인수가 `Int64`의 하한에 가까우면 함수가 오류를 보고하지 않고 랩어라운드된 값을 반환했습니다. [#112045](https://github.com/ClickHouse/ClickHouse/pull/112045) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 집계 상태(aggregate state)는 테이블 함수 매개변수에서 전혀 지원되지 않으므로 사용할 수 없도록 했습니다. [#112087](https://github.com/ClickHouse/ClickHouse/pull/112087) ([PedroTadim](https://github.com/PedroTadim)).
* `values` 테이블 함수가 `String`/텍스트 컬럼에 삽입된 비리터럴 `Bool` 상수(예: `CAST(true, 'Nullable(Bool)')`)를 `true`/`false`가 아닌 `1`/`0`으로 렌더링하던 문제를 수정했습니다. [#112308](https://github.com/ClickHouse/ClickHouse/pull/112308) ([yakov-olkhovskiy](https://github.com/yakov-olkhovskiy)).
* 상태 표현은 같지만 최종 결과 타입이 서로 다른 함수들에서 나온 집계 상태가 담긴 컬럼에 `finalizeAggregation`을 적용할 때 발생하던 논리 오류(디버그 및 새니타이저 빌드에서는 프로세스가 중단됨)를 수정했습니다. `UNION`으로 합쳐지거나 `arrayReduce`로 생성된 `quantileState`와 `quantilesState(0.9)`가 그 예입니다. 이제 이러한 쿼리는 크래시 대신 일반 오류를 발생시킵니다. [#112662](https://github.com/ClickHouse/ClickHouse/pull/112662) ([zainulabidin302](https://github.com/zainulabidin302)).
* JSON 숫자를 읽는 데 사용되는 `Poco::NumberParser`에서 대상 타입의 범위를 벗어나는 정수를 잘못 파싱하던 문제를 수정했습니다. 이러한 숫자는 거부되지 않고 아무런 경고 없이 잘못된 값으로 파싱되었으며(예: `18446744073709551617`이 `1`이 됨), `Int64` 최댓값을 초과하는 `UInt64` 숫자는 AST JSON 왕복 변환 후 값이 보존되지 않았습니다. [#112904](https://github.com/ClickHouse/ClickHouse/pull/112904) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `IN` 오른쪽의 `Bool` 상수가 `String` 타입의 왼쪽 값에 맞춰 변환될 때 표준 값인 `'true'`/`'false'`가 아닌 `'1'`/`'0'`으로 변환되던 문제를 수정했습니다(이제 `CAST` 및 `values` 테이블 함수와 일관되게 동작합니다). [#113051](https://github.com/ClickHouse/ClickHouse/pull/113051) ([yakov-olkhovskiy](https://github.com/yakov-olkhovskiy)).
* `viewIfPermitted`의 AST 포맷팅이 일관되지 않던 문제를 수정했습니다. 테이블 함수 형식의 `ELSE` 분기에서 보통 연산자로 작성되는 함수(예: `not`)가 잘못 포맷팅되던 문제와, 표현식 형식 `viewIfPermitted(...)`가 `ELSE`와 함께 잘못 포맷팅되던 문제가 이에 해당합니다. [#113652](https://github.com/ClickHouse/ClickHouse/pull/113652) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Date`/`DateTime`/`DateTime64`/`Time`/`Time64`에 대한 `avg`에서 발생하던 정의되지 않은 동작과 잘못된 결과를 수정했습니다. 이제 평균을 정수 공간에서 정확하게 계산하므로, `Int64` 경계 오버플로우(UB, x86에서 잘못된 결과 발생)와 2^53을 초과하는 값에서의 `Float64` 정밀도 손실(나노초 단위에서 드러남)이 모두 해결됩니다. [#113912](https://github.com/ClickHouse/ClickHouse/pull/113912) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Experimental `SZ3` 압축 코덱의 메모리 누수를 수정했습니다. 압축이 잘 되지 않거나 손상된 데이터를 압축하다가 예외가 발생하여 실패하면 임시 스크래치 버퍼가 해제되지 않고 남아 있었습니다. [#113916](https://github.com/ClickHouse/ClickHouse/pull/113916) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `bloom_filter` 인덱스를 `FixedString` 상수로 조회할 때 `hasAny`, `hasAll`, `has`, `indexOf`, `mapContainsKey`, `mapContainsValue`, `mapContains`가 실제보다 적은 행을 반환하거나 `TOO_LARGE_STRING_SIZE` 오류로 실패하던 문제를 수정했습니다. 인덱스는 패딩된 형태의 상수를 해시하는 반면 함수는 패딩되지 않은 형태로 비교하기 때문에, 일치하는 그래뉼을 건너뛰는 문제가 있었습니다. [#114089](https://github.com/ClickHouse/ClickHouse/pull/114089) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 집계가 JIT 컴파일되고 데이터에 1970년 이전의 타임스탬프가 포함된 경우 `DateTime64` 컬럼에 대한 `min`과 `max`가 잘못된 결과를 반환하던 문제를 수정했습니다. `Decimal64`에서 파생된 `DateTime64`와 `Time64`에 대해 `is_signed`가 특수화되지 않아 생성된 코드가 틱 수를 부호 없는 정수로 비교했고, 그 결과 1970년 이전 타임스탬프가 `max`에서는 선택되고 `min`에서는 제외되었습니다. [#114168](https://github.com/ClickHouse/ClickHouse/pull/114168) ([groeneai](https://github.com/groeneai)).
* 배열 원소와 검색 패턴의 문자열 타입이 서로 다른 경우(예: `Array(FixedString(N))` 원소와 `String` 검색 패턴을 비교하는 경우) `arrayExists(x -> x = needle, arr)`가 잘못된 결과를 반환하거나 `TOO_LARGE_STRING_SIZE` 오류로 실패하던 문제를 수정했습니다. 기본으로 활성화된 `optimize_rewrite_array_exists_to_has` 최적화가 이러한 호출을 `has`로 재작성했는데, `has`는 `=`와 달리 0 패딩을 고려하여 비교하지 않습니다. [#114496](https://github.com/ClickHouse/ClickHouse/pull/114496) ([groeneai](https://github.com/groeneai)).
* Map 또는 JSON 컨테이너에 적용된 `LIKE/ILIKE` 연산자의 텍스트 인덱스 평가 문제를 수정했습니다. [#114544](https://github.com/ClickHouse/ClickHouse/pull/114544) ([ahmadov](https://github.com/ahmadov)).
* `DateTime64` 및 넓은 `Decimal` 값에 대한 `quantile`과 `quantiles`에서 발생하던 정의되지 않은 동작과 경계값의 잘못된 결과를 수정했습니다. [#114919](https://github.com/ClickHouse/ClickHouse/pull/114919) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Time` 분기가 `Time64`, `DateTime` 또는 `DateTime64`와 함께 사용되고 표현식이 JIT 컴파일될 때 `if`와 `multiIf`가 음수 대신 큰 양수 값을 반환하던 문제를 수정했습니다. [#115146](https://github.com/ClickHouse/ClickHouse/pull/115146) ([groeneai](https://github.com/groeneai)).
* 국제 날짜 변경선을 넘은 이후의 `Pacific/Kiritimati`, `Pacific/Apia`처럼 UTC 오프셋이 1970-01-01 시점의 오프셋과 정확히 하루 차이가 나는 시간대와 1970년 이전의 대부분의 시간대에서 `timezoneOffset`(별칭 `timeZoneOffset`)이 정확히 하루만큼 어긋난 오프셋을 반환하던 문제를 수정했습니다. 이에 따라 해당 오프셋을 사용하는 `parseDateTime`, `parseDateTimeOrNull`, `parseDateTime64`, `parseDateTimeInJodaSyntax`, `EXTRACT(TIMEZONE_HOUR / TIMEZONE_MINUTE ...)`, `formatDateTime`'의 `%z`, `toUTCTimestamp`, `fromUTCTimestamp`의 동작도 함께 수정됩니다. [#115332](https://github.com/ClickHouse/ClickHouse/pull/115332) ([groeneai](https://github.com/groeneai)).
* `has` 또는 `notHas` 프레디케이트에 NULL 배열 원소가 포함되어 있고 프라이머리 키가 `String`, `Array(String)` 또는 `Map(String, String)`인 경우 `Code: 349. Cannot convert NULL value to non-Nullable type` 오류가 발생하던 문제를 수정했습니다. 또한 해당 원소가 NULL 값을 가진 `Dynamic` 또는 `Variant`일 때 잘못된 결과가 반환되던 문제도 수정했습니다. 이제 다른 키 타입과 마찬가지로 키 분석 단계에서 NULL이 집합에서 제외됩니다. [#115647](https://github.com/ClickHouse/ClickHouse/pull/115647) ([groeneai](https://github.com/groeneai)).
* 대상 타입이 `LowCardinality`일 때 `cast_keep_nullable`이 널 허용 여부를 유지하지 못하던 문제를 수정했습니다. 기존에는 NULL을 가질 수 있는 값을 `LowCardinality(T)`로 캐스팅하면 `LowCardinality(Nullable(T))`가 반환되지 않고 `CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN` 오류가 발생했습니다. [#115851](https://github.com/ClickHouse/ClickHouse/pull/115851) ([groeneai](https://github.com/groeneai)).

<h3 id="index-and-query-cache-fixes">
  인덱스 및 쿼리 캐시 관련 수정 사항
</h3>

* `DEFAULT` 표현식이 있으면서 파트에 구체화되지 않은 컬럼(예: `ALTER TABLE ADD COLUMN` 이후 또는 `ALTER TABLE MATERIALIZE COLUMN` 수행 중)의 서브컬럼을 읽을 때 발생하던 문제를 수정했습니다. 해당 서브컬럼이 평가된 `DEFAULT` 표현식 값 대신 타입 기본값으로 채워졌으며, 이러한 `QBit` 컬럼에 전치(transposed) 벡터 거리 함수(`cosineDistanceTransposed` 등)를 실행하면 `SIZES_OF_ARRAYS_DONT_MATCH` 오류가 발생했습니다. [#110636](https://github.com/ClickHouse/ClickHouse/pull/110636) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 프라이머리 키 분석 중 `IN` 서브쿼리 집합 빌드가 아무런 알림 없이 실패하면(예: `overflow_mode = 'break'`에서 서브쿼리 시간 초과) 쿼리 파이프라인에서 해당 집합이 계속 빌드되지 않은 상태로 남아 `Not-ready Set is passed as the second argument` 예외가 발생할 수 있던 문제를 수정했습니다. [#107924](https://github.com/ClickHouse/ClickHouse/pull/107924) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `set` 데이터 스키핑 인덱스가 있는 테이블에서 행 정책(row policy)이 항상 참인 조건과 인덱싱되지 않은 컬럼에 대한 검사를 조합해 필터링할 때 `SELECT`가 `NOT_FOUND_COLUMN_IN_BLOCK` 오류로 실패하던 문제를 수정했습니다. [#107971](https://github.com/ClickHouse/ClickHouse/pull/107971) ([tiandiwonder](https://github.com/tiandiwonder)).
* 이제 `getClientHTTPHeader`가 비결정적 함수로 올바르게 처리되므로, 해당 결과가 쿼리 결과 캐시에서 더 이상 잘못 재사용되지 않습니다. [#108029](https://github.com/ClickHouse/ClickHouse/pull/108029) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 쿼리 조건 캐시(`use_query_condition_cache = 1`)가 스킵 인덱스에서 도출된 마크 제외 정보를, 다른 스킵 인덱스 집합을 실행한 쿼리(예: `use_skip_indexes = 0`, `ignore_data_skipping_indices` 또는 다른 `use_skip_indexes_for_disjunctions` 모드 사용 시)에 재사용하여 잘못된 결과가 반환되던 문제를 수정했습니다. 이제 스킵 인덱스에서 도출된 캐시 엔트리는 실제로 실행된 스킵 인덱스 집합을 키로 사용하며, 행 수준의 쿼리 조건 캐시 엔트리는 이러한 모든 경우에 계속 재사용할 수 있습니다. [#108548](https://github.com/ClickHouse/ClickHouse/pull/108548) ([groeneai](https://github.com/groeneai)).
* 파일 시스템 캐시를 통해 읽는 쿼리가 `KILL QUERY`로 취소된 후에도 진행 중인 다운로드를 계속 기다릴 수 있던 멈춤 현상과, 갱신 작업이 이러한 대기 상태에 멈춘 갱신 가능 구체화 뷰를 삭제하거나 `SYSTEM STOP VIEW`를 실행하면 작업이 차단되던 문제를 수정했습니다. [#109116](https://github.com/ClickHouse/ClickHouse/pull/109116) ([murphy-4o](https://github.com/murphy-4o)).
* 파트에 최종 마크가 없는 경우(비적응형 세분화 수준, `index_granularity_bytes = 0`) 역순(`DESC`) 키 컬럼이 있는 테이블에서 프라이머리 키 인덱스가 그래뉼을 잘못 제외하여 잘못된 쿼리 결과가 반환되던 문제를 수정했습니다. [#109901](https://github.com/ClickHouse/ClickHouse/pull/109901) ([nihalzp](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/110491) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 병렬 레플리카가 활성화된 상태에서 스칼라 서브쿼리 또는 상수 참조 벡터를 사용하여 `QBit` 컬럼에 대한 전치 거리 함수(예: `cosineDistanceTransposed`)를 호출할 때 발생하던 `NOT_FOUND_COLUMN_IN_BLOCK` 오류를 수정했습니다. [#110729](https://github.com/ClickHouse/ClickHouse/pull/110729) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 텍스트 인덱스의 표현식에 `arrayFilter(s -> s != '', ...)`와 같은 빈 문자열 비교가 포함된 경우, `optimize_empty_string_comparisons` 설정이 쿼리 쪽에서만 해당 비교를 `notEmpty`로 재작성하는 탓에 텍스트 인덱스가 사용되지 않던 문제를 수정했습니다. [#112115](https://github.com/ClickHouse/ClickHouse/pull/112115) ([Ergus](https://github.com/Ergus)).
* 컬럼이 텍스트 인덱스 가상 컬럼으로 재작성되더라도 `PREWHERE`와 `WHERE` 필터 조건 모두에서 참조되는 경우에는 해당 컬럼을 제거하지 않도록 수정했습니다. [#114460](https://github.com/ClickHouse/ClickHouse/pull/114460) ([ahmadov](https://github.com/ahmadov)).
* 지연 포스팅 리스트 적용 모드에서 텍스트 인덱스가 있는 테이블에 대한 쿼리가 읽기 도중 취소될 때 발생하던 논리 오류 `Multi-block postings must be compressed`를 수정했습니다. [#114636](https://github.com/ClickHouse/ClickHouse/pull/114636) ([CurtizJ](https://github.com/CurtizJ)).
* `WHERE` 절에서 `NOT` 안에 `NULL` 표현식이 포함된 경우(예: `SELECT count() FROM t WHERE NOT (id >= 20 AND NULL)`) 잘못된 결과가 반환되던 문제를 수정했습니다. 인덱스 분석이 이러한 조건을 전체 범위에서 항상 참으로 간주해 필터를 건너뛰었기 때문에, `count()`가 쿼리에서 제외되어야 할 행까지 반환하고 해당 조건을 사용한 `ALTER TABLE ... DELETE`가 유지되어야 할 행까지 삭제했습니다. [#115152](https://github.com/ClickHouse/ClickHouse/pull/115152) ([groeneai](https://github.com/groeneai)).
* `query_plan_join_shard_by_pk_ranges`가 활성화된 `full_sorting_merge` JOIN에서 한쪽이 프라이머리 키나 컬럼 통계에 의해, 또는 테이블이 비어 있어서 파트가 하나도 남지 않을 때 발생하던 `LOGICAL_ERROR`(`Join is supported only for pipelines with one output port`)를 수정했습니다. [#115352](https://github.com/ClickHouse/ClickHouse/pull/115352) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* \_part\_starting\_offset에 대한 필터에서는 쿼리 조건 캐시를 사용하지 않도록 했습니다. [#115358](https://github.com/ClickHouse/ClickHouse/pull/115358) ([azat](https://github.com/azat)).
* 암시적 minmax 인덱스(`add_minmax_index_for_numeric_columns` 등)가 있는 테이블에서 하나의 `ALTER TABLE` SQL 문에 `RENAME COLUMN`과 `MODIFY SETTING` 같은 다른 명령을 함께 사용할 때 발생하던 `LOGICAL_ERROR: Index with name auto_minmax_index_<column> already exists`를 수정했습니다. 또한 일반 컬럼의 이름을 변경한 뒤 이어서 실행한 `DROP COLUMN`이 `UNKNOWN_IDENTIFIER`로 실패하거나, 이어서 실행한 `ADD COLUMN`에 암시적 인덱스가 생성되지 않는 문제도 더 이상 발생하지 않습니다. [#116063](https://github.com/ClickHouse/ClickHouse/pull/116063) ([groeneai](https://github.com/groeneai)).
* 와일드카드(`%`, `_`)가 없는 `LIKE`/`NOT LIKE` 패턴이 이제 정확한 프라이머리 키 범위를 사용합니다. 따라서 더 넓은 접두사 범위 대신, 동등한 `=`/`!=` 프레디케이트와 같은 수의 그래뉼만 읽습니다. [#107077](https://github.com/ClickHouse/ClickHouse/pull/107077) ([groeneai](https://github.com/groeneai)).
* 프라이머리 키에 대한 `IN`/`NOT IN` 조건이 키를 상수로 나누는 `intDiv`로 감싸고 있고, 키가 부호 없는 정수이면서 그 값이 `intDiv` 결과 타입의 부호 있는 범위 경계를 넘는 경우(예: `intDiv(uint64_column, -9223372036854775807)`) 발생하던 `LOGICAL_ERROR`(`Invalid binary search result in MergeTreeSetIndex`)와 릴리스 빌드에서 인덱스 프루닝이 누락되던 문제를 수정했습니다. [#107586](https://github.com/ClickHouse/ClickHouse/pull/107586) ([groeneai](https://github.com/groeneai)).
* 모든 원소가 1이면서 BSI 비트 구성이 다른 벡터를 곱할 때 `numericIndexedVectorPointwiseMultiply`가 빈 결과를 반환하던 문제를 수정했습니다. [#108027](https://github.com/ClickHouse/ClickHouse/pull/108027) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 서로 다른 짧은 토큰이 많은 데이터에 `positions = 1`로 텍스트 인덱스를 빌드할 때 발생하던 heap-buffer-overflow를 수정했습니다. [#108659](https://github.com/ClickHouse/ClickHouse/pull/108659) ([groeneai](https://github.com/groeneai)).
* 텍스트 인덱스의 `preprocessor` 및 `postprocessor` 표현식에서 `ALIAS` 컬럼을 참조할 수 있도록 했습니다. [#110014](https://github.com/ClickHouse/ClickHouse/pull/110014) ([Ergus](https://github.com/Ergus)).
* `LIMIT ... WITH TIES`를 사용할 때는 벡터 검색 최적화를 건너뛰도록 수정했습니다. 이 최적화는 ANN 검색 대상을 정확히 n개의 후보로 제한하므로, n번째 행과 동률인 행이 누락되기 때문입니다. [#110453](https://github.com/ClickHouse/ClickHouse/pull/110453) ([tamish560](https://github.com/tamish560)).
* 인덱스가 단순 컬럼이 아닌 표현식(예: `lower(...)` 전처리기를 사용하는 `assumeNotNull(col)`)에 정의된 경우 `ILIKE`에서 텍스트 인덱스가 사용되지 않던 문제를 수정했습니다. 이제 이러한 쿼리는 모든 그래뉼을 읽지 않고 인덱스를 사용합니다. [#110595](https://github.com/ClickHouse/ClickHouse/pull/110595) ([ahmadov](https://github.com/ahmadov)).
* `vector_search_with_rescoring = 1`과 지연 머티리얼라이즈(lazy materialization)를 함께 사용하는 벡터 검색 쿼리에서 여러 거리 값이 동률일 때 발생할 수 있던 `LOGICAL_ERROR`(`LazyMaterializingTransform: Number of rows in lazy chunk N does not match number of offsets M`)를 수정했습니다. [#111003](https://github.com/ClickHouse/ClickHouse/pull/111003) ([groeneai](https://github.com/groeneai)).
* `i8` 양자화를 사용하는 `vector_similarity` 인덱스에서 크기의 제곱이 무한대로 오버플로우되는 벡터를 거부하도록 수정했습니다. 이전에는 이러한 벡터가 usearch에서 정의되지 않은 동작을 유발하여, 오류 없이 무의미한 값을 생성했습니다. [#111085](https://github.com/ClickHouse/ClickHouse/pull/111085) ([groeneai](https://github.com/groeneai)).
* 페이지 캐시가 활성화된 `plain_rewritable` 디스크에서 오래된 데이터를 읽던 문제를 수정했습니다. [#111105](https://github.com/ClickHouse/ClickHouse/pull/111105) ([Michicosun](https://github.com/Michicosun)).
* `String`(또는 더 짧은 `FixedString`) 키나 minmax 스킵 인덱스를 더 긴 `FixedString` 상수와 비교하여 필터링할 때(예: `toFixedString('abc', 257) = string_col`) `count()` 결과가 잘못되고 행이 누락되던 문제를 수정했습니다. 기본 키 및 minmax 프루닝이 NUL로 채워진 상수를 기준으로 범위를 구성하는 바람에 조건에 맞는 그래뉼까지 잘못 건너뛰었습니다. [#111106](https://github.com/ClickHouse/ClickHouse/pull/111106) ([groeneai](https://github.com/groeneai)).
* 오프셋 인덱스가 0번 행에서 시작하지 않는 Parquet 파일을 읽을 때 발생하던 문제를 수정했습니다. 이러한 파일로 인해 네이티브 Parquet 리더가 잘못된 행을 반환하거나 `INCORRECT_DATA` 대신 `LOGICAL_ERROR`를 보고할 수 있었습니다. 이제 오프셋 인덱스를 읽을 때 유효성을 검사합니다. [#114530](https://github.com/ClickHouse/ClickHouse/pull/114530) ([groeneai](https://github.com/groeneai)).

<h3 id="security-access-backup-and-restore-fixes">
  보안, 액세스, 백업 및 복원 관련 수정 사항
</h3>

* 이제 대상 테이블에 `fsync_after_insert`가 활성화되어 있으면 `RESTORE`가 복원된 파트 파일을 fsync하므로, 복원된 파트도 삽입된 파트와 마찬가지로 정전 시 내구성이 보장됩니다. 이전에는 복원된 파일을 쓰고 닫기만 할 뿐 fsync하지 않았기 때문에, `RESTORE`가 `RESTORED`를 반환한 직후 정전이 발생하면 파트가 손상되어 테이블이 비어 있을 수 있었습니다. [#111378](https://github.com/ClickHouse/ClickHouse/pull/111378) ([groeneai](https://github.com/groeneai)).
* 인증되지 않은 TCP 클라이언트가 interserver 포트를 통해 테이블 존재 여부와 복제 상태를 탐지할 수 있던 보안 문제를 수정했습니다. [#99854](https://github.com/ClickHouse/ClickHouse/pull/99854) ([tiandiwonder](https://github.com/tiandiwonder)).
* `DELETE FROM`(경량한 삭제)이 `ALTER DELETE` 외에 `ALTER UPDATE` 권한까지 요구하던 문제를 수정했습니다. 이제 문서에 명시된 대로 `ALTER DELETE` 권한만 부여받은 사용자도 `DELETE FROM`을 실행할 수 있습니다. [#107491](https://github.com/ClickHouse/ClickHouse/pull/107491) ([tiandiwonder](https://github.com/tiandiwonder)).
* Atomic 데이터베이스에서 `CREATE TABLE ... AS SELECT` 쿼리가 실패하면(예: 서브쿼리에서 참조하는 테이블에 사용자의 액세스 권한이 없는 경우) 빈 테이블이 남던 문제를 수정했습니다. 이전에는 재시도하면 원래 오류 대신 테이블이 이미 존재한다는 오류가 보고되었습니다. 이제 테이블은 임시 테이블을 거쳐 생성되며, 데이터가 모두 채워진 후에야 표시됩니다. [#108048](https://github.com/ClickHouse/ClickHouse/pull/108048) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 사용자에게 `ALIAS` 컬럼에 대한 `SELECT` 액세스만 부여된 테이블에서 `SELECT count()`(또는 기타 단순 쿼리)를 실행하면 `LOGICAL_ERROR`(`No available columns`)가 발생하던 문제를 수정했습니다. [#108056](https://github.com/ClickHouse/ClickHouse/pull/108056) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 인증되지 않은 요청으로 인해 ClickHouse가 전달된(forwarded) 클라이언트 주소 헤더에 포함된 호스트 이름을 해석할 수 있던 문제를 수정했습니다. 이제 ClickHouse는 이러한 헤더에서 숫자 형식의 IP 주소만 허용합니다. 유효하지 않은 값은 DNS 해석 없이 전달 주소 기반 쿼터 집계에서 무시됩니다. `auth_use_forwarded_address`가 활성화된 경우, 유효하지 않은 전달 주소는 인증 단계에서 거부됩니다. 거부 내역은 debug 수준으로 로그에 기록됩니다. [#111060](https://github.com/ClickHouse/ClickHouse/pull/111060) ([otselnik](https://github.com/otselnik)).
* 분석기가 비활성화된 경우(`enable_analyzer = 0`) 매개변수화된 뷰(parameterized view)에 `SQL SECURITY DEFINER`(및 `SQL SECURITY NONE`)가 적용되지 않던 문제를 수정했습니다. 이전에는 기본 테이블에 대한 권한이 없는 사용자가 이러한 뷰를 조회하면 `ACCESS_DENIED` 오류로 실패했습니다. 분석기를 활성화한 상태에서는 동일한 뷰가 정상적으로 동작했습니다. [#111458](https://github.com/ClickHouse/ClickHouse/pull/111458) ([groeneai](https://github.com/groeneai)).
* `MySQL` 통합에서 명명된 컬렉션이 자격 증명을 내용(contents) 형식으로 저장한 경우, 빈 `ssl_ca_pem`/`ssl_cert_pem`/`ssl_key_pem` 값으로 TLS 자격 증명을 재정의하려 하면 이를 거부하지 않고 받아들여, 구성된 CA 또는 클라이언트 인증서가 별도의 알림 없이 삭제되던 결함을 수정했습니다. [#113947](https://github.com/ClickHouse/ClickHouse/pull/113947) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 본문에 JOIN이 포함되어 있고 `SQL SECURITY DEFINER` 또는 `SQL SECURITY NONE`으로 선언된 뷰에서 `EXPLAIN ANALYZE`가 조인 통계를 누락하던 문제를 수정했습니다. debug 및 sanitizer 빌드에서는 해당 쿼리가 논리 오류 `JoinStep analyzed without the analyze mode`를 일으키며 중단되었습니다. [#115156](https://github.com/ClickHouse/ClickHouse/pull/115156) ([groeneai](https://github.com/groeneai)).
* `RESTORE ... AS <new name>` 실행 후 갱신 가능 구체화 뷰의 `REFRESH ... DEPENDS ON` 목록이 계속 원래 데이터베이스를 가리키던 문제를 수정했습니다. 이로 인해 복원된 뷰는 더 이상 읽지 않는 테이블에 반응하여 갱신되고, 정작 자신의 상위 테이블 갱신은 무시했으며, 원래 데이터베이스가 삭제되면 갱신이 아예 중단되었습니다. [#115689](https://github.com/ClickHouse/ClickHouse/pull/115689) ([groeneai](https://github.com/groeneai)).
* 삭제와 재생성이 동시에 진행 중인 `Replicated` 데이터베이스를 백업할 때 발생하던 `LOGICAL_ERROR` 예외를 수정했습니다. 이제 이러한 백업은 `CANNOT_GET_REPLICATED_DATABASE_SNAPSHOT` 오류를 반환하며 깔끔하게 실패합니다. [#100651](https://github.com/ClickHouse/ClickHouse/pull/100651) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 동일한 역할에 대해 `GRANT role TO role`을 실행하면 이제 `system.role_grants`에 자기 자신을 참조하는 엔트리가 아무런 알림 없이 생성되는 대신 `BAD_ARGUMENTS` 오류와 함께 거부됩니다. [#103315](https://github.com/ClickHouse/ClickHouse/pull/103315) ([zxuhan](https://github.com/zxuhan)).
* `MaterializedPostgreSQL` 데이터베이스의 `BACKUP`이 더 이상 "Table ... were created or changed its definition during scanning" 메시지와 함께 무한정 멈추지 않으며, 이제 테이블 데이터를 실제로 백업합니다(기반 `ReplacingMergeTree`에 위임). 이 백업은 독립형 `ReplacingMergeTree`로 복원할 수 있습니다. [#107433](https://github.com/ClickHouse/ClickHouse/pull/107433) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 딕셔너리에 대해 `SHOW DICTIONARIES` 권한만 있는 사용자도 `EXISTS <dictionary>`를 실행할 수 있도록 했습니다(이전에는 `SHOW TABLES` 권한이 필요했습니다). [#108084](https://github.com/ClickHouse/ClickHouse/pull/108084) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 마무리 단계 전에 실패한 `BACKUP ... TO Memory(...)`가 제대로 정리되지 않던 문제를 수정했습니다. 이전에는 실패한 백업이 등록된 상태로 남아 있어 해당 이름을 재사용할 수 없었습니다. [#109947](https://github.com/ClickHouse/ClickHouse/pull/109947) ([jkartseva](https://github.com/jkartseva)).
* 동일한 zip 아카이브에 대한 이전 읽기가 스트림 도중 실패한 후 해당 아카이브를 다시 읽을 때(예: zip 백업에서 `RESTORE`하는 경우) 발생할 수 있던 `ReadBuffer is canceled. Can't read from it.` 논리 오류(debug/새니타이저 빌드에서는 서버 중단)를 수정했습니다. [#110197](https://github.com/ClickHouse/ClickHouse/pull/110197) ([groeneai](https://github.com/groeneai)).
* `const` 메서드인 `AccessRights::getFilters`가 동시에 실행되는 쿼리들이 공유하는 액세스 권한 트리를 변경하여 발생하던 힙 손상 문제를 수정했습니다. 이 문제로 인해 서버 종료 시 크래시가 발생할 수 있었습니다. [#112692](https://github.com/ClickHouse/ClickHouse/pull/112692) ([groeneai](https://github.com/groeneai)).

<h3 id="distributed-execution-tables-views-and-dictionaries">
  분산 실행, 테이블, 뷰 및 딕셔너리
</h3>

* `ALTER TABLE ... MOVE PART ... TO SHARD '<path>'`에서 불필요한 `Inconsistent AST formatting` 오류가 발생하던 문제를 수정했습니다. 쿼리 포매터가 `SHARD` 키워드를 누락하는 바람에 재포맷된 쿼리를 다시 파싱할 수 없었고, 그 결과 `LOGICAL_ERROR`가 발생했습니다(릴리스 빌드에서는 처리된 예외로, 디버그 및 sanitizer 빌드에서는 abort로 이어짐). [#109060](https://github.com/ClickHouse/ClickHouse/pull/109060) ([groeneai](https://github.com/groeneai)).
* 원격 데이터베이스 이름을 비워 둔 채 정의한 `Distributed` 테이블을 `distributed_product_mode = 'local'` 설정에서 JOIN에 사용할 때 발생하던 논리 오류(`!part.empty()`)를 수정했습니다. [#110677](https://github.com/ClickHouse/ClickHouse/pull/110677) ([groeneai](https://github.com/groeneai)).
* DISTINCT 조기 중단 limit 힌트로 결과의 앞부분을 한정할 수 없는 경우, 정렬된 `LIMIT`/`OFFSET`과 함께 사용한 `DISTINCT`가 잘못된 행을 반환하던 문제를 수정했습니다. 해당하는 경우는 음수 `LIMIT`(끝부분 대신 앞부분을 반환), 소수 `LIMIT`/`OFFSET`(소수 값은 전체를 읽은 후에야 결정됨), `LIMIT` 없이 단독으로 사용한 `OFFSET`(offset 이후의 끝부분이 누락됨)입니다. 예를 들어 여러 파트로 구성된 테이블에서 `SELECT DISTINCT intDiv(x, 100) FROM t ORDER BY intDiv(x, 100) LIMIT -1`을 실행하면 가장 큰 고유 값 대신 가장 작은 고유 값이 반환되었습니다. [#111326](https://github.com/ClickHouse/ClickHouse/pull/111326) ([groeneai](https://github.com/groeneai)).
* DESCRIBE TABLE에서 서브쿼리 뒤에 오는 별칭을 파서가 인식하지 못해 구문 오류가 발생하던 문제를 수정했습니다. [https://github.com/ClickHouse/ClickHouse/issues/100031](https://github.com/ClickHouse/ClickHouse/issues/100031) 을 해결합니다. [#100205](https://github.com/ClickHouse/ClickHouse/pull/100205) ([yariks5s](https://github.com/yariks5s)).
* `DETACH DATABASE` / `ATTACH DATABASE` 이후 `lazy_load_tables = 1`이 설정된 `Atomic` 데이터베이스에서 `ALTER RENAME COLUMN`이 진행되는 도중 `INSERT`를 동시에 수행하면 서버 abort(`Logical error: 'Block structure mismatch'`)가 발생할 수 있던 문제를 수정했습니다. [#104852](https://github.com/ClickHouse/ClickHouse/pull/104852) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/105896) ([groeneai](https://github.com/groeneai)).
* 서버 재시작(또는 `DETACH/ATTACH DATABASE`) 후 이미 삭제된 테이블을 다시 삭제하려 하면, 방금 삭제한 이름을 대안으로 제시하는 혼란스러운 "Maybe you meant X?" 힌트가 표시되던 문제를 수정했습니다. 이제 분리 시 `DatabaseOrdinary::startup_table` 및 `load_table`에서 비동기 로드 작업이 정리됩니다. [#106238](https://github.com/ClickHouse/ClickHouse/pull/106238) ([groeneai](https://github.com/groeneai)).
* `MaterializedPostgreSQL` 테이블 및 데이터베이스 엔진을 수정하여, 기본값이 아닌 PostgreSQL 스키마(`materialized_postgresql_schema`)에서도 단일 테이블 또는 데이터베이스를 복제할 수 있도록 했습니다. 같은 데이터베이스의 여러 스키마에 동일한 이름의 테이블이 있는 경우도 지원합니다(이전에는 이러한 테이블이 publication과 replication slot을 공유하여 서로 간섭했습니다). [#107425](https://github.com/ClickHouse/ClickHouse/pull/107425) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 병렬 레플리카를 사용하는 쿼리가 `GLOBAL JOIN` 임시 테이블로 전송된 테이블의 `ALIAS` 컬럼을 조회할 때 발생하던 `NO_SUCH_COLUMN_IN_TABLE`, 분산 `JOIN`의 양쪽에서 같은 이름의 `ALIAS` 컬럼을 선언할 때 발생하던 `MULTIPLE_EXPRESSIONS_FOR_ALIAS`, `Distributed` 테이블에서 다른 `ALIAS` 컬럼을 참조하는 `ALIAS` 컬럼을 선언할 때(`JOIN USING` 키로 사용하는 경우 포함) 발생하던 `UNKNOWN_IDENTIFIER` 오류를 수정했습니다. [#107700](https://github.com/ClickHouse/ClickHouse/pull/107700) ([yakov-olkhovskiy](https://github.com/yakov-olkhovskiy)).
* 갱신 가능 구체화 뷰(Refreshable Materialized View)가 `refresh_retries`를 매우 큰 값(`Int64` 최댓값 근처)으로 설정한 상태에서 실패한 갱신을 재시도할 때 발생하던 부호 있는 정수 오버플로우를 수정했습니다. 이 오버플로우로 인해 정의되지 않은 동작(undefined behavior) 새니타이저가 적용된 빌드에서 서버가 비정상 종료될 수 있었습니다. [#108005](https://github.com/ClickHouse/ClickHouse/pull/108005) ([groeneai](https://github.com/groeneai)).
* 키 컬럼이 딕셔너리 정의의 앞부분에 위치하지 않는 복합 키 딕셔너리를, 명시적 쿼리를 사용하는 로컬 `ClickHouse` 소스로 로드할 때 발생하던 예외(`CANNOT_PARSE_TEXT`)를 수정했습니다. 이제 원본 컬럼은 위치가 아닌 이름을 기준으로 딕셔너리 구조와 매칭됩니다. [#108053](https://github.com/ClickHouse/ClickHouse/pull/108053) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `WHERE` 절 없이 `Hive` 테이블을 쿼리할 때(예: `SELECT * FROM hive_table`) 발생하던 크래시(널 포인터 역참조)를 수정했습니다. [#108094](https://github.com/ClickHouse/ClickHouse/pull/108094) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 분산 쿼리가 아직 구체화되지 않은 `MATERIALIZED` CTE를 외부 테이블로 참조하고 원격 소스가 지연 생성(delayed source)될 때 발생할 수 있던 서버 크래시(세그멘테이션 폴트)를 수정했습니다. 이 크래시는 `RemoteQueryExecutor::sendExternalTables()` 내부에서 널 `Logger`를 역참조하여 발생했습니다. [#108547](https://github.com/ClickHouse/ClickHouse/pull/108547) ([groeneai](https://github.com/groeneai)).
* `STREAM` 읽기(`SELECT DISTINCT ... FROM table STREAM`)에서 `DISTINCT`를 실행할 때 발생하던 논리 오류(`Equal values are not contiguous within the range assumed to be sorted`)를 수정했습니다. `STREAM` 읽기는 정렬 키 순서가 아닌 커밋 순서로 행을 생성하므로, 이제 순서 기반 읽기(read-in-order) 최적화를 적용하지 않습니다. [#108568](https://github.com/ClickHouse/ClickHouse/pull/108568) ([groeneai](https://github.com/groeneai)).
* `optimize_skip_unused_shards = 1` 설정에서 `Distributed` 테이블의 세그먼트 분할 키가 분석기에 의해 상수 폴딩되는 표현식(예: `if(1, toInt32(id), toInt32(id) + 1)`)일 때 발생하던 예외(`Cannot find sharding key column`, debug/새니타이저 빌드에서는 서버 비정상 종료)를 수정했습니다. [#108737](https://github.com/ClickHouse/ClickHouse/pull/108737) ([groeneai](https://github.com/groeneai)).
* `Alias` 테이블을 통한 `INSERT ... SELECT`가 예외 없이 취소될 때(예: `timeout_overflow_mode = 'break'`) 발생하던 서버 비정상 종료(debug 및 새니타이저 빌드에서의 `LOGICAL_ERROR` / assertion)를 수정했습니다. [#108783](https://github.com/ClickHouse/ClickHouse/pull/108783) ([groeneai](https://github.com/groeneai)).
* `TimeSeries` 테이블에 대한 `INSERT ... SELECT`가 예외 없이 취소될 때(예: `timeout_overflow_mode = 'break'`) 발생하던 서버 비정상 종료(debug 및 새니타이저 빌드에서의 `LOGICAL_ERROR` / assertion)를 수정했습니다. [#108796](https://github.com/ClickHouse/ClickHouse/pull/108796) ([tiandiwonder](https://github.com/tiandiwonder)).
* 이전에 취소된 쿼리로 인해 동기화가 어긋난 연결이 풀에서 재사용될 때 분산 쿼리가 간헐적으로 `UNEXPECTED_PACKET_FROM_SERVER`("expected TablesStatusResponse, got ProfileInfo") 오류로 실패하던 문제를 수정했습니다. [#108854](https://github.com/ClickHouse/ClickHouse/pull/108854) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `Distributed` 테이블에 대한 쿼리에서 `MATERIALIZED` CTE가 조인 트리의 여러 위치(예: 조인된 서브쿼리 2개, 또는 조인된 서브쿼리와 `WHERE` 절의 스칼라 서브쿼리)에서 참조될 때 발생하던 `LOGICAL_ERROR`(`CTE '...' does not have query tree, but was not planned yet`)를 수정했습니다. 이제 해당 쿼리는 예외 없이 정상적으로 실행됩니다(이전에는 debug/새니타이저 빌드에서 서버가 비정상 종료되었습니다). [#108924](https://github.com/ClickHouse/ClickHouse/pull/108924) ([groeneai](https://github.com/groeneai)).
* materialized view 처리 중에 예약된 비동기 작업이 쿼리가 종료된 후에도 쿼리 수준의 리소스 추적 정보를 계속 사용할 수 있던 메모리 안전성 문제를 수정했습니다. [#108988](https://github.com/ClickHouse/ClickHouse/pull/108988) ([filimonov](https://github.com/filimonov)).
* analyzer를 사용하지 않는 상태에서 `UNION ALL`/`INTERSECT`/`EXCEPT`의 한 브랜치는 병렬 레플리카와 함께 `GROUP BY GROUPING SETS`를 사용하고 다른 브랜치는 `FINAL`을 사용할 때 발생할 수 있던 `LOGICAL_ERROR`("Cannot find `__grouping_set` column in header of MergingAggregatedTransform with grouping sets" 또는 "Chunk info was not set for chunk in MergingAggregatedTransform")를 수정했습니다. [#109003](https://github.com/ClickHouse/ClickHouse/pull/109003) ([groeneai](https://github.com/groeneai)).
* `Replicated` 데이터베이스에서 `CREATE TABLE ... AS SELECT FROM s3Cluster(...)`(및 `fileCluster`/`urlCluster` 등 다른 클러스터 테이블 함수)가 `NOT_FOUND_COLUMN_IN_BLOCK` 오류로 실패하던 문제를 수정했습니다. [#109266](https://github.com/ClickHouse/ClickHouse/pull/109266) ([groeneai](https://github.com/groeneai)).
* 샤드가 2개 이상인 클러스터에서 `Distributed` 테이블을 읽는 `CREATE TABLE ... ON CLUSTER ... AS SELECT`를 실행할 때 발생하던 오류(`NOT_FOUND_COLUMN_IN_BLOCK`, 이전 버전에서는 `std::bad_function_call`)를 수정했습니다. [#109407](https://github.com/ClickHouse/ClickHouse/pull/109407) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 테이블 표현식을 `IN` 연산자의 왼쪽 인수로 사용할 때 발생하던, 이해하기 어려운 내부 오류(`Method getResultType is not supported for TABLE query tree node`)를 수정했습니다. 이제 이러한 쿼리는 명확한 오류 메시지를 반환합니다. [#109412](https://github.com/ClickHouse/ClickHouse/pull/109412) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `optimize_const_name_size` 값이 낮게 설정된 상태에서 `Distributed` 테이블에 대해 `SELECT ... ORDER BY ... WITH FILL`을 실행할 때 발생하던 `Bad cast from type DB::FunctionNode to DB::ConstantNode` 논리 오류(debug/새니타이저 빌드에서는 서버 중단)를 수정했습니다. [#109938](https://github.com/ClickHouse/ClickHouse/pull/109938) ([groeneai](https://github.com/groeneai)).
* `query_plan_merge_expression_into_join`이 활성화된 상태에서 여러 테이블로 구성된 뷰에 쉼표 조인을 수행하면 조인 순서 최적화기에서 발생할 수 있던 `LOGICAL_ERROR`(`Left and right columns have same names`)를 수정했습니다. [#110227](https://github.com/ClickHouse/ClickHouse/pull/110227) ([groeneai](https://github.com/groeneai)).
* `LIMIT`이 포함된 유효한 분산 쿼리에서 드물게 `Logical error: 'No more packets are available.'`가 발생하여 debug 및 새니타이저 빌드에서 서버가 중단되던 문제를 수정했습니다. [#110334](https://github.com/ClickHouse/ClickHouse/pull/110334) ([groeneai](https://github.com/groeneai)).
* SELECT 쿼리가 별칭 없는 테이블 식별자 바로 뒤에서 끝날 때(예: `... FROM t COMMENT 'x'`) COMMENT가 암시적 별칭으로 잘못 해석되어, 코멘트가 뷰/테이블에 적용되지 않고 오해를 일으키는 구문 오류가 발생하던 파서 버그를 수정했습니다. [#110372](https://github.com/ClickHouse/ClickHouse/pull/110372) ([adityaksolves](https://github.com/adityaksolves)).
* 선택도가 높은 필터가 있는 쿼리를 병렬 레플리카로 실행할 때 `FixedString` 컬럼에 대한 `length()`(및 QBit 차원)가 고정 크기 `N` 대신 `0`을 반환하던 잘못된 결과 문제를 수정했습니다. [#110427](https://github.com/ClickHouse/ClickHouse/pull/110427) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/110690) ([groeneai](https://github.com/groeneai)).
* 일반적인 최상위 테이블 표현식이 아닌 스트리밍(`FROM ... STREAM`) 읽기가 포함된 쿼리에 대해 `EXPLAIN ANALYZE`를 실행할 때 발생하던 `Logical error: 'clock'` 문제를 수정했습니다(debug/sanitizer 빌드에서는 서버가 종료되고, 릴리스 빌드에서는 무한 대기 상태에 빠짐). 이는 스트리밍 읽기가 서브쿼리 안에 중첩되어 있거나(예: `WHERE ... IN (...)` 내부 또는 CTE) 일반 뷰나 매개변수화된 뷰 뒤에 가려져 있는 경우에 해당합니다. 이제 `EXPLAIN ANALYZE`는 최상위 스트리밍 읽기와 마찬가지로 이러한 쿼리도 `NOT_IMPLEMENTED`로 거부합니다. [#110935](https://github.com/ClickHouse/ClickHouse/pull/110935) ([groeneai](https://github.com/groeneai)).
* 테이블 이름이 데이터베이스 이름과 같을 때 분석기가 `db.table.column`과 같은 정규화된 컬럼 이름을 올바르게 해석하지 못하던 문제를 수정했습니다. [#110976](https://github.com/ClickHouse/ClickHouse/pull/110976) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `parallel_replicas_min_number_of_rows_per_replica`가 설정되어 있고 왼쪽 테이블의 컬럼을 프로젝션하는 경우 `RIGHT JOIN`에서 발생하던 `NOT_FOUND_COLUMN_IN_BLOCK` / `THERE_IS_NO_COLUMN` 오류(일부 릴리스에서는 오류 없이 잘못된 결과 반환)를 수정했습니다. [#111332](https://github.com/ClickHouse/ClickHouse/pull/111332) ([groeneai](https://github.com/groeneai)).
* 실행형 UDF, `executable` 테이블 엔진, 실행형 딕셔너리에서 이미 닫힌 파일 디스크립터에 `fcntl`을 호출하면 동시에 실행 중인 다른 쿼리의 무관한 디스크립터가 손상되어(`O_NONBLOCK` 플래그 제거) 쿼리가 무기한 멈출 수 있던 경쟁 상태를 수정했습니다. [#111779](https://github.com/ClickHouse/ClickHouse/pull/111779) ([Algunenano](https://github.com/Algunenano)).
* 2개 이상의 세그먼트로 구성된 `Distributed` 테이블, `clusterAllReplicas`, 또는 사용자 지정 키 기반 병렬 레플리카에 대해 `ORDER BY ... WITH FILL ... INTERPOLATE`를 실행할 때(결과가 비어 있는 경우 포함) 발생하던 `LOGICAL_ERROR`("Invalid number of rows in Chunk")와, 강화(hardened) 빌드에서 이와 관련해 발생하던 범위 초과로 인한 비정상 종료를 수정했습니다. 이제 `WITH FILL`은 최종 결과를 생성하는 노드에서만 적용되므로, 생성된 채우기 행이 세그먼트/레플리카 간에 중복되던 문제도 함께 해결되었습니다. [#111919](https://github.com/ClickHouse/ClickHouse/pull/111919) ([yakov-olkhovskiy](https://github.com/yakov-olkhovskiy)).
* `system.replicas`에 대한 쿼리가 상태 요청이 처리되기 전에 종료(kill)되면 `DROP TABLE ... SYNC`가 끝없이 멈춰 있던 문제를 수정했습니다. [#112164](https://github.com/ClickHouse/ClickHouse/pull/112164) ([evillique](https://github.com/evillique)).
* 두 하위 조인이 모두 출력 컬럼을 생성하지 않는 다중 테이블 조인에서 발생하던 `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](https://github.com/ClickHouse/ClickHouse/pull/112205) ([groeneai](https://github.com/groeneai)).
* `FINAL`, `PREWHERE` 필터, 작은 `LIMIT`, `make_distributed_plan = 1`을 사용하는 쿼리에서 선택한 컬럼의 순서가 테이블의 컬럼 순서와 다를 때 발생하던 논리 오류 `Cannot add step Expression to QueryPlan because it has incompatible header with root step JoinLazyColumnsStep`을 수정했습니다. 지연 materialization이 계획 노드를 교체하면서 해당 노드의 출력 헤더를 유지하지 않아 쿼리 계획의 일관성이 깨지는 문제가 있었습니다. [#112303](https://github.com/ClickHouse/ClickHouse/pull/112303) ([groeneai](https://github.com/groeneai)).
* 이전 분석기를 사용할 때 `toDecimal32`의 스케일이나 `toDateTime`의 시간대처럼 상수여야 하는 인수를 스칼라 서브쿼리로 전달하면 잘못된 결과와 논리 오류가 발생하던 문제를 수정했습니다. 이러한 인수는 값이 0이거나 비어 있는 것으로 간주되어 분석되었기 때문에 선언된 결과 유형과 실제 계산된 값이 일치하지 않았고, `CREATE VIEW` 및 `CREATE MATERIALIZED VIEW`에서는 잘못된 컬럼 유형이 저장되었습니다. [#112492](https://github.com/ClickHouse/ClickHouse/pull/112492) ([groeneai](https://github.com/groeneai)).
* 일반 `VIEW` 본문이 `CREATE VIEW v AS SELECT x FROM {db:Identifier}.t`와 같이 쿼리 매개변수를 통해 테이블 또는 딕셔너리를 참조할 때 발생하던 논리 오류와 잘못된 의존성 기록 문제를 수정했습니다. 이제 이러한 뷰는 현재 데이터베이스에 있는 같은 이름의 테이블에 대한 참조 의존성을 기록하지 않으므로, 관련 없는 테이블을 다시 삭제할 수 있습니다. [#112704](https://github.com/ClickHouse/ClickHouse/pull/112704) ([groeneai](https://github.com/groeneai)).
* `Join` 테이블 엔진을 JOIN의 오른쪽에 사용하고, 해당 JOIN의 `ON` 절에 `ON (t.key = j.key) AND (t.a < j.a)`처럼 두 테이블의 컬럼을 모두 참조하는 조건이 포함된 경우 발생하던 논리 오류를 수정했습니다. 이제 이러한 쿼리는 `required columns: ... but not found any in left table` 또는 `std::bad_variant_access`를 발생시키는 대신 명확한 예외와 함께 거부됩니다. [#112815](https://github.com/ClickHouse/ClickHouse/pull/112815) ([groeneai](https://github.com/groeneai)).
* `REFRESH AFTER` 주기가 매우 긴 갱신 가능 구체화 뷰처럼 백그라운드 작업이 매우 큰 지연 시간으로 예약될 때 발생하던 정의되지 않은 동작과, 아무런 알림 없이 발생하던 스케줄링 오류를 수정했습니다. 이제 지연 시간은 오버플로되지 않고 표현 가능한 최댓값으로 제한됩니다. [#113041](https://github.com/ClickHouse/ClickHouse/pull/113041) ([groeneai](https://github.com/groeneai)).
* `Distributed` 테이블에 대한 비동기 `INSERT`에 255바이트 파일 시스템 제한을 초과하는 이름의 큐 디렉터리가 필요할 때(`use_compact_format_in_distributed_parts_names = 0`에서 발생 가능) 보고되던 오류를 수정했습니다. 기존에는 `internal_replication`이 설정된 샤드(shard)에서는 `LOGICAL_ERROR`가, 그 외에는 출처를 알 수 없는 `Code: 1001. std::exception`이 보고되었으나, 이제 두 경우 모두 테이블, 클러스터, 제한 값을 명시한 `ARGUMENT_OUT_OF_BOUND`를 보고합니다. [#113083](https://github.com/ClickHouse/ClickHouse/pull/113083) ([groeneai](https://github.com/groeneai)).
* 이제 `UNDROP TABLE`이 실행 중인 쿼리가 삭제된 테이블을 해제하기를 기다리는 동안 `KILL QUERY`로 중단할 수 있습니다. [#113263](https://github.com/ClickHouse/ClickHouse/pull/113263) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* materialized CTE를 사용하는 쿼리가 실패한 후 `DROP TABLE`이 영구적으로 멈추고 메모리 누수가 발생하던 문제를 수정했습니다. 기존에는 해당 테이블이 서버를 재시작할 때까지 삭제 큐에 남아 있었습니다. [#113397](https://github.com/ClickHouse/ClickHouse/pull/113397) ([tiandiwonder](https://github.com/tiandiwonder)).
* `make_distributed_plan` 사용 시 서브쿼리가 자체 `SETTINGS` 절에서 `distributed_plan_execute_locally`를 설정하면 발생하던 세그멘테이션 오류(segfault)와 `LOGICAL_ERROR`(`No host found for exchange stream final_result__0_0`)를 수정했습니다. 분산 실행 계획과 이를 실행하는 코드가 서로 다른 컨텍스트에서 설정을 읽어 값이 어긋날 수 있었기 때문에, 이니시에이터가 자기모순적인 파이프라인을 구성했습니다. [#113422](https://github.com/ClickHouse/ClickHouse/pull/113422) ([groeneai](https://github.com/groeneai)).
* `database_atomic_wait_for_drop_and_detach_synchronously`가 활성화된 상태에서 데이터를 채우는 `SELECT`가 실패하면 `CREATE TABLE ... AS SELECT`를 강제 종료할 수 없게 되던 문제를 수정했습니다. 임시 테이블을 정리하는 내부 `DROP`이 백그라운드 삭제 큐를 기다리면서 `KILL QUERY`와 `max_execution_time`을 모두 무시했습니다. [#113504](https://github.com/ClickHouse/ClickHouse/pull/113504) ([groeneai](https://github.com/groeneai)).
* `join_use_nulls`가 활성화된 상태에서 `ON (t.key = d.key) AND (t.a * 10 < d.a)`처럼 `ON` 절에 두 테이블에 걸친 비등가 조건이 있는 딕셔너리 대상 `JOIN`이 잘못된 결과를 반환하고, 어서션이 활성화된 빌드에서는 어서션 실패로 중단되던 문제를 수정했습니다. 일치하지 않는 타입으로 읽은 컬럼에 대해 조건이 평가되어 행이 임의로 매칭될 수 있었습니다. [#113534](https://github.com/ClickHouse/ClickHouse/pull/113534) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 매개변수화된 뷰(parameterized view)를 데이터베이스 이름 없이 참조하는 쿼리가 세그먼트로 전송될 때 뷰의 데이터베이스 정보가 유실되어, 세그먼트가 자신의 기본 데이터베이스를 기준으로 이름을 해석하던 문제를 수정했습니다. 해당 데이터베이스의 내용에 따라 쿼리가 `UNKNOWN_FUNCTION` 오류로 실패하거나, 아무런 경고 없이 다른 뷰의 행을 반환했습니다. `Distributed` 테이블을 통한 `IN`, `JOIN`, `remote()`에 영향을 줍니다. [#113550](https://github.com/ClickHouse/ClickHouse/pull/113550) ([groeneai](https://github.com/groeneai)).
* 키가 복합 키(여러 컬럼)이거나 `UUID`, `Int256`, `FixedString(4)`처럼 16/32바이트 단일 값인 `Join` 엔진 테이블을 읽을 때 `Unsupported JOIN keys of type keys256 in StorageJoin` 오류가 발생하던 문제를 수정했습니다. 이러한 테이블은 생성, 쓰기, 조인은 가능했지만 `SELECT`로 다시 읽을 수는 없었습니다. [#113578](https://github.com/ClickHouse/ClickHouse/pull/113578) ([groeneai](https://github.com/groeneai)).
* 원격 세그먼트를 대상으로 하는 구조 정의 없는 `Distributed` 테이블을 attach하거나, 이전 버전 서버가 기록한 메타데이터에서 로드할 때 `Sending a distributed query with unknown (zero) client version` 논리 오류가 발생하던 문제를 수정했습니다. [#113675](https://github.com/ClickHouse/ClickHouse/pull/113675) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `SELECT`에서 이름이 지정된 테이블에 `STREAM` 수정자를 사용하면서 read-tasks 모드의 병렬 레플리카를 함께 사용할 때 `LOGICAL_ERROR`가 발생하던 문제를 수정했습니다. 구체화된 CTE(materialized CTE)를 `PREWHERE`의 `IN` 집합으로 사용하면 서버에서 `Reading from materialized CTE ... DelayedPortsProcessor gate is missing in the query plan` 오류가 발생했습니다(debug 및 새니타이저 빌드에서는 서버가 비정상 종료됨). 이제 병렬 레플리카가 요청되면 `STREAM`이 지정된 테이블은 거부됩니다. `enable_parallel_replicas = 2`이면 쿼리가 `SUPPORT_IS_DISABLED`로 실패하고, `1`이면 병렬 레플리카 없이 실행됩니다. 이는 기존 `FINAL`의 동작과 동일합니다. [#113754](https://github.com/ClickHouse/ClickHouse/pull/113754) ([groeneai](https://github.com/groeneai)).
* `remote`, `mysql` 등 테이블 함수의 주소 인수를 파싱할 때 2차 시간 복잡도가 발생하던 문제를 수정했습니다. 매우 긴 주소(예: 0으로 채워진 메가바이트 크기의 `FixedString`)가 주어지면 쿼리가 분석 단계에서 멈췄으며, 이 단계에서는 쿼리를 취소할 수도 없었습니다. [#113918](https://github.com/ClickHouse/ClickHouse/pull/113918) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `database_atomic_wait_for_drop_and_detach_synchronously`가 활성화된 상태에서 갱신 가능 구체화 뷰의 갱신이 취소될 때(예: 서버 종료) `Failed to drop temporary table after refresh. Table ... is left behind and requires manual cleanup.` 오류가 잘못 기록되던 문제를 수정했습니다. 실제로는 임시 테이블이 정상적으로 삭제되었으므로 수동 정리가 필요한 경우는 없었습니다. [#113957](https://github.com/ClickHouse/ClickHouse/pull/113957) ([groeneai](https://github.com/groeneai)).
* `materialized_views_ignore_errors`가 활성화된 상태에서 의존성 수집 중 실패한 materialized view에 대해 `system.query_views_log` 행이 누락되던 문제를 수정했습니다. debug 및 새니타이저 빌드에서는 해당 뷰를 로그에 기록하는 대신 `std::out_of_range`로 서버가 비정상 종료되기도 했습니다. [#114064](https://github.com/ClickHouse/ClickHouse/pull/114064) ([groeneai](https://github.com/groeneai)).
* 오른쪽 테이블의 키가 아닌 컬럼에 대한 필터가 ANY INNER JOIN 아래로 푸시다운될 때 결과가 일관되지 않던 문제를 수정했습니다. [#114313](https://github.com/ClickHouse/ClickHouse/pull/114313) ([kirillshokhin](https://github.com/kirillshokhin)).
* `ignore_drop_queries_probability`가 설정되어 있으면 `CREATE OR REPLACE`가 내부 `_tmp_replace_*` 테이블을 남기고, `CREATE OR REPLACE VIEW`가 `NOT_IMPLEMENTED`로 실패하던 문제를 수정했습니다. 내부적으로 실행되는 DROP은 하나의 사용자 구문을 구성하는 단계이므로, 이제 DROP 장애 주입이 적용되지 않습니다. [#114420](https://github.com/ClickHouse/ClickHouse/pull/114420) ([groeneai](https://github.com/groeneai)).
* `metaData.partitionColumns`에 `metaData.schemaString`에서 선언되지 않은 컬럼이 지정된 Delta Lake 테이블을 읽을 때 `LOGICAL_ERROR`가 발생하던 문제를 수정했습니다. 이제 이러한 메타데이터는 쿼리에 프레디케이트가 포함된 경우뿐만 아니라 테이블이나 스키마를 스냅샷에서 읽을 때마다 거부되며, delta-kernel 리더에서는 `BAD_ARGUMENTS`, 레거시 리더에서는 `INCORRECT_DATA` 오류가 반환됩니다. [#114538](https://github.com/ClickHouse/ClickHouse/pull/114538) ([groeneai](https://github.com/groeneai)).
* 지연 `FINAL` 최적화(`query_plan_optimize_lazy_final`)를 사용하는 쿼리가 서버 시작 후 처음 실행되는 집계일 때, 해시 테이블 통계와 이에 따른 집계 해시 테이블 사전 할당이 서버 전체에서 아무런 알림 없이 영구적으로 비활성화되던 문제를 수정했습니다. [#114597](https://github.com/ClickHouse/ClickHouse/pull/114597) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `ignore_drop_queries_probability`가 활성화된 경우 갱신 가능 구체화 뷰에서 교체되어 빠진 target table이 삭제되지 않고 남던(누수) 문제를 수정했습니다. 갱신 과정에서 이전 target을 정리하기 위해 실행하는 `DROP`은 사용자가 요청한 `DROP`이 아니라 갱신의 한 단계이므로, 이제 여기에는 장애 주입이 적용되지 않습니다. [#114622](https://github.com/ClickHouse/ClickHouse/pull/114622) ([groeneai](https://github.com/groeneai)).
* `ON` 절에 `OR`로 연결된 조건이 여러 개 있을 때 `ANY RIGHT JOIN` 및 `SEMI RIGHT JOIN`이 오른쪽 테이블의 일부 행을 중복 반환하고 다른 행의 매칭은 누락하던 문제를 수정했습니다. 플래너가 테이블 순서를 바꿔 `ANY RIGHT JOIN`으로 실행할 수 있으므로, 직접 작성한 `ANY LEFT JOIN`도 영향을 받았습니다. [#114676](https://github.com/ClickHouse/ClickHouse/pull/114676) ([vdimir](https://github.com/vdimir)).
* 텍스트 인덱스가 적용된 컬럼이 `PREWHERE`와 `WHERE` 텍스트 검색 프레디케이트에 모두 사용되는 테이블 위에 `JOIN`이 있는 쿼리에서 `LOGICAL_ERROR`(`Cannot find input column ... on its position in inputs of expression actions DAG`)가 발생하던 문제를 수정했습니다. [#114771](https://github.com/ClickHouse/ClickHouse/pull/114771) ([groeneai](https://github.com/groeneai)).
* `ALIAS` 또는 `EPHEMERAL` 컬럼에 `STATISTICS(...)`를 선언한 테이블에 `INSERT`할 때마다 `NOT_FOUND_COLUMN_IN_BLOCK`이 발생하여 해당 테이블이 사실상 읽기 전용이 되던 문제를 수정했습니다. [#115231](https://github.com/ClickHouse/ClickHouse/pull/115231) ([groeneai](https://github.com/groeneai)).
* 분산 쿼리에서 `dictGet` 및 관련 변형 함수의 동작을 수정했습니다. 이제 데이터베이스가 지정되지 않은 딕셔너리 이름은 각 샤드의 현재 데이터베이스가 아니라 initiator의 현재 데이터베이스를 기준으로 바인딩됩니다. 기존에는 샤드에서 딕셔너리를 찾지 못하거나 같은 이름의 다른 딕셔너리로 해석되는 문제가 있었습니다. [#115541](https://github.com/ClickHouse/ClickHouse/pull/115541) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 데이터베이스나 테이블을 새 이름으로 복원할 때 저장된 뷰 본문에서 테이블 별칭이 누락되어, 복원된 뷰를 읽으면 `UNKNOWN_IDENTIFIER` 오류가 발생하던 버그를 수정했습니다. [#115645](https://github.com/ClickHouse/ClickHouse/pull/115645) ([groeneai](https://github.com/groeneai)).
* `Distributed` 테이블에 대한 `IN` 서브쿼리 내부에서 `MATERIALIZED` CTE를 읽을 때 `LOGICAL_ERROR` "Reading from materialized CTE 'X' before its materialization completed - DelayedPortsProcessor gate is missing in the query plan"이 발생하던 문제를 수정했습니다. [#115740](https://github.com/ClickHouse/ClickHouse/pull/115740) ([groeneai](https://github.com/groeneai)).
* 의존성 검사(HAVE\_DEPENDENT\_OBJECTS)로 인해 DETACH DICTIONARY ... PERMANENTLY가 거부된 후 dictGet에서 BAD\_ARGUMENTS "Dictionary not found" 오류가 발생하던 문제를 수정했습니다. 이제 분리가 거부되면 딕셔너리를 그대로 정상 사용할 수 있습니다. [#105259](https://github.com/ClickHouse/ClickHouse/pull/105259) ([groeneai](https://github.com/groeneai)).
* 백그라운드 테이블 삭제 큐에서 발생하던 `Logical error: 'removed'`(디버그 빌드에서는 서버 중단)를 수정했습니다. 이 오류는 동일한 명시적 UUID를 여러 `CREATE OR REPLACE TABLE` 쿼리에서 재사용할 때 발생할 수 있었으며, 이 경우 같은 UUID를 공유하는 삭제된 테이블이 두 개 이상 큐에 추가되었습니다. [#107031](https://github.com/ClickHouse/ClickHouse/pull/107031) ([groeneai](https://github.com/groeneai)).
* 서버가 중단된 동안 복제된 테이블 하나의 구조가 변경되면 `MaterializedPostgreSQL`이 데이터베이스 전체의 복제를 중지하던(`LOGICAL_ERROR: Columns number mismatch` 발생) 문제를 수정했습니다. 이제 영향을 받은 테이블만 건너뛰며, 해당 테이블은 `DETACH`/`ATTACH`로 복구할 수 있습니다. [#107427](https://github.com/ClickHouse/ClickHouse/pull/107427) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 클러스터에 비활성 레플리카(예: 오토스케일링 후 남은 오래된 항목)가 있을 때 병렬 레플리카의 작업 분배가 심하게 편중되던 문제를 수정했습니다. 이제 읽기 코디네이터가 이러한 레플리카를 집계하지 않으므로, 작업이 한 레플리카에 몰리지 않고 온라인 레플리카 전체에 고르게 분배됩니다. [#107805](https://github.com/ClickHouse/ClickHouse/pull/107805) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* XML로 정의된 여러 MySQL 딕셔너리가 `share_connection`을 통해 하나의 연결 풀을 공유할 때 `SYSTEM RELOAD DICTIONARIES`(및 `RELOAD DICTIONARY`)가 멈추던 문제를 수정했습니다. 이제 이러한 풀은 이름이 지정된 컬렉션으로 정의된 딕셔너리와 마찬가지로 구성의 `connection_pool_size` 및 `connection_wait_timeout`(기본값 5초)을 따릅니다. [#108083](https://github.com/ClickHouse/ClickHouse/pull/108083) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 리더가 실행하는 복제된 분산 DDL의 재시도 횟수가 소진되어도 이후의 `ON CLUSTER` DDL 쿼리가 영구적으로 차단되지 않도록 수정했습니다. [#108505](https://github.com/ClickHouse/ClickHouse/pull/108505) ([ahaanlimaye](https://github.com/ahaanlimaye)).
* 동일한 `Distributed` 테이블에 대해 `SYSTEM FLUSH DISTRIBUTED`와 `DROP TABLE`이 동시에 실행될 때 발생할 수 있던 크래시(use-after-free)를 수정했습니다. [#108684](https://github.com/ClickHouse/ClickHouse/pull/108684) ([groeneai](https://github.com/groeneai)).
* `automatic_parallel_replicas_mode`를 활성화하고 `parallel_replicas_min_number_of_rows_per_replica`를 0보다 큰 값으로 설정했을 때 자동 병렬 레플리카 플래너에서 발생할 수 있던 `LOGICAL_ERROR`(`local_replica_plan_reading_step->getAnalyzedResult() == nullptr`)를 수정했습니다. [#109011](https://github.com/ClickHouse/ClickHouse/pull/109011) ([groeneai](https://github.com/groeneai)).
* 비트랜잭션 `TRUNCATE`가 같은 테이블에 데이터를 삽입한 미커밋 트랜잭션과 동시에 실행될 때 발생할 수 있던 `LOGICAL_ERROR`(`creation_csn is not set while removal_csn is set to 1`)를 수정했습니다. 이제 이러한 `TRUNCATE`는 아직 커밋되지 않은 트랜잭션이 생성한 파트를 제거하지 않습니다. [#109598](https://github.com/ClickHouse/ClickHouse/pull/109598) ([tuanpach](https://github.com/tuanpach)).
* 외부 데이터베이스 엔진(예: `PostgreSQL`)이 더 이상 `UUID` 컬럼에 대한 범위 비교(`>=`, `>`, `<=`, `<`)를 푸시다운하지 않습니다. ClickHouse와 외부 데이터베이스는 UUID 정렬 방식이 서로 달라, 이러한 비교를 푸시다운하면 결과에서 행이 아무런 경고 없이 누락되었습니다. 이제 이러한 조건식은 ClickHouse에서 평가합니다. [#109833](https://github.com/ClickHouse/ClickHouse/pull/109833) ([vismaytiwari](https://github.com/vismaytiwari)).
* 동기화 대기 중인 테이블이 분리되거나 구조가 변경될 때 `MaterializedPostgreSQL` 데이터베이스 엔진에서 발생할 수 있던 서버 크래시를 수정했습니다. [#110596](https://github.com/ClickHouse/ClickHouse/pull/110596) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 서버의 `query_masking_rules`로 인해 `EPHEMERAL` 컬럼의 유형이 변경되던 문제를 수정했습니다. 유형 내부와 일치하는 규칙이 있으면 `CREATE TABLE`이 잘못된 유형을 저장하거나 실패했습니다. [#112048](https://github.com/ClickHouse/ClickHouse/pull/112048) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 테이블 이름 길이 검사에서 발생하던 부호 없는 정수 언더플로(underflow)를 수정했습니다. 이 문제로 인해 삭제할 수 없는 테이블이 생성될 수 있었습니다. 이스케이프된 데이터베이스 이름이 214바이트에 도달하면 `metadata_dropped` 파일 이름에 대해 계산된 제한 값이 랩어라운드되어, `CREATE TABLE`은 허용되지만 이후의 `DROP TABLE` 또는 `DROP DATABASE`는 `File name too long` 오류로 실패했습니다. 이제 이러한 이름은 해당 경계 바로 아래에서 이미 반환되던 것과 동일한 `ARGUMENT_OUT_OF_BOUND` 오류로 거부됩니다. [#112527](https://github.com/ClickHouse/ClickHouse/pull/112527) ([groeneai](https://github.com/groeneai)).
* `RENAME TABLE`이 최대 테이블 이름 길이를 대상 데이터베이스가 아닌 원본 데이터베이스 기준으로 검사하던 문제를 수정했습니다. 이름이 긴 데이터베이스로 테이블을 옮기며 이름을 변경하면 `DROP TABLE`로 제거할 수 없는 테이블이 생성될 수 있었고, 반대로 그러한 데이터베이스에서 테이블을 다른 데이터베이스로 옮기는 이름 변경은 잘못 거부되었습니다. [#113019](https://github.com/ClickHouse/ClickHouse/pull/113019) ([groeneai](https://github.com/groeneai)).
* 대상 테이블이 materialized view를 트리거하는 `Alias` 테이블에 삽입할 때 `query_log`의 `views` 컬럼이 항상 비어 있던 문제를 수정했습니다. [#113076](https://github.com/ClickHouse/ClickHouse/pull/113076) ([eclbg](https://github.com/eclbg)).
* `tuple()` 또는 `(x, y)`와 같은 잘못된 `parallel_replicas_custom_key` 표현식은 이제 사용자 정의 키 타입 목록의 범위를 넘어 읽는 대신 `ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER` 오류로 거부됩니다. [#113359](https://github.com/ClickHouse/ClickHouse/pull/113359) ([nickitat](https://github.com/nickitat)).
* `RENAME DATABASE`가 데이터베이스의 테이블을 삭제할 수 없게 만들 만큼 긴 대상 이름을 허용하던 문제를 수정했습니다. 이제 테이블 이름 길이 검사는 `check_table_dependencies`와 관계없이 실행되며, 분리된 테이블(detached table)도 검사 대상에 포함됩니다. 분리된 테이블은 이전에는 전혀 검사되지 않아 기본 설정에서도 이 문제의 영향을 받았습니다. [#113557](https://github.com/ClickHouse/ClickHouse/pull/113557) ([groeneai](https://github.com/groeneai)).
* `Distributed` 엔진을 사용하는 테이블에 백그라운드 삽입을 수행할 때, 원격 샤드(shard)로 데이터를 전송하는 중 반복된 오류로 인해 발생한 지연이 이제 오류가 해소되면 감소합니다. 이전에는 지연이 증가하기만 하고 초기화되지 않았습니다. [#87378](https://github.com/ClickHouse/ClickHouse/pull/87378) ([Blackmorse](https://github.com/Blackmorse)).
* 알 수 없는 클러스터 또는 `<secret>` 없이 구성된 클러스터에 대해 `USER_INTERSERVER_MARKER`를 사용하는 native protocol 핸드셰이크를 거부합니다. 이전에는 이러한 핸드셰이크를 통해 인증되지 않은 클라이언트가 서버 간(interserver) 모드에 진입하여 `fake_interserver_context` 기반의 인증 전 프로토콜 패킷(예: `TablesStatusRequest`)을 실행할 수 있었으며, 클러스터 시크릿을 알고 있음을 증명하지 않고도 로컬 테이블 정보를 알아낼 수 있었습니다. [#99675](https://github.com/ClickHouse/ClickHouse/pull/99675) ([MillaFleurs](https://github.com/MillaFleurs)).

<h3 id="sql-analyzer-and-join-fixes">
  SQL, 분석기 및 JOIN 관련 수정 사항
</h3>

* 이름이 지정된 `WINDOW` 절의 정의 내부에서 쿼리 매개변수 치환이 이루어지지 않던 문제를 수정했습니다. 이전에는 이 위치의 매개변수가 아무런 알림 없이 치환되지 않은 채 남아 있었으며, 설정되지 않은 `Identifier` 매개변수로 인해 `EXPLAIN SYNTAX` 실행 중 `Logical error: '!part.empty()'` 예외가 발생할 수 있었습니다. [#110506](https://github.com/ClickHouse/ClickHouse/pull/110506) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 갱신 가능 구체화 뷰(Refreshable Materialized View)가 동시에 삭제되거나 교체될 때 드물게 서버가 비정상 종료되던 문제를 수정했습니다. 스케줄링 코드가 일시적으로 뮤텍스를 해제한 사이에 다른 스레드가 작업의 `view`를 `nullptr`로 설정하면 `RefreshTask::doScheduling`에서 널 포인터 역참조가 발생했습니다. [#105588](https://github.com/ClickHouse/ClickHouse/pull/105588) ([groeneai](https://github.com/groeneai)).
* 피연산자가 `UNION` 체인인 `EXCEPT` 또는 `INTERSECT`로 정의된 뷰가 `DETACH`/`ATTACH` 또는 서버 재시작 후 잘못된 결과를 반환하던 문제를 수정했습니다. 포매터가 `INTERSECT`/`EXCEPT`의 하위 `UNION` 항목을 괄호로 감싸지 않아, 저장된 SQL을 다시 파싱할 때 연산자 우선순위가 뒤바뀌었습니다. [#105935](https://github.com/ClickHouse/ClickHouse/pull/105935) ([groeneai](https://github.com/groeneai)).
* 동일한 키에 대해 `WITH CUBE`, `WITH ROLLUP` 또는 `GROUPING SETS`를 사용하는 `GROUP BY` 결과에 `SELECT DISTINCT`를 적용할 때 잘못된 결과(중복 행)가 반환되던 문제를 수정했습니다. 그룹화 수정자는 키 컬럼이 기본값으로 채워진 추가 행을 생성하며, 이 행이 실제 그룹 값과 충돌할 수 있습니다. 따라서 이제 `query_plan_remove_redundant_distinct` 최적화는 이러한 경우 `DISTINCT`를 제거하지 않습니다. [#107072](https://github.com/ClickHouse/ClickHouse/pull/107072) ([groeneai](https://github.com/groeneai)).
* `WHERE` 필터가 상수 항을 포함하는 논리곱일 때(예: `p AND 1`, 또는 `QUALIFY NULL`이 `WHERE`에 병합되는 `WHERE p QUALIFY NULL`) OUTER JOIN이 잘못된 결과를 반환하던 문제를 수정했습니다. 상수 논리곱 항이 조인의 비보존 측으로 푸시다운되면서 조인 후 필터에서 제거될 수 있었고, 그 결과 조인이 해당 측 컬럼이 기본값으로 채워진 비매칭 행을 생성했으며 이 행들이 필터를 잘못 통과했습니다. [#107084](https://github.com/ClickHouse/ClickHouse/pull/107084) ([groeneai](https://github.com/groeneai)).
* `correlated_subqueries_default_join_kind = 'left'`일 때, 동일한 컬럼 식별자를 두 번 프로젝션하는 소스(예: `SELECT number, *`)에 대한 상관 스칼라 서브쿼리로 인해 서버가 중단되던 `LOGICAL_ERROR`("Cannot find input column ... on its position in inputs of expression actions DAG")를 수정했습니다. [#107112](https://github.com/ClickHouse/ClickHouse/pull/107112) ([groeneai](https://github.com/groeneai)).
* 이전 분석기(`enable_analyzer = 0`) 사용 시, `JOIN`에서 널 안전 비교 연산자(`<=>` / `IS NOT DISTINCT FROM`)를 사용하고 키 중 하나가 스칼라 서브쿼리일 때(예: `... JOIN t2 ON (SELECT x FROM t1) <=> t2.k`) 발생하던 `LOGICAL_ERROR`(디버그/새니타이저 빌드에서 서버 중단)를 수정했습니다. 이제 이러한 쿼리는 논리 오류 대신 일반적인 `NOT_FOUND_COLUMN_IN_BLOCK` 오류를 반환합니다. [#108123](https://github.com/ClickHouse/ClickHouse/pull/108123) ([groeneai](https://github.com/groeneai)).
* `SEMI`/`ANTI` 조인(`EXISTS` 상관 서브쿼리의 비상관화로 생성된 조인 포함)에 `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`는 실행할 수 없는 엄격성/종류 조합을 거부하므로, 플래너는 활성화된 다른 알고리즘으로 대체하거나 조인을 실행할 수 없다고 보고합니다. [#108658](https://github.com/ClickHouse/ClickHouse/pull/108658) ([groeneai](https://github.com/groeneai)).
* 조인의 한쪽에 상수 서브쿼리가 있을 때 `JOIN`의 `WITH TOTALS` 행에 상수 서브쿼리의 상수 값 대신 기본값(예: `0`)이 포함될 수 있던 버그를 수정했습니다. 이 잘못된 결과는 일부 조인 순서에서만 나타나거나 `query_plan_join_swap_table` 설정을 사용할 때만 나타났습니다. [#108807](https://github.com/ClickHouse/ClickHouse/pull/108807) ([vdimir](https://github.com/vdimir)).
* 시그널 스택 크기가 큰 CPU(예: AMX를 인식하는 커널을 사용하는 Intel Sapphire Rapids / Granite Rapids)에서 실행되는 glibc 빌드에서 `aligned_alloc` 호출 전에 시그널 대체 스택 크기가 페이지 크기의 배수로 올림되지 않아 시작 시 비정상 종료(`Cannot allocate ThreadStack`, `EINVAL`)되던 문제를 수정했습니다. [#108813](https://github.com/ClickHouse/ClickHouse/pull/108813) ([groeneai](https://github.com/groeneai)).
* 상관 서브쿼리가 조인으로 비상관화되고 소스 릴레이션에 동일한 컬럼명이 두 번 이상 포함된 경우(예: `correlated_subqueries_default_join_kind = 'right'` 설정에서 `WITH t AS (SELECT number, * FROM numbers(3)) SELECT *, (SELECT t.number WHERE t.number >= 0) FROM t` 실행) 발생하던 `Block structure mismatch in JoinStep` 논리 오류(debug/새니타이저 빌드에서 서버 비정상 종료)를 수정했습니다. [#109114](https://github.com/ClickHouse/ClickHouse/pull/109114) ([groeneai](https://github.com/groeneai)).
* `CREATE USER ... HOST LIKE 'a', 'b'`(및 이에 상응하는 `ALTER USER`)가 아무런 알림 없이 첫 번째 패턴만 유지하던 문제를 수정했습니다. 이제 지정된 모든 `HOST LIKE` 패턴이 사용자의 호스트 허용 목록에 저장됩니다. [#109187](https://github.com/ClickHouse/ClickHouse/pull/109187) ([groeneai](https://github.com/groeneai)).
* 상수 `ON` 조건을 사용하는 `ANY JOIN`(예: `t1 ANY INNER JOIN t2 ON 1`)에서 쿼리가 ANY 조인 결과 대신 전체 카테시안 곱을 반환하던 문제를 수정했습니다 [#109207](https://github.com/ClickHouse/ClickHouse/pull/109207) ([vdimir](https://github.com/vdimir)).
* parallel\_hash 조인 알고리즘에서 전역 `max_rows_in_join` / `max_bytes_in_join` 제한이 적용되지 않아, `join_overflow_mode = 'throw'`를 사용하는 쿼리가 `SET_SIZE_LIMIT_EXCEEDED`를 발생시키지 않고 그대로 성공할 수 있던 문제를 수정했습니다. [#109488](https://github.com/ClickHouse/ClickHouse/pull/109488) ([m-selmi](https://github.com/m-selmi)).
* 서버 측 인라인 삽입 파싱 경로(`send_table_structure_on_insert_with_inline_data = 0`)에서 다중 쿼리 스트림의 `INSERT ... VALUES` 뒤에 후행 SQL 주석(예: `VALUES (1) -- comment`)이 오는 경우 데이터가 알림 없이 손실되던 문제를 수정했습니다. 후행 주석이 종료 문자 `;` 이후까지 행 데이터로 스캔되어, 스트림의 후속 쿼리가 아무런 알림 없이 건너뛰어졌습니다. [#109643](https://github.com/ClickHouse/ClickHouse/pull/109643) ([groeneai](https://github.com/groeneai)).
* `PREWHERE`가 `FINAL` 이후에 실행될 때 `optimize_move_to_prewhere = 1`과 함께 사용되는 지연된 `PREWHERE`의 동작을 수정했습니다. 이제 `WHERE` 조건이 지연된 ROW POLICY보다 앞으로 이동하지 않습니다. 기존에는 이로 인해 쿼리 결과가 달라질 수 있었습니다. [#109703](https://github.com/ClickHouse/ClickHouse/pull/109703) ([yariks5s](https://github.com/yariks5s)).
* 재귀 CTE가 외부 스코프의 식별자를 상관 컬럼으로 해석할 때(`allow_experimental_correlated_subqueries = 1` 사용 시) 발생하던 `LOGICAL_ERROR`(`query tree node does not have valid source node`)를 수정했습니다. 이제 이러한 쿼리는 명확한 `UNSUPPORTED_METHOD` 오류를 반환합니다. [#109863](https://github.com/ClickHouse/ClickHouse/pull/109863) ([groeneai](https://github.com/groeneai)).
* `ORDER BY ... WITH FILL`이 `Int64`/`UInt64` 컬럼에서 매우 큰 공백을 건너뛸 때(예: 2^63 부근의 공백을 간격 2로 건너뛰는 경우) 발생하던 부호 있는 정수 오버플로우를 수정했습니다. 이 오버플로우는 새니타이저에서 정의되지 않은 동작(undefined behavior)으로 감지되었으며, 릴리스 빌드에서는 알림 없이 랩어라운드되었습니다. [#109937](https://github.com/ClickHouse/ClickHouse/pull/109937) ([groeneai](https://github.com/groeneai)).
* 이전 분석기(`enable_analyzer = 0`)를 사용할 때 `INTERPOLATE` 대상이 `WITH FILL` 컬럼의 별칭이면 발생하던 `Invalid number of rows in Chunk` 논리 오류를 수정했습니다. 이제 이러한 쿼리는 명확한 `INVALID_WITH_FILL_EXPRESSION` 오류와 함께 거부됩니다. [#110103](https://github.com/ClickHouse/ClickHouse/pull/110103) ([groeneai](https://github.com/groeneai)).
* 상관 서브쿼리(예: `exists((SELECT ...))`)를 포함하는 필터가 `convert_query_to_cnf` 또는 `optimize_and_compare_chain`으로 최적화될 때 발생하던 논리 오류(`Unexpected number of columns in result sample block`)를 수정했습니다. [#110187](https://github.com/ClickHouse/ClickHouse/pull/110187) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 바로 바깥의 외부 쿼리를 넘어 더 상위 범위의 컬럼을 참조하는(중간 범위를 건너뛰는) 중첩 상관 `EXISTS` 서브쿼리는 이제 내부 오류인 `NOT_FOUND_COLUMN_IN_BLOCK` 대신 명확한 `NOT_IMPLEMENTED` 오류와 함께 실패합니다. [#110310](https://github.com/ClickHouse/ClickHouse/pull/110310) ([groeneai](https://github.com/groeneai)).
* 외부 쿼리의 상관 컬럼에 중복 값이 있고 서브쿼리가 CROSS JOIN 경로를 통해 비상관화될 때 상관 스칼라 서브쿼리가 잘못된 결과를 반환하던 문제를 수정했습니다. 이전에는 `count()`, `sum()` 같은 집계 결과에 중복 개수가 곱해졌습니다. 이 문제는 Experimental 기능인 `allow_experimental_correlated_subqueries`에 해당합니다. [#110311](https://github.com/ClickHouse/ClickHouse/pull/110311) ([groeneai](https://github.com/groeneai)).
* 큰 채우기 범위를 생성할 때(특히 `INTERPOLATE` 사용 시) `ORDER BY ... WITH FILL`이 `max_execution_time`을 준수하지 않고 취소에 오랜 시간이 걸리던 문제를 수정했습니다. [#110332](https://github.com/ClickHouse/ClickHouse/pull/110332) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 지연 실행 `FINAL` 최적화(`query_plan_optimize_lazy_final`, 기본값은 비활성화)는 이제 쿼리가 정렬 키 순서로 데이터를 읽을 때 적용되지 않습니다. 이 최적화의 대체 계획은 정렬 키 순서로 행을 생성하지 않지만, 상위 계획은 read-in-order 최적화 이후 이미 해당 순서에 의존하고 있을 수 있어 결과가 잘못된 순서로 반환될 수 있기 때문입니다. 또한 읽을 행 수보다 작은 `LIMIT`이 읽기 단계에 직접 적용되는 경우에도 이 최적화가 적용되지 않습니다. 이 경우 필수적인 집합 구성 단계 때문에 조기 종료의 이점이 사라지기 때문입니다. [#110576](https://github.com/ClickHouse/ClickHouse/pull/110576) ([KochetovNicolai](https://github.com/KochetovNicolai)).
* 이제 백그라운드 비동기 insert 플러시를 `KILL QUERY`로 종료하면 즉시 중지됩니다. 이전에는 버퍼링된 대용량 페이로드를 플러시하는 경우 취소를 무시하고 끝까지 파싱을 계속했습니다. [#110652](https://github.com/ClickHouse/ClickHouse/pull/110652) ([tiandiwonder](https://github.com/tiandiwonder)).
* `partial_merge` JOIN 위에 배치된 `GROUP BY ... optimize_aggregation_in_order` 및 `DISTINCT ... optimize_distinct_in_order`가 잘못된 결과를 반환하던 문제를 수정했습니다. read-in-order 최적화가 `PartialMergeJoin`을 통해 전파되었는데, `PartialMergeJoin`은 왼쪽 입력을 조인 키 기준으로 다시 정렬하므로 왼쪽 스트림의 원래 순서가 유지되지 않아 행이 잘못 그룹화되었습니다. [#110671](https://github.com/ClickHouse/ClickHouse/pull/110671) ([groeneai](https://github.com/groeneai)).
* `INTERSECT` 또는 `EXCEPT` 쿼리에서 CTE 컬럼 별칭을 사용할 때(예: `WITH t (a, b) AS (SELECT 1, 2 INTERSECT SELECT 1, 2) SELECT a, b FROM t`) 쿼리가 UNKNOWN\_IDENTIFIER 오류로 실패하던 문제를 수정했습니다. [#110885](https://github.com/ClickHouse/ClickHouse/pull/110885) ([yariks5s](https://github.com/yariks5s)).
* 여러 스레드가 리더를 공유하는 상황에서 스필된 블록을 읽는 도중 실패하면 `grace_hash` 조인에서 발생할 수 있던 `LOGICAL_ERROR: ReadBuffer is canceled. Can't read from it.` 오류를 수정했습니다. [#111056](https://github.com/ClickHouse/ClickHouse/pull/111056) ([groeneai](https://github.com/groeneai)).
* \*\_hash JOIN 수행 중 우측(right-side) 컬럼을 구체화할 때 잘못된 시간대가 적용되던 버그를 수정했습니다. [#111074](https://github.com/ClickHouse/ClickHouse/pull/111074) ([yariks5s](https://github.com/yariks5s)).
* `COMMENT` 절이 포함된 `CREATE` 문에서 주석 문자열 리터럴이 누락되면, 잘못 파싱된 쿼리를 오류 없이 허용하는 대신 구문 오류를 발생시키도록 수정했습니다(예: `CREATE VIEW v COMMENT AS SELECT 1`은 더 이상 주석 없는 뷰를 생성하지 않습니다). [#111159](https://github.com/ClickHouse/ClickHouse/pull/111159) ([tiandiwonder](https://github.com/tiandiwonder)).
* 재사용되는 구체화된 CTE(`enable_materialized_cte`)를 `WITH TOTALS` 또는 `extremes` 출력이 버려지는 브랜치에서 읽을 때 발생하던 `LOGICAL_ERROR`(`Reading from materialized CTE '...' before its materialization completed - DelayedPortsProcessor gate is missing in the query plan`)를 수정했습니다. 외부 집계, `INSERT ... SELECT`, 집합 연산, `EXPLAIN ANALYZE`에서 발생하던 경우도 함께 수정되었습니다. [#111194](https://github.com/ClickHouse/ClickHouse/pull/111194) ([groeneai](https://github.com/groeneai)).
* `join_algorithm = 'full_sorting_merge'` 사용 시 `LEFT`/`RIGHT`/`FULL`/`ASOFJOIN`에서 조인되지 않은 행을 컬럼 타입 기본값 대신 원시 0으로 채우던 문제를 수정했습니다. 기본값이 `0`이 아니라 첫 번째 원소인 `Enum` 컬럼에서는 이로 인해 잘못된 결과가 발생했으며(채워진 값에 대한 필터가 매칭되지 않은 행을 제거하여 외부 조인이 경고 없이 내부 조인처럼 동작함), 해당 컬럼을 선택하면 `UNKNOWN_ELEMENT_OF_ENUM` 오류가 발생했습니다. [#111197](https://github.com/ClickHouse/ClickHouse/pull/111197) ([groeneai](https://github.com/groeneai)).
* `optimize_move_to_prewhere_if_final = 1`이고 `WHERE` 절이 정렬 키 컬럼에 대한 암시적 불리언 조건(예: `WHERE k`)일 때, `FINAL`을 사용한 `SummingMergeTree`(및 `CoalescingMergeTree`)가 잘못된 결과를 반환하던 문제를 수정했습니다. 키 컬럼이 원래 값을 유지하지 않고 머지되지 않은 파트들에 걸쳐 합산된 값으로 반환되었습니다. [#111342](https://github.com/ClickHouse/ClickHouse/pull/111342) ([groeneai](https://github.com/groeneai)).
* 좌측에 `UNION ALL`을 거쳐서도 남아 있는 동일한 이름의 중복 컬럼(예: `1 AS b, 1 AS b`)이 있을 때 `RIGHT`/`FULL JOIN`에서 발생할 수 있던 논리 오류(`Unexpected number of columns in result sample block`)를 수정했습니다. [#111554](https://github.com/ClickHouse/ClickHouse/pull/111554) ([groeneai](https://github.com/groeneai)).
* AST fuzzer처럼 AST의 자식 노드가 교체된 `EXECUTE AS` 쿼리를 포맷팅할 때 클라이언트가 크래시되던 문제를 수정했습니다. 이제 `ASTExecuteAsQuery`는 `children`을 가리키는 비소유 포인터를 보유하는 대신 `target_user` 및 `subquery` 자식을 직접 소유합니다. [#111725](https://github.com/ClickHouse/ClickHouse/pull/111725) ([groeneai](https://github.com/groeneai)).
* `join_any_take_last_row = 1`인 상태에서 `query_plan_join_swap_table`이 `ANY JOIN`을 스왑하면 잘못된 결과가 반환되던 문제를 수정했습니다. 이제 ClickHouse는 원래의 조인 측 순서를 유지하므로 `ANY JOIN`이 계속 마지막으로 매칭된 행을 반환합니다. [#112458](https://github.com/ClickHouse/ClickHouse/pull/112458) ([vdimir](https://github.com/vdimir)).
* 서브쿼리 내부에서 `getClientHTTPHeader`를 사용할 때 발생하던 `Context has expired` 예외를 수정했습니다. [#112533](https://github.com/ClickHouse/ClickHouse/pull/112533) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `ON` 절에 혼합 조건, 즉 `ON (t1.key = t2.key) AND (t1.a * 10 < t2.a)`와 같이 양측에 걸친 비등가 잔여 조건이 포함된 `JOIN`이 잘못된 결과를 반환하던 문제를 수정했습니다. 이러한 조건은 해시 계열 알고리즘만 평가할 수 있지만, `full_sorting_merge`, `partial_merge` 및 직접 키-값 조인이 해당 조인을 실행할 수 있다고 응답한 뒤 잔여 조건을 경고 없이 무시하여 불필요한 행까지 반환했습니다. 이제 이들 알고리즘은 실행을 거부하며, 대신 해시 알고리즘이 사용됩니다. [#112831](https://github.com/ClickHouse/ClickHouse/pull/112831) ([groeneai](https://github.com/groeneai)).
* `WHERE`가 `rand`와 같은 비결정적 표현식으로 두 테이블의 컬럼을 비교하는 쉼표 조인 또는 `CROSS` 조인에서 잘못된 결과가 반환되던 문제를 수정했습니다. 조인을 `INNER` 조인으로 재작성하는 과정에서 해당 표현식이 조인 키로 옮겨졌고, 조인 키에서는 양쪽의 행마다 표현식이 다시 평가됩니다. 이 때문에 쿼리가 자신의 `WHERE` 절과 모순되는 행을 반환할 수 있었습니다. [#112938](https://github.com/ClickHouse/ClickHouse/pull/112938) ([groeneai](https://github.com/groeneai)).
* 인식되지 않는 문자가 길게 이어지는 PromQL 쿼리(예: NUL 바이트로 채워진 `FixedString` 값)를 파싱할 때 처리 시간이 2차적으로 증가하던 문제를 수정했습니다. 이 파싱은 쿼리 분석 단계에서 수행되므로, 메가바이트 크기의 잘못된 입력을 파싱하면 스레드가 수십 분 동안 점유되었고 취소할 수도 없었습니다. 이제 파서는 첫 번째 오류에서 바로 중단됩니다. [#112944](https://github.com/ClickHouse/ClickHouse/pull/112944) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 상수가 아닌 컬럼을 상수 -1로 나누는 `intDiv`가 부호 있는 정수의 최솟값에 대한 나눗셈(예: `intDiv(-9223372036854775808, -1)`)에서 다른 실행 경로처럼 `ILLEGAL_DIVISION` 예외를 발생시키지 않고 오류 없이 오버플로(wrap)되던 문제를 수정했습니다. 순서 기반 읽기(read-in-order) 최적화는 음수 상수로 나누는 `intDiv`를 단조 함수로 올바르게 취급하는데, 오버플로된 값이 이에 따른 정렬 순서를 깨뜨리기 때문에 `ORDER BY`/`DISTINCT` 결과가 잘못될 수도 있었습니다. [#113048](https://github.com/ClickHouse/ClickHouse/pull/113048) ([alexey-milovidov](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/113760) ([groeneai](https://github.com/groeneai)).
* 오른쪽에 합계(totals)가 포함된 경우 `join_algorithm = 'partial_merge'`를 사용하는 `JOIN`에서 잘못된 결과가 반환되던 문제를 수정했습니다. 오른쪽 입력이 머지되지 않은 상태로 남을 수 있어, `LEFT` 조인은 실제로 일치하는 값 대신 기본값을 채웠고 `INNER`/`RIGHT` 조인은 행을 전혀 반환하지 않았습니다. 또한 `RIGHT`/`FULL`의 비조인 경로에서는 같은 상태로 인해 널 포인터가 역참조되어 서버가 비정상 종료되었습니다. [#113936](https://github.com/ClickHouse/ClickHouse/pull/113936) ([groeneai](https://github.com/groeneai)).
* 전체 입력을 읽어야 하는 `LIMIT`가 포함된 `SELECT DISTINCT`에서 잘못된 결과가 반환되던 문제를 수정했습니다. `LIMIT n WITH TIES`는 동점 행을 누락했고, `exact_rows_before_limit = 1`은 실제보다 작은 `rows_before_limit_at_least` 값을 보고했으며, `GROUP BY ... WITH TOTALS`는 스트림의 앞부분만으로 합계 행을 계산했습니다. [#114025](https://github.com/ClickHouse/ClickHouse/pull/114025) ([groeneai](https://github.com/groeneai)).
* `PREWHERE`에서 `FINAL`이 머지에 필요로 하는 컬럼(`ver`, `is_deleted`, `sign`)을 사용하면서 해당 컬럼은 선택하지 않는 `SELECT ... FINAL` 쿼리에서 `LOGICAL_ERROR`("Unexpected number of kept output positions after removing unused columns from `ReadFromMergeTree`")가 발생하던 문제를 수정했습니다. [#114746](https://github.com/ClickHouse/ClickHouse/pull/114746) ([groeneai](https://github.com/groeneai)).
* 비동기 INSERT 플러시, 구체화된 뷰(Materialized View) 처리, `EXPLAIN ANALYZE`에서 이미 만료된 쿼리 추적 상태에 접근할 수 있던 수명(lifetime) 관련 문제를 수정했습니다. [#114940](https://github.com/ClickHouse/ClickHouse/pull/114940) ([azat](https://github.com/azat)).
* 인터벌 사이의 구분 쉼표를 생략하면 `CREATE QUOTA`와 `ALTER QUOTA`가 마지막 `FOR INTERVAL` 블록을 제외한 나머지를 모두 경고 없이 버리던 문제를 수정했습니다. 이 경우 SQL 문은 성공했지만 앞선 제한은 하나도 적용되지 않았습니다. 이제 2020년 이전과 마찬가지로 인터벌이 다시 누적됩니다. [#115320](https://github.com/ClickHouse/ClickHouse/pull/115320) ([groeneai](https://github.com/groeneai)).
* `randConstant` 호출에 서로 다른 별칭이 지정되면 하나의 쿼리에서 서로 다른 두 값을 반환하던 문제를 수정했습니다. 문서상 `randConstant`는 쿼리 전체에서 하나의 값을 유지하며 `SELECT randConstant() = randConstant()`도 이미 `1`을 반환했지만, `SELECT randConstant() AS a, randConstant() AS b`처럼 별칭을 붙이면 서로 무관한 두 값이 생성되었습니다. [#115384](https://github.com/ClickHouse/ClickHouse/pull/115384) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 손상된 `MsgPack` 또는 `ProtobufList` 파일에서 `SELECT count()`가 끝나지 않거나 실제와 다른 행 수를 반환하던 문제를 수정했습니다. `optimize_count_from_files` 고속 경로(fast path)는 읽기 위치가 실제로 진행되는지 확인하지 않고 행을 셌기 때문에, 2바이트짜리 `ProtobufList` 파일에서 수십억 개의 행이 생성되어 쿼리가 끝나지 않았습니다. 이제 이러한 입력은 일반 읽기 경로와 동일한 오류를 반환하며 거부됩니다. [#115884](https://github.com/ClickHouse/ClickHouse/pull/115884) ([groeneai](https://github.com/groeneai)).
* `system.distribution_queue`의 `broken_data_files`와 `BrokenDistributedFilesToInsert` 메트릭이 항상 `0`으로 보고되던 문제를 수정했습니다. 서버 시작 시 비동기 삽입 큐를 스캔할 때 `DistributedAsyncInsertDirectoryQueue::initializeFilesFromDisk`가 손상된 바이트 수는 집계했지만 손상된 파일 카운터는 증가시키지 않았습니다. [#92124](https://github.com/ClickHouse/ClickHouse/pull/92124) ([squalfof](https://github.com/squalfof)).

<h3 id="other-bug-fixes">
  기타 버그 수정
</h3>

* 내부 쿼리의 일부로 실행되는 보조 쿼리가 이제 내부 쿼리로 기록됩니다. [#108506](https://github.com/ClickHouse/ClickHouse/pull/108506) ([mstetsyuk](https://github.com/mstetsyuk)).
* PREWHERE 조건이 여러 읽기 단계로 분할될 때, 파트에 없는 DEFAULT 컬럼이 DEFAULT 표현식 대신 해당 유형의 기본값으로 채워지던 문제를 수정했습니다. [#111795](https://github.com/ClickHouse/ClickHouse/pull/111795) ([yariks5s](https://github.com/yariks5s)).
* `normalized_query_hash`를 키로 하는 쿼터가 이제 모든 리소스(`read_rows`, `read_bytes`, `result_rows`, `result_bytes`, `execution_time`, `written_bytes`, `errors`)를 사용자별 단일 공유 버킷에 합산하지 않고, 쿼리 수 카운터와 마찬가지로 쿼리 패턴별로 집계합니다. [#107681](https://github.com/ClickHouse/ClickHouse/pull/107681) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* MySQL `connect_timeout` 및 읽기/쓰기 타임아웃이 적용되지 않던 문제를 수정했습니다. 샘플링 쿼리 프로파일러의 주기적 시그널이 MySQL 클라이언트의 내부 폴링 기한을 계속 재설정했기 때문에, `connect_timeout = 1`로 설정하더라도 응답하지 않는 MySQL 서버에 연결을 시도하면 2분 이상 멈춰 있을 수 있었습니다. [#109592](https://github.com/ClickHouse/ClickHouse/pull/109592) ([tiandiwonder](https://github.com/tiandiwonder)).
* 쿼리 프로파일러가 활성화된 상태에서 스트리밍 삽입의 블록 대기 타임아웃(`input_format_max_block_wait_ms`)이 만료되지 않을 수 있던 문제를 수정했습니다. 프로파일러 시그널이 발생할 때마다 파일 디스크립터 폴링이 전체 타임아웃으로 다시 시작되었기 때문에, 입력 소스가 멈추면 대기 한도에 도달해도 부분 블록이 플러시되지 않고 무기한 지연될 수 있었습니다. [#109602](https://github.com/ClickHouse/ClickHouse/pull/109602) ([tiandiwonder](https://github.com/tiandiwonder)).
* Experimental 설정 `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](https://github.com/ClickHouse/ClickHouse/pull/109770) ([groeneai](https://github.com/groeneai)).
* `distinct_overflow_mode = 'break'` 동작을 수정했습니다. 이제 문서에 명시된 대로 DISTINCT가 한도까지 누적된 부분 결과를 반환하고 소스 읽기를 중단합니다. 이전에는 `max_rows_in_distinct` / `max_bytes_in_distinct`를 초과한 청크가 버려졌고(결과가 잘리거나 비어 있음), 쿼리는 입력이 끝날 때까지 계속 읽으면서 해시 세트에 삽입했기 때문에 `MEMORY_LIMIT_EXCEEDED`가 발생할 수 있었습니다. [#110075](https://github.com/ClickHouse/ClickHouse/pull/110075) ([skuznetsov-clickhouse](https://github.com/skuznetsov-clickhouse)).
* `optimize_aggregation_in_order`가 쿼리 취소를 무시하던 문제를 수정했습니다. 이제 `AggregatingInOrderTransform`이 청크를 집계하는 도중에도 취소 여부를 확인하므로, `KILL QUERY` 또는 `max_execution_time`(기본값인 `timeout_overflow_mode = 'throw'` 기준)으로 중지된 쿼리가 청크 전체를 끝까지 처리하지 않고 즉시 중단됩니다. [#110104](https://github.com/ClickHouse/ClickHouse/pull/110104) ([groeneai](https://github.com/groeneai)).
* `mysql`/`postgresql`/`sqlite` 계열 PostgreSQL 소스의 값을 파싱할 수 없는 유형으로 선언된 컬럼에 읽어 들일 때(예: `text` 컬럼을 `Int32`로 선언한 경우) 발생하던 서버 중단(디버그 및 새니타이저 빌드)을 수정했습니다. 이제 이러한 유형 불일치는 서버를 중단시키지 않고 쿼리 오류로 보고됩니다. [#110264](https://github.com/ClickHouse/ClickHouse/pull/110264) ([groeneai](https://github.com/groeneai)).
* 특정 PRQL 쿼리(`SET dialect = 'prql'`)를 파싱할 때 발생하던 서버 중단을 수정했습니다. 그동안 `prqlc` 컴파일러 내부에서 발생한 패닉이 쿼리 오류로 보고되지 않고 프로세스를 중단시켰습니다. [#110316](https://github.com/ClickHouse/ClickHouse/pull/110316) ([groeneai](https://github.com/groeneai)).
* 행 정책(row policy)과 `additional_table_filters`가 쿼리에서 따로 선택하지 않은 동일한 컬럼을 참조할 때 발생하던 `NOT_FOUND_COLUMN_IN_BLOCK` 오류를 수정했습니다. [#111099](https://github.com/ClickHouse/ClickHouse/pull/111099) ([groeneai](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/111909) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 문서에 명시된 기본값 `0`이 무한 타임아웃을 의미하도록 `connection_pool_max_wait_ms`를 수정했습니다. 이전에는 연결 풀이 가득 찬 상태에서 쿼리가 쉴 새 없이 재시도하면서 CPU를 소모하고, 반복할 때마다 `No free connections in pool. Waiting 0 ms.`를 로그에 기록했습니다. 이제는 연결이 풀에 반환될 때까지 대기합니다. [#112380](https://github.com/ClickHouse/ClickHouse/pull/112380) ([groeneai](https://github.com/groeneai)).
* `replaceOne`, `replaceAll`, `replaceRegexpOne`, `replaceRegexpAll`이 `max_execution_time`과 `KILL QUERY`를 무시하는 문제를 수정했습니다. 이제 단일 호출도 작업 도중 취소 여부를 확인하므로, 큰 값이나 많은 행에 대한 장기 실행 대체 작업이 끝날 때까지 서버 스레드를 점유하지 않고 중단됩니다. 이러한 호출은 반환할 부분 결과가 없으므로, `timeout_overflow_mode = 'break'`에서는 기한 초과를 오류로 발생시킵니다. 상수 폴딩(constant folding)된 경우에는 항상 오류가 발생하며, 파이프라인에서는 실행기의 블록 간 검사보다 이 체크포인트에 먼저 도달할 때마다 오류가 발생합니다. 블록 간 검사에서는 기존과 같이 쿼리가 오류 없이 중단됩니다. [#112483](https://github.com/ClickHouse/ClickHouse/pull/112483) ([groeneai](https://github.com/groeneai)).
* `countSubstrings`, `countSubstringsCaseInsensitive`, `countSubstringsCaseInsensitiveUTF8`이 `KILL QUERY`와 `max_execution_time`을 무시하는 문제를 수정했습니다. 행이나 일치 항목이 많으면 쿼리가 취소된 후에도 호출이 수 분간 계속 실행될 수 있었습니다. [#113369](https://github.com/ClickHouse/ClickHouse/pull/113369) ([groeneai](https://github.com/groeneai)).
* initiator에서 쿼리가 매우 빠르게 완료되면 쿼리가 (`receive_timeout`초 동안) 멈출 수 있는 문제를 수정했습니다. [#113551](https://github.com/ClickHouse/ClickHouse/pull/113551) ([nickitat](https://github.com/nickitat)).
* `countMatches`와 `countMatchesCaseInsensitive`가 하나의 큰 값에서 일치 항목을 세는 동안 `max_execution_time`과 `KILL QUERY`를 무시하여, 취소된 쿼리가 수 분간 계속 실행되던 문제를 수정했습니다. 인수가 상수이면 호출이 쿼리 분석 단계에서 이루어지므로 이를 취소할 파이프라인이 존재하지 않습니다. [#113886](https://github.com/ClickHouse/ClickHouse/pull/113886) ([groeneai](https://github.com/groeneai)).
* 쿼리가 `max_execution_time`에 도달하기 최대 1ms 전에 취소되어 `Timeout exceeded: elapsed 999.672 ms, maximum: 1000 ms`라는 모순된 오류로 실패할 수 있던 문제를 수정했습니다. [#114559](https://github.com/ClickHouse/ClickHouse/pull/114559) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 경계 상자가 무한한 상수 폴리곤(예: 좌표가 `+-DBL_MAX`에 도달하는 경우)을 사용할 때 `pointInPolygon`에서 범위를 벗어난 읽기가 발생하던 문제를 수정했습니다. 이제 이러한 폴리곤은 `BAD_ARGUMENTS`로 거부되며, 빈 링이 있는 폴리곤은 내부가 없는 것으로 처리됩니다. 이전에는 쿼리가 잘못된 결과를 반환하거나, 하드닝 또는 새니타이저가 활성화된 빌드에서 서버가 비정상 종료될 수 있었습니다. [#115035](https://github.com/ClickHouse/ClickHouse/pull/115035) ([groeneai](https://github.com/groeneai)).
* `STREAM BOUNDED` 쿼리가 시작 전에 커밋된 행보다 적은 수의 행(대개 0개)을 반환할 수 있던 경쟁 상태를 수정했습니다. [#115543](https://github.com/ClickHouse/ClickHouse/pull/115543) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `make_distributed_plan = 1` 설정에서 윈도우 쿼리의 정렬 컬럼이 해당 컬럼을 참조하지 않는 `Expression` 단계를 거칠 때, 쿼리 계획 최적화 중 `Unknown identifier` 오류가 발생하던 문제를 수정했습니다. [#115890](https://github.com/ClickHouse/ClickHouse/pull/115890) ([groeneai](https://github.com/groeneai)).
* `h3kRing`, `h3HexRing`, `h3Line`, `h3ToChildren`이 행 블록을 확장하는 동안 `max_execution_time` 및 `KILL QUERY`를 무시하던 문제를 수정했습니다. [#115893](https://github.com/ClickHouse/ClickHouse/pull/115893) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `PREWHERE`의 조건절(conjunct)들이 공통 중간 표현식을 공유할 때 네이티브 Parquet V3 리더에서 `NOT_FOUND_COLUMN_IN_BLOCK`이 발생하던 문제(이전 회귀로 인해 발생)를 수정했습니다. [#107059](https://github.com/ClickHouse/ClickHouse/pull/107059) ([groeneai](https://github.com/groeneai)).
* `output_format_parquet_parallel_encoding`이 활성화되어 있고(기본값) `max_threads`가 1보다 클 때 Parquet 쓰기가 멈추던 문제를 수정했습니다. 인코더가 추가 스레드 예약에 실패하면 활성 스레드 카운터에 언더플로가 발생하여, 쓰기가 완료되거나 오류를 보고하지 못하고 영구적으로 멈출 수 있었습니다. [#112959](https://github.com/ClickHouse/ClickHouse/pull/112959) ([groeneai](https://github.com/groeneai)).
* Thrift 메타데이터에 선언된 컨테이너 또는 문자열 길이가 메타데이터 자체보다 큰 Parquet 파일을 읽을 때 메모리가 무제한으로 할당되던 문제를 수정했습니다. 이제 이러한 길이는 메모리를 할당하지 않고 거부합니다. [#113212](https://github.com/ClickHouse/ClickHouse/pull/113212) ([groeneai](https://github.com/groeneai)).
* 필터 평가에만 필요한 컬럼이 출력 슬롯이 이미 삭제된 후에 디코딩되도록 예약된 경우, Parquet v3 리더에서 `std::out_of_range` 예외(`Logical error: 'std::exception. Code: 1001, type: std::out_of_range'`, 디버그 및 새니타이저 빌드에서는 서버가 중단되기도 함)가 발생하던 문제를 수정했습니다. [#113956](https://github.com/ClickHouse/ClickHouse/pull/113956) ([groeneai](https://github.com/groeneai)).
* 프로필 이벤트와 메모리 트래커에서 발생하던 데이터 경쟁(data race)을 수정했습니다. [#112466](https://github.com/ClickHouse/ClickHouse/pull/112466) ([mstetsyuk](https://github.com/mstetsyuk)).
* `trace_profile_events_list` 설정으로 특정 프로필 이벤트의 스택 트레이스를 `system.trace_log`에 기록할 때 프로필 이벤트에서 이론적으로 발생할 수 있는 데이터 경쟁을 수정했습니다. [#113553](https://github.com/ClickHouse/ClickHouse/pull/113553) ([mstetsyuk](https://github.com/mstetsyuk)).
* 나눗셈에서 부동 소수점 예외(0으로 나누기 또는 `INT_MIN / -1`)가 발생할 때, 부호 있는/부호 없는 인수가 혼합된 경우를 포함하여 `intDivOrNull`, `moduloOrNull`, `positiveModuloOrNull`이 `NULL` 대신 `0`을 반환하고, `intDivOrNull` 및 `intDivOrZero`가 `NULL` / `0`을 반환하지 않고 예외를 발생시키던 문제를 수정했습니다. [#101976](https://github.com/ClickHouse/ClickHouse/pull/101976) ([yariks5s](https://github.com/yariks5s)).
* `Array` 및 `Map` 값을 `NULL`과 비교할 때 `IS DISTINCT FROM`이 잘못 동작하던 문제를 수정했습니다. [#103162](https://github.com/ClickHouse/ClickHouse/pull/103162) ([ylw510](https://github.com/ylw510)).
* `groupConcat(',', 2)(x, '/')`처럼 매개변수 방식과 2-인수 방식을 혼용할 때 `groupConcat`이 잘못 동작하던 문제를 수정했습니다. 행 제한 매개변수가 별도의 알림 없이 무시되어 요청한 개수 대신 모든 행이 반환되었습니다. 이제 두 번째 인수의 구분자가 매개변수를 올바르게 재정의합니다. [#104882](https://github.com/ClickHouse/ClickHouse/pull/104882) ([yariks5s](https://github.com/yariks5s)).
* 작은 인터벌 단위에서 큰 인터벌 단위로 CAST할 때 발생하던 버그를 수정했습니다. [#105058](https://github.com/ClickHouse/ClickHouse/pull/105058) ([yariks5s](https://github.com/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](https://github.com/ClickHouse/ClickHouse/pull/105102) ([groeneai](https://github.com/groeneai)).
* `enable_sharding_aggregator = 1`을 `UNION ALL`과 함께 사용하고 `max_streams_for_union_step`이 파이프라인 폭보다 작은 쿼리에서 발생하던 `Logical error: 'Pipeline stuck'`을 수정했습니다. 이제 `BufferedShardByHashTransform`은 입력이 소진되는 즉시 비어 있는 큐의 출력 포트를 종료하며, 요청된 빈 포트에 내보낼 데이터가 없으면 형제 큐가 백프레셔 한도에 도달했더라도 계속 입력을 가져옵니다. [#106251](https://github.com/ClickHouse/ClickHouse/pull/106251) ([groeneai](https://github.com/groeneai)).
* `plain` 객체 스토리지 디스크(예: `s3_plain`)에서 `removeDirectory`가 비어 있지 않은 디렉터리 내부의 모든 파일을 재귀 삭제처럼 제거하던 문제를 수정했습니다. 이제 비어 있지 않은 디렉터리를 삭제하면 `CANNOT_RMDIR` 오류로 실패하며, 재귀 삭제는 내용물을 명시적으로 처리합니다. [#106281](https://github.com/ClickHouse/ClickHouse/pull/106281) ([RinChanNOWWW](https://github.com/RinChanNOWWW)).
* `<lifetime>`이 설정된 `executable_pool` 사용자 정의 함수가 기반 스크립트의 변경 사항을 반영하지 않던 문제를 수정했습니다. 이전에는 `SYSTEM RELOAD FUNCTIONS`를 실행해야만 수정된 스크립트를 다시 읽었으며, `<lifetime>`에 따른 주기적 다시 로드에서는 이전 버전이 계속 실행되었습니다. [#107087](https://github.com/ClickHouse/ClickHouse/pull/107087) ([groeneai](https://github.com/groeneai)).
* 워커 스레드가 프로파일러를 시작하는 과정과 서버 종료 과정 사이에서 서버 전역 트레이스 collector에 발생하던 데이터 경합을 수정했습니다. [#107307](https://github.com/ClickHouse/ClickHouse/pull/107307) ([groeneai](https://github.com/groeneai)).
* `threadPoolCallbackRunnerUnsafe`를 통해 예약된 작업이 실행되기 전에 스레드 풀 큐에서 제거되면서 종료 중에 드물게 서버가 비정상 종료되던 문제(`std::future_error`, "The associated promise has been destructed prior to the associated state becoming ready")를 수정했습니다. [#107383](https://github.com/ClickHouse/ClickHouse/pull/107383) ([groeneai](https://github.com/groeneai)).
* 감시 중인 파일이 삭제된 뒤 동일한 inode를 재사용해 다시 생성될 때 발생할 수 있던 `FileLog` 논리 오류(`Last stored last_written_position in meta file ... is bigger than current last_written_pos`)를 수정했습니다. [#107617](https://github.com/ClickHouse/ClickHouse/pull/107617) ([groeneai](https://github.com/groeneai)).
* `saturate` 및 `ignore` 오버플로우 모드에서 `toTime64`와 `CAST(... AS Time64)`가 범위를 벗어난 값을 `Time64` 범위로 제한하지 않아, 표시는 같지만 비교하면 서로 다른 값이 생성될 수 있던 문제를 수정했습니다. [#108028](https://github.com/ClickHouse/ClickHouse/pull/108028) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 정규식 「전체 매칭」 함수인 `extractAll`, `extractAllGroupsVertical`, `extractAllGroupsHorizontal`, `countMatches`, `splitByRegexp`에서 너비가 0인 어서션(`\b`, `^`, `$`)을 잘못 처리하던 문제를 수정했습니다. 예를 들어 `extractAll('new york is the greatest', '\b(\w)')`는 이제 모든 글자가 아닌 각 단어의 첫 글자를 올바르게 반환합니다. [#108047](https://github.com/ClickHouse/ClickHouse/pull/108047) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `splitByNonAlpha`가 아닌 토크나이저를 사용하는 텍스트 인덱스에서 `hasToken`을 사용하면 잘못된 결과가 반환되던 문제를 수정했습니다. [#108066](https://github.com/ClickHouse/ClickHouse/pull/108066) ([rschu1ze](https://github.com/rschu1ze)).
* 입력값의 정밀도가 인터벌 단위보다 세밀할 때 `toStartOfInterval`과 `dateTrunc`가 해당 값이 속한 인터벌의 시작 대신 반올림된 값을 반환하던 문제를 수정했습니다. 예를 들어 `toStartOfInterval(toDateTime64('2023-10-09 10:11:12.000999', 6), INTERVAL 1 millisecond)`가 `10:11:12.000` 대신 `10:11:12.001`을 반환했습니다. 명시적 기준점(origin)을 지정하는 오버로드에도 같은 문제가 있었습니다. [#108186](https://github.com/ClickHouse/ClickHouse/pull/108186) ([yariks5s](https://github.com/yariks5s)).
* `replaceRegexpOne`과 `replaceRegexpAll`에서 다른 정규식 함수와 마찬가지로 `.`가 기본적으로 개행 문자와도 일치하도록 수정했습니다. [#108265](https://github.com/ClickHouse/ClickHouse/pull/108265) ([linjiayu1025-collab](https://github.com/linjiayu1025-collab)).
* 경량 UPDATE/DELETE의 조건이 두 번 평가되던 문제를 수정했습니다. [#108323](https://github.com/ClickHouse/ClickHouse/pull/108323) ([ofeliacode](https://github.com/ofeliacode)).
* 상수가 아닌 limit 인수를 사용할 때 `arrayPartialSort()`가 올바르게 동작하지 않던 문제를 수정했습니다. [#108327](https://github.com/ClickHouse/ClickHouse/pull/108327) ([vitlibar](https://github.com/vitlibar)).
* 패턴에 NUL(`\0`) 바이트가 포함된 경우 정규식 함수(`match`, `extract`, `extractAll`, `replaceRegexpOne`, `replaceRegexpAll` 등)가 오류 없이 잘못된 결과를 반환하던 문제를 수정했습니다. 이제 NUL은 RE2와 동일하게 일반 리터럴 바이트로 처리됩니다. [#108427](https://github.com/ClickHouse/ClickHouse/pull/108427) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `DateTime64(N)` 인수에 `changeYear`/`changeMonth`/`changeDay`/`changeHour`/`changeMinute`/`changeSecond`를 적용하면 `N` 대신 하드코딩된 기본 scale(3)로 결과 컬럼이 생성되던 문제를 수정했습니다. 값은 scale `N`으로 계산되었지만 컬럼 객체는 scale 3으로 선언되어 타입과 구조적으로 일치하지 않았습니다. [#108551](https://github.com/ClickHouse/ClickHouse/pull/108551) ([groeneai](https://github.com/groeneai)).
* `correlated_subqueries_default_join_kind = 'left'`로 설정된 상태에서 집합 연산(`INTERSECT` / `UNION ALL` / `EXCEPT`)이 상관 서브쿼리(correlated subquery)를 사용하는 분기를 결합할 때 발생하던 `LOGICAL_ERROR`("Trying to extract chunk from ChunkBuffer before all inputs are finished")를 수정했습니다. [#108554](https://github.com/ClickHouse/ClickHouse/pull/108554) ([groeneai](https://github.com/groeneai)).
* `changeYear`, `changeMonth`, `changeDay`, `changeHour`, `changeMinute`, `changeSecond`의 `DateTime64` 관련 버그를 수정했습니다. 이제 나노초 정밀도(scale 9) 입력에서 `DECIMAL_OVERFLOW`가 발생하지 않으며, epoch 이전의 1초 미만 단위 입력에 대해서도 올바른 달력상의 초를 반환합니다. [#108681](https://github.com/ClickHouse/ClickHouse/pull/108681) ([takumihara](https://github.com/takumihara)).
* 매우 큰 정규식(예: 와일드카드가 수십만 개 포함된 `LIKE` 또는 `match` 패턴)을 컴파일할 때 서버 로그가 과도하게 출력되고 오류 메시지가 지나치게 커지는 문제를 방지했습니다. 이제 이러한 패턴은 명확한 `CANNOT_COMPILE_REGEXP` 오류와 함께 실패합니다. [#108821](https://github.com/ClickHouse/ClickHouse/pull/108821) ([Algunenano](https://github.com/Algunenano)).
* 소스와 대상의 물리적 타입이 같을 때 `reinterpret(x, 'Decimal128(scale)')`(및 `Decimal32`/`Decimal64`/`Decimal256`/`DateTime64` 대상)가 요청한 대상 scale이 아닌 소스 scale을 내부 scale로 갖는 결과 컬럼을 생성하던 문제를 수정했습니다. 값 자체는 올바랐지만 컬럼 객체가 선언된 타입과 구조적으로 일치하지 않았습니다. [#108878](https://github.com/ClickHouse/ClickHouse/pull/108878) ([groeneai](https://github.com/groeneai)).
* 동기화가 어긋났거나 퍼징된 연결에서 범위를 벗어난 프로토콜 패킷 유형을 문자열로 변환할 때(예: "Unexpected packet from server" / "Received ... packet" 오류 메시지) 발생하던 정의되지 않은 동작을 수정했습니다. [#108885](https://github.com/ClickHouse/ClickHouse/pull/108885) ([groeneai](https://github.com/groeneai)).
* `DateTime64(N)`에 대한 `changeYear`/`changeMonth`/`changeDay`/`changeHour`/`changeMinute`/`changeSecond`가 결과 컬럼을 `N`이 아닌 하드코딩된 기본 scale 3으로 생성하던 문제와, `DateTime64`에 대한 `timeSlots`가 선언된 반환 타입에 선택적 `Size` 인수의 scale을 반영하지 않던 문제를 수정했습니다. 두 경우 모두 물리적 scale이 선언된 타입과 다른 컬럼이 생성되어, 결과를 `arrayPushBack`/`arrayPushFront`/`arrayConcat`에 전달하면 `LOGICAL_ERROR`(`writeSlice expects same column types`)가 발생했습니다. 또한 `Size`에 가장 큰 scale을 지정한 `timeSlots`는 잘못된 타임스탬프를 반환했습니다. [#108994](https://github.com/ClickHouse/ClickHouse/pull/108994) ([groeneai](https://github.com/groeneai)).
* ProfileEvents 값이 단조 증가하지 않던 문제를 수정했습니다. [#109180](https://github.com/ClickHouse/ClickHouse/pull/109180) ([azat](https://github.com/azat)).
* 지수의 크기가 `Int32` 범위를 넘어 오버플로우되는 `SAMPLE` 비율(예: `SAMPLE 1e-3000000000`)이 경고 없이 `SAMPLE 1`로 처리되던 문제를 수정했습니다. [#109197](https://github.com/ClickHouse/ClickHouse/pull/109197) ([Algunenano](https://github.com/Algunenano)).
* `toUTCTimestamp`/`fromUTCTimestamp`(및 별칭 `to_utc_timestamp`/`from_utc_timestamp`)와 `toTime64`의 `DateTime64` 처리 경로에서 발생하던 두 가지 버그를 수정했습니다. 첫째, `Int64` 경계 근처에서 발생하던 부호 있는 정수 오버플로우를 수정했습니다(이제 `Int128`로 계산한 후 표현 가능한 범위로 제한합니다). 둘째, 시간대 오프셋 경계 근처의 음수 소수 값에 대해 잘못된 결과가 반환되던 문제를 수정했습니다. 초 단위 분리 시 0 방향으로 절사되어 `timezoneOffset()`이 다음 초를 검사했고, 이로 인해 DST/오프셋 변경 시점의 반대편 값을 잘못 선택할 수 있었습니다. [#109738](https://github.com/ClickHouse/ClickHouse/pull/109738) ([groeneai](https://github.com/groeneai)).
* row policy 필터 표현식에서 `arrayJoin`을 사용할 때 발생하던 논리 오류(`column->size() == num_rows`)를 수정했습니다. 이제 이러한 필터는 허용되지 않습니다. [#109753](https://github.com/ClickHouse/ClickHouse/pull/109753) ([Algunenano](https://github.com/Algunenano)).
* 타입 중첩이 내부 깊이 제한을 초과할 때 `generateRandomStructure()`가 두 데이터 타입이 붙어 있는 잘못된 structure 문자열(예: `Decimal32(7)IPv4`)을 간헐적으로 생성하여 결과를 파싱할 수 없던 문제를 수정했습니다. [#109928](https://github.com/ClickHouse/ClickHouse/pull/109928) ([groeneai](https://github.com/groeneai)).
* `accurateCastOrDefault`에서 쿼리 설정이 전달되지 않던 문제와 `Dynamic` 및 `Variant`로 인코딩된 원본 `NULL` 값이 보존되지 않던 문제를 수정했습니다. [#109946](https://github.com/ClickHouse/ClickHouse/pull/109946) ([Avogar](https://github.com/Avogar)). [#114912](https://github.com/ClickHouse/ClickHouse/pull/114912) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `max_bytes_in_distinct` 및 `max_bytes_in_set`을 수정했습니다. 문자열 키는 제한 검사에 집계되지 않는 arena에 저장되므로, 문자열 키에 대한 DISTINCT / IN이 전체 키 페이로드만큼(키 길이에 비례해 제한 없이) 바이트 제한을 초과하여 메모리를 점유할 수 있었습니다. 이제 문서에 명시된 대로 제한 계산에 arena가 포함됩니다. 따라서 바이트 제한에 근접한 문자열 키를 사용하는 쿼리는 (올바르게) 이전보다 일찍 제한에 걸릴 수 있습니다. [#110120](https://github.com/ClickHouse/ClickHouse/pull/110120) ([skuznetsov-clickhouse](https://github.com/skuznetsov-clickhouse)).
* 내부 차원의 크기가 0인 Npy 파일을 읽을 때 구체화된 행과 최적화 및 비최적화 `count()` 결과가 서로 일치하도록 수정했습니다. [#110146](https://github.com/ClickHouse/ClickHouse/pull/110146) ([qiuyanjun888](https://github.com/qiuyanjun888)).
* `indexHint`/`ignore`/`isZeroOrNull` 함수에 타입이 `Nothing`으로 결정되는 인수가 전달될 때(예: `indexHint(assumeNotNull(materialize(NULL)))`와 같은 표현식 내부) 발생하던 논리 오류(디버그/sanitizer 빌드에서 서버 중단)를 수정했습니다. [#110192](https://github.com/ClickHouse/ClickHouse/pull/110192) ([groeneai](https://github.com/groeneai)).
* 기존 경로를 크기가 다른 내용으로 재작성한 후 `plain_rewritable` 디스크에서 파일을 읽을 때 발생하던 문제를 수정했습니다. 인메모리 메타데이터에 이전 파일 크기가 그대로 남아 있어 `UNEXPECTED_END_OF_FILE` 오류와 함께 읽기가 실패할 수 있었습니다. [#110304](https://github.com/ClickHouse/ClickHouse/pull/110304) ([thevar1able](https://github.com/thevar1able)).
* 계산된 fetch 개수가 0으로 잘려 ANN 검색 결과가 비는 문제를 방지하기 위해, 이제 1.0 미만의 `vector_search_index_fetch_multiplier` 값을 거부합니다. [#110452](https://github.com/ClickHouse/ClickHouse/pull/110452) ([tamish560](https://github.com/tamish560)).
* `initializeAggregation('sumState', 0::UInt64)`와 같이 숫자 캐스트가 포함된 표현식을 사용하는 값을 삽입할 때 간헐적으로 발생하던 `Cannot parse string ... as UInt64 ... While executing ValuesBlockInputFormat` 오류를 수정했습니다. [#110637](https://github.com/ClickHouse/ClickHouse/pull/110637) ([groeneai](https://github.com/groeneai)).
* `readWKT`가 선행 공백이 있는 WKT 문자열(예: `readWKT(' POINT(1 2)')`)을 거부하던 문제를 수정했습니다. 이러한 문자열은 타입별 `readWKTPoint`/`readWKTPolygon`/... 리더와 WKT 문법에서는 허용됩니다. [#110706](https://github.com/ClickHouse/ClickHouse/pull/110706) ([groeneai](https://github.com/groeneai)).
* 길이가 0인 인터벌을 가진 쿼터(예: CREATE QUOTA q FOR INTERVAL 0 SECOND MAX queries = 1000)를 소비할 때 발생하던 서버 크래시(정수를 0으로 나누기)를 수정했습니다. 이제 쿼터 생성 시 0 이하의 쿼터 인터벌 기간은 거부됩니다. [#110846](https://github.com/ClickHouse/ClickHouse/pull/110846) ([PedroTadim](https://github.com/PedroTadim)).
* FIPS 빌드에서 Ed25519 SSH 키(`CREATE USER ... IDENTIFIED WITH ssh_key ... TYPE 'ssh-ed25519'` 또는 `users.xml`에 지정된 해당 키)를 사용할 때 발생하던 크래시를 수정했습니다. Ed25519는 FIPS 승인 알고리즘이 아니므로, 이제 이러한 키는 명확한 `LIBSSH_ERROR` 오류와 함께 거부됩니다. [#110891](https://github.com/ClickHouse/ClickHouse/pull/110891) ([thevar1able](https://github.com/thevar1able)).
* `QBit`에 대한 전치(transposed) 거리 함수(`cosineDistanceTransposed`, `L2DistanceTransposed`, `dotProductTransposed`)는 이제 `precision`개의 비트 평면으로 잘린 값을 거친 셀의 하한 경계로 재구성(삭제된 비트를 0으로 채움)하지 않고, 범위가 제한된 저정밀도 재구성을 사용합니다. 0으로 채우는 방식은 재구성된 모든 값을 0 쪽으로 편향시켰고 낮은 정밀도에서는 제대로 동작하지 않았습니다. 예를 들어 정밀도 1의 `QBit(BFloat16)`에서는 부호 비트만 남기 때문에 모든 값이 `±0.0`으로 재구성되었고, 거리가 모든 행에서 동일한 상수가 되어 순위 정보를 전혀 제공하지 못했습니다. 이제 재구성 방식은 어떤 비트가 삭제되는지에 따라 달라집니다. 원시 `Int8` 코드는 셀 중심으로 재구성되며(`...TransposedQuantized` 경로에서 이미 사용하던 `Lloyd-Max` 재구성과 동일), 정밀도 1의 부동소수점 값은 올바른 부호 양자화로 처리됩니다. 지수 전체를 유지하고 가수 비트만 삭제하는 부동소수점 값은 해당 binade 내에서 범위가 제한된 중간점으로 재구성됩니다(실제 0 또는 `±0.0`은 정확히 0으로 유지되고, 비유한(non-finite) 셀은 별도로 분리되어 `±inf`는 정확히 무한대로 유지됩니다. 모호한 `NaN` 셀에 대해서는 아래 참고 사항을 참조하십시오). 지수 비트가 아직 잘리는 단계에서는 범위가 제한된 하한 경계를 유지하므로, `precision`을 낮추면 값의 크기가 수십 배로 부풀려지는 일 없이 정확도를 낮추는 대신 속도를 높일 수 있습니다. 전체 정밀도 결과는 변경되지 않습니다. [#110911](https://github.com/ClickHouse/ClickHouse/pull/110911) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* 타입 트리에 선언된 컬럼 수가 스트라이프 푸터의 컬럼 인코딩 수보다 많은 손상된 ORC 파일에 대해 스키마 추론을 수행할 때, 네이티브 ORC 리더에서 발생하던 범위 초과 읽기를 수정했습니다. 이제 debug/새니타이저 빌드에서 서버가 중단되지 않고 `CANNOT_EXTRACT_TABLE_STRUCTURE` 오류와 함께 거부됩니다. [#110967](https://github.com/ClickHouse/ClickHouse/pull/110967) ([groeneai](https://github.com/groeneai)).
* 이제 각 SSH 키가 `max_authentication_methods_per_user` 한도에 개별적으로 계산되므로, 구문과 관계없이 한도가 일관되게 적용됩니다. 이전에는 단일 `ssh_key` 메서드에 포함된 여러 키가 하나로 계산되었습니다. [#111181](https://github.com/ClickHouse/ClickHouse/pull/111181) ([TheMC47](https://github.com/TheMC47)).
* 이제 Iceberg REST 카탈로그는 자격 증명이 만료된 경우 별다른 안내 없이 `UNKNOWN_TABLE`을 보고하는 대신 근본 원인이 되는 오류와 함께 보고합니다. [#111379](https://github.com/ClickHouse/ClickHouse/pull/111379) ([alesapin](https://github.com/alesapin)).
* `POINT M EMPTY`와 같이 차원 태그가 지정된 빈 포인트에 대해 `readWKTPoint`/`readWKT`가 초기화되지 않은 좌표(스칼라) 또는 이전 행의 좌표(벡터화)를 반환하던 문제를 수정했습니다. 이제 이러한 입력은 `POINT EMPTY`와 마찬가지로 `CANNOT_PARSE_TEXT` 오류와 함께 거부됩니다. [#111517](https://github.com/ClickHouse/ClickHouse/pull/111517) ([groeneai](https://github.com/groeneai)).
* 이제 `minmax` 통계를 생성할 때 예외를 발생시키는 대신 경고를 출력합니다. [#111785](https://github.com/ClickHouse/ClickHouse/pull/111785) ([hanfei1991](https://github.com/hanfei1991)).
* 시행 횟수와 관계없이 퇴화 확률 `0` 및 `1`에서도 `randBinomial`을 사용할 수 있도록 했습니다. [#112021](https://github.com/ClickHouse/ClickHouse/pull/112021) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* `system.s3_queue_settings`가 `bucketing_mode`, `partitioning_mode`, `partition_regex`, `partition_component`에 대해 잘못된 값을 보고하던 문제를 수정했습니다. [#112300](https://github.com/ClickHouse/ClickHouse/pull/112300) ([bharatnc](https://github.com/bharatnc)).
* PromQL 쿼리에서 발생한 오류의 위치를 올바르게 보고하도록 했습니다. [#112494](https://github.com/ClickHouse/ClickHouse/pull/112494) ([fallintoplace](https://github.com/fallintoplace)).
* 이제 `SYSTEM DISABLE FAILPOINT`는 존재하지 않는 fail point 이름을 거부하며, `SYSTEM ENABLE FAILPOINT`와 마찬가지로 `BAD_ARGUMENTS`를 발생시킵니다. 이전에는 이름을 잘못 입력해도 성공으로 보고되어 의도한 fail point가 활성화된 상태로 남았으며, 아무것도 비활성화되지 않았다는 사실도 알 수 없었습니다. [#112680](https://github.com/ClickHouse/ClickHouse/pull/112680) ([groeneai](https://github.com/groeneai)).
* 컬럼이 삭제된 후 다시 추가된 `Nested` 원소 서브컬럼을 잘못된 타입으로 읽던 문제를 수정했습니다. 이러한 서브컬럼을 해당 상위 컬럼과 함께 선택하면, 블록에는 여전히 원소 타입이 선언된 상태에서 서브컬럼 자리에 원소 전체가 반환되어 릴리스 빌드에서는 임의의 값이, 디버그 및 새니타이저 빌드에서는 논리 오류가 발생했습니다. [#112769](https://github.com/ClickHouse/ClickHouse/pull/112769) ([groeneai](https://github.com/groeneai)).
* 단위가 반복되거나 큰 단위에서 작은 단위 순으로 정렬되지 않은 PromQL 기간 값을 거부하도록 했습니다. [#112954](https://github.com/ClickHouse/ClickHouse/pull/112954) ([fallintoplace](https://github.com/fallintoplace)).
* 대체 문자열이 매치에 참여하지 않은 캡처 그룹을 참조할 때 `replaceRegexpOne`/`replaceRegexpAll`에서 발생하던 정의되지 않은 동작(`memcpy`에 null 포인터 전달)을 수정했습니다. 예: `replaceRegexpAll('abc', '(a)|(b)', '\\2')`. [#113012](https://github.com/ClickHouse/ClickHouse/pull/113012) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* ClickHouse 26.3에서 `unicode_word` 토크나이저로 생성한 텍스트 인덱스를 이후 버전에서 로드할 수 없던 호환성 문제를 수정했습니다 [#113061](https://github.com/ClickHouse/ClickHouse/pull/113061) ([rschu1ze](https://github.com/rschu1ze)).
* PromQL 문자열 이스케이프에서 유효하지 않은 유니코드 서로게이트 코드 포인트를 거부하도록 했습니다. [#113203](https://github.com/ClickHouse/ClickHouse/pull/113203) ([fallintoplace](https://github.com/fallintoplace)).
* PromQL 문자열에서 유효하지 않은 교차 구분자 이스케이프를 거부하도록 했습니다. [#113587](https://github.com/ClickHouse/ClickHouse/pull/113587) ([fallintoplace](https://github.com/fallintoplace)).
* 첫 번째 인수가 윈도우 프레임 내에서 상수일 때 해당 프레임에 대한 `theilsU`가 0 대신 임의의 값을 반환하던 문제를 수정했습니다. [#113691](https://github.com/ClickHouse/ClickHouse/pull/113691) ([alexey-milovidov](https://github.com/alexey-milovidov)).
* Native protocol로 수신된 일부 잘못된 형식의 `Replicated` 직렬화 컬럼에 대해 보고되는 오류 코드를 수정했습니다. 이제 이러한 컬럼은 `LOGICAL_ERROR`(디버그 및 새니타이저 빌드에서 서버를 중단시킴) 대신 `INCORRECT_DATA`로 거부됩니다. [#114186](https://github.com/ClickHouse/ClickHouse/pull/114186) ([Avogar](https://github.com/Avogar)).
* 더 낮은 스케일의 `Decimal64`을 재조정하는 과정에서 `Int64` 오버플로우가 발생하면 잘못된(종종 부호가 뒤바뀐) `Time64` 리터럴과 `IN` 목록 상수가 생성되던 문제를 수정했습니다. 이제 이러한 변환은 `DateTime64` 분기 및 명시적 `CAST`와 마찬가지로 `DECIMAL_OVERFLOW`를 보고합니다. [#114546](https://github.com/ClickHouse/ClickHouse/pull/114546) ([groeneai](https://github.com/groeneai)).
* PromQL 셀렉터에서 따옴표로 묶인 메트릭 이름과 레이블 이름을 지원합니다. [#114551](https://github.com/ClickHouse/ClickHouse/pull/114551) ([fallintoplace](https://github.com/fallintoplace)).
* attach 스레드를 통해 실행된 시작 시도가 실패한 후 `ReplicatedMergeTree` 테이블이 무기한 읽기 전용 상태로 남아 있던 문제를 수정했습니다. 이제 재시작 재시도가 올바르게 예약되므로 자동 복구와 세션 검사가 다시 정상적으로 동작합니다. [#114802](https://github.com/ClickHouse/ClickHouse/pull/114802) ([azat](https://github.com/azat)).
* `timeSeriesRange`와 `timeSeriesFromGrid`가 시작/종료 타임스탬프를 부호 없는 값으로 읽는 바람에 1970년 이전 타임스탬프에 대해 잘못된 `DECIMAL_OVERFLOW`를 발생시키던 문제를 수정했습니다. 또한 `DateTime`/`UInt32` 타임스탬프에서는 step이 경고 없이 하위 32비트로 잘렸습니다. 이제 모든 계산은 `Int64`로 수행됩니다. [#114815](https://github.com/ClickHouse/ClickHouse/pull/114815) ([vitlibar](https://github.com/vitlibar)).
* 쿼리가 `MEMORY_LIMIT_EXCEEDED`로 실패한 후 비동기 삽입에서 발생할 수 있던 예외를 수정했으며, 서버 종료 시 큐에 남아 있는 삽입이 플러시되도록 `async_insert_queue_flush_on_shutdown`을 수정했습니다. [#114839](https://github.com/ClickHouse/ClickHouse/pull/114839) ([azat](https://github.com/azat)).
* `sequenceMatch`, `sequenceCount` 또는 `sequenceMatchEvents` 패턴에 이벤트 번호 `0`이 포함된 경우(예: `sequenceMatch('(?0)')`) `out_of_range` 예외가 내부 `Code: 1001` 오류로 발생하던 문제를 수정했습니다. 이제 이러한 패턴은 `BAD_ARGUMENTS`로 거부됩니다. 또한 `sequenceMatch('(?1)(?t>+)(?2)')`처럼 부호만 있는 시간 조건은 경고 없이 `(?t>0)`으로 처리되었으나, 이제 `SYNTAX_ERROR`로 거부됩니다. [#115056](https://github.com/ClickHouse/ClickHouse/pull/115056) ([groeneai](https://github.com/groeneai)).
* 좌표가 `Float64`가 아닐 때 `geoToH3`의 오류 메시지에 잘못된 인수 위치와 잘못된 유형이 표시되던 문제를 수정했습니다. 기본값인 `geotoh3_argument_order = 'lat_lon'`에서는 오류 메시지가 다른 인수를 가리키고 그 인수의 유형을 출력했습니다. [#115503](https://github.com/ClickHouse/ClickHouse/pull/115503) ([groeneai](https://github.com/groeneai)).
* text, tokenbf\_v1 및 ngrambf\_v1 인덱스에서 잘못된 백슬래시 이스케이프 문자를 수정했습니다. [#115634](https://github.com/ClickHouse/ClickHouse/pull/115634) ([ahmadov](https://github.com/ahmadov)).
* `TZ` 환경 변수가 비어 있으면 서버가 시작되지 않던 문제를 수정했습니다. [#68921](https://github.com/ClickHouse/ClickHouse/pull/68921) ([ardenwick](https://github.com/ardenwick)).
