Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ or anything at all about performance.
| Engine / 엔진 | Schema / 스키마 | Load / 적재 | Queries / 쿼리 |
| --- | --- | --- | --- |
| PostgreSQL 16 | ✅ 25 tables | ✅ 24/24 | ✅ **103/103** |
| ClickHouse 25.11 | ✅ 24 tables | ✅ 24/24 | ⚠️ **100/103** — see below / 아래 참고 |
| ClickHouse 26.7 | ✅ 24 tables | ✅ 24/24 | **102/103** (+1 known) — see below / 아래 참고 |
| StarRocks 3.x | ✅ 24 tables | ✅ 24/24 | ✅ **103/103** |
| Oracle | ⬜ not run | ⬜ | ⬜ |
| Vertica | ⬜ not run | ⬜ | ⬜ |
Expand All @@ -120,8 +120,8 @@ ClickHouse 의 세 건 실패이며, 어느 것도 이 저장소의 결함이

| Query | Cause / 원인 |
| --- | --- |
| q61 | Divides by a `count(*)` that the small fixture leaves at 0. Needs a real dataset. / 작은 픽스처에서 0 이 되는 `count(*)` 로 나눕니다. 실제 데이터셋이 필요합니다. |
| q30, q81 | ClickHouse 25.11 cannot resolve an outer CTE alias referenced inside a subquery over a second instance of the same CTE (`ctr1.ctr_state`). Not listed in upstream's own known-issues file. / ClickHouse 25.11 같은 CTE 의 두 번째 인스턴스에 대한 서브쿼리 안에서 참조된 외부 CTE 별칭(`ctr1.ctr_state`)을 해석하지 못합니다. 상류 known-issues 목록에 없는 항목입니다. |
| q61 | Divides by a `count(*)` that the small verification fixture leaves at 0. A fixture-size artifact, not a query or engine defect — the query is correct and runs on a real dataset. Listed in `expected_failures()` in `tools/verify.sh`, so a run with only this failure still passes. / 검증 픽스처가 작아 0 이 되는 `count(*)` 로 나눕니다. 쿼리·엔진 결함이 아니라 픽스처 크기에서 오는 현상입니다. `tools/verify.sh` 의 `expected_failures()` 에 등록되어 이 실패만 있으면 통과로 처리됩니다. |
| ~~q30, q81~~ | **Fixed upstream.** These failed on ClickHouse 25.11, which could not resolve an outer CTE alias referenced inside a subquery over a second instance of the same CTE (`ctr1.ctr_state`). They pass on 26.7. Found by CI pulling a newer image than the local run had. / **상류에서 수정됨.** ClickHouse 25.11 에서는 같은 CTE 의 두 번째 인스턴스에 대한 서브쿼리 안의 외부 CTE 별칭을 해석하지 못해 실패했지만 26.7 에서는 통과합니다. CI 가 로컬보다 새 이미지를 받아 발견했습니다. |

### What verification found / 검증으로 발견한 것

Expand Down
16 changes: 8 additions & 8 deletions docs/engines/clickhouse.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ Schema and queries are imported **verbatim** from

## Verified / 검증 결과

`tools/verify.sh --engine clickhouse` against ClickHouse 25.11: schema applies,
24/24 tables load, **100/103 queries run**.
`tools/verify.sh --engine clickhouse` against ClickHouse 26.7: schema applies,
24/24 tables load, **102/103 queries run** — the one failure is expected and the run passes.

ClickHouse 25.11 에 대한 `tools/verify.sh --engine clickhouse` 결과: 스키마 적용,
24/24 테이블 적재, **103개 중 100개 쿼리 실행**.
ClickHouse 26.7 에 대한 `tools/verify.sh --engine clickhouse` 결과: 스키마 적용,
24/24 테이블 적재, **103개 중 102개 쿼리 실행**. 남은 1건은 예상된 실패이며 검증은 통과합니다.

| Query | Cause / 원인 |
| --- | --- |
| q61 | Divides by a `count(*)` the small verification fixture leaves at 0. Needs a real dataset. / 검증용 소규모 픽스처에서 0 이 되는 `count(*)` 로 나눕니다. |
| q30, q81 | ClickHouse 25.11 cannot resolve an outer CTE alias referenced inside a subquery over a second instance of the same CTE — `WHERE ctr1.ctr_state = ctr2.ctr_state` over `customer_total_return`. Fails with both `enable_analyzer=1` and `=0`, and is not in the upstream known-issues file. / 같은 CTE 의 두 번째 인스턴스에 대한 서브쿼리 안에서 참조된 외부 CTE 별칭을 해석하지 못합니다. `enable_analyzer` 를 켜도 꺼도 실패하며 상류 known-issues 목록에 없습니다. |
| q61 | Divides by a `count(*)` the small verification fixture leaves at 0 — a fixture-size artifact, not a defect. Registered in `expected_failures()` in `tools/verify.sh`, so a run whose only failure is this one still passes, while any new failure turns the run red. / 검증용 소규모 픽스처에서 0 이 되는 `count(*)` 로 나눕니다. 결함이 아니라 픽스처 크기에서 오는 현상입니다. `tools/verify.sh` 의 `expected_failures()` 에 등록되어 이 실패만 있으면 통과하고, 새로운 실패가 생기면 실패로 바뀝니다. |
| ~~q30, q81~~ | **Fixed upstream.** On ClickHouse 25.11 these failed because the engine could not resolve an outer CTE alias referenced inside a subquery over a second instance of the same CTE — `WHERE ctr1.ctr_state = ctr2.ctr_state` over `customer_total_return` with `enable_analyzer` either on or off. They pass on 26.7. CI caught the difference by pulling a newer image than the local run had, which is a good argument for not pinning `latest` in the compose profile. / **상류에서 수정됨.** ClickHouse 25.11 에서는 `enable_analyzer` 를 켜도 꺼도 실패했지만 26.7 에서는 통과합니다. CI 가 로컬보다 새 이미지를 받아 차이를 발견했습니다. |

!!! warning "Warning / 주의"

Expand Down Expand Up @@ -53,10 +53,10 @@ without them:
| `data_type_default_nullable=1` | columns are non-Nullable, changing NULL semantics throughout |

The last three are the dangerous ones: they do not fail, they quietly change results.
Verified: applying them took the run from 96/103 to 100/103.
Verified: applying them took the run from 96/103 to 102/103.

마지막 세 개가 위험합니다. 실패하지 않고 결과를 조용히 바꿉니다. 이 설정을 적용해
96/103 에서 100/103 으로 개선되는 것을 확인했습니다.
96/103 에서 102/103 으로 개선되는 것을 확인했습니다.

## Setup / 설정

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Two things this repository takes seriously:
| [Oracle](engines/oracle.md) | 103 | SQL\*Loader | ✖ | <span class="pill unrun">not run</span> |
| [PostgreSQL](engines/postgres.md) | 103 | `COPY` | ✅ | <span class="pill pass">103/103</span> |
| [Vertica](engines/vertica.md) | 103 | `COPY … DIRECT` | BYO image | <span class="pill unrun">not run</span> |
| [ClickHouse](engines/clickhouse.md) | 103 | `INSERT … FORMAT CSV` | ✅ | <span class="pill partial">100/103</span> |
| [ClickHouse](engines/clickhouse.md) | 103 | `INSERT … FORMAT CSV` | ✅ | <span class="pill pass">102/103</span> |
| [StarRocks](engines/starrocks.md) | 103 | Stream Load | ✅ | <span class="pill pass">103/103</span> |

103 = the 99 TPC-DS queries, where 14, 23, 24 and 39 each have two formulations.
Expand Down
8 changes: 4 additions & 4 deletions results/verification.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Verification report / 검증 보고서

Generated by `tools/verify.sh` on 2026-08-11 13:54 UTC.
Generated by `tools/verify.sh` on 2026-08-11 14:36 UTC.
`tools/verify.sh` 가 생성했습니다.

Each engine is started from `docker/docker-compose.yml`, given the schema,
Expand All @@ -12,9 +12,9 @@ through all 103 queries.

| Engine / 엔진 | Schema / 스키마 | Load / 적재 | Queries / 쿼리 | Time / 소요 |
| --- | --- | --- | --- | --- |
| postgres | ✅ applied | ✅ 24/24 tables | ✅ 103/103 | 17s |
| clickhouse | ✅ applied | ✅ 24/24 tables | ⚠️ 100/103 | 12s |
| starrocks | ✅ applied | ✅ 24/24 tables | ✅ 103/103 | 34s |
| postgres | ✅ applied | ✅ 24/24 tables | ✅ 103/103 | 14s |
| clickhouse | ✅ applied | ✅ 24/24 tables | ✅ 102/103 (+1 known) | 14s |
| starrocks | ✅ applied | ✅ 24/24 tables | ✅ 103/103 | 37s |

> This proves the SQL runs. It does **not** validate answers — the official
> TPC-DS answer sets are TPC EULA material and are not available here — and it
Expand Down
89 changes: 84 additions & 5 deletions tools/verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,45 @@ VERIFIABLE=(postgres clickhouse starrocks)
# 사용자가 이미지를 제공해야 하는 엔진. 명시적으로 요청할 때만 검증합니다.
BYO_IMAGE=(vertica)

# Known failures that are NOT defects in this repository.
#
# Without this, CI is permanently red for a reason nobody can act on, which trains people
# to ignore it. With it, a run passes when the failures match this list exactly, fails
# when a new query breaks, and warns when a listed query starts passing — so the list
# cannot quietly go stale in either direction.
# 이 저장소의 결함이 **아닌** 알려진 실패 목록입니다.
#
# 이것이 없으면 CI 가 아무도 조치할 수 없는 이유로 영구히 빨간 상태가 되고, 사람들이 CI 를
# 무시하도록 길들입니다. 이 목록이 있으면 실패가 목록과 정확히 일치할 때 통과하고, 새로운
# 쿼리가 깨지면 실패하며, 목록의 쿼리가 통과하기 시작하면 경고합니다. 따라서 목록이 어느
# 방향으로든 조용히 낡아버리지 않습니다.
#
# Record the reason, not just the number. If the reason is an engine bug, link it.
# 숫자만이 아니라 이유를 기록하십시오. 엔진 버그라면 링크를 남기십시오.
expected_failures() {
case "$1" in
clickhouse)
# q61 divides by a count(*) that the verification fixture leaves at 0. It is a
# fixture-size artifact, not a query or engine defect: the query is correct and
# runs on a real dataset. Fixing it would mean generating a fixture that satisfies
# every predicate in all 103 queries, which the fixture does not aim to do.
# q61 은 검증 픽스처에서 0 이 되는 count(*) 로 나눕니다. 쿼리나 엔진의 결함이 아니라
# 픽스처 크기에서 오는 현상이며, 쿼리 자체는 정상이고 실제 데이터셋에서는 실행됩니다.
# 이를 없애려면 103개 쿼리의 모든 조건을 만족하는 픽스처가 필요한데, 픽스처의 목표가
# 아닙니다.
printf '61\n'
;;
*) : ;;
esac
}

expected_reason() {
case "$1:$2" in
clickhouse:61) printf 'divides by a count(*) the fixture leaves at 0 / 픽스처에서 0 이 되는 count(*) 로 나눔' ;;
*) printf 'see expected_failures() in tools/verify.sh' ;;
esac
}

usage() {
cat <<'EOF'
Usage / 사용법: tools/verify.sh --engine <engine> | --all
Expand Down Expand Up @@ -247,13 +286,53 @@ verify_one() {
pass="$(awk -F, 'NR>1 && $8=="ok"' "$csv" | wc -l | tr -d ' ')"
fail="$(awk -F, 'NR>1 && $8=="error"' "$csv" | wc -l | tr -d ' ')"
rows_total="$(awk -F, 'NR>1 && $8=="ok" {s+=$7} END {print s+0}' "$csv")"
if [[ "$fail" -eq 0 ]]; then
# Space-separated strings, not arrays: this script runs on the HOST, and macOS ships
# bash 3.2, where mapfile/readarray do not exist and an empty array expansion trips
# set -u. The in-container scripts can use arrays because those run on bash 5.
# 배열이 아니라 공백 구분 문자열을 사용합니다. 이 스크립트는 호스트에서 실행되고 macOS 는
# bash 3.2 를 제공하는데, 거기에는 mapfile/readarray 가 없고 빈 배열 전개가 set -u 를
# 건드립니다. 컨테이너 안에서 실행되는 스크립트는 bash 5 이므로 배열을 쓸 수 있습니다.
local failed_qs expected_qs unexpected="" now_passing="" q e hit known
failed_qs="$(awk -F, 'NR>1 && $8=="error" {print $4}' "$csv" | sort -u | tr '\n' ' ')"
expected_qs="$(expected_failures "$engine" | sort -u | tr '\n' ' ')"

for q in $failed_qs; do
hit=0
for e in $expected_qs; do [ "$q" = "$e" ] && hit=1; done
[ "$hit" -eq 0 ] && unexpected="$unexpected $q"
done
for e in $expected_qs; do
hit=0
for q in $failed_qs; do [ "$q" = "$e" ] && hit=1; done
[ "$hit" -eq 0 ] && now_passing="$now_passing $e"
done
unexpected="$(printf '%s' "$unexpected" | tr -s ' ' | sed 's/^ //;s/ $//')"
now_passing="$(printf '%s' "$now_passing" | tr -s ' ' | sed 's/^ //;s/ $//')"

local n_unexpected=0
for q in $unexpected; do n_unexpected=$((n_unexpected + 1)); done
known=$(( fail - n_unexpected ))

if [ "$fail" -eq 0 ]; then
query_res="✅ $pass/103"
ok "all $pass queries ran ($rows_total rows returned in total)"
elif [ "$n_unexpected" -eq 0 ]; then
query_res="✅ $pass/103 (+$known known)"
ok "$pass queries ran; $known known failure(s), none unexpected / 알려진 실패만 발생"
for e in $failed_qs; do
dim " q$e — $(expected_reason "$engine" "$e")"
done
else
query_res="⚠️ $pass/103"
warn "$fail queries failed:"
awk -F, 'NR>1 && $8=="error" {printf " q%s\n", $4}' "$csv" | head -12
query_res="❌ $pass/103 ($n_unexpected unexpected)"
warn "$n_unexpected unexpected failure(s):"
for q in $unexpected; do printf ' q%s\n' "$q" >&2; done
fi

# A listed query that now passes means the list is stale — say so rather than hide it.
# 목록의 쿼리가 이제 통과한다면 목록이 낡은 것이므로 숨기지 않고 알립니다.
if [ -n "$now_passing" ]; then
warn "expected-failure list is stale: q${now_passing} now passes — remove it from expected_failures()"
warn "expected-failure 목록이 낡았습니다: q${now_passing} 가 통과합니다. expected_failures() 에서 제거하십시오"
fi
else
query_res="❌ no results"
Expand All @@ -276,7 +355,7 @@ verify_one() {
# loaded nothing at all.
# 부분 적재를 통과로 처리해서는 안 됩니다. 빈 테이블에 대한 쿼리는 대부분 성공하므로
# 쿼리 결과만으로 판단하면 아무것도 적재하지 못한 실행도 "통과" 로 보고됩니다.
[[ "$fail" -eq 0 && "$schema_res" == "✅ applied" && "$load_res" == ✅* ]]
[[ "$query_res" == ✅* && "$schema_res" == "✅ applied" && "$load_res" == ✅* ]]
}

record() {
Expand Down
Loading