W17 · SQL 분석·CTE·윈도 함수
17주차 코드 뒤풀이: 분석 SQL을 근거까지 읽기
정본 실행 파일과 학습용 SQL 예시를 분리하고, 각 줄의 입력·결과·한계를 13단계로 추적합니다.
01compose.yaml — W17 owner용 PostgreSQL service·health·volume
runtime/compose.yaml
정본 YAML 런타임 · 정본 · W17-F0118줄 연결18줄 번역5 chunks
compose.yaml — W17 owner용 PostgreSQL service·health·volume
runtime/compose.yaml
정본 YAML 런타임 · 정본 · W17-F01STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
W17 Compose mode가 소유할 PostgreSQL service의 image·port·환경값·healthcheck·volume 계약을 source line에서 읽는다.
- `:-`와 `:?`는 unset·empty를 어떻게 다르게 처리할까?
- pg_isready가 직접 확인하지 않는 것은 무엇일까?
- image tag와 digest는 왜 다른가?
- owned Compose와 supplied Container cleanup은 어떻게 다를까?
- host port fallback이 bind 성공까지 뜻할까?
service=dbpostgres:17.10-alpinehost fallback=5432financial_core/apphealth=2s/2s/30named volume=financial-core-dbSTEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 db 상자에 문 번호·환경표·건강 검진표·저장 보관함을 붙인다.
두 W17 owner가 공유하는 disposable PostgreSQL 준비표
이 파일은 postgres 17.10-alpine db service와 port·database·user·필수 password 환경값을 선언한다.
pg_isready timing과 named volume을 더해 Reconcile Compose mode와 CTE validator가 올릴 runtime model을 만든다.
딱 여기까지만 준비표는 app 인증·schema·query Green이나 immutable image를 증명하지 않고 Container mode는 이 owner lifecycle을 사용하지 않는다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
DB 방 하나
services 아래 db 한 개와 image tag를 선언한다.
- 코드 연결
1~3줄- 비유
- 연습실 열쇠에 db 방 번호와 PostgreSQL 상자표를 붙인다.
- 비유의 끝
- image tag는 digest가 아니고 방을 즉시 실행하지도 않는다.
밖 문과 안 문
host 쪽 port는 환경값 또는 5432이고 container 안은 5432다.
- 코드 연결
4~5줄- 비유
- 건물 초인종을 방 안 5432번 전화에 연결한다.
- 비유의 끝
- 이미 사용 중인 host port면 충돌한다.
초기 쪽지
database·user·필수 password를 container 환경으로 넘긴다.
- 코드 연결
6~9줄- 비유
- 빈 방을 열 때 쓸 이름표 세 장을 접수대에 낸다.
- 비유의 끝
- 이미 채운 volume에는 초기값이 다시 적용되지 않을 수 있다.
준비 벨과 선반
pg_isready 설정과 data volume mount를 선언한다.
- 코드 연결
10~19줄- 비유
- 문이 응답하는지 확인하고 기록 상자를 별도 선반에 둔다.
- 비유의 끝
- 준비 응답은 query 정답이 아니며 volume 수명은 실행 명령에 달렸다.
왜 먼저 보는가히토리 → 니지카 → 료 → 키타
-
히토리
SQL부터 보면 안 되나요?
-
니지카
SQL이 들어갈 PostgreSQL 방의 버전과 이름부터 같아야 해.
-
료
이 파일은 runtime 계약이고 schema Green은 runner가 따로 판단한다.
-
키타
service가 db 하나인지부터 확인할게요.
두 개의 5432히토리 → 니지카 → 료 → 키타
-
히토리
5432가 두 번이면 DB도 두 개인가요?
-
니지카
왼쪽은 host 문, 오른쪽은 container 안 PostgreSQL 문이야.
-
료
:-는 port 변수가 unset 또는 empty일 때 왼쪽 기본값을 고른다.
-
키타
55432를 넣은 경우도 따로 적어 볼게요.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 18줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F01-L01 | services: |
STARRY 임시 연습실 목록의 맨 표지를 펼친다. | Compose 문서에서 services 최상위 mapping을 시작한다.
|
| 2줄F01-L02 | db: |
목록에 `db`라고 적힌 한 칸짜리 방 열쇠를 건다. | services 아래에 이름이 db인 service 정의를 연다.
|
| 3줄F01-L03 | image: |
DB 방의 재료 상자에 PostgreSQL 17.10 Alpine 꼬리표를 붙인다. | db container image를 postgres:17.10-alpine으로 지정한다.
|
| 4줄F01-L04 | ports: |
건물 밖과 DB 방 안을 잇는 문 번호 묶음을 펼친다. | db service의 ports 배열을 시작한다.
|
| 5줄F01-L05 | - "${ |
밖 번호표가 미설정이거나 빈칸이면 5432를 쓰고 안쪽 5432번 문에 연결한다. | FCL_DB_PORT가 미설정이거나 빈 문자열이면 기본 5432를, 값이 있으면 그 값을 host port로 써 container 5432에 publish한다.
|
| 6줄F01-L06 | environment: |
DB가 시작할 때 받을 설정 쪽지 봉투를 연다. | db container에 전달할 environment mapping을 시작한다.
|
| 7줄F01-L07 | POSTGRES_DB: |
첫 쪽지에 만들 database 이름 `financial_core`를 적는다. | POSTGRES_DB 환경값을 financial_core로 설정한다.
|
| 8줄F01-L08 | POSTGRES_USER: |
둘째 쪽지에는 접속 사용자 이름 `app`을 쓴다. | POSTGRES_USER 환경값을 app으로 설정한다.
|
| 9줄F01-L09 | POSTGRES_PASSWORD: |
셋째 쪽지는 terminal에 없거나 내용이 빈 봉투면 접수대에서 막고, 공백 글자만 든 봉투는 일단 값이 있는 것으로 본다. | Compose의 ${FCL_DB_PASSWORD:?message} 보간은 변수가 unset 또는 empty string이면 config error를 내고 whitespace-only nonempty 값은 치환을 통과시킨다.
|
| 10줄F01-L10 | healthcheck: |
DB service 안에 아직 내용이 없는 건강 점검표 칸을 펼친다. | db service 아래에 healthcheck child mapping scope를 시작한다.
|
| 11줄F01-L11 | test: |
`app`·`financial_core` 목적지표를 달고 서버가 연결을 받는지만 묻는 초인종을 단다. | CMD-SHELL에서 -U app과 -d financial_core를 probe target으로 붙여 pg_isready를 실행한다.
|
| 12줄F01-L12 | interval: |
준비 확인 벨이 2초마다 다시 울리도록 간격을 맞춘다. | healthcheck 실행 간격을 2초로 지정한다.
|
| 13줄F01-L13 | timeout: |
한 번 문을 두드리고 기다릴 시간은 2초로 자른다. | 각 healthcheck 시도의 timeout을 2초로 지정한다.
|
| 14줄F01-L14 | retries: |
준비 확인이 30번 연속 실패하면 `unhealthy` 표를 붙이는 기준을 둔다. | 연속 healthcheck 실패 30회를 unhealthy 판정 임계값으로 지정한다.
|
| 15줄F01-L15 | volumes: |
DB 방 바닥과 기록 창고를 이을 끈 목록을 펼친다. | db service에 연결할 volumes 배열을 시작한다.
|
| 16줄F01-L16 | - financial-core-db: |
`financial-core-db` 창고를 PostgreSQL 자료 선반에 바로 잇는다. | named volume financial-core-db를 /var/lib/postgresql/data에 mount한다.
|
| 18줄F01-L18 | volumes: |
서비스 밖에서도 부를 공용 기록 창고 명부를 연다. | 문서 최상위 volumes mapping을 시작한다.
|
| 19줄F01-L19 | financial-core-db: |
명부에 `financial-core-db` 창고 이름만 등록한다. | financial-core-db named volume을 기본 옵션으로 선언한다.
|
필수 password히토리 → 니지카 → 료 → 키타
-
히토리
실험용이면 password가 비어도 켜지나요?
-
니지카
물음표 보간식이 config 단계에서 빈 값을 거절해.
-
료
존재 검사는 secret storage가 아니라 fail-fast 설정이다.
-
키타
값이 있는 경우와 없는 경우를 나눠 보겠습니다.
STEP 05 / 13
원본 코드 조각
원본을 5개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 hash로 고정한 native 정본 source에서 그대로 잘랐습니다.
services:
db:
image: postgres:17.10-alpine
ports:
- "${FCL_DB_PORT:-5432}:5432"
environment:
POSTGRES_DB: financial_core
POSTGRES_USER: app
POSTGRES_PASSWORD: ${FCL_DB_PASSWORD:?set FCL_DB_PASSWORD in this terminal}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d financial_core"]
interval: 2s
timeout: 2s
retries: 30
volumes:
- financial-core-db:/var/lib/postgresql/data
volumes:
financial-core-db:
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 18줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | services: | Compose 문서에서 services 최상위 mapping을 시작한다. |
| 2 | db: | services 아래에 이름이 db인 service 정의를 연다. |
| 3 | image: postgres:17.10-alpine | db container image를 postgres:17.10-alpine으로 지정한다. |
| 4 | ports: | db service의 ports 배열을 시작한다. |
| 5 | - "${FCL_DB_PORT:-5432}:5432" | FCL_DB_PORT가 미설정이거나 빈 문자열이면 기본 5432를, 값이 있으면 그 값을 host port로 써 container 5432에 publish한다. |
| 6 | environment: | db container에 전달할 environment mapping을 시작한다. |
| 7 | POSTGRES_DB: financial_core | POSTGRES_DB 환경값을 financial_core로 설정한다. |
| 8 | POSTGRES_USER: app | POSTGRES_USER 환경값을 app으로 설정한다. |
| 9 | POSTGRES_PASSWORD: ${FCL_DB_PASSWORD:?set FCL_DB_PASSWORD in this terminal} | Compose의 ${FCL_DB_PASSWORD:?message} 보간은 변수가 unset 또는 empty string이면 config error를 내고 whitespace-only nonempty 값은 치환을 통과시킨다. |
| 10 | healthcheck: | db service 아래에 healthcheck child mapping scope를 시작한다. |
| 11 | test: ["CMD-SHELL", "pg_isready -U app -d financial_core"] | CMD-SHELL에서 -U app과 -d financial_core를 probe target으로 붙여 pg_isready를 실행한다. |
| 12 | interval: 2s | healthcheck 실행 간격을 2초로 지정한다. |
| 13 | timeout: 2s | 각 healthcheck 시도의 timeout을 2초로 지정한다. |
| 14 | retries: 30 | 연속 healthcheck 실패 30회를 unhealthy 판정 임계값으로 지정한다. |
| 15 | volumes: | db service에 연결할 volumes 배열을 시작한다. |
| 16 | - financial-core-db:/var/lib/postgresql/data | named volume financial-core-db를 /var/lib/postgresql/data에 mount한다. |
| 18 | volumes: | 문서 최상위 volumes mapping을 시작한다. |
| 19 | financial-core-db: | financial-core-db named volume을 기본 옵션으로 선언한다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기Compose YAML은 W17 runtime model 입력이며 image provenance·application readiness·Container-mode cleanup의 완전한 proof가 아니다.
문법 해부
- YAML 들여쓰기가 최상위 services와 db 속성의 소속을 정한다.
- ${VAR:-default}는 unset 또는 empty에 default를 쓰고 ${VAR:?message}는 값을 요구한다.
- host:container와 volume:container-path의 콜론 양쪽 역할은 다르다.
실행 순서
- YAML parse
- environment interpolation
- container configuration
- PostgreSQL initialization when data directory is empty
- health monitoring
- volume-backed writes
원래 W6 수준의 조각별 정밀 해설
F01-C01 · service and image
- 문법 해부
- `service and image` 범위는 Compose 문서에서 services 최상위 mapping을 시작한다. 이어서 db container image를 postgres:17.10-alpine으로 지정한다.
- 실제 값 추적
- 구체 입력은 Compose가 services 안의 첫 이름을 읽어 service 식별자를 정한다. 처리 뒤 관찰 가능한 끝 상태는 container 생성 단계에서 postgres:17.10-alpine tag reference가 pull·실행 대상으로 해석된다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 YAML parser가 service 정의들을 담을 최상위 객체를 얻는다. 그리고 범위 끝에서 container 생성 단계에서 postgres:17.10-alpine tag reference가 pull·실행 대상으로 해석된다.
- 틀린 예·반례
- postgres:17.10-alpine tag를 immutable digest로 간주하면 같은 tag가 언제나 같은 image bytes라는 잘못된 결론에 이른다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: 이 표지만으로 service가 생성되거나 실행되지는 않는다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: 이 표지만으로 service가 생성되거나 실행되지는 않는다.
- 다음 연결
- 끝 상태를 기록한다: container 생성 단계에서 postgres:17.10-alpine tag reference가 pull·실행 대상으로 해석된다. 이어지는 `host port mapping` 범위에서 이 상태의 입력 경계를 확인한다.
F01-C02 · host port mapping
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 db service의 ports 배열을 시작한다. 끝에서 FCL_DB_PORT가 미설정이거나 빈 문자열이면 기본 5432를, 값이 있으면 그 값을 host port로 써 container 5432에 publish한다.
- 실제 값 추적
- 시작 조건 Compose가 container port를 host에 공개할 규칙을 받을 준비를 한다.에서 범위를 통과하면 중간에 미설정·빈 문자열은 5432:5432가 되고, 예를 들어 55432는 55432:5432 binding이 된다. 마지막에 미설정·빈 문자열은 5432:5432가 되고, 예를 들어 55432는 55432:5432 binding이 된다.
- 정상 예
- 원본 `ports:`를 정확히 유지하고 이 범위를 실행·해석했을 때 미설정·빈 문자열은 5432:5432가 되고, 예를 들어 55432는 55432:5432 binding이 된다.
- 틀린 예·반례
- FCL_DB_PORT에 공백 문자열을 넣고 default 5432가 선택된다고 기대하면 Compose `:-`의 nonempty 판정과 어긋난다.
- 착각 방지
- port 공개는 인증·방화벽·충돌 회피를 보장하지 않으며 이미 쓰는 port면 시작이 실패할 수 있다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `host port mapping`의 source state만 다루며 port 공개는 인증·방화벽·충돌 회피를 보장하지 않으며 이미 쓰는 port면 시작이 실패할 수 있다.
- 다음 연결
- 끝 상태를 기록한다: 미설정·빈 문자열은 5432:5432가 되고, 예를 들어 55432는 55432:5432 binding이 된다. 이어지는 `database initialization` 범위에서 이 상태의 입력 경계를 확인한다.
F01-C03 · database initialization
- 문법 해부
- 이 source slice의 문법 축은 POSTGRES_USER 환경값을 app으로 설정한다. 앞뒤로 db container에 전달할 environment mapping을 시작한다. 및 Compose의 ${FCL_DB_PASSWORD:?message} 보간은 변수가 unset 또는 empty string이면 config error를 내고 whitespace-only nonempty 값은 치환을 통과시킨다.
- 실제 값 추적
- PostgreSQL image의 초기화 변수를 묶어 전달하려고 Compose가 environment를 읽는다. 그 상태가 진행되면 unset/empty이면 지정 message로 config가 실패하고, 공백만을 포함한 nonempty 값까지 POSTGRES_PASSWORD에 그대로 치환된다.
- 정상 예
- 유효한 예는 'environment:' bytes를 보존해 초기 PostgreSQL 접속 주체 이름이 app으로 준비된다.
- 틀린 예·반례
- FCL_DB_PASSWORD가 whitespace-only여도 `:?`가 반드시 막는다고 쓰면 unset·empty와 공백 값을 혼동한 설명이다.
- 착각 방지
- app 이름만으로 최소 권한·role 분리·운영 권한 정책이 완성되지는 않는다. 따라서 `database initialization`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. app 이름만으로 최소 권한·role 분리·운영 권한 정책이 완성되지는 않는다.
- 다음 연결
- 끝 상태를 기록한다: unset/empty이면 지정 message로 config가 실패하고, 공백만을 포함한 nonempty 값까지 POSTGRES_PASSWORD에 그대로 치환된다. 이어지는 `readiness probe` 범위에서 이 상태의 입력 경계를 확인한다.
F01-C04 · readiness probe
- 문법 해부
- `readiness probe` 범위는 db service 아래에 healthcheck child mapping scope를 시작한다. 이어서 연속 healthcheck 실패 30회를 unhealthy 판정 임계값으로 지정한다.
- 실제 값 추적
- 구체 입력은 한 번의 health test가 끝난 뒤 다음 점검까지 Docker가 2초 주기를 사용한다. 처리 뒤 관찰 가능한 끝 상태는 연속 실패 허용 횟수가 30으로 설정되어 그 뒤 unhealthy 판정 근거가 된다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 healthcheck child scope만 열리고 이 줄에서는 test·timing key/value가 아직 하나도 등록되지 않는다. 그리고 범위 끝에서 연속 실패 허용 횟수가 30으로 설정되어 그 뒤 unhealthy 판정 근거가 된다.
- 틀린 예·반례
- pg_isready가 성공했다는 이유로 app password 인증, migration, W17 query까지 Green이라 선언하는 것은 probe 범위를 넘는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: scope opener만으로 probe 종류·readiness 결과·인증·schema 상태는 정해지지 않는다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: scope opener만으로 probe 종류·readiness 결과·인증·schema 상태는 정해지지 않는다.
- 다음 연결
- 끝 상태를 기록한다: 연속 실패 허용 횟수가 30으로 설정되어 그 뒤 unhealthy 판정 근거가 된다. 이어지는 `named volume` 범위에서 이 상태의 입력 경계를 확인한다.
F01-C05 · named volume
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 db service에 연결할 volumes 배열을 시작한다. 끝에서 financial-core-db named volume을 기본 옵션으로 선언한다.
- 실제 값 추적
- 시작 조건 Compose가 이 service의 filesystem mount 항목을 받을 준비를 한다.에서 범위를 통과하면 중간에 service 밖에서 참조할 named volume registry가 YAML 객체에 생긴다. 마지막에 Compose가 project 범위의 financial-core-db resource를 생성·재사용할 수 있다.
- 정상 예
- 원본 `volumes:`를 정확히 유지하고 이 범위를 실행·해석했을 때 Compose가 project 범위의 financial-core-db resource를 생성·재사용할 수 있다.
- 틀린 예·반례
- named volume 선언만 보고 backup·encryption·down -v 이후 복구까지 보장된다고 말할 수 없다.
- 착각 방지
- 기본 옵션 선언은 volume 내용·용량·backup·수명 정책을 고정하지 않는다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `named volume`의 source state만 다루며 기본 옵션 선언은 volume 내용·용량·backup·수명 정책을 고정하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: Compose가 project 범위의 financial-core-db resource를 생성·재사용할 수 있다. 이어지는 `account table and owner index` 범위에서 이 상태의 입력 경계를 확인한다.
healthy의 작은 범위히토리 → 니지카 → 료 → 키타
-
히토리
healthy면 V001과 key도 맞았나요?
-
니지카
아니, 여기서는 server가 연결을 받을 상태인지 본 거야.
-
료
인증·schema·index·성능은 pg_isready exit가 직접 증명하지 않는다.
-
키타
readiness와 runner gate를 다른 칸에 적을게요.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| 1 | FCL_DB_PORT unset, FCL_DB_PASSWORD=lab-secret | 두 보간식을 평가한다. | 5432:5432와 password 환경값이 config에 들어간다. | password가 없거나 빈 값이면 config 단계에서 실패한다. |
| 2 | 빈 financial-core-db volume | PostgreSQL image entrypoint가 init 환경을 읽는다. | financial_core database와 app user를 만들 초기화 요청이 수행된다. | 기존 data directory에는 같은 init 과정이 다시 적용되지 않을 수 있다. |
| 3 | server process는 떴지만 아직 connection을 받지 않는 상태 | 2초 간격·시도당 2초 timeout으로 pg_isready를 반복한다. | accepting 상태 응답이 Docker health 판정에 반영된다. | retries=30은 정확한 60초 상한이나 총 검사 횟수가 아니다. |
| 4 | /var/lib/postgresql/data에 기록할 page | named volume mount로 보낸다. | container writable layer 밖 volume에 DB data가 놓인다. | W17 Compose owner가 down -v를 실행하면 이 disposable volume 제거를 요청한다. |
volume의 수명히토리 → 니지카 → 료 → 키타
-
히토리
named volume이면 실험 결과가 계속 남죠?
-
니지카
Compose owner가 down -v를 부르면 제거 요청이 간다.
-
료
mount 선언은 backup이나 영구 보존 계약이 아니다.
-
키타
실행 mode와 cleanup flag를 함께 확인하겠습니다.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
YAML mapping/list와 환경 보간을 service model로 만든다.
parse 성공은 Docker engine 사용 가능성을 보장하지 않는다.image·port·environment·mount·healthcheck를 container에 적용한다.
host port와 volume lifecycle은 project 이름과 명령에도 좌우된다.빈 data directory에서 POSTGRES_* 초기값으로 cluster를 준비한다.
기존 volume의 schema를 자동 교정하지 않는다.pg_isready exit를 주기적으로 읽어 starting/healthy/unhealthy를 갱신한다.
V001·seed·key·index·latency는 검사하지 않는다.STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ healthy면 app 인증과 schema query도 Green이다.
왜 틀리나 pg_isready는 server가 연결 요청을 받는 상태인지 묻는 readiness 도구다.
바르게 읽기 server readiness와 인증·V001·SQL 결과를 별도 gate로 본다.
반례 index가 없거나 schema가 비어도 server는 accepting 상태일 수 있다.
❌ postgres:17.10-alpine이면 image bytes가 영원히 같다.
왜 틀리나 tag는 registry에서 가리키는 manifest가 바뀔 수 있고 digest가 아니다.
바르게 읽기 재현에 immutable image가 필요하면 digest를 별도로 고정한다.
반례 같은 tag를 나중에 pull했을 때 다른 image digest를 받을 수 있다.
❌ retries=30이면 healthcheck가 정확히 30번 뒤 영원히 멈춘다.
왜 틀리나 값은 연속 실패를 unhealthy로 바꾸는 임계이며 이후 monitoring은 계속될 수 있다.
바르게 읽기 interval·timeout·retries를 startup 절대시간과 분리한다.
반례 성공이 끼면 연속 실패 수가 달라지고 scheduling overhead도 있다.
❌ 필수 password 보간식이 secret vault 역할까지 한다.
왜 틀리나 보간식은 값 존재를 확인해 container 환경으로 넘길 뿐이다.
바르게 읽기 실험용 fail-fast와 운영 secret 관리를 나눈다.
반례 process environment나 config 취급을 통해 값이 노출될 수 있다.
❌ named volume은 runner가 끝나도 반드시 보존된다.
왜 틀리나 W17 Compose mode는 소유 project를 down -v로 정리한다.
바르게 읽기 이 volume을 disposable schema 실험 저장소로 읽는다.
반례 Container mode와 Compose mode는 소유권·정리 경계가 다르다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
app 인증·database 존재·V001 적용·query 성공
이 책임을 맡는 곳: runner psql and schema gatesimmutable PostgreSQL image bytes
이 책임을 맡는 곳: digest-pinned deployment manifestPK·FK·UNIQUE·index·cardinality 결과
이 책임을 맡는 곳: W17 reconcile/CTE psql sentinel gate discovery and checksbackup·restore·HA·volume 영구 보존
이 책임을 맡는 곳: operations and backup designsupplied Container 실행도 이 Compose project·volume을 소유하거나 정리함
이 책임을 맡는 곳: selected W17 runner mode and external container ownerSTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
db service→image→port→세 환경값→healthcheck→mount→top-level volume 순서로 말한다.
2단계 · 코드 조각 재조립
- services/db/image/ports
- POSTGRES_DB/USER/PASSWORD
- pg_isready/2s/2s/30
- service mount/top-level named volume
3단계 · 파일 전체 다시 쓰기
blank 한 줄을 포함한 19개 물리 줄을 다시 쓰고 canonical SHA-256과 대조한다.
자가 점검
- image tag와 service 이름을 확인한다.
- 두 port의 방향을 바꾸지 않는다.
- password 보간식의 물음표를 유지한다.
- pg_isready를 인증·schema proof라고 쓰지 않는다.
- volume 수명을 실행 mode와 분리한다.
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
정본 전체 코드 확인하기
services:
db:
image: postgres:17.10-alpine
ports:
- "${FCL_DB_PORT:-5432}:5432"
environment:
POSTGRES_DB: financial_core
POSTGRES_USER: app
POSTGRES_PASSWORD: ${FCL_DB_PASSWORD:?set FCL_DB_PASSWORD in this terminal}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d financial_core"]
interval: 2s
timeout: 2s
retries: 30
volumes:
- financial-core-db:/var/lib/postgresql/data
volumes:
financial-core-db:
02V001__common.sql — W17 drill이 읽는 네 core table·constraint·index
schema/V001__common.sql
정본 SQL 마이그레이션 · 정본 · W17-F0245줄 연결45줄 번역4 chunks
V001__common.sql — W17 drill이 읽는 네 core table·constraint·index
schema/V001__common.sql
정본 SQL 마이그레이션 · 정본 · W17-F02STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
learner ProjectRoot V001의 네 table 저장 모양과 W17 runner가 이 bytes를 인증하지 않는 경계를 함께 읽는다.
- 네 table의 PK·FK·UNIQUE·CHECK는 각각 어떤 값을 막을까?
- amount와 signed_amount 사이에 빠진 invariant는 무엇일까?
- ledger REFERENCES가 owner authorization까지 보장할까?
- V001 correlation_id UNIQUE와 workbook Q26은 왜 다른 schema일까?
- runner가 learner V001 hash와 SQL shape를 인증할까?
tables=4PRIMARY KEY tokens=4REFERENCES tokens=3UNIQUE tokens=4CHECK tokens=5explicit CREATE INDEX=2account status=ACTIVE|CLOSEDcurrency=KRWSTEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 계좌·업무거래·원장·재요청 보관함에 열쇠와 연결끈을 단다.
W17 대사 무대에 놓는 네 보관함의 물리 설계
V001은 네 table을 만들고 필수 column, key, CHECK, UNIQUE, REFERENCES와 두 explicit index를 선언한다.
Reconcile/Savepoint owner는 learner ProjectRoot의 같은 상대경로를 raw로 읽어 fresh w17_drill search_path에서 실행한다.
딱 여기까지만 DDL은 저장 모양만 제한하고 runner는 learner V001 hash·meta-command·marker output을 인증하지 않으며 workbook duplicate schema와도 별개다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
PRIMARY KEY는 row 번호표
각 table에서 한 row를 겹치지 않게 가리키는 기본 번호다.
- 코드 연결
2·14·23·39줄- 비유
- 공연 티켓의 일련번호처럼 같은 보관함 안에서 한 장을 찾는다.
- 비유의 끝
- 업무에서 의미 있는 account_no·correlation_id·복합 key와는 역할이 다르다.
FOREIGN KEY는 존재 확인 끈
ledger가 가리키는 거래·계좌·원장 row가 실제로 있는지 DB가 확인한다.
- 코드 연결
24·25·30줄- 비유
- 없는 공연표 번호에 영수증을 묶지 못하게 한다.
- 비유의 끝
- 그 row를 볼 권한이나 금액이 맞다는 뜻은 아니다.
CHECK는 한 row의 문턱
status·currency·amount·balance 값이 지정 predicate를 통과해야 저장된다.
- 코드 연결
5~7·27·29줄- 비유
- 한 표를 입구에서 재는 키 제한 장치다.
- 비유의 끝
- 여러 row와 여러 transaction 사이의 합계·경쟁까지 보지 않는다.
UNIQUE는 조합 중복 방지
한 column 또는 여러 column tuple이 같은 값을 다시 갖지 못하게 한다.
- 코드 연결
4·17·32·49줄- 비유
- 같은 scope·actor·key 접수표를 두 장 받지 않는 접수 seal이다.
- 비유의 끝
- request hash 비교와 replay response 반환 로직은 application 책임이다.
learner V001의 신뢰 경계히토리 → 니지카 → 료 → 키타
-
히토리
packaged path와 이름이 같으니 runner가 hash도 확인하죠?
-
니지카
runner는 learner ProjectRoot의 text를 그대로 읽고 packaged drill 앞에 붙여.
-
료
expected SHA·SQL parser·meta-command ban이 없어 marker 출력이나 early quit도 이 branch의 입력이 될 수 있다.
-
키타
reference DDL 의미와 runtime source 인증을 다른 칸에 기록하겠습니다.
FK는 권한이 아니다히토리 → 니지카 → 료 → 키타
-
히토리
ledger의 account_id가 존재하면 내 계좌라는 뜻인가요?
-
니지카
연결끈은 그 번호표가 실제 account에 있는지만 확인해.
-
료
authorization에는 authenticated actor와 account.owner_id 비교가 더 필요하다.
-
키타
25줄 한계에 존재 O·소유권 X를 표시할게요.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 45줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F02-L01 | CREATE TABLE account ( |
STARRY가 계좌 보관함의 빈 설계도를 작업대에 펼친다. | `account` table 정의를 여는 CREATE TABLE 문장을 시작한다.
|
| 2줄F02-L02 | id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, |
새 계좌표마다 큰 정수 자동 번호표와 중복 금지 도장을 붙인다. | id를 BIGINT identity column이자 account의 PRIMARY KEY로 선언한다.
|
| 3줄F02-L03 | owner_id VARCHAR( |
계좌표에 최대 64자의 주인 식별 띠를 빈칸 없이 매단다. | owner_id를 길이 64 이하의 필수 VARCHAR column으로 선언한다.
|
| 4줄F02-L04 | account_no VARCHAR( |
외부에 보일 계좌번호는 32자 안에서 한 장만 존재하도록 봉인한다. | account_no를 NOT NULL·UNIQUE인 VARCHAR(32) column으로 선언한다.
|
| 5줄F02-L05 | status VARCHAR( |
계좌 상태등에는 ACTIVE와 CLOSED 두 색만 꽂을 수 있게 홈을 판다. | status를 필수 VARCHAR(16)으로 두고 두 literal만 허용하는 CHECK를 건다.
|
| 6줄F02-L06 | currency VARCHAR( |
통화 칸은 세 글자 KRW 도장만 통과하는 좁은 슬롯으로 만든다. | currency를 NOT NULL VARCHAR(3)으로 선언하고 값이 KRW인지 CHECK한다.
|
| 7줄F02-L07 | balance BIGINT NOT NULL CHECK ( |
현재 잔액 저울에는 0 아래로 내려가지 못하는 바닥턱을 둔다. | balance를 필수 BIGINT로 선언하고 `balance >= 0` CHECK를 붙인다.
|
| 8줄F02-L08 | version BIGINT NOT NULL DEFAULT 0 |
변경 횟수표는 값을 안 적으면 0부터 시작하도록 기본 숫자를 놓는다. | version을 NOT NULL BIGINT로 두고 누락 시 DEFAULT 0을 사용하게 한다.
|
| 9줄F02-L09 | ); |
계좌 보관함 설계의 마지막 괄호를 닫고 제작 승인표를 낸다. | account relation definition의 닫는 괄호와 semicolon을 적는다.
|
| 11줄F02-L11 | CREATE INDEX idx_account_owner_id ON account( |
주인 띠와 계좌 번호 순으로 서랍을 찾는 별도 색인을 만든다. | account(owner_id, id)에 `idx_account_owner_id` index를 생성한다.
|
| 13줄F02-L13 | CREATE TABLE business_tx ( |
업무 거래표를 담을 새 보관함의 이름판만 먼저 세운다. | `business_tx` table 정의를 여는 CREATE TABLE 문장을 시작한다.
|
| 14줄F02-L14 | id UUID PRIMARY KEY, |
거래 한 건에는 겹칠 수 없는 UUID 봉인을 기본 열쇠로 붙인다. | id를 UUID PRIMARY KEY로 선언한다.
|
| 15줄F02-L15 | tx_type VARCHAR( |
거래 종류 표찰은 32자 안에서 반드시 적게 한다. | business transaction category용 required text slot의 최대 길이를 32로 정한다.
|
| 16줄F02-L16 | status VARCHAR( |
처리 상태 칸은 16자 표시판으로 두되 빈칸만 금지한다. | business_tx 처리 상태용 필수 VARCHAR(16) column을 추가한다.
|
| 17줄F02-L17 | correlation_id VARCHAR( |
추적 리본 번호는 64자 안에서 거래마다 하나만 쓰게 한다. | correlation_id를 필수 VARCHAR(64)로 두고 UNIQUE를 건다.
|
| 18줄F02-L18 | requested_at TIMESTAMPTZ NOT NULL, |
요청 시각 도장은 시간대가 있는 칸에 빠짐없이 찍게 한다. | business_tx 요청 instant를 필수 TIMESTAMPTZ requested_at에 보관한다.
|
| 19줄F02-L19 | completed_at TIMESTAMPTZ |
완료 전 거래도 놓을 수 있도록 완료 시각 칸은 비워 둘 수 있게 한다. | business_tx 완료 instant용 nullable TIMESTAMPTZ slot을 둔다.
|
| 20줄F02-L20 | ); |
업무 거래 보관함의 설계 괄호를 닫아 하나의 DDL로 제출한다. | business_tx relation DDL의 닫는 괄호와 semicolon을 적는다.
|
| 22줄F02-L22 | CREATE TABLE ledger_entry ( |
원장 사건표를 쌓을 세 번째 보관함 설계의 문을 연다. | `ledger_entry` table 정의를 시작한다.
|
| 23줄F02-L23 | id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, |
원장표마다 자동 증가 가능한 BIGINT 일련번호 열쇠를 붙인다. | ledger_entry row key로 generated identity BIGINT id를 둔다.
|
| 24줄F02-L24 | business_tx_id UUID NOT NULL REFERENCES business_tx( |
각 원장표를 존재하는 업무 거래 UUID에 끊어지지 않는 끈으로 묶는다. | business_tx_id를 필수 UUID로 두고 business_tx(id)를 REFERENCES한다.
|
| 25줄F02-L25 | account_id BIGINT NOT NULL REFERENCES account( |
원장표의 계좌 끈은 실제 account 번호표가 있는 곳에만 걸리게 한다. | account_id를 필수 BIGINT로 두고 account(id)를 REFERENCES한다.
|
| 26줄F02-L26 | entry_type VARCHAR( |
원장 사건 종류 칸은 32자 안에서 반드시 채우는 표찰로 둔다. | 각 ledger event의 분류 label은 최대 32자이며 null을 허용하지 않게 한다.
|
| 27줄F02-L27 | amount BIGINT NOT NULL CHECK ( |
금액의 절댓값 칸은 0보다 큰 BIGINT만 통과하는 문턱을 둔다. | amount를 필수 BIGINT로 선언하고 `amount > 0`을 CHECK한다.
|
| 28줄F02-L28 | signed_amount BIGINT NOT NULL, |
원장 화살표 숫자는 부호를 그대로 적되 빈칸만 허용하지 않는다. | signed_amount를 NOT NULL BIGINT column으로 선언한다.
|
| 29줄F02-L29 | balance_after BIGINT NOT NULL CHECK ( |
사건 뒤 잔액 칸에도 0 아래로 내려가지 않는 바닥선을 긋는다. | balance_after를 필수 BIGINT로 두고 nonnegative CHECK를 건다.
|
| 30줄F02-L30 | reversal_of BIGINT REFERENCES ledger_entry( |
취소표에는 원래 원장표 번호로 돌아가는 선택적 되감기 끈을 둔다. | reversal_of를 nullable BIGINT self-FK로 두어 ledger_entry(id)를 참조한다.
|
| 31줄F02-L31 | created_at TIMESTAMPTZ NOT NULL, |
원장표 작성 시각은 시간대 포함 칸에 반드시 적게 한다. | ledger 사건 작성 instant를 필수 TIMESTAMPTZ created_at에 보관한다.
|
| 32줄F02-L32 | UNIQUE ( |
한 거래·한 계좌·한 사건종류 조합에는 원장표 한 장만 허용하는 삼중 봉인을 찍는다. | business_tx_id·account_id·entry_type 세 column에 composite UNIQUE를 건다.
|
| 33줄F02-L33 | ); |
원장 보관함의 column·constraint 설계를 닫아 제작 명령을 완성한다. | ledger_entry definition list를 `);`로 마감한다.
|
| 35줄F02-L35 | CREATE INDEX idx_ledger_account_created_id |
원장 찾기 표지판에 `idx_ledger_account_created_id`라는 고유 이름만 먼저 적는다. | 해당 이름의 CREATE INDEX statement를 시작한다.
|
| 36줄F02-L36 | ON ledger_entry( |
계좌를 먼저 찾고 최신 작성시각, 최신 원장번호 순으로 내려가는 탐색길을 완성한다. | ledger_entry(account_id, created_at DESC, id DESC)에 앞서 이름 붙인 index를 생성한다.
|
| 38줄F02-L38 | CREATE TABLE idempotency_request ( |
재요청 접수표를 보관할 네 번째 cabinet의 빈 설계도를 연다. | `idempotency_request` table 정의를 시작한다.
|
| 39줄F02-L39 | id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, |
접수표마다 자동 번호를 쓸 수 있는 BIGINT 기본 열쇠를 단다. | idempotency_request surrogate key를 BY DEFAULT identity BIGINT로 만든다.
|
| 40줄F02-L40 | scope VARCHAR( |
멱등 처리가 적용되는 작업 영역 이름을 64자 안에서 필수로 적는다. | scope를 NOT NULL VARCHAR(64) column으로 선언한다.
|
| 41줄F02-L41 | actor_id VARCHAR( |
요청 주체 표찰도 64자 안에서 비워 둘 수 없게 한다. | actor_id를 NOT NULL VARCHAR(64) column으로 선언한다.
|
| 42줄F02-L42 | idempotency_key VARCHAR( |
재시도 표의 핵심 key 칸은 128자까지 허용하되 반드시 채운다. | idempotency_key를 NOT NULL VARCHAR(128) column으로 선언한다.
|
| 43줄F02-L43 | request_hash CHAR( |
요청 내용 지문은 고정 64칸짜리 필수 표찰에 저장한다. | request_hash를 NOT NULL CHAR(64) column으로 선언한다.
|
| 44줄F02-L44 | status VARCHAR( |
접수 처리 상태는 16자 칸에 반드시 적게만 하고 색 목록은 열어 둔다. | 멱등 요청 처리 상태용 필수 VARCHAR(16) column을 추가한다.
|
| 45줄F02-L45 | response_status INTEGER, |
아직 응답하지 않은 접수표도 놓도록 응답 status 숫자 칸은 선택으로 둔다. | response_status를 nullable INTEGER column으로 선언한다.
|
| 46줄F02-L46 | response_body TEXT, |
재전달할 응답 본문은 길이 제한 없는 선택적 종이에 보관한다. | response_body를 nullable TEXT column으로 선언한다.
|
| 47줄F02-L47 | created_at TIMESTAMPTZ NOT NULL, |
접수 생성 시각은 시간대 포함 도장을 빠짐없이 요구한다. | 멱등 접수 생성 instant용 필수 TIMESTAMPTZ created_at을 둔다.
|
| 48줄F02-L48 | completed_at TIMESTAMPTZ, |
처리 중인 접수표를 위해 완료 시각 도장은 비워 둘 수 있게 한다. | 멱등 접수 종료 instant를 선택적으로 저장하는 TIMESTAMPTZ column을 둔다.
|
| 49줄F02-L49 | UNIQUE ( |
같은 작업영역·주체·멱등 key 조합에는 접수표 한 장만 두는 삼중 seal을 건다. | scope·actor_id·idempotency_key에 composite UNIQUE를 선언한다.
|
| 50줄F02-L50 | ); |
멱등 접수 보관함의 마지막 괄호를 닫아 V001의 네 번째 table 명령을 끝낸다. | idempotency_request relation definition의 마지막 괄호를 닫는다.
|
CHECK와 동시성히토리 → 니지카 → 료 → 키타
-
히토리
balance가 음수가 아니면 동시 출금도 안전하죠?
-
니지카
두 요청이 같은 옛 balance를 읽는 경쟁은 한 row의 최종 숫자 검사와 달라.
-
료
constraint proof와 isolation/lock proof의 관찰 범위를 분리해야 한다.
-
키타
동시성 test와 대사 규칙을 별도 책임 칸에 남기겠습니다.
STEP 05 / 13
원본 코드 조각
원본을 4개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 hash로 고정한 native 정본 source에서 그대로 잘랐습니다.
CREATE TABLE account (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
owner_id VARCHAR(64) NOT NULL,
account_no VARCHAR(32) NOT NULL UNIQUE,
status VARCHAR(16) NOT NULL CHECK (status IN ('ACTIVE', 'CLOSED')),
currency VARCHAR(3) NOT NULL CHECK (currency = 'KRW'),
balance BIGINT NOT NULL CHECK (balance >= 0),
version BIGINT NOT NULL DEFAULT 0
);
CREATE INDEX idx_account_owner_id ON account(owner_id, id);
CREATE TABLE business_tx (
id UUID PRIMARY KEY,
tx_type VARCHAR(32) NOT NULL,
status VARCHAR(16) NOT NULL,
correlation_id VARCHAR(64) NOT NULL UNIQUE,
requested_at TIMESTAMPTZ NOT NULL,
completed_at TIMESTAMPTZ
);
CREATE TABLE ledger_entry (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
business_tx_id UUID NOT NULL REFERENCES business_tx(id),
account_id BIGINT NOT NULL REFERENCES account(id),
entry_type VARCHAR(32) NOT NULL,
amount BIGINT NOT NULL CHECK (amount > 0),
signed_amount BIGINT NOT NULL,
balance_after BIGINT NOT NULL CHECK (balance_after >= 0),
reversal_of BIGINT REFERENCES ledger_entry(id),
created_at TIMESTAMPTZ NOT NULL,
UNIQUE (business_tx_id, account_id, entry_type)
);
CREATE INDEX idx_ledger_account_created_id
ON ledger_entry(account_id, created_at DESC, id DESC);
CREATE TABLE idempotency_request (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
scope VARCHAR(64) NOT NULL,
actor_id VARCHAR(64) NOT NULL,
idempotency_key VARCHAR(128) NOT NULL,
request_hash CHAR(64) NOT NULL,
status VARCHAR(16) NOT NULL,
response_status INTEGER,
response_body TEXT,
created_at TIMESTAMPTZ NOT NULL,
completed_at TIMESTAMPTZ,
UNIQUE (scope, actor_id, idempotency_key)
);
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 45줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | CREATE TABLE account ( | `account` table 정의를 여는 CREATE TABLE 문장을 시작한다. |
| 2 | id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, | id를 BIGINT identity column이자 account의 PRIMARY KEY로 선언한다. |
| 3 | owner_id VARCHAR(64) NOT NULL, | owner_id를 길이 64 이하의 필수 VARCHAR column으로 선언한다. |
| 4 | account_no VARCHAR(32) NOT NULL UNIQUE, | account_no를 NOT NULL·UNIQUE인 VARCHAR(32) column으로 선언한다. |
| 5 | status VARCHAR(16) NOT NULL CHECK (status IN ('ACTIVE', 'CLOSED')), | status를 필수 VARCHAR(16)으로 두고 두 literal만 허용하는 CHECK를 건다. |
| 6 | currency VARCHAR(3) NOT NULL CHECK (currency = 'KRW'), | currency를 NOT NULL VARCHAR(3)으로 선언하고 값이 KRW인지 CHECK한다. |
| 7 | balance BIGINT NOT NULL CHECK (balance >= 0), | balance를 필수 BIGINT로 선언하고 `balance >= 0` CHECK를 붙인다. |
| 8 | version BIGINT NOT NULL DEFAULT 0 | version을 NOT NULL BIGINT로 두고 누락 시 DEFAULT 0을 사용하게 한다. |
| 9 | ); | account relation definition의 닫는 괄호와 semicolon을 적는다. |
| 11 | CREATE INDEX idx_account_owner_id ON account(owner_id, id); | account(owner_id, id)에 `idx_account_owner_id` index를 생성한다. |
| 13 | CREATE TABLE business_tx ( | `business_tx` table 정의를 여는 CREATE TABLE 문장을 시작한다. |
| 14 | id UUID PRIMARY KEY, | id를 UUID PRIMARY KEY로 선언한다. |
| 15 | tx_type VARCHAR(32) NOT NULL, | business transaction category용 required text slot의 최대 길이를 32로 정한다. |
| 16 | status VARCHAR(16) NOT NULL, | business_tx 처리 상태용 필수 VARCHAR(16) column을 추가한다. |
| 17 | correlation_id VARCHAR(64) NOT NULL UNIQUE, | correlation_id를 필수 VARCHAR(64)로 두고 UNIQUE를 건다. |
| 18 | requested_at TIMESTAMPTZ NOT NULL, | business_tx 요청 instant를 필수 TIMESTAMPTZ requested_at에 보관한다. |
| 19 | completed_at TIMESTAMPTZ | business_tx 완료 instant용 nullable TIMESTAMPTZ slot을 둔다. |
| 20 | ); | business_tx relation DDL의 닫는 괄호와 semicolon을 적는다. |
| 22 | CREATE TABLE ledger_entry ( | `ledger_entry` table 정의를 시작한다. |
| 23 | id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, | ledger_entry row key로 generated identity BIGINT id를 둔다. |
| 24 | business_tx_id UUID NOT NULL REFERENCES business_tx(id), | business_tx_id를 필수 UUID로 두고 business_tx(id)를 REFERENCES한다. |
| 25 | account_id BIGINT NOT NULL REFERENCES account(id), | account_id를 필수 BIGINT로 두고 account(id)를 REFERENCES한다. |
| 26 | entry_type VARCHAR(32) NOT NULL, | 각 ledger event의 분류 label은 최대 32자이며 null을 허용하지 않게 한다. |
| 27 | amount BIGINT NOT NULL CHECK (amount > 0), | amount를 필수 BIGINT로 선언하고 `amount > 0`을 CHECK한다. |
| 28 | signed_amount BIGINT NOT NULL, | signed_amount를 NOT NULL BIGINT column으로 선언한다. |
| 29 | balance_after BIGINT NOT NULL CHECK (balance_after >= 0), | balance_after를 필수 BIGINT로 두고 nonnegative CHECK를 건다. |
| 30 | reversal_of BIGINT REFERENCES ledger_entry(id), | reversal_of를 nullable BIGINT self-FK로 두어 ledger_entry(id)를 참조한다. |
| 31 | created_at TIMESTAMPTZ NOT NULL, | ledger 사건 작성 instant를 필수 TIMESTAMPTZ created_at에 보관한다. |
| 32 | UNIQUE (business_tx_id, account_id, entry_type) | business_tx_id·account_id·entry_type 세 column에 composite UNIQUE를 건다. |
| 33 | ); | ledger_entry definition list를 `);`로 마감한다. |
| 35 | CREATE INDEX idx_ledger_account_created_id | 해당 이름의 CREATE INDEX statement를 시작한다. |
| 36 | ON ledger_entry(account_id, created_at DESC, id DESC); | ledger_entry(account_id, created_at DESC, id DESC)에 앞서 이름 붙인 index를 생성한다. |
| 38 | CREATE TABLE idempotency_request ( | `idempotency_request` table 정의를 시작한다. |
| 39 | id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, | idempotency_request surrogate key를 BY DEFAULT identity BIGINT로 만든다. |
| 40 | scope VARCHAR(64) NOT NULL, | scope를 NOT NULL VARCHAR(64) column으로 선언한다. |
| 41 | actor_id VARCHAR(64) NOT NULL, | actor_id를 NOT NULL VARCHAR(64) column으로 선언한다. |
| 42 | idempotency_key VARCHAR(128) NOT NULL, | idempotency_key를 NOT NULL VARCHAR(128) column으로 선언한다. |
| 43 | request_hash CHAR(64) NOT NULL, | request_hash를 NOT NULL CHAR(64) column으로 선언한다. |
| 44 | status VARCHAR(16) NOT NULL, | 멱등 요청 처리 상태용 필수 VARCHAR(16) column을 추가한다. |
| 45 | response_status INTEGER, | response_status를 nullable INTEGER column으로 선언한다. |
| 46 | response_body TEXT, | response_body를 nullable TEXT column으로 선언한다. |
| 47 | created_at TIMESTAMPTZ NOT NULL, | 멱등 접수 생성 instant용 필수 TIMESTAMPTZ created_at을 둔다. |
| 48 | completed_at TIMESTAMPTZ, | 멱등 접수 종료 instant를 선택적으로 저장하는 TIMESTAMPTZ column을 둔다. |
| 49 | UNIQUE (scope, actor_id, idempotency_key) | scope·actor_id·idempotency_key에 composite UNIQUE를 선언한다. |
| 50 | ); | idempotency_request relation definition의 마지막 괄호를 닫는다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기V001은 네 physical relation을 선언하지만 learner runtime source authenticity·authorization·ledger completeness를 완성하지 않는다.
문법 해부
- GENERATED BY DEFAULT AS IDENTITY는 값 생략 시 생성하되 명시값도 허용한다.
- inline REFERENCES는 지정 parent key 존재를 검사한다.
- composite UNIQUE는 나열된 column tuple 전체를 비교한다.
- DESC는 index key order이며 SELECT 결과 순서를 자동 보장하지 않는다.
실행 순서
- account table과 owner index를 만든다.
- business_tx table을 만든다.
- ledger_entry table과 account/time index를 만든다.
- idempotency_request table을 만든다.
원래 W6 수준의 조각별 정밀 해설
F02-C01 · account table and owner index
- 문법 해부
- 이 source slice의 문법 축은 currency를 NOT NULL VARCHAR(3)으로 선언하고 값이 KRW인지 CHECK한다. 앞뒤로 `account` table 정의를 여는 CREATE TABLE 문장을 시작한다. 및 account(owner_id, id)에 `idx_account_owner_id` index를 생성한다.
- 실제 값 추적
- PostgreSQL parser가 `CREATE TABLE account (` 토큰을 읽는다. 그 상태가 진행되면 성공하면 owner_id를 먼저, id를 다음 key로 둔 nonunique index가 catalog에 추가된다.
- 정상 예
- 유효한 예는 'CREATE TABLE account (' bytes를 보존해 DDL 적용 후 null 또는 KRW가 아닌 currency를 넣는 row는 저장되지 않는다.
- 틀린 예·반례
- account balance>=0 CHECK가 owner uniqueness나 ACTIVE-only update policy까지 강제한다고 읽으면 table constraint를 과장한다.
- 착각 방지
- 환율·다중 통화 계좌·통화 변경 같은 업무 규칙은 이 equality check 밖이다. 따라서 `account table and owner index`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. 환율·다중 통화 계좌·통화 변경 같은 업무 규칙은 이 equality check 밖이다.
- 다음 연결
- 끝 상태를 기록한다: 성공하면 owner_id를 먼저, id를 다음 key로 둔 nonunique index가 catalog에 추가된다. 이어지는 `business transaction table` 범위에서 이 상태의 입력 경계를 확인한다.
F02-C02 · business transaction table
- 문법 해부
- `business transaction table` 범위는 `business_tx` table 정의를 여는 CREATE TABLE 문장을 시작한다. 이어서 business_tx relation DDL의 닫는 괄호와 semicolon을 적는다.
- 실제 값 추적
- 구체 입력은 business_tx definition이 단일 correlation_id uniqueness를 입력받는다. 처리 뒤 관찰 가능한 끝 상태는 성공 시 business_tx table과 그 PK·UNIQUE constraint가 catalog에 기록된다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 미완성 transaction table definition이 생겨 뒤 column clause를 받을 준비를 한다. 그리고 범위 끝에서 성공 시 business_tx table과 그 PK·UNIQUE constraint가 catalog에 기록된다.
- 틀린 예·반례
- business_tx correlation_id UNIQUE를 workbook Q26 duplicate fixture에도 적용하면 두 번째 CORR-DUP row 자체가 들어가지 못한다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: 이 opener만 실행 단위로 떼면 table이나 column은 아직 완성되지 않는다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: 이 opener만 실행 단위로 떼면 table이나 column은 아직 완성되지 않는다.
- 다음 연결
- 끝 상태를 기록한다: 성공 시 business_tx table과 그 PK·UNIQUE constraint가 catalog에 기록된다. 이어지는 `ledger table and stable-order index` 범위에서 이 상태의 입력 경계를 확인한다.
F02-C03 · ledger table and stable-order index
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 `ledger_entry` table 정의를 시작한다. 끝에서 ledger_entry(account_id, created_at DESC, id DESC)에 앞서 이름 붙인 index를 생성한다.
- 실제 값 추적
- 시작 조건 parser가 CREATE TABLE과 ledger_entry identifier, 여는 괄호를 읽는다.에서 범위를 통과하면 중간에 완성된 constraint는 음수 balance_after를 가진 ledger row를 차단한다. 마지막에 DDL 성공 시 지정 key 순서를 가진 nonunique index가 PostgreSQL catalog에 추가된다.
- 정상 예
- 원본 `CREATE TABLE ledger_entry (`를 정확히 유지하고 이 범위를 실행·해석했을 때 DDL 성공 시 지정 key 순서를 가진 nonunique index가 PostgreSQL catalog에 추가된다.
- 틀린 예·반례
- signed_amount가 NOT NULL이라는 사실을 amount·entry_type·balance_after와 자동 일관된다는 보증으로 바꾸면 틀리다.
- 착각 방지
- planner 사용·속도 개선·SELECT 결과 정렬은 보장되지 않으며 query에는 별도 ORDER BY가 필요하다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `ledger table and stable-order index`의 source state만 다루며 planner 사용·속도 개선·SELECT 결과 정렬은 보장되지 않으며 query에는 별도 ORDER BY가 필요하다.
- 다음 연결
- 끝 상태를 기록한다: DDL 성공 시 지정 key 순서를 가진 nonunique index가 PostgreSQL catalog에 추가된다. 이어지는 `idempotency request table` 범위에서 이 상태의 입력 경계를 확인한다.
F02-C04 · idempotency request table
- 문법 해부
- 이 source slice의 문법 축은 멱등 요청 처리 상태용 필수 VARCHAR(16) column을 추가한다. 앞뒤로 `idempotency_request` table 정의를 시작한다. 및 idempotency_request relation definition의 마지막 괄호를 닫는다.
- 실제 값 추적
- PostgreSQL parser가 relation name과 여는 괄호를 읽는다. 그 상태가 진행되면 성공하면 idempotency_request table과 PK·composite UNIQUE가 catalog에 기록된다.
- 정상 예
- 유효한 예는 'CREATE TABLE idempotency_request (' bytes를 보존해 완성된 table은 null status를 가진 request row를 차단한다.
- 틀린 예·반례
- idempotency UNIQUE tuple이 동일 payload, 영구 response, concurrent ownership을 모두 해결한다고 단정할 수 없다.
- 착각 방지
- PROCESSING·COMPLETED 같은 허용값, 전이, timeout 상태는 CHECK하지 않는다. 따라서 `idempotency request table`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. PROCESSING·COMPLETED 같은 허용값, 전이, timeout 상태는 CHECK하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: 성공하면 idempotency_request table과 PK·composite UNIQUE가 catalog에 기록된다. 이어지는 `fail-fast and pre-BEGIN W17 opening seed` 범위에서 이 상태의 입력 경계를 확인한다.
signed_amount 빈 규칙히토리 → 니지카 → 료 → 키타
-
히토리
amount가 양수라서 signed_amount 부호도 맞을 것 같아요.
-
니지카
27줄은 amount만 보고 28줄은 signed_amount가 null 아닌지만 봐.
-
료
현재 DDL에는 abs equality와 entry_type별 sign predicate가 없다.
-
키타
amount=20·signed_amount=0 반례로 확인할게요.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| account row | owner_id=customer-1, account_no=A-100, status=ACTIVE, currency=KRW, balance=0 | id·version을 생략해 INSERT한다. | identity id와 default version=0을 사용할 수 있고 inline checks를 통과한다. | owner 존재나 actor 권한은 확인하지 않는다. |
| ledger parent links | 존재하는 business_tx_id와 account_id | ledger_entry FK 세 개 중 두 parent FK를 평가한다. | 두 parent row가 있으면 existence check를 통과할 수 있다. | 같은 업무 주체·정상 pair·atomic write는 별도 규칙이다. |
| ledger amounts | amount=20, signed_amount=0, balance_after=100 | 현재 V001의 CHECK만 평가한다. | amount>0과 balance_after>=0이라 schema상 signed_amount=0도 거절되지 않는다. | application test나 추가 CHECK가 부호·절댓값 invariant를 맡아야 한다. |
| idempotency tuple | scope=TRANSFER, actor_id=customer-1, key=req-7 | 같은 triple을 두 번째로 INSERT한다. | composite UNIQUE conflict가 발생한다. | 기존 response replay와 다른 request_hash conflict 처리는 자동으로 일어나지 않는다. |
UNIQUE와 멱등 protocol히토리 → 니지카 → 료 → 키타
-
히토리
복합 UNIQUE가 있으면 replay response도 자동인가요?
-
니지카
DB는 같은 세 표찰의 두 번째 접수만 막고 첫 응답을 돌려주지는 않아.
-
료
request_hash conflict·claim serialization·response replay는 application transaction 책임이다.
-
키타
49줄 직접 효과와 미증명을 분리해 적겠습니다.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
각 CREATE TABLE statement를 parse해 relation·column·constraint metadata를 catalog에 기록한다.
뒤 statement나 migration transaction이 실패하면 최종 지속 여부가 달라질 수 있다.INSERT·UPDATE 시 NOT NULL·CHECK·UNIQUE·FK predicate를 평가한다.
constraint가 표현하지 않은 cross-row business invariant는 평가하지 않는다.explicit index 두 개 외에 PK·UNIQUE 구현을 위한 implicit index가 생길 수 있다.
source의 CREATE INDEX token 두 개를 전체 physical index count로 읽으면 안 된다.service transaction과 lock이 여러 statement의 원자성·경쟁 순서를 맡는다.
V001 text만으로 특정 isolation·lock order·rollback path를 증명할 수 없다.STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ account_id FK가 있으면 caller가 그 account의 owner다.
왜 틀리나 FK는 account(id) row 존재만 본다.
바르게 읽기 authorization은 authenticated actor와 owner_id를 application/query에서 비교한다.
반례 다른 고객 account의 실제 id도 FK는 통과한다.
❌ balance>=0 CHECK가 있으면 동시 출금에 안전하다.
왜 틀리나 두 transaction의 read-modify-write 경쟁은 한 최종 row predicate와 다른 문제다.
바르게 읽기 transaction isolation·lock·version과 concurrency test를 따로 확인한다.
반례 두 요청이 같은 old balance를 읽고 각각 nonnegative 값으로 덮어쓸 수 있다.
❌ amount>0이면 signed_amount 방향도 자동으로 맞다.
왜 틀리나 signed_amount column에는 NOT NULL 외 CHECK가 없다.
바르게 읽기 entry_type별 sign과 abs equality를 service 또는 추가 constraint로 검증한다.
반례 amount=20, signed_amount=0도 현재 두 relevant clauses를 통과할 수 있다.
❌ 복합 UNIQUE가 멱등 replay를 완성한다.
왜 틀리나 DB는 duplicate triple을 막을 뿐 기존 response 선택·hash 비교를 하지 않는다.
바르게 읽기 claim, semantic conflict, stored response replay protocol을 application transaction으로 둔다.
반례 같은 triple·다른 request_hash는 unique conflict만 주고 어떤 response를 낼지 말하지 않는다.
❌ application V001의 correlation_id UNIQUE table에 workbook Q26 duplicate seed도 그대로 들어간다.
왜 틀리나 workbook business_tx는 중복 후보 연습을 위해 별도 schema를 사용한다.
바르게 읽기 application migration과 workbook fixture의 table contract를 이름이 아니라 source path로 구분한다.
반례 CORR-DUP 두 행은 workbook에서는 가능하지만 이 V001 relation에서는 UNIQUE conflict가 난다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
ledger account_id가 요청 actor 소유 account임
이 책임을 맡는 곳: authentication/authorization service와 owner predicatebalance>=0 CHECK만으로 lost update·overspend가 없음
이 책임을 맡는 곳: transaction isolation, lock/version, concurrency integration testaccount.balance가 ledger signed sum과 항상 일치함
이 책임을 맡는 곳: source-of-truth 정책, atomic write, reconciliation job/evidence3NF·BCNF와 모든 functional dependency 준수
이 책임을 맡는 곳: ERD/FD 분석과 사람 의미 검토두 explicit index가 모든 운영 query를 빠르게 함
이 책임을 맡는 곳: 실제 workload EXPLAIN ANALYZE와 index 운영learner V001 bytes·SQL shape·marker provenance가 packaged reference와 같음
이 책임을 맡는 곳: expected SHA allowlist and inspected migration execution ownerSTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
각 constraint line 옆에 '직접 막는 값'과 '막지 못하는 업무 의미'를 한 줄씩 쓴다.
2단계 · 코드 조각 재조립
- account_id FK → 존재 O / 소유권 X
- balance CHECK → 저장 음수 X / 동시성 proof X
- ledger composite UNIQUE → 동일 tuple 중복 X / transfer pair 강제 X
- idempotency UNIQUE → duplicate triple X / replay policy X
3단계 · 파일 전체 다시 쓰기
빈 종이에 네 table의 PK·FK·UNIQUE·CHECK·두 explicit index를 다시 그리고 source line과 대조한다.
자가 점검
- REFERENCES 세 개를 business_tx/account/self-reversal로 정확히 구분했는가?
- amount와 signed_amount 사이에 빠진 invariant를 말했는가?
- FK와 authorization, CHECK와 concurrency를 분리했는가?
- explicit index 두 개와 implicit PK/UNIQUE index를 혼동하지 않았는가?
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
정본 전체 코드 확인하기
CREATE TABLE account (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
owner_id VARCHAR(64) NOT NULL,
account_no VARCHAR(32) NOT NULL UNIQUE,
status VARCHAR(16) NOT NULL CHECK (status IN ('ACTIVE', 'CLOSED')),
currency VARCHAR(3) NOT NULL CHECK (currency = 'KRW'),
balance BIGINT NOT NULL CHECK (balance >= 0),
version BIGINT NOT NULL DEFAULT 0
);
CREATE INDEX idx_account_owner_id ON account(owner_id, id);
CREATE TABLE business_tx (
id UUID PRIMARY KEY,
tx_type VARCHAR(32) NOT NULL,
status VARCHAR(16) NOT NULL,
correlation_id VARCHAR(64) NOT NULL UNIQUE,
requested_at TIMESTAMPTZ NOT NULL,
completed_at TIMESTAMPTZ
);
CREATE TABLE ledger_entry (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
business_tx_id UUID NOT NULL REFERENCES business_tx(id),
account_id BIGINT NOT NULL REFERENCES account(id),
entry_type VARCHAR(32) NOT NULL,
amount BIGINT NOT NULL CHECK (amount > 0),
signed_amount BIGINT NOT NULL,
balance_after BIGINT NOT NULL CHECK (balance_after >= 0),
reversal_of BIGINT REFERENCES ledger_entry(id),
created_at TIMESTAMPTZ NOT NULL,
UNIQUE (business_tx_id, account_id, entry_type)
);
CREATE INDEX idx_ledger_account_created_id
ON ledger_entry(account_id, created_at DESC, id DESC);
CREATE TABLE idempotency_request (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
scope VARCHAR(64) NOT NULL,
actor_id VARCHAR(64) NOT NULL,
idempotency_key VARCHAR(128) NOT NULL,
request_hash CHAR(64) NOT NULL,
status VARCHAR(16) NOT NULL,
response_status INTEGER,
response_body TEXT,
created_at TIMESTAMPTZ NOT NULL,
completed_at TIMESTAMPTZ,
UNIQUE (scope, actor_id, idempotency_key)
);
03reconcile-drill.sql — pre-BEGIN seed와 post-BEGIN SAVEPOINT 0→1→0
sql/w17/reconcile-drill.sql
정본 SQL 실습 · 정본 · W17-F0315줄 연결15줄 번역4 chunks
reconcile-drill.sql — pre-BEGIN seed와 post-BEGIN SAVEPOINT 0→1→0
sql/w17/reconcile-drill.sql
정본 SQL 실습 · 정본 · W17-F03STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
opening seed의 autocommit 경계와 +7 mismatch를 savepoint로 복구하는 transaction 범위를 정확히 나눈다.
- lines 2~4 seed는 마지막 ROLLBACK으로 지워질까?
- baseline·injected·restored DO는 무엇을 count할까?
- minimum account id가 W17-001인 이유는 무엇일까?
- ROLLBACK TO와 마지막 ROLLBACK의 범위는 어떻게 다를까?
- 세 marker가 직접 담지 않는 값은 무엇일까?
seed balance=100ledger sum=100BEGIN=line5injected balance=107mismatch sequence=0/1/0seed persists after line15STEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 opening 표 세 장을 먼저 보관하고, 투명 작업막 안에서 잔액 +7 자국만 시험한다.
확정된 opening 표 위에서 오류만 넣었다 되돌리는 연습
lines 2~4는 BEGIN 전에 account·business_tx·ledger_entry seed를 statement별로 autocommit하고 저장값과 원장합 100을 만든다.
line 5 이후에는 mismatch 0을 확인하고 +7로 1을 만든 뒤 savepoint rollback으로 0을 복구해 post-BEGIN transaction을 닫는다.
딱 여기까지만 마지막 ROLLBACK은 pre-BEGIN seed를 지우지 않고 marker는 mismatch count만 말하므로 Container mode의 schema+seed persistence와 account/difference 미증명을 함께 적어야 한다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
BEGIN 전과 후는 다른 봉투
앞 세 INSERT는 각각 commit되고 line 5 뒤 변경만 explicit transaction에 들어간다.
- 코드 연결
2~5줄- 비유
- 영수증을 먼저 금고에 넣은 뒤 별도 투명 봉투에서 연필 실험을 시작한다.
- 비유의 끝
- psql이 바깥 transaction에 감싸져 있지 않은 current runner 실행을 기준으로 한다.
대사는 계좌 단위 저울
account.balance와 account별 signed_amount 합을 LEFT JOIN해 다른 계좌 수를 센다.
- 코드 연결
6·10·13줄- 비유
- 각 이름표별 저장 숫자와 원장 묶음의 합을 맞춰 본다.
- 비유의 끝
- count는 어느 계좌가 얼마 다른지 보여 주지 않는다.
SAVEPOINT는 부분 되감기
line 8 뒤 +7만 line 12에서 취소하고 transaction은 계속 열린다.
- 코드 연결
8~12줄- 비유
- 책갈피 뒤 연필 자국만 지우고 책은 덮지 않는다.
- 비유의 끝
- BEGIN 전 seed와 Compose volume lifecycle은 이 책갈피 밖이다.
marker는 계산식이 아님
DO가 통과한 뒤 literal 0·1·0 text를 출력한다.
- 코드 연결
7·11·14줄- 비유
- 저울 검사 뒤 사람이 붙이는 합격 스티커다.
- 비유의 끝
- runner는 substring 존재만 보고 순서·유일성·출처를 인증하지 않는다.
seed는 왜 남나히토리 → 니지카 → 료 → 키타
-
히토리
마지막에 ROLLBACK이 있으니 opening row도 없어지죠?
-
니지카
lines 2~4 영수증은 BEGIN 전에 이미 금고에 들어갔어.
-
료
psql default autocommit에서 final rollback scope는 line5 이후뿐이다.
-
키타
INSERT·BEGIN·ROLLBACK 줄 번호를 timeline에 다시 적겠습니다.
savepoint의 범위히토리 → 니지카 → 료 → 키타
-
히토리
ROLLBACK TO면 transaction 전체가 끝난 건가요?
-
니지카
책갈피 뒤 +7만 지우고 책은 계속 펼쳐져 있어.
-
료
line13·14가 같은 transaction에서 이어지고 line15가 별도 종료다.
-
키타
두 rollback 명령의 target과 session 상태를 나눠 확인할게요.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 15줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F03-L01 | \set ON_ERROR_STOP on |
STARRY가 SQL 묶음에서 오류가 나면 다음 장을 넘기지 않는 빨간 정지표를 세운다. | psql client variable ON_ERROR_STOP을 on으로 설정한다.
|
| 2줄F03-L02 | INSERT INTO account( |
빈 W17 연습장에 잔액 100인 첫 계좌표를 놓고 주인·번호·상태·통화 표찰을 붙인다. | account에 owner w17-owner, account_no W17-001, ACTIVE, KRW, balance 100을 insert한다.
|
| 3줄F03-L03 | INSERT INTO business_tx( |
opening 업무표에 고정 UUID와 추적 리본을 달고 요청·완료 시각 도장을 함께 찍는다. | business_tx에 fixed UUID, OPENING, COMPLETED, w17-open과 두 now() 값을 insert한다.
|
| 4줄F03-L04 | INSERT INTO ledger_entry( |
W17-001 계좌표를 찾아 +100 opening 원장표 한 장을 그 계좌 번호에 연결한다. | account_no W17-001의 id를 SELECT해 amount·signed_amount·balance_after 100인 ledger_entry를 insert한다.
|
| 5줄F03-L05 | BEGIN; |
확정된 opening 표는 그대로 둔 채 그 이후의 오류 주입만 담을 새 투명 작업막을 펼친다. | 명시적 PostgreSQL transaction을 BEGIN으로 시작한다.
|
| 6줄F03-L06 | DO $g$ BEGIN IF ( |
모든 계좌의 저장 잔액과 계좌별 원장 합을 저울에 올려 어긋난 표가 0장인지 검사한다. | LEFT JOIN한 account와 account-grain signed sum의 mismatch count가 0이 아니면 baseline exception을 낸다.
|
| 7줄F03-L07 | SELECT 'W17_BASELINE= |
baseline 저울이 통과한 뒤 transcript에 0이라고 적힌 확인 도장 한 줄을 찍는다. | literal text `W17_BASELINE=0`을 한 행 SELECT한다.
|
| 8줄F03-L08 | SAVEPOINT injected; |
오류를 넣기 직전 상태에 `injected`라는 책갈피를 꽂아 돌아올 위치를 기억한다. | 현재 transaction에 이름이 injected인 SAVEPOINT를 만든다.
|
| 9줄F03-L09 | UPDATE account SET balance= |
가장 작은 계좌 번호표 한 장의 잔액만 7 올려 원장표와 일부러 어긋나게 만든다. | minimum account id row의 balance를 기존 값에 7 더해 update한다.
|
| 10줄F03-L10 | DO $g$ BEGIN IF ( |
오류 표가 정확히 한 장인지 다시 세어 0장이나 두 장이면 경보를 울린다. | 같은 account-to-ledger 비교의 mismatch count가 1이 아니면 injected exception을 발생시킨다.
|
| 11줄F03-L11 | SELECT 'W17_INJECTED= |
한 장 불일치 검사가 끝났다는 `INJECTED=1` 영수증을 transcript 줄에 남긴다. | literal marker `W17_INJECTED=1`을 SELECT 결과로 낸다.
|
| 12줄F03-L12 | ROLLBACK TO SAVEPOINT injected; |
책갈피 위치로 되감아 그 뒤에 적은 +7 연필 자국만 지우고 작업막은 계속 펼쳐 둔다. | ROLLBACK TO SAVEPOINT injected로 savepoint 이후 update를 취소한다.
|
| 13줄F03-L13 | DO $g$ BEGIN IF ( |
복구된 저울을 한 번 더 재서 어긋난 표가 다시 0장인지 확인한다. | account와 ledger aggregate의 mismatch count가 0이 아니면 rollback-restore exception을 낸다.
|
| 14줄F03-L14 | SELECT 'W17_RESTORED= |
복구 검사까지 통과했다는 `RESTORED=0` 확인표를 마지막 transcript 칸에 붙인다. | literal string `W17_RESTORED=0`을 한 행 반환한다.
|
| 15줄F03-L15 | ROLLBACK; |
post-BEGIN 투명 작업막을 접어 그 안의 남은 미확정 변경을 모두 버리고 session을 정상 경계로 돌린다. | 현재 explicit transaction을 ROLLBACK으로 종료한다.
|
count가 잃는 정보히토리 → 니지카 → 료 → 키타
-
히토리
count 1이면 W17-001과 difference 7도 검증된 거죠?
-
니지카
한 장이라는 수만 남고 그 표의 이름과 차이는 출력되지 않아.
-
료
fresh fixture 추론과 direct assertion은 같은 proof가 아니다.
-
키타
id·stored·ledger·difference가 predicate에 있는지 원문에서 찾겠습니다.
STEP 05 / 13
원본 코드 조각
원본을 4개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 hash로 고정한 native 정본 source에서 그대로 잘랐습니다.
\set ON_ERROR_STOP on
INSERT INTO account(owner_id,account_no,status,currency,balance) VALUES ('w17-owner','W17-001','ACTIVE','KRW',100);
INSERT INTO business_tx(id,tx_type,status,correlation_id,requested_at,completed_at) VALUES ('00000000-0000-0000-0000-000000000017','OPENING','COMPLETED','w17-open',now(),now());
INSERT INTO ledger_entry(business_tx_id,account_id,entry_type,amount,signed_amount,balance_after,created_at) SELECT '00000000-0000-0000-0000-000000000017',id,'OPENING',100,100,100,now() FROM account WHERE account_no='W17-001';
BEGIN;
DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>0 THEN RAISE EXCEPTION 'baseline mismatch';END IF;END $g$;
SELECT 'W17_BASELINE=0';
SAVEPOINT injected;
UPDATE account SET balance=balance+7 WHERE id=(SELECT min(id) FROM account);
DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>1 THEN RAISE EXCEPTION 'injected mismatch not exact one';END IF;END $g$;
SELECT 'W17_INJECTED=1';
ROLLBACK TO SAVEPOINT injected;
DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>0 THEN RAISE EXCEPTION 'rollback did not restore';END IF;END $g$;
SELECT 'W17_RESTORED=0';
ROLLBACK;
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 15줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | \set ON_ERROR_STOP on | psql client variable ON_ERROR_STOP을 on으로 설정한다. |
| 2 | INSERT INTO account(owner_id,account_no,status,currency,balance) VALUES ('w17-owner','W17-001','ACTIVE','KRW',100); | account에 owner w17-owner, account_no W17-001, ACTIVE, KRW, balance 100을 insert한다. |
| 3 | INSERT INTO business_tx(id,tx_type,status,correlation_id,requested_at,completed_at) VALUES ('00000000-0000-0000-0000-000000000017','OPENING','COMPLETED','w17-open',now(),now()); | business_tx에 fixed UUID, OPENING, COMPLETED, w17-open과 두 now() 값을 insert한다. |
| 4 | INSERT INTO ledger_entry(business_tx_id,account_id,entry_type,amount,signed_amount,balance_after,created_at) SELECT '00000000-0000-0000-0000-000000000017',id,'OPENING',100,100,100,now() FROM account WHERE account_no='W17-001'; | account_no W17-001의 id를 SELECT해 amount·signed_amount·balance_after 100인 ledger_entry를 insert한다. |
| 5 | BEGIN; | 명시적 PostgreSQL transaction을 BEGIN으로 시작한다. |
| 6 | DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>0 THEN RAISE EXCEPTION 'baseline mismatch';END IF;END $g$; | LEFT JOIN한 account와 account-grain signed sum의 mismatch count가 0이 아니면 baseline exception을 낸다. |
| 7 | SELECT 'W17_BASELINE=0'; | literal text `W17_BASELINE=0`을 한 행 SELECT한다. |
| 8 | SAVEPOINT injected; | 현재 transaction에 이름이 injected인 SAVEPOINT를 만든다. |
| 9 | UPDATE account SET balance=balance+7 WHERE id=(SELECT min(id) FROM account); | minimum account id row의 balance를 기존 값에 7 더해 update한다. |
| 10 | DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>1 THEN RAISE EXCEPTION 'injected mismatch not exact one';END IF;END $g$; | 같은 account-to-ledger 비교의 mismatch count가 1이 아니면 injected exception을 발생시킨다. |
| 11 | SELECT 'W17_INJECTED=1'; | literal marker `W17_INJECTED=1`을 SELECT 결과로 낸다. |
| 12 | ROLLBACK TO SAVEPOINT injected; | ROLLBACK TO SAVEPOINT injected로 savepoint 이후 update를 취소한다. |
| 13 | DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>0 THEN RAISE EXCEPTION 'rollback did not restore';END IF;END $g$; | account와 ledger aggregate의 mismatch count가 0이 아니면 rollback-restore exception을 낸다. |
| 14 | SELECT 'W17_RESTORED=0'; | literal string `W17_RESTORED=0`을 한 행 반환한다. |
| 15 | ROLLBACK; | 현재 explicit transaction을 ROLLBACK으로 종료한다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기이 drill은 fresh w17_drill의 post-BEGIN mismatch-count sequence를 재현하지만 pre-BEGIN seed durability와 marker authenticity는 별도 경계다.
문법 해부
- psql default autocommit에서는 BEGIN 밖의 INSERT statement가 각각 commit된다.
- LEFT JOIN aggregated subquery와 COALESCE가 ledger 0건 account도 비교한다.
- ROLLBACK TO SAVEPOINT는 transaction을 종료하지 않고 target 이후 변경만 취소한다.
- DO exception은 predicate failure를 SQL error로 바꾸지만 literal marker는 계산을 반복하지 않는다.
실행 순서
- error-stop을 켜고 opening account·business_tx·ledger를 autocommit한다.
- BEGIN 뒤 baseline mismatch 0과 marker를 낸다.
- savepoint 뒤 minimum account balance를 107로 바꾸고 count 1을 확인한다.
- savepoint로 돌아가 count 0을 재확인한다.
- 마지막 ROLLBACK으로 post-BEGIN transaction만 닫는다.
원래 W6 수준의 조각별 정밀 해설
F03-C01 · fail-fast and pre-BEGIN W17 opening seed
- 문법 해부
- `fail-fast and 트랜잭션 시작 전 W17 opening seed` 범위는 psql client variable ON_ERROR_STOP을 on으로 설정한다. 이어서 account_no W17-001의 id를 SELECT해 amount·signed_amount·balance_after 100인 ledger_entry를 insert한다.
- 실제 값 추적
- 구체 입력은 business_tx PK·correlation UNIQUE가 비어 있는 fresh schema와 한 statement transaction clock을 사용한다. 처리 뒤 관찰 가능한 끝 상태는 opening ledger row가 commit되어 저장 balance 100과 account-grain signed sum 100이 맞는 seed가 된다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 뒤 statement가 SQL error를 내면 남은 input을 중단할 client 정책이 활성화된다. 그리고 범위 끝에서 opening ledger row가 commit되어 저장 balance 100과 account-grain signed sum 100이 맞는 seed가 된다.
- 틀린 예·반례
- 2~4줄 INSERT가 트랜잭션 시작 전에 실행됐는데 나중 취소 구문이 opening seed까지 지운다고 설명하면 psql autocommit 경계를 거꾸로 읽은 것이다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: transaction을 만들지 않고 false predicate·영행 SELECT를 오류로 바꾸지도 않는다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: transaction을 만들지 않고 false predicate·영행 SELECT를 오류로 바꾸지도 않는다.
- 다음 연결
- 끝 상태를 기록한다: opening ledger row가 commit되어 저장 balance 100과 account-grain signed sum 100이 맞는 seed가 된다. 이어지는 `transaction baseline invariant` 범위에서 이 상태의 입력 경계를 확인한다.
F03-C02 · transaction baseline invariant
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 명시적 PostgreSQL transaction을 BEGIN으로 시작한다. 끝에서 literal text `W17_BASELINE=0`을 한 행 SELECT한다.
- 실제 값 추적
- 시작 조건 psql session이 현재 autocommit 경계 뒤에서 BEGIN statement를 server에 보낸다.에서 범위를 통과하면 중간에 불일치가 없으면 DO가 조용히 끝나고 하나라도 있으면 transaction이 error 상태가 된다. 마지막에 psql output에 baseline marker 후보가 나타나 runner transcript에 수집될 수 있다.
- 정상 예
- 원본 `BEGIN;`를 정확히 유지하고 이 범위를 실행·해석했을 때 psql output에 baseline marker 후보가 나타나 runner transcript에 수집될 수 있다.
- 틀린 예·반례
- W17_BASELINE=0 literal 한 줄만 보고 packaged DO block이 실행됐거나 account id·difference가 검증됐다고 볼 수 없다.
- 착각 방지
- 문자열 자체는 대사를 다시 계산하지 않고 runner도 순서·유일성·출처를 인증하지 않는다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `transaction baseline invariant`의 source state만 다루며 문자열 자체는 대사를 다시 계산하지 않고 runner도 순서·유일성·출처를 인증하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: psql output에 baseline marker 후보가 나타나 runner transcript에 수집될 수 있다. 이어지는 `mismatch injection and exact-one invariant` 범위에서 이 상태의 입력 경계를 확인한다.
F03-C03 · mismatch injection and exact-one invariant
- 문법 해부
- 이 source slice의 문법 축은 같은 account-to-ledger 비교의 mismatch count가 1이 아니면 injected exception을 발생시킨다. 앞뒤로 현재 transaction에 이름이 injected인 SAVEPOINT를 만든다. 및 literal marker `W17_INJECTED=1`을 SELECT 결과로 낸다.
- 실제 값 추적
- 열린 post-BEGIN transaction과 savepoint identifier가 server에 전달된다. 그 상태가 진행되면 runner가 substring으로 찾을 수 있는 injected marker 한 행이 생성된다.
- 정상 예
- 유효한 예는 'SAVEPOINT injected;' bytes를 보존해 fresh fixture에서는 count 1이라 통과하고 다른 개수면 SQL error로 남은 input이 중단된다.
- 틀린 예·반례
- minimum account update와 mismatch count 1을 모든 기존 schema에 일반화하면 fresh w17_drill fixture 전제를 잃는다.
- 착각 방지
- 정확히 한 행이라는 사실만 보며 그 행이 W17-001인지 difference가 7인지 직접 assert하지 않는다. 따라서 `mismatch injection and exact-one invariant`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. 정확히 한 행이라는 사실만 보며 그 행이 W17-001인지 difference가 7인지 직접 assert하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: runner가 substring으로 찾을 수 있는 injected marker 한 행이 생성된다. 이어지는 `savepoint restore and post-BEGIN rollback` 범위에서 이 상태의 입력 경계를 확인한다.
F03-C04 · savepoint restore and post-BEGIN rollback
- 문법 해부
- `savepoint restore and post-BEGIN rollback` 범위는 ROLLBACK TO SAVEPOINT injected로 savepoint 이후 update를 취소한다. 이어서 현재 explicit transaction을 ROLLBACK으로 종료한다.
- 실제 값 추적
- 구체 입력은 성공한 restore DO 뒤의 open transaction과 고정 marker text를 사용한다. 처리 뒤 관찰 가능한 끝 상태는 post-BEGIN scope가 닫히지만 lines 2~4에서 이미 commit된 opening seed는 database에 유지된다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 W17-001 balance가 100으로 복구되고 transaction은 종료되지 않은 채 다음 statement를 받는다. 그리고 범위 끝에서 post-BEGIN scope가 닫히지만 lines 2~4에서 이미 commit된 opening seed는 database에 유지된다.
- 틀린 예·반례
- ROLLBACK TO가 transaction을 끝낸다거나 final ROLLBACK이 트랜잭션 시작 전 committed seed를 취소한다고 말하면 두 rollback scope를 섞는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: BEGIN 전 autocommit seed는 범위 밖이라 남고 전체 transaction cleanup이나 container cleanup도 아니다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: BEGIN 전 autocommit seed는 범위 밖이라 남고 전체 transaction cleanup이나 container cleanup도 아니다.
- 다음 연결
- 끝 상태를 기록한다: post-BEGIN scope가 닫히지만 lines 2~4에서 이미 commit된 opening seed는 database에 유지된다. 이어지는 `parameters and absolute-path preparation` 범위에서 이 상태의 입력 경계를 확인한다.
marker spoof 경계히토리 → 니지카 → 료 → 키타
-
히토리
세 marker가 있으면 packaged drill 실행을 믿어도 되나요?
-
니지카
raw V001도 그 글자를 먼저 말하거나 psql을 끝낼 수 있어.
-
료
runner loop는 존재만 확인하고 order·uniqueness·source SHA를 묶지 않는다.
-
키타
runner acceptance와 authenticated evidence를 서로 다른 표찰로 쓰겠습니다.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| opening seed autocommit | fresh schema, W17-001 balance100, ledger signed100 | lines 2~4를 BEGIN 전에 실행한다. | account·business_tx·ledger row가 각각 commit되고 mismatch는 0이다. | timestamps는 run-variable이고 seed는 line15 rollback 대상이 아니다. |
| baseline gate | stored100 / ledger100 | account-grain mismatch count를 센다. | 0이라 DO가 통과하고 W17_BASELINE=0 text가 출력된다. | marker text는 query result tuple이 아니라 literal이다. |
| injected mismatch | fresh minimum id=W17-001 | balance를 100+7로 update한다. | stored107 / ledger100 / difference7인 한 mismatch가 생겨 count1을 통과한다. | DO와 marker는 id·difference를 직접 assert하거나 출력하지 않는다. |
| savepoint restore | injected savepoint 이후 +7 | ROLLBACK TO 뒤 mismatch를 다시 센다. | balance100으로 돌아가 count0이고 마지막 ROLLBACK 뒤 seed는 남는다. | Compose mode에서만 owner down -v가 volume을 제거한다. |
Container에 남는 것히토리 → 니지카 → 료 → 키타
-
히토리
cleanup=1이면 supplied container도 깨끗해지겠네요?
-
니지카
down -v는 owner가 만든 Compose mode에서만 불려.
-
료
Container mode에는 w17_drill과 committed seed가 남고 다음 run 시작 때 drop된다.
-
키타
mode별 종료 상태를 schema·container·volume 세 칸으로 대조하겠습니다.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
ON_ERROR_STOP과 autocommit/explicit transaction 경계를 server statement에 적용한다.
marker substring의 의미나 evidence freshness를 인증하지 않는다.BEGIN·SAVEPOINT·ROLLBACK TO·ROLLBACK의 visibility와 undo 범위를 관리한다.
BEGIN 전 committed seed를 마지막 rollback scope로 소급하지 않는다.account-grain aggregate·LEFT JOIN·COALESCE로 mismatch row count를 계산한다.
account id·difference·double-entry completeness는 count observable에 없다.raw V001과 packaged drill output에서 세 marker substring의 존재를 확인한다.
raw V001 spoof와 Container schema persistence 때문에 transcript만으로 authenticated proof가 아니다.STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ 마지막 ROLLBACK이 opening seed까지 모두 지운다.
왜 틀리나 세 INSERT는 BEGIN보다 앞에서 autocommit된다.
바르게 읽기 pre-BEGIN seed와 post-BEGIN +7 scope를 별도 timeline으로 그린다.
반례 supplied Container 성공 뒤 w17_drill의 W17-001·opening tx·ledger가 남는다.
❌ ROLLBACK TO를 하면 transaction도 끝난다.
왜 틀리나 savepoint 이후 변경만 취소하고 transaction은 열린다.
바르게 읽기 line12 이후 line13·14가 같은 transaction에서 실행됨을 표시한다.
반례 마지막 line15 ROLLBACK이 별도로 있어야 scope가 닫힌다.
❌ mismatch count 1이면 W17-001이 7만큼 다른 것도 assert됐다.
왜 틀리나 predicate는 count만 비교한다.
바르게 읽기 필요하면 account_id·stored·ledger·difference exact row를 별도 assert한다.
반례 다른 한 계좌가 다른 차이로 어긋나도 count 1은 같다.
❌ 세 marker가 있으면 packaged drill 순서대로 실행됐다는 뜻이다.
왜 틀리나 runner는 raw V001 뒤 transcript에서 substring 존재만 본다.
바르게 읽기 source hash·exact ordered structured output·marker uniqueness를 함께 검증한다.
반례 learner V001이 marker 세 개를 출력하고 early quit할 수 있다.
❌ now()가 두 번이라 requested_at과 completed_at은 서로 다르다.
왜 틀리나 PostgreSQL now()는 같은 statement transaction 안에서 같은 transaction timestamp다.
바르게 읽기 같은 run의 두 값 equality와 run 간 byte variability를 분리한다.
반례 한 INSERT의 두 now()는 같아도 다음 실행의 timestamp는 달라질 수 있다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
final ROLLBACK이 pre-BEGIN account·tx·ledger seed를 제거함
이 책임을 맡는 곳: explicit transaction placement or owned Compose down -vmarker가 packaged drill에서 ordered·unique하게 생성됨
이 책임을 맡는 곳: pinned source plus exact ordered structured output validationcount 1의 account id와 difference가 W17-001·7임
이 책임을 맡는 곳: row-level projection and exact oracleopening 한 행이 double-entry·status·authorization 정책을 만족함
이 책임을 맡는 곳: domain ledger contract and reconciliation controlscleanup=1 text가 supplied schema·container를 제거함
이 책임을 맡는 곳: external container owner or next-run DROP SCHEMASTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
각 줄에 autocommit seed·post-BEGIN transaction·savepoint-local·literal marker 중 하나를 표시한다.
2단계 · 코드 조각 재조립
- L2~4 → committed seed
- L5 → explicit scope start
- L8~12 → +7 and partial undo
- L15 → post-BEGIN scope end only
3단계 · 파일 전체 다시 쓰기
빈 timeline에 stored/ledger/mismatch를 100/100/0 → 107/100/1 → 100/100/0으로 쓰고 seed durability를 별도 줄로 남긴다.
자가 점검
- BEGIN 전 세 INSERT와 마지막 ROLLBACK 범위를 분리했는가?
- ROLLBACK TO 뒤 transaction이 열린다는 점을 적었는가?
- count observable과 account/difference 미증명을 구분했는가?
- Container schema+seed persistence와 Compose down -v를 나눴는가?
- marker presence와 authenticated ordered proof를 혼동하지 않았는가?
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
정본 전체 코드 확인하기
\set ON_ERROR_STOP on
INSERT INTO account(owner_id,account_no,status,currency,balance) VALUES ('w17-owner','W17-001','ACTIVE','KRW',100);
INSERT INTO business_tx(id,tx_type,status,correlation_id,requested_at,completed_at) VALUES ('00000000-0000-0000-0000-000000000017','OPENING','COMPLETED','w17-open',now(),now());
INSERT INTO ledger_entry(business_tx_id,account_id,entry_type,amount,signed_amount,balance_after,created_at) SELECT '00000000-0000-0000-0000-000000000017',id,'OPENING',100,100,100,now() FROM account WHERE account_no='W17-001';
BEGIN;
DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>0 THEN RAISE EXCEPTION 'baseline mismatch';END IF;END $g$;
SELECT 'W17_BASELINE=0';
SAVEPOINT injected;
UPDATE account SET balance=balance+7 WHERE id=(SELECT min(id) FROM account);
DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>1 THEN RAISE EXCEPTION 'injected mismatch not exact one';END IF;END $g$;
SELECT 'W17_INJECTED=1';
ROLLBACK TO SAVEPOINT injected;
DO $g$ BEGIN IF (SELECT count(*) FROM account a LEFT JOIN(SELECT account_id,sum(signed_amount)b FROM ledger_entry GROUP BY account_id)l ON l.account_id=a.id WHERE a.balance<>coalesce(l.b,0))<>0 THEN RAISE EXCEPTION 'rollback did not restore';END IF;END $g$;
SELECT 'W17_RESTORED=0';
ROLLBACK;
04run-w17-reconcile.ps1 - 세 drill과 약한 증거 경계
scripts/run-w17-reconcile.ps1
정본 PowerShell 러너 · 정본 · W17-F0479줄 연결79줄 번역6 chunks
run-w17-reconcile.ps1 - 세 drill과 약한 증거 경계
scripts/run-w17-reconcile.ps1
정본 PowerShell 러너 · 정본 · W17-F04STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
Ranking 또는 raw V001+packaged reconcile drill을 PostgreSQL에 보내되, 실제 oracle·evidence·resource ownership의 닫힌 범위와 열린 틈을 정확히 구분한다.
- raw learner V001이 packaged drill보다 먼저 무엇을 출력하거나 중단할 수 있을까?
- 세 marker 존재 검사가 순서와 유일성도 보장할까?
- Compare-Object는 네 numeric row의 출력 위치를 볼까?
- 이전 transcript와 ranking-result.txt가 current failure 뒤 남을 수 있을까?
- Compose up nonzero와 Container mode에서 cleanup 책임은 어떻게 달라질까?
drills=Reconcile/Ranking/Savepointranking numeric rows=4 unordered multisetmarker presence=baseline/injected/restoredowned=true only after successful upContainer cleanup=noneSTEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 Ranking 표와 대사 transcript를 모으면서 어느 검사가 실제로 닫혔는지 표시한다.
세 실험 통로의 증거 표
Ranking 통로는 숫자 다섯 칸인 네 행의 multiset을 보고, 대사 통로는 세 marker가 어디엔가 있는지만 본다.
파일이 생긴 시점과 Compose 소유권을 따로 읽어야 이전 증거나 남은 resource를 Green으로 착각하지 않는다.
딱 여기까지만 한계: 점검표 비유는 raw V001의 실제 SQL 의미나 PostgreSQL 실행 결과를 대신 인증하지 않는다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
원문 두 겹
Reconcile은 learner V001 뒤에 packaged drill을 붙인다.
- 코드 연결
28~30줄- 비유
- 학생 메모 뒤에 공식 시험지를 붙여 한 봉투로 넣는다.
- 비유의 끝
- 앞 메모가 marker를 흉내 내거나 psql을 일찍 끝낼 수 있다.
두 oracle
Ranking은 numeric row multiset, 대사는 marker substring presence를 본다.
- 코드 연결
50~52줄·67~69줄- 비유
- 한 표는 행 구성만, 다른 표는 도장 존재만 센다.
- 비유의 끝
- 어느 쪽도 모든 stdout의 exact ordered transcript를 보지 않는다.
증거와 Green
transcript는 validation 전에 써지고 Ranking target도 선삭제하지 않는다.
- 코드 연결
54·64줄- 비유
- 검수 전 종이가 서랍에 들어가거나 어제 종이가 남을 수 있다.
- 비유의 끝
- file existence는 current successful run의 postcondition이 아니다.
소유권 bit
Compose up 성공 뒤에만 owned=true이고 Container에는 down이 없다.
- 코드 연결
34·39~43·78~81줄- 비유
- 열쇠 인수 도장을 받은 방만 철거한다.
- 비유의 끝
- 기동 중 일부가 생긴 뒤 실패하면 도장 없이 resource가 남을 수 있다.
앞에 붙는 raw V001히토리 → 니지카 → 료 → 키타
-
히토리
packaged drill이 있으니 marker는 믿어도 되나요?
-
니지카
먼저 붙는 learner V001은 hash pin도 inspection도 없어.
-
료
그 source가 marker를 내거나 psql meta-command로 일찍 끝낼 수도 있다.
-
키타
marker 존재와 packaged drill provenance를 분리해 적겠습니다.
존재와 순서히토리 → 니지카 → 료 → 키타
-
히토리
세 문구가 모두 있으면 순서도 맞는 거죠?
-
니지카
loop는 각 substring이 한 번이라도 있는지만 봐.
-
료
역순·중복·spoof는 현재 조건 밖이다.
-
키타
exact joined sequence oracle과 비교해 보겠습니다.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 79줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F04-L01 | param( |
STARRY 운영실의 다중 drill owner의 parameter contract·일 좌표 스위치는 ‘multi-drill runner parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다’라는 현재 동작만 맡는다. | 다중 drill owner의 parameter contract·일 좌표의 실제 뜻: multi-drill runner parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C01 원문 〔param(〕다.
|
| 2줄F04-L02 | [ |
대사 실험대 다중 drill owner의 parameter contract·이 좌표 레버를 당기면 parameter binder에 $Mode 선언과 기본값 'Compose' 계약을 추가한다. | 다중 drill owner의 parameter contract·이 좌표의 실제 뜻: parameter binder에 $Mode 선언과 기본값 'Compose' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[ValidateSet('Compose','Container')][string]$Mode='Compose',〕다.
|
| 3줄F04-L03 | [ |
검증 관제판의 다중 drill owner의 parameter contract·삼 좌표 표식은 ‘parameter binder에 $Drill 선언과 기본값 'Reconcile' 계약을 추가한다’ 상태 전환을 가리킨다. | 다중 drill owner의 parameter contract·삼 좌표의 실제 뜻: parameter binder에 $Drill 선언과 기본값 'Reconcile' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[ValidateSet('Reconcile','Ranking','Savepoint')][string]$Drill='Reconcile',〕다.
|
| 4줄F04-L04 | [ |
격리 장부 다중 drill owner의 parameter contract·사 좌표 절차 카드는 ‘parameter binder에 $Container 선언과 기본값 '' 계약을 추가한다’라고 읽는다. | 다중 drill owner의 parameter contract·사 좌표의 실제 뜻: parameter binder에 $Container 선언과 기본값 '' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[string]$Container='',〕다.
|
| 5줄F04-L05 | [ |
증거 포장대의 다중 drill owner의 parameter contract·오 좌표 봉인 공정은 parameter binder에 $ComposeProject 선언과 기본값 'w17-reconcile-lab' 계약을 추가한다. | 다중 drill owner의 parameter contract·오 좌표의 실제 뜻: parameter binder에 $ComposeProject 선언과 기본값 'w17-reconcile-lab' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[string]$ComposeProject='w17-reconcile-lab',〕다.
|
| 6줄F04-L06 | [ |
실패 폐쇄형 통로에서 다중 drill owner의 parameter contract·육 좌표 문턱은 ‘parameter binder에 $ProjectRoot 선언과 mandatory 또는 caller supplied 값 계약을 추가한다’ 역할이다. | 다중 drill owner의 parameter contract·육 좌표의 실제 뜻: parameter binder에 $ProjectRoot 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[Parameter(Mandatory=$true)][string]$ProjectRoot,〕다.
|
| 7줄F04-L07 | [ |
컨테이너 실험실 다중 drill owner의 parameter contract·칠 좌표 안내는 ‘parameter binder에 $EvidenceDir 선언과 mandatory 또는 caller supplied 값 계약을 추가한다’ 작업만 지시한다. | 다중 drill owner의 parameter contract·칠 좌표의 실제 뜻: parameter binder에 $EvidenceDir 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[Parameter(Mandatory=$true)][string]$EvidenceDir,〕다.
|
| 8줄F04-L08 | [ |
SQL 검수대의 다중 drill owner의 parameter contract·팔 좌표 한 동작은 parameter binder에 $SqlPath 선언과 기본값 '' 계약을 추가한다. | 다중 drill owner의 parameter contract·팔 좌표의 실제 뜻: parameter binder에 $SqlPath 선언과 기본값 '' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[string]$SqlPath=''〕다.
|
| 9줄F04-L09 | ) |
원장 대사 시뮬레이터 다중 drill owner의 parameter contract·구 좌표 단추는 script parameter list의 마지막 delimiter를 닫는다. | 다중 drill owner의 parameter contract·구 좌표의 실제 뜻: script parameter list의 마지막 delimiter를 닫는다. 근거 원문은 F04-C01 원문 〔)〕다.
|
| 10줄F04-L10 | $ErrorActionPreference= |
파일 증거 조립선 다중 drill owner의 absolute-path setup·십 좌표 공정이 맡은 일은 PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. | 다중 drill owner의 absolute-path setup·십 좌표의 실제 뜻: PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. 근거 원문은 F04-C01 원문 〔$ErrorActionPreference='Stop'〕다.
|
| 11줄F04-L11 | $root= |
다중 drill owner의 absolute-path setup·십일 좌표는 매개변수와 절대 경로 준비 점검표에서 ‘$root에 현재 식 Split-Path -Parent $PSScriptRoot의 평가값을 할당한다’ 봉투에 대응한다. | 다중 drill owner의 absolute-path setup·십일 좌표의 실제 뜻: $root에 현재 식 Split-Path -Parent $PSScriptRoot의 평가값을 할당한다. 근거 원문은 F04-C01 원문 〔$root=Split-Path -Parent $PSScriptRoot〕다.
|
| 12줄F04-L12 | if( |
STARRY 운영실의 다중 drill owner의 absolute-path setup·십이 좌표 스위치는 ‘조건식 if(-not [IO.Path]::IsPathRooted($ProjectRoot)){throw 'ProjectRoot must be an absolute learner…의 참·거짓을 평가한다’라는 현재 동작만 맡는다. | 다중 drill owner의 absolute-path setup·십이 좌표의 실제 뜻: 조건식 if(-not [IO.Path]::IsPathRooted($ProjectRoot)){throw 'ProjectRoot must be an absolute learner…의 참·거짓을 평가한다. 근거 원문은 F04-C01 원문 〔if(-not [IO.Path]::IsPathRooted($ProjectRoot)){throw 'ProjectRoot must be an absolute learner…〕다.
|
| 13줄F04-L13 | if( |
대사 실험대 다중 drill owner의 absolute-path setup·십삼 좌표 레버를 당기면 조건식 if(-not [IO.Path]::IsPathRooted($EvidenceDir)){throw 'EvidenceDir must be an absolute learner…의 참·거짓을 평가한다. | 다중 drill owner의 absolute-path setup·십삼 좌표의 실제 뜻: 조건식 if(-not [IO.Path]::IsPathRooted($EvidenceDir)){throw 'EvidenceDir must be an absolute learner…의 참·거짓을 평가한다. 근거 원문은 F04-C01 원문 〔if(-not [IO.Path]::IsPathRooted($EvidenceDir)){throw 'EvidenceDir must be an absolute learner…〕다.
|
| 14줄F04-L14 | $project= |
검증 관제판의 다중 drill owner의 absolute-path setup·십사 좌표 표식은 ‘$project에 현재 식 (Resolve-Path -LiteralPath $ProjectRoot).Path의 평가값을 할당한다’ 상태 전환을 가리킨다. | 다중 drill owner의 absolute-path setup·십사 좌표의 실제 뜻: $project에 현재 식 (Resolve-Path -LiteralPath $ProjectRoot).Path의 평가값을 할당한다. 근거 원문은 F04-C01 원문 〔$project=(Resolve-Path -LiteralPath $ProjectRoot).Path〕다.
|
| 15줄F04-L15 | $e= |
격리 장부 다중 drill owner의 absolute-path setup·십오 좌표 절차 카드는 ‘$e에 현재 식 [IO.Path]::GetFullPath($EvidenceDir)의 평가값을 할당한다’라고 읽는다. | 다중 drill owner의 absolute-path setup·십오 좌표의 실제 뜻: $e에 현재 식 [IO.Path]::GetFullPath($EvidenceDir)의 평가값을 할당한다. 근거 원문은 F04-C01 원문 〔$e=[IO.Path]::GetFullPath($EvidenceDir)〕다.
|
| 16줄F04-L16 | New-Item -ItemType Directory -Force $e|Out-Null |
증거 포장대의 다중 drill owner의 absolute-path setup·십육 좌표 봉인 공정은 pipeline stage New-Item -ItemType Directory -Force $e|Out-Null로 왼쪽 값을 오른쪽 command에 전달한다. | 다중 drill owner의 absolute-path setup·십육 좌표의 실제 뜻: pipeline stage New-Item -ItemType Directory -Force $e|Out-Null로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F04-C01 원문 〔New-Item -ItemType Directory -Force $e|Out-Null〕다.
|
| 18줄F04-L18 | if( |
컨테이너 실험실 다중 drill owner의 Ranking source inspection·십팔 좌표 안내는 ‘Ranking drill condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | 다중 drill owner의 Ranking source inspection·십팔 좌표의 실제 뜻: Ranking drill condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C02 원문 〔if($Drill-eq'Ranking'){〕다.
|
| 19줄F04-L19 | if( |
SQL 검수대의 다중 drill owner의 Ranking source inspection·십구 좌표 한 동작은 Ranking SqlPath가 absolute이고 비어 있지 않은지만 검사한다. | 다중 drill owner의 Ranking source inspection·십구 좌표의 실제 뜻: Ranking SqlPath가 absolute이고 비어 있지 않은지만 검사한다. 근거 원문은 F04-C02 원문 〔if([string]::IsNullOrWhiteSpace($SqlPath)-or-not[IO.Path]::IsPathRooted($SqlPath)){throw 'Ran…〕다.
|
| 20줄F04-L20 | $ranking= |
원장 대사 시뮬레이터 다중 drill owner의 Ranking source inspection·이십 좌표 단추는 $ranking에 현재 식 (Resolve-Path -LiteralPath $SqlPath).Path의 평가값을 할당한다. | 다중 drill owner의 Ranking source inspection·이십 좌표의 실제 뜻: $ranking에 현재 식 (Resolve-Path -LiteralPath $SqlPath).Path의 평가값을 할당한다. 근거 원문은 F04-C02 원문 〔$ranking=(Resolve-Path -LiteralPath $SqlPath).Path〕다.
|
| 21줄F04-L21 | $learnerSql= |
파일 증거 조립선 다중 drill owner의 Ranking source inspection·이십일 좌표 공정이 맡은 일은 $learnerSql에 현재 식 Get-Content -Raw -LiteralPath $ranking의 평가값을 할당한다. | 다중 drill owner의 Ranking source inspection·이십일 좌표의 실제 뜻: $learnerSql에 현재 식 Get-Content -Raw -LiteralPath $ranking의 평가값을 할당한다. 근거 원문은 F04-C02 원문 〔$learnerSql=Get-Content -Raw -LiteralPath $ranking〕다.
|
| 22줄F04-L22 | foreach( |
다중 drill owner의 Ranking source inspection·이십이 좌표는 Ranking 검사 또는 물리 drill 조립 점검표에서 ‘required ranking-pattern iteration header foreach($pattern in @('\bROW_NUMBER\s*\(','(?<!DENSE_)\bRANK\s*\(','\bDENSE_RANK\s*\(','ORDER…가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | 다중 drill owner의 Ranking source inspection·이십이 좌표의 실제 뜻: required ranking-pattern iteration header foreach($pattern in @('\bROW_NUMBER\s*\(','(?<!DENSE_)\bRANK\s*\(','\bDENSE_RANK\s*\(','ORDER…가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C02 원문 〔foreach($pattern in @('\bROW_NUMBER\s*\(','(?<!DENSE_)\bRANK\s*\(','\bDENSE_RANK\s*\(','ORDER…〕다.
|
| 23줄F04-L23 | if( |
STARRY 운영실의 다중 drill owner의 Ranking source inspection·이십삼 좌표 스위치는 ‘조건식 if($learnerSql-cnotmatch $pattern){throw "ranking.sql missing required construct: $pattern"}의 참·거짓을 평가한다’라는 현재 동작만 맡는다. | 다중 drill owner의 Ranking source inspection·이십삼 좌표의 실제 뜻: 조건식 if($learnerSql-cnotmatch $pattern){throw "ranking.sql missing required construct: $pattern"}의 참·거짓을 평가한다. 근거 원문은 F04-C02 원문 〔if($learnerSql-cnotmatch $pattern){throw "ranking.sql missing required construct: $pattern"}〕다.
|
| 24줄F04-L24 | } |
대사 실험대 다중 drill owner의 Ranking source inspection·이십사 좌표 레버를 당기면 one required ranking-pattern check의 마지막 delimiter를 닫는다. | 다중 drill owner의 Ranking source inspection·이십사 좌표의 실제 뜻: one required ranking-pattern check의 마지막 delimiter를 닫는다. 근거 원문은 F04-C02 원문 〔}〕다.
|
| 25줄F04-L25 | if( |
검증 관제판의 다중 drill owner의 Ranking source inspection·이십오 좌표 표식은 ‘TODO류 placeholder 단어가 있으면 Ranking source를 거절한다’ 상태 전환을 가리킨다. | 다중 drill owner의 Ranking source inspection·이십오 좌표의 실제 뜻: TODO류 placeholder 단어가 있으면 Ranking source를 거절한다. 근거 원문은 F04-C02 원문 〔if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an…〕다.
|
| 26줄F04-L26 | $sql= |
격리 장부 다중 drill owner의 Ranking source inspection·이십육 좌표 절차 카드는 ‘$sql에 현재 식 $learnerSql의 평가값을 할당한다’라고 읽는다. | 다중 drill owner의 Ranking source inspection·이십육 좌표의 실제 뜻: $sql에 현재 식 $learnerSql의 평가값을 할당한다. 근거 원문은 F04-C02 원문 〔$sql=$learnerSql〕다.
|
| 27줄F04-L27 | }else{ |
증거 포장대의 다중 drill owner의 raw assembly·이십칠 좌표 봉인 공정은 non-Ranking assembly branch header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. | 다중 drill owner의 raw assembly·이십칠 좌표의 실제 뜻: non-Ranking assembly branch header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C02 원문 〔}else{〕다.
|
| 28줄F04-L28 | $v001= |
실패 폐쇄형 통로에서 다중 drill owner의 raw assembly·이십팔 좌표 문턱은 ‘learner V001 파일을 raw 문자열로 읽으며 hash pin이나 SQL inspection을 하지 않는다’ 역할이다. | 다중 drill owner의 raw assembly·이십팔 좌표의 실제 뜻: learner V001 파일을 raw 문자열로 읽으며 hash pin이나 SQL inspection을 하지 않는다. 근거 원문은 F04-C02 원문 〔$v001=Get-Content -Raw (Join-Path $project 'src/main/resources/db/migration/V001__common.sql')〕다.
|
| 29줄F04-L29 | $drillSql= |
컨테이너 실험실 다중 drill owner의 raw assembly·이십구 좌표 안내는 ‘$drillSql에 현재 식 Get-Content -Raw (Join-Path $root 'sql/w17/reconcile-drill.sql')의 평가값을 할당한다’ 작업만 지시한다. | 다중 drill owner의 raw assembly·이십구 좌표의 실제 뜻: $drillSql에 현재 식 Get-Content -Raw (Join-Path $root 'sql/w17/reconcile-drill.sql')의 평가값을 할당한다. 근거 원문은 F04-C02 원문 〔$drillSql=Get-Content -Raw (Join-Path $root 'sql/w17/reconcile-drill.sql')〕다.
|
| 30줄F04-L30 | $sql= |
SQL 검수대의 다중 drill owner의 raw assembly·삼십 좌표 한 동작은 fresh w17_drill DROP/CREATE/search_path 앞에 두고 raw V001과 packaged drill을 한 SQL 문자열로 합친다. | 다중 drill owner의 raw assembly·삼십 좌표의 실제 뜻: fresh w17_drill DROP/CREATE/search_path 앞에 두고 raw V001과 packaged drill을 한 SQL 문자열로 합친다. 근거 원문은 F04-C02 원문 〔$sql="DO ˋ$ddlˋ$ BEGIN IF EXISTS(SELECT 1 FROM pg_namespace WHERE nspname='w17_drill') THEN E…〕다.
|
| 31줄F04-L31 | } |
원장 대사 시뮬레이터 다중 drill owner의 raw assembly·삼십일 좌표 단추는 Ranking/non-Ranking source selection의 마지막 delimiter를 닫는다. | 다중 drill owner의 raw assembly·삼십일 좌표의 실제 뜻: Ranking/non-Ranking source selection의 마지막 delimiter를 닫는다. 근거 원문은 F04-C02 원문 〔}〕다.
|
| 33줄F04-L33 | $compose= |
다중 drill owner의 runtime ownership·삼십삼 좌표는 Compose·지정 Container 소유권 점검표에서 ‘$compose에 현재 식 Join-Path $root 'compose.yaml'의 평가값을 할당한다’ 봉투에 대응한다. | 다중 drill owner의 runtime ownership·삼십삼 좌표의 실제 뜻: $compose에 현재 식 Join-Path $root 'compose.yaml'의 평가값을 할당한다. 근거 원문은 F04-C03 원문 〔$compose=Join-Path $root 'compose.yaml'〕다.
|
| 34줄F04-L34 | $owned= |
STARRY 운영실의 다중 drill owner의 runtime ownership·삼십사 좌표 스위치는 ‘Compose resource ownership flag를 false로 시작한다’라는 현재 동작만 맡는다. | 다중 drill owner의 runtime ownership·삼십사 좌표의 실제 뜻: Compose resource ownership flag를 false로 시작한다. 근거 원문은 F04-C03 원문 〔$owned=$false〕다.
|
| 35줄F04-L35 | try{ |
대사 실험대 다중 drill owner의 runtime ownership·삼십오 좌표 레버를 당기면 runner try scope header try{가 child 범위를 연다. body는 아직 실행되지 않았다. | 다중 drill owner의 runtime ownership·삼십오 좌표의 실제 뜻: runner try scope header try{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C03 원문 〔try{〕다.
|
| 36줄F04-L36 | if( |
검증 관제판의 다중 drill owner의 runtime ownership·삼십육 좌표 표식은 ‘Compose mode condition header if($Mode-eq'Compose'){가 child 범위를 연다. body는 아직 실행되지 않았다’ 상태 전환을 가리킨다. | 다중 drill owner의 runtime ownership·삼십육 좌표의 실제 뜻: Compose mode condition header if($Mode-eq'Compose'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C03 원문 〔if($Mode-eq'Compose'){〕다.
|
| 37줄F04-L37 | if( |
격리 장부 다중 drill owner의 runtime ownership·삼십칠 좌표 절차 카드는 ‘조건식 if($Container){throw 'W17 Compose mode rejects -Container'}의 참·거짓을 평가한다’라고 읽는다. | 다중 drill owner의 runtime ownership·삼십칠 좌표의 실제 뜻: 조건식 if($Container){throw 'W17 Compose mode rejects -Container'}의 참·거짓을 평가한다. 근거 원문은 F04-C03 원문 〔if($Container){throw 'W17 Compose mode rejects -Container'}〕다.
|
| 38줄F04-L38 | if( |
증거 포장대의 다중 drill owner의 runtime ownership·삼십팔 좌표 봉인 공정은 조건식 if([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)){$env:FCL_DB_PASSWORD='w17-disposable-p…의 참·거짓을 평가한다. | 다중 drill owner의 runtime ownership·삼십팔 좌표의 실제 뜻: 조건식 if([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)){$env:FCL_DB_PASSWORD='w17-disposable-p…의 참·거짓을 평가한다. 근거 원문은 F04-C03 원문 〔if([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)){$env:FCL_DB_PASSWORD='w17-disposable-p…〕다.
|
| 39줄F04-L39 | & docker compose -f $compose -p $ComposeProject up -d --wait db |
실패 폐쇄형 통로에서 다중 drill owner의 runtime ownership·삼십구 좌표 문턱은 ‘native Compose command & docker compose -f $compose -p $ComposeProject up -d --wait db를 호출한다’ 역할이다. | 다중 drill owner의 runtime ownership·삼십구 좌표의 실제 뜻: native Compose command & docker compose -f $compose -p $ComposeProject up -d --wait db를 호출한다. 근거 원문은 F04-C03 원문 〔& docker compose -f $compose -p $ComposeProject up -d --wait db〕다.
|
| 40줄F04-L40 | if( |
컨테이너 실험실 다중 drill owner의 runtime ownership·사십 좌표 안내는 ‘compose up의 native exit가 0이 아니면 즉시 실패시킨다’ 작업만 지시한다. | 다중 drill owner의 runtime ownership·사십 좌표의 실제 뜻: compose up의 native exit가 0이 아니면 즉시 실패시킨다. 근거 원문은 F04-C03 원문 〔if($LASTEXITCODE-ne 0){throw "W17 compose up exit=$LASTEXITCODE"}〕다.
|
| 41줄F04-L41 | $owned= |
SQL 검수대의 다중 drill owner의 runtime ownership·사십일 좌표 한 동작은 성공한 Compose up 뒤에만 owned를 true로 바꾼다. | 다중 drill owner의 runtime ownership·사십일 좌표의 실제 뜻: 성공한 Compose up 뒤에만 owned를 true로 바꾼다. 근거 원문은 F04-C03 원문 〔$owned=$true〕다.
|
| 42줄F04-L42 | $Container= |
원장 대사 시뮬레이터 다중 drill owner의 runtime ownership·사십이 좌표 단추는 $Container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. | 다중 drill owner의 runtime ownership·사십이 좌표의 실제 뜻: $Container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. 근거 원문은 F04-C03 원문 〔$Container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim()〕다.
|
| 43줄F04-L43 | }elseif( |
파일 증거 조립선 다중 drill owner의 runtime ownership·사십삼 좌표 공정이 맡은 일은 mode selection with Container requirement의 마지막 delimiter를 닫는다. | 다중 drill owner의 runtime ownership·사십삼 좌표의 실제 뜻: mode selection with Container requirement의 마지막 delimiter를 닫는다. 근거 원문은 F04-C03 원문 〔}elseif([string]::IsNullOrWhiteSpace($Container)){throw 'W17 Container mode requires -Contain…〕다.
|
| 44줄F04-L44 | if( |
다중 drill owner의 runtime ownership·사십사 좌표는 Compose·지정 Container 소유권 점검표에서 ‘조건식 if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}의 참·거짓을 평가한다’ 봉투에 대응한다. | 다중 drill owner의 runtime ownership·사십사 좌표의 실제 뜻: 조건식 if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}의 참·거짓을 평가한다. 근거 원문은 F04-C03 원문 〔if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}〕다.
|
| 46줄F04-L46 | if( |
대사 실험대 다중 drill owner의 Ranking multiset oracle·사십육 좌표 레버를 당기면 Ranking execution condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. | 다중 drill owner의 Ranking multiset oracle·사십육 좌표의 실제 뜻: Ranking execution condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C04 원문 〔if($Drill-eq'Ranking'){〕다.
|
| 47줄F04-L47 | $out= |
검증 관제판의 다중 drill owner의 Ranking multiset oracle·사십칠 좌표 표식은 ‘Ranking SQL을 psql에 pipe하고 stdout·stderr를 out 배열로 모은다’ 상태 전환을 가리킨다. | 다중 drill owner의 Ranking multiset oracle·사십칠 좌표의 실제 뜻: Ranking SQL을 psql에 pipe하고 stdout·stderr를 out 배열로 모은다. 근거 원문은 F04-C04 원문 〔$out=@($sql|docker exec -i $Container psql -X -q -A -t -F '|' -v ON_ERROR_STOP=1 -U app -d fi…〕다.
|
| 48줄F04-L48 | $exit= |
격리 장부 다중 drill owner의 Ranking multiset oracle·사십팔 좌표 절차 카드는 ‘$exit에 현재 식 $LASTEXITCODE의 평가값을 할당한다’라고 읽는다. | 다중 drill owner의 Ranking multiset oracle·사십팔 좌표의 실제 뜻: $exit에 현재 식 $LASTEXITCODE의 평가값을 할당한다. 근거 원문은 F04-C04 원문 〔$exit=$LASTEXITCODE〕다.
|
| 49줄F04-L49 | if( |
증거 포장대의 다중 drill owner의 Ranking multiset oracle·사십구 좌표 봉인 공정은 조건식 if($exit-ne0){throw "W17 ranking psql exit=$exitˋn$($out-join"ˋn")"}의 참·거짓을 평가한다. | 다중 drill owner의 Ranking multiset oracle·사십구 좌표의 실제 뜻: 조건식 if($exit-ne0){throw "W17 ranking psql exit=$exitˋn$($out-join"ˋn")"}의 참·거짓을 평가한다. 근거 원문은 F04-C04 원문 〔if($exit-ne0){throw "W17 ranking psql exit=$exitˋn$($out-join"ˋn")"}〕다.
|
| 50줄F04-L50 | $actual= |
실패 폐쇄형 통로에서 다중 drill owner의 Ranking multiset oracle·오십 좌표 문턱은 ‘공백 제거 뒤 숫자 다섯 field인 줄만 actual 배열에 남긴다’ 역할이다. | 다중 drill owner의 Ranking multiset oracle·오십 좌표의 실제 뜻: 공백 제거 뒤 숫자 다섯 field인 줄만 actual 배열에 남긴다. 근거 원문은 F04-C04 원문 〔$actual=@($out|ForEach-Object{([string]$_)-replace'\s',''}|Where-Object{$_-match'^\d+\|\d+\|\…〕다.
|
| 51줄F04-L51 | $expected= |
컨테이너 실험실 다중 drill owner의 Ranking multiset oracle·오십일 좌표 안내는 ‘네 Ranking oracle 행을 expected 배열에 고정한다’ 작업만 지시한다. | 다중 drill owner의 Ranking multiset oracle·오십일 좌표의 실제 뜻: 네 Ranking oracle 행을 expected 배열에 고정한다. 근거 원문은 F04-C04 원문 〔$expected=@('1|100|1|1|1','2|100|2|1|1','3|80|3|3|2','4|70|4|4|3')〕다.
|
| 52줄F04-L52 | if( |
SQL 검수대의 다중 drill owner의 Ranking multiset oracle·오십이 좌표 한 동작은 Compare-Object로 expected와 actual의 행 membership·multiplicity 차이를 찾는다. | 다중 drill owner의 Ranking multiset oracle·오십이 좌표의 실제 뜻: Compare-Object로 expected와 actual의 행 membership·multiplicity 차이를 찾는다. 근거 원문은 F04-C04 원문 〔if(Compare-Object $expected $actual){throw "W17 ranking exact rows mismatch expected=$expecte…〕다.
|
| 53줄F04-L53 | $sourceHash= |
원장 대사 시뮬레이터 다중 drill owner의 Ranking multiset oracle·오십삼 좌표 단추는 learner Ranking file SHA-256을 계산해 소문자로 만든다. | 다중 drill owner의 Ranking multiset oracle·오십삼 좌표의 실제 뜻: learner Ranking file SHA-256을 계산해 소문자로 만든다. 근거 원문은 F04-C04 원문 〔$sourceHash=(Get-FileHash -LiteralPath $ranking -Algorithm SHA256).Hash.ToLowerInvariant()〕다.
|
| 54줄F04-L54 | $target= |
파일 증거 조립선 다중 drill owner의 Ranking multiset oracle·오십사 좌표 공정이 맡은 일은 ranking-result.txt target 경로를 만든다. | 다중 drill owner의 Ranking multiset oracle·오십사 좌표의 실제 뜻: ranking-result.txt target 경로를 만든다. 근거 원문은 F04-C04 원문 〔$target=Join-Path $e 'ranking-result.txt'〕다.
|
| 55줄F04-L55 | $lines= |
다중 drill owner의 Ranking multiset oracle·오십오 좌표는 Ranking 실행과 행 multiset oracle 점검표에서 ‘$lines에 현재 식 @('W17_RANKING_RESULT','rows=4','ties=rank-1-1-dense-1-1',"source_sha256=$sourceHash",'native…의 평가값을 할당한다’ 봉투에 대응한다. | 다중 drill owner의 Ranking multiset oracle·오십오 좌표의 실제 뜻: $lines에 현재 식 @('W17_RANKING_RESULT','rows=4','ties=rank-1-1-dense-1-1',"source_sha256=$sourceHash",'native…의 평가값을 할당한다. 근거 원문은 F04-C04 원문 〔$lines=@('W17_RANKING_RESULT','rows=4','ties=rank-1-1-dense-1-1',"source_sha256=$sourceHash",…〕다.
|
| 56줄F04-L56 | $lines+ |
STARRY 운영실의 다중 drill owner의 Ranking multiset oracle·오십육 좌표 스위치는 ‘pipeline stage $lines+=@($actual|ForEach-Object{"row=$_"})로 왼쪽 값을 오른쪽 command에 전달한다’라는 현재 동작만 맡는다. | 다중 drill owner의 Ranking multiset oracle·오십육 좌표의 실제 뜻: pipeline stage $lines+=@($actual|ForEach-Object{"row=$_"})로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F04-C04 원문 〔$lines+=@($actual|ForEach-Object{"row=$_"})〕다.
|
| 57줄F04-L57 | $lines|Set-Content -Encoding utf8 $target |
대사 실험대 다중 drill owner의 Ranking multiset oracle·오십칠 좌표 레버를 당기면 현재 pipeline payload를 $lines|Set-Content -Encoding utf8 $target 대상에 쓴다. | 다중 drill owner의 Ranking multiset oracle·오십칠 좌표의 실제 뜻: 현재 pipeline payload를 $lines|Set-Content -Encoding utf8 $target 대상에 쓴다. 근거 원문은 F04-C04 원문 〔$lines|Set-Content -Encoding utf8 $target〕다.
|
| 58줄F04-L58 | "W17_RANKING_GREEN rows= |
검증 관제판의 다중 drill owner의 Ranking multiset oracle·오십팔 좌표 표식은 ‘Ranking oracle and evidence branch의 마지막 delimiter를 닫는다’ 상태 전환을 가리킨다. | 다중 drill owner의 Ranking multiset oracle·오십팔 좌표의 실제 뜻: Ranking oracle and evidence branch의 마지막 delimiter를 닫는다. 근거 원문은 F04-C04 원문 〔"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sour…〕다.
|
| 59줄F04-L59 | }else{ |
격리 장부 다중 drill owner의 transcript presence gate·오십구 좌표 절차 카드는 ‘Reconcile·Savepoint execution branch header }else{가 child 범위를 연다. body는 아직 실행되지 않았다’라고 읽는다. | 다중 drill owner의 transcript presence gate·오십구 좌표의 실제 뜻: Reconcile·Savepoint execution branch header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔}else{〕다.
|
| 60줄F04-L60 | $out= |
증거 포장대의 다중 drill owner의 transcript presence gate·육십 좌표 봉인 공정은 $out에 현재 식 @($sql|docker exec -i $Container psql -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)의 평가값을 할당한다. | 다중 drill owner의 transcript presence gate·육십 좌표의 실제 뜻: $out에 현재 식 @($sql|docker exec -i $Container psql -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$out=@($sql|docker exec -i $Container psql -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)〕다.
|
| 61줄F04-L61 | $exit= |
실패 폐쇄형 통로에서 다중 drill owner의 transcript presence gate·육십일 좌표 문턱은 ‘$exit에 현재 식 $LASTEXITCODE의 평가값을 할당한다’ 역할이다. | 다중 drill owner의 transcript presence gate·육십일 좌표의 실제 뜻: $exit에 현재 식 $LASTEXITCODE의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$exit=$LASTEXITCODE〕다.
|
| 62줄F04-L62 | $name= |
컨테이너 실험실 다중 drill owner의 transcript presence gate·육십이 좌표 안내는 ‘$name에 현재 식 if($Drill-eq'Savepoint'){'savepoint-transcript.txt'}else{'reconcile-transcript.txt'}의 평가값을 할당한다’ 작업만 지시한다. | 다중 drill owner의 transcript presence gate·육십이 좌표의 실제 뜻: $name에 현재 식 if($Drill-eq'Savepoint'){'savepoint-transcript.txt'}else{'reconcile-transcript.txt'}의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$name=if($Drill-eq'Savepoint'){'savepoint-transcript.txt'}else{'reconcile-transcript.txt'}〕다.
|
| 63줄F04-L63 | $target= |
SQL 검수대의 다중 drill owner의 transcript presence gate·육십삼 좌표 한 동작은 $target에 현재 식 Join-Path $e $name의 평가값을 할당한다. | 다중 drill owner의 transcript presence gate·육십삼 좌표의 실제 뜻: $target에 현재 식 Join-Path $e $name의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$target=Join-Path $e $name〕다.
|
| 64줄F04-L64 | $out|Set-Content -Encoding utf8 $target |
원장 대사 시뮬레이터 다중 drill owner의 transcript presence gate·육십사 좌표 단추는 reconcile/savepoint native output을 marker 검사 전에 transcript target에 쓴다. | 다중 drill owner의 transcript presence gate·육십사 좌표의 실제 뜻: reconcile/savepoint native output을 marker 검사 전에 transcript target에 쓴다. 근거 원문은 F04-C05 원문 〔$out|Set-Content -Encoding utf8 $target〕다.
|
| 65줄F04-L65 | if( |
파일 증거 조립선 다중 drill owner의 transcript presence gate·육십오 좌표 공정이 맡은 일은 조건식 if($exit-ne 0){throw "W17 psql exit=$exitˋn$($out-join"ˋn")"}의 참·거짓을 평가한다. | 다중 drill owner의 transcript presence gate·육십오 좌표의 실제 뜻: 조건식 if($exit-ne 0){throw "W17 psql exit=$exitˋn$($out-join"ˋn")"}의 참·거짓을 평가한다. 근거 원문은 F04-C05 원문 〔if($exit-ne 0){throw "W17 psql exit=$exitˋn$($out-join"ˋn")"}〕다.
|
| 66줄F04-L66 | $text= |
다중 drill owner의 transcript presence gate·육십육 좌표는 대사·savepoint transcript와 marker 점검표에서 ‘$text에 현재 식 $out-join"ˋn"의 평가값을 할당한다’ 봉투에 대응한다. | 다중 drill owner의 transcript presence gate·육십육 좌표의 실제 뜻: $text에 현재 식 $out-join"ˋn"의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$text=$out-join"ˋn"〕다.
|
| 67줄F04-L67 | foreach( |
STARRY 운영실의 다중 drill owner의 transcript presence gate·육십칠 좌표 스위치는 ‘required marker iteration header foreach($marker in @('W17_BASELINE=0','W17_INJECTED=1','W17_RESTORED=0')){가 child 범위를 연다. body는 아직 실행되지 않았다’라는 현재 동작만 맡는다. | 다중 drill owner의 transcript presence gate·육십칠 좌표의 실제 뜻: required marker iteration header foreach($marker in @('W17_BASELINE=0','W17_INJECTED=1','W17_RESTORED=0')){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔foreach($marker in @('W17_BASELINE=0','W17_INJECTED=1','W17_RESTORED=0')){〕다.
|
| 68줄F04-L68 | if( |
대사 실험대 다중 drill owner의 transcript presence gate·육십팔 좌표 레버를 당기면 joined transcript에 현재 marker substring이 하나라도 있는지 본다. | 다중 drill owner의 transcript presence gate·육십팔 좌표의 실제 뜻: joined transcript에 현재 marker substring이 하나라도 있는지 본다. 근거 원문은 F04-C05 원문 〔if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"}〕다.
|
| 69줄F04-L69 | } |
검증 관제판의 다중 drill owner의 transcript presence gate·육십구 좌표 표식은 ‘three-marker presence loop의 마지막 delimiter를 닫는다’ 상태 전환을 가리킨다. | 다중 drill owner의 transcript presence gate·육십구 좌표의 실제 뜻: three-marker presence loop의 마지막 delimiter를 닫는다. 근거 원문은 F04-C05 원문 〔}〕다.
|
| 70줄F04-L70 | $hash= |
격리 장부 다중 drill owner의 transcript presence gate·칠십 좌표 절차 카드는 ‘검사를 통과한 transcript file의 SHA-256을 계산한다’라고 읽는다. | 다중 drill owner의 transcript presence gate·칠십 좌표의 실제 뜻: 검사를 통과한 transcript file의 SHA-256을 계산한다. 근거 원문은 F04-C05 원문 〔$hash=(Get-FileHash -LiteralPath $target -Algorithm SHA256).Hash.ToLowerInvariant()〕다.
|
| 71줄F04-L71 | if( |
증거 포장대의 다중 drill owner의 drill Green selection·칠십일 좌표 봉인 공정은 Savepoint Green selection header if($Drill-eq'Savepoint'){가 child 범위를 연다. body는 아직 실행되지 않았다. | 다중 drill owner의 drill Green selection·칠십일 좌표의 실제 뜻: Savepoint Green selection header if($Drill-eq'Savepoint'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔if($Drill-eq'Savepoint'){〕다.
|
| 72줄F04-L72 | "W17_SAVEPOINT_GREEN injected= |
실패 폐쇄형 통로에서 다중 drill owner의 drill Green selection·칠십이 좌표 문턱은 ‘현재 success/failure summary literal "W17_SAVEPOINT_GREEN injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"을 output stream에 보낸다’ 역할이다. | 다중 drill owner의 drill Green selection·칠십이 좌표의 실제 뜻: 현재 success/failure summary literal "W17_SAVEPOINT_GREEN injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"을 output stream에 보낸다. 근거 원문은 F04-C05 원문 〔"W17_SAVEPOINT_GREEN injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"〕다.
|
| 73줄F04-L73 | }else{ |
컨테이너 실험실 다중 drill owner의 drill Green selection·칠십삼 좌표 안내는 ‘Reconcile Green selection header }else{가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | 다중 drill owner의 drill Green selection·칠십삼 좌표의 실제 뜻: Reconcile Green selection header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔}else{〕다.
|
| 74줄F04-L74 | "W17_RECONCILE_GREEN baseline= |
SQL 검수대의 다중 drill owner의 drill Green selection·칠십사 좌표 한 동작은 현재 success/failure summary literal "W17_RECONCILE_GREEN baseline=0 injected=1 restored=0 transcript_sha256=$hash native_exit=0 c…을 output stream에 보낸다. | 다중 drill owner의 drill Green selection·칠십사 좌표의 실제 뜻: 현재 success/failure summary literal "W17_RECONCILE_GREEN baseline=0 injected=1 restored=0 transcript_sha256=$hash native_exit=0 c…을 output stream에 보낸다. 근거 원문은 F04-C05 원문 〔"W17_RECONCILE_GREEN baseline=0 injected=1 restored=0 transcript_sha256=$hash native_exit=0 c…〕다.
|
| 75줄F04-L75 | } |
원장 대사 시뮬레이터 다중 drill owner의 drill Green selection·칠십오 좌표 단추는 Savepoint/Reconcile Green selection의 마지막 delimiter를 닫는다. | 다중 drill owner의 drill Green selection·칠십오 좌표의 실제 뜻: Savepoint/Reconcile Green selection의 마지막 delimiter를 닫는다. 근거 원문은 F04-C05 원문 〔}〕다.
|
| 76줄F04-L76 | } |
파일 증거 조립선 다중 drill owner의 drill Green selection·칠십육 좌표 공정이 맡은 일은 drill execution branch의 마지막 delimiter를 닫는다. | 다중 drill owner의 drill Green selection·칠십육 좌표의 실제 뜻: drill execution branch의 마지막 delimiter를 닫는다. 근거 원문은 F04-C05 원문 〔}〕다.
|
| 77줄F04-L77 | }finally{ |
다중 drill owner의 owned cleanup·칠십칠 좌표는 소유한 Compose 정리 점검표에서 ‘finally cleanup scope header }finally{가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | 다중 drill owner의 owned cleanup·칠십칠 좌표의 실제 뜻: finally cleanup scope header }finally{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C06 원문 〔}finally{〕다.
|
| 78줄F04-L78 | if( |
STARRY 운영실의 다중 drill owner의 owned cleanup·칠십팔 좌표 스위치는 ‘owned-resource cleanup condition header if($owned){가 child 범위를 연다. body는 아직 실행되지 않았다’라는 현재 동작만 맡는다. | 다중 drill owner의 owned cleanup·칠십팔 좌표의 실제 뜻: owned-resource cleanup condition header if($owned){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C06 원문 〔if($owned){〕다.
|
| 79줄F04-L79 | & docker compose -f $compose -p $ComposeProject down -v|Out-Null |
대사 실험대 다중 drill owner의 owned cleanup·칠십구 좌표 레버를 당기면 owned Compose project에 down -v를 요청한다. | 다중 drill owner의 owned cleanup·칠십구 좌표의 실제 뜻: owned Compose project에 down -v를 요청한다. 근거 원문은 F04-C06 원문 〔& docker compose -f $compose -p $ComposeProject down -v|Out-Null〕다.
|
| 80줄F04-L80 | if( |
검증 관제판의 다중 drill owner의 owned cleanup·팔십 좌표 표식은 ‘Compose cleanup native exit가 nonzero면 실패시킨다’ 상태 전환을 가리킨다. | 다중 drill owner의 owned cleanup·팔십 좌표의 실제 뜻: Compose cleanup native exit가 nonzero면 실패시킨다. 근거 원문은 F04-C06 원문 〔if($LASTEXITCODE-ne 0){throw 'W17 compose cleanup failed'}〕다.
|
| 81줄F04-L81 | } |
격리 장부 다중 drill owner의 owned cleanup·팔십일 좌표 절차 카드는 ‘owned Compose cleanup guard의 마지막 delimiter를 닫는다’라고 읽는다. | 다중 drill owner의 owned cleanup·팔십일 좌표의 실제 뜻: owned Compose cleanup guard의 마지막 delimiter를 닫는다. 근거 원문은 F04-C06 원문 〔}〕다.
|
| 82줄F04-L82 | } |
증거 포장대의 다중 drill owner의 owned cleanup·팔십이 좌표 봉인 공정은 runner finally block의 마지막 delimiter를 닫는다. | 다중 drill owner의 owned cleanup·팔십이 좌표의 실제 뜻: runner finally block의 마지막 delimiter를 닫는다. 근거 원문은 F04-C06 원문 〔}〕다.
|
Ranking의 네 행히토리 → 니지카 → 료 → 키타
-
히토리
expected 배열 순서대로 출력해야 통과하나요?
-
니지카
Compare-Object는 기본적으로 membership과 multiplicity를 비교해.
-
료
게다가 numeric five-field가 아닌 줄은 filter에서 사라진다.
-
키타
unordered numeric multiset이라고 표시하겠습니다.
STEP 05 / 13
원본 코드 조각
원본을 6개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 hash로 고정한 native 정본 source에서 그대로 잘랐습니다.
param(
[ValidateSet('Compose','Container')][string]$Mode='Compose',
[ValidateSet('Reconcile','Ranking','Savepoint')][string]$Drill='Reconcile',
[string]$Container='',
[string]$ComposeProject='w17-reconcile-lab',
[Parameter(Mandatory=$true)][string]$ProjectRoot,
[Parameter(Mandatory=$true)][string]$EvidenceDir,
[string]$SqlPath=''
)
$ErrorActionPreference='Stop'
$root=Split-Path -Parent $PSScriptRoot
if(-not [IO.Path]::IsPathRooted($ProjectRoot)){throw 'ProjectRoot must be an absolute learner project path'}
if(-not [IO.Path]::IsPathRooted($EvidenceDir)){throw 'EvidenceDir must be an absolute learner-owned path'}
$project=(Resolve-Path -LiteralPath $ProjectRoot).Path
$e=[IO.Path]::GetFullPath($EvidenceDir)
New-Item -ItemType Directory -Force $e|Out-Null
if($Drill-eq'Ranking'){
if([string]::IsNullOrWhiteSpace($SqlPath)-or-not[IO.Path]::IsPathRooted($SqlPath)){throw 'Ranking requires an absolute learner-owned -SqlPath'}
$ranking=(Resolve-Path -LiteralPath $SqlPath).Path
$learnerSql=Get-Content -Raw -LiteralPath $ranking
foreach($pattern in @('\bROW_NUMBER\s*\(','(?<!DENSE_)\bRANK\s*\(','\bDENSE_RANK\s*\(','ORDER\s+BY\s+amount\s+DESC','account_id')){
if($learnerSql-cnotmatch $pattern){throw "ranking.sql missing required construct: $pattern"}
}
if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an unresolved placeholder'}
$sql=$learnerSql
}else{
$v001=Get-Content -Raw (Join-Path $project 'src/main/resources/db/migration/V001__common.sql')
$drillSql=Get-Content -Raw (Join-Path $root 'sql/w17/reconcile-drill.sql')
$sql="DO `$ddl`$ BEGIN IF EXISTS(SELECT 1 FROM pg_namespace WHERE nspname='w17_drill') THEN EXECUTE 'DROP SCHEMA w17_drill CASCADE'; END IF; END `$ddl`$; CREATE SCHEMA w17_drill; SET search_path TO w17_drill;`n$v001`n$drillSql"
}
$compose=Join-Path $root 'compose.yaml'
$owned=$false
try{
if($Mode-eq'Compose'){
if($Container){throw 'W17 Compose mode rejects -Container'}
if([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)){$env:FCL_DB_PASSWORD='w17-disposable-password'}
& docker compose -f $compose -p $ComposeProject up -d --wait db
if($LASTEXITCODE-ne 0){throw "W17 compose up exit=$LASTEXITCODE"}
$owned=$true
$Container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim()
}elseif([string]::IsNullOrWhiteSpace($Container)){throw 'W17 Container mode requires -Container'}
if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}
if($Drill-eq'Ranking'){
$out=@($sql|docker exec -i $Container psql -X -q -A -t -F '|' -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)
$exit=$LASTEXITCODE
if($exit-ne0){throw "W17 ranking psql exit=$exit`n$($out-join"`n")"}
$actual=@($out|ForEach-Object{([string]$_)-replace'\s',''}|Where-Object{$_-match'^\d+\|\d+\|\d+\|\d+\|\d+$'})
$expected=@('1|100|1|1|1','2|100|2|1|1','3|80|3|3|2','4|70|4|4|3')
if(Compare-Object $expected $actual){throw "W17 ranking exact rows mismatch expected=$expected actual=$actual"}
$sourceHash=(Get-FileHash -LiteralPath $ranking -Algorithm SHA256).Hash.ToLowerInvariant()
$target=Join-Path $e 'ranking-result.txt'
$lines=@('W17_RANKING_RESULT','rows=4','ties=rank-1-1-dense-1-1',"source_sha256=$sourceHash",'native_exit=0')
$lines+=@($actual|ForEach-Object{"row=$_"})
$lines|Set-Content -Encoding utf8 $target
"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sourceHash native_exit=0 cleanup=1"
}else{
$out=@($sql|docker exec -i $Container psql -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)
$exit=$LASTEXITCODE
$name=if($Drill-eq'Savepoint'){'savepoint-transcript.txt'}else{'reconcile-transcript.txt'}
$target=Join-Path $e $name
$out|Set-Content -Encoding utf8 $target
if($exit-ne 0){throw "W17 psql exit=$exit`n$($out-join"`n")"}
$text=$out-join"`n"
foreach($marker in @('W17_BASELINE=0','W17_INJECTED=1','W17_RESTORED=0')){
if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"}
}
$hash=(Get-FileHash -LiteralPath $target -Algorithm SHA256).Hash.ToLowerInvariant()
if($Drill-eq'Savepoint'){
"W17_SAVEPOINT_GREEN injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"
}else{
"W17_RECONCILE_GREEN baseline=0 injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"
}
}
}finally{
if($owned){
& docker compose -f $compose -p $ComposeProject down -v|Out-Null
if($LASTEXITCODE-ne 0){throw 'W17 compose cleanup failed'}
}
}
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 79줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | param( | 다중 drill owner의 parameter contract·일 좌표의 실제 뜻: multi-drill runner parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C01 원문 〔param(〕다. |
| 2 | [ValidateSet('Compose','Container')][string]$Mode='Compose', | 다중 drill owner의 parameter contract·이 좌표의 실제 뜻: parameter binder에 $Mode 선언과 기본값 'Compose' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[ValidateSet('Compose','Container')][string]$Mode='Compose',〕다. |
| 3 | [ValidateSet('Reconcile','Ranking','Savepoint')][string]$Drill='Reconcile', | 다중 drill owner의 parameter contract·삼 좌표의 실제 뜻: parameter binder에 $Drill 선언과 기본값 'Reconcile' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[ValidateSet('Reconcile','Ranking','Savepoint')][string]$Drill='Reconcile',〕다. |
| 4 | [string]$Container='', | 다중 drill owner의 parameter contract·사 좌표의 실제 뜻: parameter binder에 $Container 선언과 기본값 '' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[string]$Container='',〕다. |
| 5 | [string]$ComposeProject='w17-reconcile-lab', | 다중 drill owner의 parameter contract·오 좌표의 실제 뜻: parameter binder에 $ComposeProject 선언과 기본값 'w17-reconcile-lab' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[string]$ComposeProject='w17-reconcile-lab',〕다. |
| 6 | [Parameter(Mandatory=$true)][string]$ProjectRoot, | 다중 drill owner의 parameter contract·육 좌표의 실제 뜻: parameter binder에 $ProjectRoot 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[Parameter(Mandatory=$true)][string]$ProjectRoot,〕다. |
| 7 | [Parameter(Mandatory=$true)][string]$EvidenceDir, | 다중 drill owner의 parameter contract·칠 좌표의 실제 뜻: parameter binder에 $EvidenceDir 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[Parameter(Mandatory=$true)][string]$EvidenceDir,〕다. |
| 8 | [string]$SqlPath='' | 다중 drill owner의 parameter contract·팔 좌표의 실제 뜻: parameter binder에 $SqlPath 선언과 기본값 '' 계약을 추가한다. 근거 원문은 F04-C01 원문 〔[string]$SqlPath=''〕다. |
| 9 | ) | 다중 drill owner의 parameter contract·구 좌표의 실제 뜻: script parameter list의 마지막 delimiter를 닫는다. 근거 원문은 F04-C01 원문 〔)〕다. |
| 10 | $ErrorActionPreference='Stop' | 다중 drill owner의 absolute-path setup·십 좌표의 실제 뜻: PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. 근거 원문은 F04-C01 원문 〔$ErrorActionPreference='Stop'〕다. |
| 11 | $root=Split-Path -Parent $PSScriptRoot | 다중 drill owner의 absolute-path setup·십일 좌표의 실제 뜻: $root에 현재 식 Split-Path -Parent $PSScriptRoot의 평가값을 할당한다. 근거 원문은 F04-C01 원문 〔$root=Split-Path -Parent $PSScriptRoot〕다. |
| 12 | if(-not [IO.Path]::IsPathRooted($ProjectRoot)){throw 'ProjectRoot must be an absolute learner project path'} | 다중 drill owner의 absolute-path setup·십이 좌표의 실제 뜻: 조건식 if(-not [IO.Path]::IsPathRooted($ProjectRoot)){throw 'ProjectRoot must be an absolute learner…의 참·거짓을 평가한다. 근거 원문은 F04-C01 원문 〔if(-not [IO.Path]::IsPathRooted($ProjectRoot)){throw 'ProjectRoot must be an absolute learner…〕다. |
| 13 | if(-not [IO.Path]::IsPathRooted($EvidenceDir)){throw 'EvidenceDir must be an absolute learner-owned path'} | 다중 drill owner의 absolute-path setup·십삼 좌표의 실제 뜻: 조건식 if(-not [IO.Path]::IsPathRooted($EvidenceDir)){throw 'EvidenceDir must be an absolute learner…의 참·거짓을 평가한다. 근거 원문은 F04-C01 원문 〔if(-not [IO.Path]::IsPathRooted($EvidenceDir)){throw 'EvidenceDir must be an absolute learner…〕다. |
| 14 | $project=(Resolve-Path -LiteralPath $ProjectRoot).Path | 다중 drill owner의 absolute-path setup·십사 좌표의 실제 뜻: $project에 현재 식 (Resolve-Path -LiteralPath $ProjectRoot).Path의 평가값을 할당한다. 근거 원문은 F04-C01 원문 〔$project=(Resolve-Path -LiteralPath $ProjectRoot).Path〕다. |
| 15 | $e=[IO.Path]::GetFullPath($EvidenceDir) | 다중 drill owner의 absolute-path setup·십오 좌표의 실제 뜻: $e에 현재 식 [IO.Path]::GetFullPath($EvidenceDir)의 평가값을 할당한다. 근거 원문은 F04-C01 원문 〔$e=[IO.Path]::GetFullPath($EvidenceDir)〕다. |
| 16 | New-Item -ItemType Directory -Force $e|Out-Null | 다중 drill owner의 absolute-path setup·십육 좌표의 실제 뜻: pipeline stage New-Item -ItemType Directory -Force $e|Out-Null로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F04-C01 원문 〔New-Item -ItemType Directory -Force $e|Out-Null〕다. |
| 18 | if($Drill-eq'Ranking'){ | 다중 drill owner의 Ranking source inspection·십팔 좌표의 실제 뜻: Ranking drill condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C02 원문 〔if($Drill-eq'Ranking'){〕다. |
| 19 | if([string]::IsNullOrWhiteSpace($SqlPath)-or-not[IO.Path]::IsPathRooted($SqlPath)){throw 'Ranking requires an absolute learner-owned -SqlPath'} | 다중 drill owner의 Ranking source inspection·십구 좌표의 실제 뜻: Ranking SqlPath가 absolute이고 비어 있지 않은지만 검사한다. 근거 원문은 F04-C02 원문 〔if([string]::IsNullOrWhiteSpace($SqlPath)-or-not[IO.Path]::IsPathRooted($SqlPath)){throw 'Ran…〕다. |
| 20 | $ranking=(Resolve-Path -LiteralPath $SqlPath).Path | 다중 drill owner의 Ranking source inspection·이십 좌표의 실제 뜻: $ranking에 현재 식 (Resolve-Path -LiteralPath $SqlPath).Path의 평가값을 할당한다. 근거 원문은 F04-C02 원문 〔$ranking=(Resolve-Path -LiteralPath $SqlPath).Path〕다. |
| 21 | $learnerSql=Get-Content -Raw -LiteralPath $ranking | 다중 drill owner의 Ranking source inspection·이십일 좌표의 실제 뜻: $learnerSql에 현재 식 Get-Content -Raw -LiteralPath $ranking의 평가값을 할당한다. 근거 원문은 F04-C02 원문 〔$learnerSql=Get-Content -Raw -LiteralPath $ranking〕다. |
| 22 | foreach($pattern in @('\bROW_NUMBER\s*\(','(?<!DENSE_)\bRANK\s*\(','\bDENSE_RANK\s*\(','ORDER\s+BY\s+amount\s+DESC','account_id')){ | 다중 drill owner의 Ranking source inspection·이십이 좌표의 실제 뜻: required ranking-pattern iteration header foreach($pattern in @('\bROW_NUMBER\s*\(','(?<!DENSE_)\bRANK\s*\(','\bDENSE_RANK\s*\(','ORDER…가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C02 원문 〔foreach($pattern in @('\bROW_NUMBER\s*\(','(?<!DENSE_)\bRANK\s*\(','\bDENSE_RANK\s*\(','ORDER…〕다. |
| 23 | if($learnerSql-cnotmatch $pattern){throw "ranking.sql missing required construct: $pattern"} | 다중 drill owner의 Ranking source inspection·이십삼 좌표의 실제 뜻: 조건식 if($learnerSql-cnotmatch $pattern){throw "ranking.sql missing required construct: $pattern"}의 참·거짓을 평가한다. 근거 원문은 F04-C02 원문 〔if($learnerSql-cnotmatch $pattern){throw "ranking.sql missing required construct: $pattern"}〕다. |
| 24 | } | 다중 drill owner의 Ranking source inspection·이십사 좌표의 실제 뜻: one required ranking-pattern check의 마지막 delimiter를 닫는다. 근거 원문은 F04-C02 원문 〔}〕다. |
| 25 | if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an unresolved placeholder'} | 다중 drill owner의 Ranking source inspection·이십오 좌표의 실제 뜻: TODO류 placeholder 단어가 있으면 Ranking source를 거절한다. 근거 원문은 F04-C02 원문 〔if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an…〕다. |
| 26 | $sql=$learnerSql | 다중 drill owner의 Ranking source inspection·이십육 좌표의 실제 뜻: $sql에 현재 식 $learnerSql의 평가값을 할당한다. 근거 원문은 F04-C02 원문 〔$sql=$learnerSql〕다. |
| 27 | }else{ | 다중 drill owner의 raw assembly·이십칠 좌표의 실제 뜻: non-Ranking assembly branch header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C02 원문 〔}else{〕다. |
| 28 | $v001=Get-Content -Raw (Join-Path $project 'src/main/resources/db/migration/V001__common.sql') | 다중 drill owner의 raw assembly·이십팔 좌표의 실제 뜻: learner V001 파일을 raw 문자열로 읽으며 hash pin이나 SQL inspection을 하지 않는다. 근거 원문은 F04-C02 원문 〔$v001=Get-Content -Raw (Join-Path $project 'src/main/resources/db/migration/V001__common.sql')〕다. |
| 29 | $drillSql=Get-Content -Raw (Join-Path $root 'sql/w17/reconcile-drill.sql') | 다중 drill owner의 raw assembly·이십구 좌표의 실제 뜻: $drillSql에 현재 식 Get-Content -Raw (Join-Path $root 'sql/w17/reconcile-drill.sql')의 평가값을 할당한다. 근거 원문은 F04-C02 원문 〔$drillSql=Get-Content -Raw (Join-Path $root 'sql/w17/reconcile-drill.sql')〕다. |
| 30 | $sql="DO `$ddl`$ BEGIN IF EXISTS(SELECT 1 FROM pg_namespace WHERE nspname='w17_drill') THEN EXECUTE 'DROP SCHEMA w17_drill CASCADE'; END IF; END `$ddl`$; CREATE SCHEMA w17_drill; SET search_path TO w17_drill;`n$v001`n$drillSql" | 다중 drill owner의 raw assembly·삼십 좌표의 실제 뜻: fresh w17_drill DROP/CREATE/search_path 앞에 두고 raw V001과 packaged drill을 한 SQL 문자열로 합친다. 근거 원문은 F04-C02 원문 〔$sql="DO ˋ$ddlˋ$ BEGIN IF EXISTS(SELECT 1 FROM pg_namespace WHERE nspname='w17_drill') THEN E…〕다. |
| 31 | } | 다중 drill owner의 raw assembly·삼십일 좌표의 실제 뜻: Ranking/non-Ranking source selection의 마지막 delimiter를 닫는다. 근거 원문은 F04-C02 원문 〔}〕다. |
| 33 | $compose=Join-Path $root 'compose.yaml' | 다중 drill owner의 runtime ownership·삼십삼 좌표의 실제 뜻: $compose에 현재 식 Join-Path $root 'compose.yaml'의 평가값을 할당한다. 근거 원문은 F04-C03 원문 〔$compose=Join-Path $root 'compose.yaml'〕다. |
| 34 | $owned=$false | 다중 drill owner의 runtime ownership·삼십사 좌표의 실제 뜻: Compose resource ownership flag를 false로 시작한다. 근거 원문은 F04-C03 원문 〔$owned=$false〕다. |
| 35 | try{ | 다중 drill owner의 runtime ownership·삼십오 좌표의 실제 뜻: runner try scope header try{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C03 원문 〔try{〕다. |
| 36 | if($Mode-eq'Compose'){ | 다중 drill owner의 runtime ownership·삼십육 좌표의 실제 뜻: Compose mode condition header if($Mode-eq'Compose'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C03 원문 〔if($Mode-eq'Compose'){〕다. |
| 37 | if($Container){throw 'W17 Compose mode rejects -Container'} | 다중 drill owner의 runtime ownership·삼십칠 좌표의 실제 뜻: 조건식 if($Container){throw 'W17 Compose mode rejects -Container'}의 참·거짓을 평가한다. 근거 원문은 F04-C03 원문 〔if($Container){throw 'W17 Compose mode rejects -Container'}〕다. |
| 38 | if([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)){$env:FCL_DB_PASSWORD='w17-disposable-password'} | 다중 drill owner의 runtime ownership·삼십팔 좌표의 실제 뜻: 조건식 if([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)){$env:FCL_DB_PASSWORD='w17-disposable-p…의 참·거짓을 평가한다. 근거 원문은 F04-C03 원문 〔if([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)){$env:FCL_DB_PASSWORD='w17-disposable-p…〕다. |
| 39 | & docker compose -f $compose -p $ComposeProject up -d --wait db | 다중 drill owner의 runtime ownership·삼십구 좌표의 실제 뜻: native Compose command & docker compose -f $compose -p $ComposeProject up -d --wait db를 호출한다. 근거 원문은 F04-C03 원문 〔& docker compose -f $compose -p $ComposeProject up -d --wait db〕다. |
| 40 | if($LASTEXITCODE-ne 0){throw "W17 compose up exit=$LASTEXITCODE"} | 다중 drill owner의 runtime ownership·사십 좌표의 실제 뜻: compose up의 native exit가 0이 아니면 즉시 실패시킨다. 근거 원문은 F04-C03 원문 〔if($LASTEXITCODE-ne 0){throw "W17 compose up exit=$LASTEXITCODE"}〕다. |
| 41 | $owned=$true | 다중 drill owner의 runtime ownership·사십일 좌표의 실제 뜻: 성공한 Compose up 뒤에만 owned를 true로 바꾼다. 근거 원문은 F04-C03 원문 〔$owned=$true〕다. |
| 42 | $Container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim() | 다중 drill owner의 runtime ownership·사십이 좌표의 실제 뜻: $Container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. 근거 원문은 F04-C03 원문 〔$Container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim()〕다. |
| 43 | }elseif([string]::IsNullOrWhiteSpace($Container)){throw 'W17 Container mode requires -Container'} | 다중 drill owner의 runtime ownership·사십삼 좌표의 실제 뜻: mode selection with Container requirement의 마지막 delimiter를 닫는다. 근거 원문은 F04-C03 원문 〔}elseif([string]::IsNullOrWhiteSpace($Container)){throw 'W17 Container mode requires -Contain…〕다. |
| 44 | if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'} | 다중 drill owner의 runtime ownership·사십사 좌표의 실제 뜻: 조건식 if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}의 참·거짓을 평가한다. 근거 원문은 F04-C03 원문 〔if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}〕다. |
| 46 | if($Drill-eq'Ranking'){ | 다중 drill owner의 Ranking multiset oracle·사십육 좌표의 실제 뜻: Ranking execution condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C04 원문 〔if($Drill-eq'Ranking'){〕다. |
| 47 | $out=@($sql|docker exec -i $Container psql -X -q -A -t -F '|' -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1) | 다중 drill owner의 Ranking multiset oracle·사십칠 좌표의 실제 뜻: Ranking SQL을 psql에 pipe하고 stdout·stderr를 out 배열로 모은다. 근거 원문은 F04-C04 원문 〔$out=@($sql|docker exec -i $Container psql -X -q -A -t -F '|' -v ON_ERROR_STOP=1 -U app -d fi…〕다. |
| 48 | $exit=$LASTEXITCODE | 다중 drill owner의 Ranking multiset oracle·사십팔 좌표의 실제 뜻: $exit에 현재 식 $LASTEXITCODE의 평가값을 할당한다. 근거 원문은 F04-C04 원문 〔$exit=$LASTEXITCODE〕다. |
| 49 | if($exit-ne0){throw "W17 ranking psql exit=$exit`n$($out-join"`n")"} | 다중 drill owner의 Ranking multiset oracle·사십구 좌표의 실제 뜻: 조건식 if($exit-ne0){throw "W17 ranking psql exit=$exitˋn$($out-join"ˋn")"}의 참·거짓을 평가한다. 근거 원문은 F04-C04 원문 〔if($exit-ne0){throw "W17 ranking psql exit=$exitˋn$($out-join"ˋn")"}〕다. |
| 50 | $actual=@($out|ForEach-Object{([string]$_)-replace'\s',''}|Where-Object{$_-match'^\d+\|\d+\|\d+\|\d+\|\d+$'}) | 다중 drill owner의 Ranking multiset oracle·오십 좌표의 실제 뜻: 공백 제거 뒤 숫자 다섯 field인 줄만 actual 배열에 남긴다. 근거 원문은 F04-C04 원문 〔$actual=@($out|ForEach-Object{([string]$_)-replace'\s',''}|Where-Object{$_-match'^\d+\|\d+\|\…〕다. |
| 51 | $expected=@('1|100|1|1|1','2|100|2|1|1','3|80|3|3|2','4|70|4|4|3') | 다중 drill owner의 Ranking multiset oracle·오십일 좌표의 실제 뜻: 네 Ranking oracle 행을 expected 배열에 고정한다. 근거 원문은 F04-C04 원문 〔$expected=@('1|100|1|1|1','2|100|2|1|1','3|80|3|3|2','4|70|4|4|3')〕다. |
| 52 | if(Compare-Object $expected $actual){throw "W17 ranking exact rows mismatch expected=$expected actual=$actual"} | 다중 drill owner의 Ranking multiset oracle·오십이 좌표의 실제 뜻: Compare-Object로 expected와 actual의 행 membership·multiplicity 차이를 찾는다. 근거 원문은 F04-C04 원문 〔if(Compare-Object $expected $actual){throw "W17 ranking exact rows mismatch expected=$expecte…〕다. |
| 53 | $sourceHash=(Get-FileHash -LiteralPath $ranking -Algorithm SHA256).Hash.ToLowerInvariant() | 다중 drill owner의 Ranking multiset oracle·오십삼 좌표의 실제 뜻: learner Ranking file SHA-256을 계산해 소문자로 만든다. 근거 원문은 F04-C04 원문 〔$sourceHash=(Get-FileHash -LiteralPath $ranking -Algorithm SHA256).Hash.ToLowerInvariant()〕다. |
| 54 | $target=Join-Path $e 'ranking-result.txt' | 다중 drill owner의 Ranking multiset oracle·오십사 좌표의 실제 뜻: ranking-result.txt target 경로를 만든다. 근거 원문은 F04-C04 원문 〔$target=Join-Path $e 'ranking-result.txt'〕다. |
| 55 | $lines=@('W17_RANKING_RESULT','rows=4','ties=rank-1-1-dense-1-1',"source_sha256=$sourceHash",'native_exit=0') | 다중 drill owner의 Ranking multiset oracle·오십오 좌표의 실제 뜻: $lines에 현재 식 @('W17_RANKING_RESULT','rows=4','ties=rank-1-1-dense-1-1',"source_sha256=$sourceHash",'native…의 평가값을 할당한다. 근거 원문은 F04-C04 원문 〔$lines=@('W17_RANKING_RESULT','rows=4','ties=rank-1-1-dense-1-1',"source_sha256=$sourceHash",…〕다. |
| 56 | $lines+=@($actual|ForEach-Object{"row=$_"}) | 다중 drill owner의 Ranking multiset oracle·오십육 좌표의 실제 뜻: pipeline stage $lines+=@($actual|ForEach-Object{"row=$_"})로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F04-C04 원문 〔$lines+=@($actual|ForEach-Object{"row=$_"})〕다. |
| 57 | $lines|Set-Content -Encoding utf8 $target | 다중 drill owner의 Ranking multiset oracle·오십칠 좌표의 실제 뜻: 현재 pipeline payload를 $lines|Set-Content -Encoding utf8 $target 대상에 쓴다. 근거 원문은 F04-C04 원문 〔$lines|Set-Content -Encoding utf8 $target〕다. |
| 58 | "W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sourceHash native_exit=0 cleanup=1" | 다중 drill owner의 Ranking multiset oracle·오십팔 좌표의 실제 뜻: Ranking oracle and evidence branch의 마지막 delimiter를 닫는다. 근거 원문은 F04-C04 원문 〔"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sour…〕다. |
| 59 | }else{ | 다중 drill owner의 transcript presence gate·오십구 좌표의 실제 뜻: Reconcile·Savepoint execution branch header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔}else{〕다. |
| 60 | $out=@($sql|docker exec -i $Container psql -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1) | 다중 drill owner의 transcript presence gate·육십 좌표의 실제 뜻: $out에 현재 식 @($sql|docker exec -i $Container psql -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$out=@($sql|docker exec -i $Container psql -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)〕다. |
| 61 | $exit=$LASTEXITCODE | 다중 drill owner의 transcript presence gate·육십일 좌표의 실제 뜻: $exit에 현재 식 $LASTEXITCODE의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$exit=$LASTEXITCODE〕다. |
| 62 | $name=if($Drill-eq'Savepoint'){'savepoint-transcript.txt'}else{'reconcile-transcript.txt'} | 다중 drill owner의 transcript presence gate·육십이 좌표의 실제 뜻: $name에 현재 식 if($Drill-eq'Savepoint'){'savepoint-transcript.txt'}else{'reconcile-transcript.txt'}의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$name=if($Drill-eq'Savepoint'){'savepoint-transcript.txt'}else{'reconcile-transcript.txt'}〕다. |
| 63 | $target=Join-Path $e $name | 다중 drill owner의 transcript presence gate·육십삼 좌표의 실제 뜻: $target에 현재 식 Join-Path $e $name의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$target=Join-Path $e $name〕다. |
| 64 | $out|Set-Content -Encoding utf8 $target | 다중 drill owner의 transcript presence gate·육십사 좌표의 실제 뜻: reconcile/savepoint native output을 marker 검사 전에 transcript target에 쓴다. 근거 원문은 F04-C05 원문 〔$out|Set-Content -Encoding utf8 $target〕다. |
| 65 | if($exit-ne 0){throw "W17 psql exit=$exit`n$($out-join"`n")"} | 다중 drill owner의 transcript presence gate·육십오 좌표의 실제 뜻: 조건식 if($exit-ne 0){throw "W17 psql exit=$exitˋn$($out-join"ˋn")"}의 참·거짓을 평가한다. 근거 원문은 F04-C05 원문 〔if($exit-ne 0){throw "W17 psql exit=$exitˋn$($out-join"ˋn")"}〕다. |
| 66 | $text=$out-join"`n" | 다중 drill owner의 transcript presence gate·육십육 좌표의 실제 뜻: $text에 현재 식 $out-join"ˋn"의 평가값을 할당한다. 근거 원문은 F04-C05 원문 〔$text=$out-join"ˋn"〕다. |
| 67 | foreach($marker in @('W17_BASELINE=0','W17_INJECTED=1','W17_RESTORED=0')){ | 다중 drill owner의 transcript presence gate·육십칠 좌표의 실제 뜻: required marker iteration header foreach($marker in @('W17_BASELINE=0','W17_INJECTED=1','W17_RESTORED=0')){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔foreach($marker in @('W17_BASELINE=0','W17_INJECTED=1','W17_RESTORED=0')){〕다. |
| 68 | if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"} | 다중 drill owner의 transcript presence gate·육십팔 좌표의 실제 뜻: joined transcript에 현재 marker substring이 하나라도 있는지 본다. 근거 원문은 F04-C05 원문 〔if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"}〕다. |
| 69 | } | 다중 drill owner의 transcript presence gate·육십구 좌표의 실제 뜻: three-marker presence loop의 마지막 delimiter를 닫는다. 근거 원문은 F04-C05 원문 〔}〕다. |
| 70 | $hash=(Get-FileHash -LiteralPath $target -Algorithm SHA256).Hash.ToLowerInvariant() | 다중 drill owner의 transcript presence gate·칠십 좌표의 실제 뜻: 검사를 통과한 transcript file의 SHA-256을 계산한다. 근거 원문은 F04-C05 원문 〔$hash=(Get-FileHash -LiteralPath $target -Algorithm SHA256).Hash.ToLowerInvariant()〕다. |
| 71 | if($Drill-eq'Savepoint'){ | 다중 drill owner의 drill Green selection·칠십일 좌표의 실제 뜻: Savepoint Green selection header if($Drill-eq'Savepoint'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔if($Drill-eq'Savepoint'){〕다. |
| 72 | "W17_SAVEPOINT_GREEN injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1" | 다중 drill owner의 drill Green selection·칠십이 좌표의 실제 뜻: 현재 success/failure summary literal "W17_SAVEPOINT_GREEN injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"을 output stream에 보낸다. 근거 원문은 F04-C05 원문 〔"W17_SAVEPOINT_GREEN injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"〕다. |
| 73 | }else{ | 다중 drill owner의 drill Green selection·칠십삼 좌표의 실제 뜻: Reconcile Green selection header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔}else{〕다. |
| 74 | "W17_RECONCILE_GREEN baseline=0 injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1" | 다중 drill owner의 drill Green selection·칠십사 좌표의 실제 뜻: 현재 success/failure summary literal "W17_RECONCILE_GREEN baseline=0 injected=1 restored=0 transcript_sha256=$hash native_exit=0 c…을 output stream에 보낸다. 근거 원문은 F04-C05 원문 〔"W17_RECONCILE_GREEN baseline=0 injected=1 restored=0 transcript_sha256=$hash native_exit=0 c…〕다. |
| 75 | } | 다중 drill owner의 drill Green selection·칠십오 좌표의 실제 뜻: Savepoint/Reconcile Green selection의 마지막 delimiter를 닫는다. 근거 원문은 F04-C05 원문 〔}〕다. |
| 76 | } | 다중 drill owner의 drill Green selection·칠십육 좌표의 실제 뜻: drill execution branch의 마지막 delimiter를 닫는다. 근거 원문은 F04-C05 원문 〔}〕다. |
| 77 | }finally{ | 다중 drill owner의 owned cleanup·칠십칠 좌표의 실제 뜻: finally cleanup scope header }finally{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C06 원문 〔}finally{〕다. |
| 78 | if($owned){ | 다중 drill owner의 owned cleanup·칠십팔 좌표의 실제 뜻: owned-resource cleanup condition header if($owned){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C06 원문 〔if($owned){〕다. |
| 79 | & docker compose -f $compose -p $ComposeProject down -v|Out-Null | 다중 drill owner의 owned cleanup·칠십구 좌표의 실제 뜻: owned Compose project에 down -v를 요청한다. 근거 원문은 F04-C06 원문 〔& docker compose -f $compose -p $ComposeProject down -v|Out-Null〕다. |
| 80 | if($LASTEXITCODE-ne 0){throw 'W17 compose cleanup failed'} | 다중 drill owner의 owned cleanup·팔십 좌표의 실제 뜻: Compose cleanup native exit가 nonzero면 실패시킨다. 근거 원문은 F04-C06 원문 〔if($LASTEXITCODE-ne 0){throw 'W17 compose cleanup failed'}〕다. |
| 81 | } | 다중 drill owner의 owned cleanup·팔십일 좌표의 실제 뜻: owned Compose cleanup guard의 마지막 delimiter를 닫는다. 근거 원문은 F04-C06 원문 〔}〕다. |
| 82 | } | 다중 drill owner의 owned cleanup·팔십이 좌표의 실제 뜻: runner finally block의 마지막 delimiter를 닫는다. 근거 원문은 F04-C06 원문 〔}〕다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기세 drill을 실행하는 fail-fast owner지만 source authenticity, exact marker sequence, stale-evidence invalidation, 모든 mode cleanup을 완전히 닫지 않는다.
문법 해부
- Ranking regex는 다섯 construct와 placeholder만 보고 read-only·single statement·ProjectRoot containment는 강제하지 않는다.
- numeric five-field filter 뒤 Compare-Object는 membership와 multiplicity를 비교하며 positional order는 보지 않는다.
- raw V001은 unpinned/uninspected이고 marker loop는 escaped substring presence만 검사한다.
- 순서·유일성·packaged provenance는 presence-only marker gate 밖에 남는다.
- finally는 owned bit만 소비하며 supplied Container와 pre-owned partial startup resource를 정리하지 않는다.
실행 순서
- absolute paths
- Ranking validation or raw V001+drill assembly
- mode/startup
- numeric multiset or marker presence
- evidence/Green text
- owned Compose down -v
원래 W6 수준의 조각별 정밀 해설
F04-C01 · parameters and absolute-path preparation
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 다중 drill owner의 parameter contract·일 좌표의 실제 뜻: multi-drill runner parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C01 원문 〔param(〕다. 끝에서 다중 drill owner의 absolute-path setup·십육 좌표의 실제 뜻: pipeline stage New-Item -ItemType Directory -Force $e|Out-Null로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F04-C01 원문 〔New-Item -ItemType Directory -Force $e|Out-Null〕다.
- 실제 값 추적
- 시작 조건 다중 drill owner의 parameter contract·일 좌표 입력: multi-drill runner parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 매개변수와 절대 경로 준비 직전 state와 〔param(〕의 operand만 받는다; 미래 child 산출은 제외한다.에서 범위를 통과하면 중간에 다중 drill owner의 parameter contract·구 좌표 직후 상태: parser와 PowerShell 제어가 script parameter list 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔)〕이며 이 변화는 F04-C01 안에 머문다. 마지막에 다중 drill owner의 absolute-path setup·십육 좌표 직후 상태: 변환·filter 결과가 다음 pipeline stage 또는 변수에 도착한다. source 단서는 〔New-Item -ItemType Directory -Force $e|Out-Null〕이며 이 변화는 F04-C01 안에 머문다.
- 정상 예
- 원본 `param(`를 정확히 유지하고 이 범위를 실행·해석했을 때 다중 drill owner의 absolute-path setup·십육 좌표 직후 상태: 변환·filter 결과가 다음 pipeline stage 또는 변수에 도착한다. source 단서는 〔New-Item -ItemType Directory -Force $e|Out-Null〕이며 이 변화는 F04-C01 안에 머문다.
- 틀린 예·반례
- absolute path 검사만으로 ProjectRoot·EvidenceDir·SqlPath가 learner-owned tree 안에 있다고 보장되지는 않는다.
- 착각 방지
- 다중 drill owner의 absolute-path setup·십육 좌표 책임 경계: pipeline에 포함되지 않은 output·error·source 의미는 관찰하지 않는다. 현재 operation은 pipeline stage New-Item -ItemType Directory -Force $e|Out-Null로 왼쪽 값을 오른쪽 command에 전달한다. 확인 근거는 〔New-Item -ItemType Directory -Force $e|Out-Null〕다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `parameters and absolute-path preparation`의 source state만 다루며 다중 drill owner의 absolute-path setup·십육 좌표 책임 경계: pipeline에 포함되지 않은 output·error·source 의미는 관찰하지 않는다. 현재 operation은 pipeline stage New-Item -ItemType Directory -Force $e|Out-Null로 왼쪽 값을 오른쪽 command에 전달한다. 확인 근거는 〔New-Item -ItemType Directory -Force $e|Out-Null〕다.
- 다음 연결
- 끝 상태를 기록한다: 다중 drill owner의 absolute-path setup·십육 좌표 직후 상태: 변환·filter 결과가 다음 pipeline stage 또는 변수에 도착한다. source 단서는 〔New-Item -ItemType Directory -Force $e|Out-Null〕이며 이 변화는 F04-C01 안에 머문다. 이어지는 `ranking validation or physical drill assembly` 범위에서 이 상태의 입력 경계를 확인한다.
F04-C02 · ranking validation or physical drill assembly
- 문법 해부
- 이 source slice의 문법 축은 다중 drill owner의 Ranking source inspection·이십오 좌표의 실제 뜻: TODO류 placeholder 단어가 있으면 Ranking source를 거절한다. 근거 원문은 F04-C02 원문 〔if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an…〕다. 앞뒤로 다중 drill owner의 Ranking source inspection·십팔 좌표의 실제 뜻: Ranking drill condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C02 원문 〔if($Drill-eq'Ranking'){〕다. 및 다중 drill owner의 raw assembly·삼십일 좌표의 실제 뜻: Ranking/non-Ranking source selection의 마지막 delimiter를 닫는다. 근거 원문은 F04-C02 원문 〔}〕다.
- 실제 값 추적
- 다중 drill owner의 Ranking source inspection·십팔 좌표 입력: Ranking drill condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 Ranking 검사 또는 물리 drill 조립 직전 state와 〔if($Drill-eq'Ranking'){〕의 operand만 받는다; 미래 child 산출은 제외한다. 그 상태가 진행되면 다중 drill owner의 raw assembly·삼십일 좌표 직후 상태: parser와 PowerShell 제어가 Ranking/non-Ranking source selection 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F04-C02 안에 머문다.
- 정상 예
- 유효한 예는 "if($Drill-eq'Ranking'){" bytes를 보존해 다중 drill owner의 Ranking source inspection·이십오 좌표 직후 상태: 미해결 표식이 없는 source만 다음 assignment 후보가 된다. source 단서는 〔if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an…〕이며 이 변화는 F04-C02 안에 머문다.
- 틀린 예·반례
- 필수 문자열 패턴이 모두 맞았다는 이유로 Ranking SQL이 read-only 단일 statement라고 선언하면 shape guard의 빈틈을 놓친다.
- 착각 방지
- 다중 drill owner의 Ranking source inspection·이십오 좌표 책임 경계: SQL parser가 아니어서 quoted 검사 문자열의 단어에도 반응할 수 있다. 현재 operation은 TODO류 placeholder 단어가 있으면 Ranking source를 거절한다. 확인 근거는 〔if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an…〕다. 따라서 `ranking validation or physical drill assembly`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. 다중 drill owner의 Ranking source inspection·이십오 좌표 책임 경계: SQL parser가 아니어서 quoted 검사 문자열의 단어에도 반응할 수 있다. 현재 operation은 TODO류 placeholder 단어가 있으면 Ranking source를 거절한다. 확인 근거는 〔if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an…〕다.
- 다음 연결
- 끝 상태를 기록한다: 다중 drill owner의 raw assembly·삼십일 좌표 직후 상태: parser와 PowerShell 제어가 Ranking/non-Ranking source selection 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F04-C02 안에 머문다. 이어지는 `Compose or supplied-container ownership` 범위에서 이 상태의 입력 경계를 확인한다.
F04-C03 · Compose or supplied-container ownership
- 문법 해부
- `Compose or supplied-container ownership` 범위는 다중 drill owner의 runtime ownership·삼십삼 좌표의 실제 뜻: $compose에 현재 식 Join-Path $root 'compose.yaml'의 평가값을 할당한다. 근거 원문은 F04-C03 원문 〔$compose=Join-Path $root 'compose.yaml'〕다. 이어서 다중 drill owner의 runtime ownership·사십사 좌표의 실제 뜻: 조건식 if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}의 참·거짓을 평가한다. 근거 원문은 F04-C03 원문 〔if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}〕다.
- 실제 값 추적
- 구체 입력은 다중 drill owner의 runtime ownership·삼십구 좌표 입력: native Compose command & docker compose -f $compose -p $ComposeProject up -d --wait db를 호출한다. 수행에 필요한 Compose·지정 Container 소유권 직전 state와 〔& docker compose -f $compose -p $ComposeProject up -d --wait db〕의 operand만 받는다; 미래 child 산출은 제외한다. 처리 뒤 관찰 가능한 끝 상태는 다중 drill owner의 runtime ownership·사십사 좌표 직후 상태: 평가 결과에 따라 inline failure 또는 선택 branch로 제어가 갈라진다. source 단서는 〔if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}〕이며 이 변화는 F04-C03 안에 머문다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 다중 drill owner의 runtime ownership·삼십삼 좌표 직후 상태: 뒤 sibling statement가 $compose의 새 값을 읽을 수 있는 state가 된다. source 단서는 〔$compose=Join-Path $root 'compose.yaml'〕이며 이 변화는 F04-C03 안에 머문다. 그리고 범위 끝에서 다중 drill owner의 runtime ownership·사십사 좌표 직후 상태: 평가 결과에 따라 inline failure 또는 선택 branch로 제어가 갈라진다. source 단서는 〔if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}〕이며 이 변화는 F04-C03 안에 머문다.
- 틀린 예·반례
- compose up이 일부 resource를 만들고 nonzero로 끝난 경우에도 owned=true가 됐다고 가정하면 후속 정리 블록의 경계를 잘못 읽는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: 다중 drill owner의 runtime ownership·삼십삼 좌표 책임 경계: 이 assignment 하나는 $compose이 가리키는 외부 file·container·SQL 의미를 검증하지 않는다. 현재 operation은 $compose에 현재 식 Join-Path $root 'compose.yaml'의 평가값을 할당한다. 확인 근거는 〔$compose=Join-Path $root 'compose.yaml'〕다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: 다중 drill owner의 runtime ownership·삼십삼 좌표 책임 경계: 이 assignment 하나는 $compose이 가리키는 외부 file·container·SQL 의미를 검증하지 않는다. 현재 operation은 $compose에 현재 식 Join-Path $root 'compose.yaml'의 평가값을 할당한다. 확인 근거는 〔$compose=Join-Path $root 'compose.yaml'〕다.
- 다음 연결
- 끝 상태를 기록한다: 다중 drill owner의 runtime ownership·사십사 좌표 직후 상태: 평가 결과에 따라 inline failure 또는 선택 branch로 제어가 갈라진다. source 단서는 〔if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}〕이며 이 변화는 F04-C03 안에 머문다. 이어지는 `ranking native execution and exact oracle` 범위에서 이 상태의 입력 경계를 확인한다.
F04-C04 · ranking native execution and exact oracle
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 다중 drill owner의 Ranking multiset oracle·사십육 좌표의 실제 뜻: Ranking execution condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C04 원문 〔if($Drill-eq'Ranking'){〕다. 끝에서 다중 drill owner의 Ranking multiset oracle·오십팔 좌표의 실제 뜻: Ranking oracle and evidence branch의 마지막 delimiter를 닫는다. 근거 원문은 F04-C04 원문 〔"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sour…〕다.
- 실제 값 추적
- 시작 조건 다중 drill owner의 Ranking multiset oracle·사십육 좌표 입력: Ranking execution condition header if($Drill-eq'Ranking'){가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 Ranking 실행과 행 multiset oracle 직전 state와 〔if($Drill-eq'Ranking'){〕의 operand만 받는다; 미래 child 산출은 제외한다.에서 범위를 통과하면 중간에 다중 drill owner의 Ranking multiset oracle·오십이 좌표 직후 상태: 차이가 있으면 exact rows mismatch로 실패한다. source 단서는 〔if(Compare-Object $expected $actual){throw "W17 ranking exact rows mismatch expected=$expecte…〕이며 이 변화는 F04-C04 안에 머문다. 마지막에 다중 drill owner의 Ranking multiset oracle·오십팔 좌표 직후 상태: parser와 PowerShell 제어가 Ranking oracle and evidence branch 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sour…〕이며 이 변화는 F04-C04 안에 머문다.
- 정상 예
- 원본 `if($Drill-eq'Ranking'){`를 정확히 유지하고 이 범위를 실행·해석했을 때 다중 drill owner의 Ranking multiset oracle·오십팔 좌표 직후 상태: parser와 PowerShell 제어가 Ranking oracle and evidence branch 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sour…〕이며 이 변화는 F04-C04 안에 머문다.
- 틀린 예·반례
- numeric five-field rows가 expected multiset과 같다는 사실을 nonnumeric output 부재나 exact position order의 증명으로 확대하면 안 된다.
- 착각 방지
- 다중 drill owner의 Ranking multiset oracle·오십팔 좌표 책임 경계: 닫는 기호만으로 Ranking oracle and evidence branch 안 명령의 성공·Green은 증명되지 않는다. 현재 operation은 Ranking oracle and evidence branch의 마지막 delimiter를 닫는다. 확인 근거는 〔"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sour…〕다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `ranking native execution and exact oracle`의 source state만 다루며 다중 drill owner의 Ranking multiset oracle·오십팔 좌표 책임 경계: 닫는 기호만으로 Ranking oracle and evidence branch 안 명령의 성공·Green은 증명되지 않는다. 현재 operation은 Ranking oracle and evidence branch의 마지막 delimiter를 닫는다. 확인 근거는 〔"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sour…〕다.
- 다음 연결
- 끝 상태를 기록한다: 다중 drill owner의 Ranking multiset oracle·오십팔 좌표 직후 상태: parser와 PowerShell 제어가 Ranking oracle and evidence branch 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sour…〕이며 이 변화는 F04-C04 안에 머문다. 이어지는 `reconcile/savepoint execution and marker evidence` 범위에서 이 상태의 입력 경계를 확인한다.
F04-C05 · reconcile/savepoint execution and marker evidence
- 문법 해부
- 이 source slice의 문법 축은 다중 drill owner의 transcript presence gate·육십팔 좌표의 실제 뜻: joined transcript에 현재 marker substring이 하나라도 있는지 본다. 근거 원문은 F04-C05 원문 〔if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"}〕다. 앞뒤로 다중 drill owner의 transcript presence gate·오십구 좌표의 실제 뜻: Reconcile·Savepoint execution branch header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C05 원문 〔}else{〕다. 및 다중 drill owner의 drill Green selection·칠십육 좌표의 실제 뜻: drill execution branch의 마지막 delimiter를 닫는다. 근거 원문은 F04-C05 원문 〔}〕다.
- 실제 값 추적
- 다중 drill owner의 transcript presence gate·오십구 좌표 입력: Reconcile·Savepoint execution branch header }else{가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 대사·savepoint transcript와 marker 직전 state와 〔}else{〕의 operand만 받는다; 미래 child 산출은 제외한다. 그 상태가 진행되면 다중 drill owner의 drill Green selection·칠십육 좌표 직후 상태: parser와 PowerShell 제어가 drill execution branch 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F04-C05 안에 머문다.
- 정상 예
- 유효한 예는 '}else{' bytes를 보존해 다중 drill owner의 transcript presence gate·육십팔 좌표 직후 상태: 없으면 missing marker 오류가 나고 있으면 다음 marker로 간다. source 단서는 〔if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"}〕이며 이 변화는 F04-C05 안에 머문다.
- 틀린 예·반례
- 세 marker substring이 존재한다고 packaged source의 순서·유일 실행·raw V001 비스푸핑까지 인증되지는 않는다.
- 착각 방지
- 다중 drill owner의 transcript presence gate·육십팔 좌표 책임 경계: presence-only라 순서·중복·raw V001의 spoof 출력을 인증하지 않는다. 현재 operation은 joined transcript에 현재 marker substring이 하나라도 있는지 본다. 확인 근거는 〔if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"}〕다. 따라서 `reconcile/savepoint execution and marker evidence`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. 다중 drill owner의 transcript presence gate·육십팔 좌표 책임 경계: presence-only라 순서·중복·raw V001의 spoof 출력을 인증하지 않는다. 현재 operation은 joined transcript에 현재 marker substring이 하나라도 있는지 본다. 확인 근거는 〔if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"}〕다.
- 다음 연결
- 끝 상태를 기록한다: 다중 drill owner의 drill Green selection·칠십육 좌표 직후 상태: parser와 PowerShell 제어가 drill execution branch 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F04-C05 안에 머문다. 이어지는 `owned Compose cleanup` 범위에서 이 상태의 입력 경계를 확인한다.
F04-C06 · owned Compose cleanup
- 문법 해부
- `owned Compose cleanup` 범위는 다중 drill owner의 owned cleanup·칠십칠 좌표의 실제 뜻: finally cleanup scope header }finally{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F04-C06 원문 〔}finally{〕다. 이어서 다중 drill owner의 owned cleanup·팔십이 좌표의 실제 뜻: runner finally block의 마지막 delimiter를 닫는다. 근거 원문은 F04-C06 원문 〔}〕다.
- 실제 값 추적
- 구체 입력은 다중 drill owner의 owned cleanup·팔십 좌표 입력: Compose cleanup native exit가 nonzero면 실패시킨다. 수행에 필요한 소유한 Compose 정리 직전 state와 〔if($LASTEXITCODE-ne 0){throw 'W17 compose cleanup failed'}〕의 operand만 받는다; 미래 child 산출은 제외한다. 처리 뒤 관찰 가능한 끝 상태는 다중 drill owner의 owned cleanup·팔십이 좌표 직후 상태: parser와 PowerShell 제어가 runner finally block 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F04-C06 안에 머문다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 다중 drill owner의 owned cleanup·칠십칠 좌표 직후 상태: 소유한 Compose 정리에서 finally cleanup scope의 빈 scope가 생겨 바로 뒤 child를 받을 준비만 한다. source 단서는 〔}finally{〕이며 이 변화는 F04-C06 안에 머문다. 그리고 범위 끝에서 다중 drill owner의 owned cleanup·팔십이 좌표 직후 상태: parser와 PowerShell 제어가 runner finally block 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F04-C06 안에 머문다.
- 틀린 예·반례
- Green 문구 cleanup=1을 supplied Container mode에서 container·schema가 제거됐다는 실제 관찰로 바꾸면 `$owned` 조건과 충돌한다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: 다중 drill owner의 owned cleanup·칠십칠 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 finally cleanup scope header }finally{가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔}finally{〕다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: 다중 drill owner의 owned cleanup·칠십칠 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 finally cleanup scope header }finally{가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔}finally{〕다.
- 다음 연결
- 끝 상태를 기록한다: 다중 drill owner의 owned cleanup·팔십이 좌표 직후 상태: parser와 PowerShell 제어가 runner finally block 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F04-C06 안에 머문다. 이어지는 `parameters and strict failure mode` 범위에서 이 상태의 입력 경계를 확인한다.
남아 있는 파일히토리 → 니지카 → 료 → 키타
-
히토리
ranking-result.txt가 있으면 성공 기록 아닌가요?
-
니지카
실행 시작 때 지우지 않아 이전 성공 file일 수 있어.
-
료
reconcile transcript도 validation 전에 쓰여 존재만으로 Green이 아니다.
-
키타
current invocation과 atomic promotion을 새 gate로 제안할게요.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| 1 | Drill=Ranking과 external absolute SqlPath | construct regex와 placeholder를 검사한 뒤 learner SQL을 실행한다. | numeric five-field 줄 네 개가 expected multiset과 같으면 evidence를 쓴다. | nonnumeric 추가 output과 row order는 oracle 밖이고 hash는 record-only다. |
| 2 | Drill=Reconcile 또는 Savepoint | raw V001을 fresh w17_drill wrapper와 packaged drill 앞에 결합한다. | psql output을 transcript에 먼저 쓴 뒤 세 marker 존재를 본다. | V001 marker spoof/meta-command/early quit와 marker 순서·중복을 닫지 않는다. |
| 3 | Compose up exit=nonzero after partial creation | throw 전에 owned는 false로 남는다. | finally의 down -v branch가 실행되지 않는다. | partial Compose resources may remain. |
| 4 | Mode=Container 성공 run | caller container에서 drill을 실행한다. | Green 문구에는 cleanup=1이 있어도 w17_drill schema와 F03 pre-BEGIN seed가 남을 수 있다. | F03의 lines 2~4는 BEGIN 전 autocommit이고 다음 run은 시작 시 schema를 drop한다는 cross-source 경계다. |
소유와 정리히토리 → 니지카 → 료 → 키타
-
히토리
Compose up이 실패하면 finally가 정리하죠?
-
니지카
owned는 successful up 뒤에만 true가 돼.
-
료
Container mode도 down이 없고 cleanup=1은 literal summary다.
-
키타
partial startup과 supplied container 잔류를 따로 경고하겠습니다.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
absolute path와 evidence directory를 준비한다.
SqlPath·EvidenceDir의 ProjectRoot containment를 보지 않는다.uninspected V001과 packaged reconcile drill을 한 psql input으로 만든다.
learner prefix가 packaged source 실행·marker origin을 바꿀 수 있다.numeric five-field lines만 뽑아 Compare-Object multiset으로 네 행을 검사한다.
nonnumeric output과 row position은 무시한다.joined transcript에서 세 escaped literal의 존재를 각각 확인한다.
sequence·uniqueness·provenance는 인증하지 않는다.Ranking result 또는 raw transcript를 target에 기록한다.
두 target 모두 current failure와 stale success를 원자적으로 구분하지 못한다.successful up 뒤 owned=true이면 finally에서 down -v와 exit를 확인한다.
partial startup nonzero와 supplied Container cleanup은 caller 책임이다.STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ 세 marker가 있으면 packaged drill이 순서대로 실행됐다.
왜 틀리나 loop는 substring presence만 보고 raw V001도 먼저 output을 만들 수 있다.
바르게 읽기 presence, sequence, uniqueness, provenance를 네 축으로 나눈다.
반례 V001이 세 marker를 역순으로 출력한 뒤 psql quit를 실행해도 presence 후보는 생긴다.
❌ Compare-Object가 Ranking row 순서를 검증한다.
왜 틀리나 기본 비교는 object multiset 차이를 찾고 positional index를 대조하지 않는다.
바르게 읽기 unordered numeric four-row multiset oracle이라고 부른다.
반례 네 numeric row의 순서를 뒤집어도 membership과 multiplicity가 같으면 차이가 없다.
❌ transcript file이 있으면 방금 run은 Green이다.
왜 틀리나 current output은 validation 전에 쓰이고 early failure는 이전 file을 남길 수 있다.
바르게 읽기 current invocation id와 final atomic promotion이 없는 evidence window를 공개한다.
반례 psql nonzero라도 이번 transcript가 생길 수 있고 실행 전 실패면 어제 file이 유지된다.
❌ cleanup=1이면 Container schema도 사라졌다.
왜 틀리나 finally down -v는 owned Compose에만 실행된다.
바르게 읽기 literal summary와 mode별 actual cleanup statement를 구분한다.
반례 supplied Container 성공 뒤 fresh w17_drill과 pre-BEGIN seed가 남는다.
❌ compose up 실패면 아무 resource도 없다.
왜 틀리나 owned=true는 successful up 뒤에만 설정된다.
바르게 읽기 partial creation 뒤 nonzero 가능성과 finally predicate를 함께 읽는다.
반례 network나 container 일부가 생긴 뒤 wait 실패하면 down branch를 건너뛸 수 있다.
❌ source SHA가 evidence에 있으므로 canonical SQL이 인증됐다.
왜 틀리나 Ranking hash는 expected allowlist와 비교되지 않고 reconcile은 packaged/learner source hash를 evidence에 bind하지 않는다.
바르게 읽기 record-only fingerprint와 allowlisted authenticity를 구분한다.
반례 다른 absolute Ranking file도 shape/oracle을 통과하면 자신의 hash로 Green이 된다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
raw V001 또는 Ranking SQL이 approved bytes임
이 책임을 맡는 곳: expected-SHA allowlist and inspected assemblybaseline→injected→restored exact sequence와 unique origin
이 책임을 맡는 곳: structured exact transcript oracletranscript/ranking-result가 current successful invocation의 것임
이 책임을 맡는 곳: preclear plus staged atomic promotion and run idnumeric rows의 positional order 또는 nonnumeric output absence
이 책임을 맡는 곳: ordered full-output comparisonnonzero compose up 뒤 resource absence
이 책임을 맡는 곳: ownership-before-up and unconditional scoped cleanupcaller container의 w17_drill schema와 seed 제거
이 책임을 맡는 곳: caller isolation or explicit schema cleanupF03 seed INSERT lines 2~4 rollback
이 책임을 맡는 곳: BEGIN placement or explicit cleanup in reconcile-drill.sqlSTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
path/source 선택→mode/ownership→Ranking multiset 또는 reconcile presence→evidence timing→finally cleanup 순서로 말한다.
2단계 · 코드 조각 재조립
- raw V001 before packaged drill
- numeric-only unordered multiset
- presence-only markers
- stale transcript and ranking result
- owned after successful up
- Container residue and F03 pre-BEGIN autocommit
3단계 · 파일 전체 다시 쓰기
82개 물리 줄과 79개 nonblank mapping을 canonical SHA-256 b21c4d34...ea9와 대조한다.
자가 점검
- read-only/single-statement gap을 적는다.
- marker order·uniqueness·origin을 overclaim하지 않는다.
- 두 stale-evidence 경로를 나눈다.
- Compare-Object를 positional oracle로 부르지 않는다.
- partial startup과 Container cleanup을 별도 경계로 적는다.
- source audit가 runner를 실행했다고 쓰지 않는다.
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
정본 전체 코드 확인하기
param(
[ValidateSet('Compose','Container')][string]$Mode='Compose',
[ValidateSet('Reconcile','Ranking','Savepoint')][string]$Drill='Reconcile',
[string]$Container='',
[string]$ComposeProject='w17-reconcile-lab',
[Parameter(Mandatory=$true)][string]$ProjectRoot,
[Parameter(Mandatory=$true)][string]$EvidenceDir,
[string]$SqlPath=''
)
$ErrorActionPreference='Stop'
$root=Split-Path -Parent $PSScriptRoot
if(-not [IO.Path]::IsPathRooted($ProjectRoot)){throw 'ProjectRoot must be an absolute learner project path'}
if(-not [IO.Path]::IsPathRooted($EvidenceDir)){throw 'EvidenceDir must be an absolute learner-owned path'}
$project=(Resolve-Path -LiteralPath $ProjectRoot).Path
$e=[IO.Path]::GetFullPath($EvidenceDir)
New-Item -ItemType Directory -Force $e|Out-Null
if($Drill-eq'Ranking'){
if([string]::IsNullOrWhiteSpace($SqlPath)-or-not[IO.Path]::IsPathRooted($SqlPath)){throw 'Ranking requires an absolute learner-owned -SqlPath'}
$ranking=(Resolve-Path -LiteralPath $SqlPath).Path
$learnerSql=Get-Content -Raw -LiteralPath $ranking
foreach($pattern in @('\bROW_NUMBER\s*\(','(?<!DENSE_)\bRANK\s*\(','\bDENSE_RANK\s*\(','ORDER\s+BY\s+amount\s+DESC','account_id')){
if($learnerSql-cnotmatch $pattern){throw "ranking.sql missing required construct: $pattern"}
}
if($learnerSql-cmatch'(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'){throw 'ranking.sql contains an unresolved placeholder'}
$sql=$learnerSql
}else{
$v001=Get-Content -Raw (Join-Path $project 'src/main/resources/db/migration/V001__common.sql')
$drillSql=Get-Content -Raw (Join-Path $root 'sql/w17/reconcile-drill.sql')
$sql="DO `$ddl`$ BEGIN IF EXISTS(SELECT 1 FROM pg_namespace WHERE nspname='w17_drill') THEN EXECUTE 'DROP SCHEMA w17_drill CASCADE'; END IF; END `$ddl`$; CREATE SCHEMA w17_drill; SET search_path TO w17_drill;`n$v001`n$drillSql"
}
$compose=Join-Path $root 'compose.yaml'
$owned=$false
try{
if($Mode-eq'Compose'){
if($Container){throw 'W17 Compose mode rejects -Container'}
if([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)){$env:FCL_DB_PASSWORD='w17-disposable-password'}
& docker compose -f $compose -p $ComposeProject up -d --wait db
if($LASTEXITCODE-ne 0){throw "W17 compose up exit=$LASTEXITCODE"}
$owned=$true
$Container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim()
}elseif([string]::IsNullOrWhiteSpace($Container)){throw 'W17 Container mode requires -Container'}
if([string]::IsNullOrWhiteSpace($Container)){throw 'W17 PostgreSQL container resolution failed'}
if($Drill-eq'Ranking'){
$out=@($sql|docker exec -i $Container psql -X -q -A -t -F '|' -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)
$exit=$LASTEXITCODE
if($exit-ne0){throw "W17 ranking psql exit=$exit`n$($out-join"`n")"}
$actual=@($out|ForEach-Object{([string]$_)-replace'\s',''}|Where-Object{$_-match'^\d+\|\d+\|\d+\|\d+\|\d+$'})
$expected=@('1|100|1|1|1','2|100|2|1|1','3|80|3|3|2','4|70|4|4|3')
if(Compare-Object $expected $actual){throw "W17 ranking exact rows mismatch expected=$expected actual=$actual"}
$sourceHash=(Get-FileHash -LiteralPath $ranking -Algorithm SHA256).Hash.ToLowerInvariant()
$target=Join-Path $e 'ranking-result.txt'
$lines=@('W17_RANKING_RESULT','rows=4','ties=rank-1-1-dense-1-1',"source_sha256=$sourceHash",'native_exit=0')
$lines+=@($actual|ForEach-Object{"row=$_"})
$lines|Set-Content -Encoding utf8 $target
"W17_RANKING_GREEN rows=4 ties=ROW_NUMBER:1,2 RANK:1,1,3 DENSE_RANK:1,1,2 source_sha256=$sourceHash native_exit=0 cleanup=1"
}else{
$out=@($sql|docker exec -i $Container psql -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)
$exit=$LASTEXITCODE
$name=if($Drill-eq'Savepoint'){'savepoint-transcript.txt'}else{'reconcile-transcript.txt'}
$target=Join-Path $e $name
$out|Set-Content -Encoding utf8 $target
if($exit-ne 0){throw "W17 psql exit=$exit`n$($out-join"`n")"}
$text=$out-join"`n"
foreach($marker in @('W17_BASELINE=0','W17_INJECTED=1','W17_RESTORED=0')){
if($text-cnotmatch [regex]::Escape($marker)){throw "missing $marker"}
}
$hash=(Get-FileHash -LiteralPath $target -Algorithm SHA256).Hash.ToLowerInvariant()
if($Drill-eq'Savepoint'){
"W17_SAVEPOINT_GREEN injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"
}else{
"W17_RECONCILE_GREEN baseline=0 injected=1 restored=0 transcript_sha256=$hash native_exit=0 cleanup=1"
}
}
}finally{
if($owned){
& docker compose -f $compose -p $ComposeProject down -v|Out-Null
if($LASTEXITCODE-ne 0){throw 'W17 compose cleanup failed'}
}
}
05run-w17-cte-retrieval.ps1 - 두 계정 sentinel과 cleanup 후 evidence
scripts/run-w17-cte-retrieval.ps1
정본 PowerShell 검증기 · 정본 · W17-F05259줄 연결259줄 번역15 chunks
run-w17-cte-retrieval.ps1 - 두 계정 sentinel과 cleanup 후 evidence
scripts/run-w17-cte-retrieval.ps1
정본 PowerShell 검증기 · 정본 · W17-F05STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
learner CTE를 fail-closed regex contract로 거른 뒤 random transaction fixture에서 baseline·202·복구·101·복구 exact sequence를 확인하고 cleanup 뒤 evidence를 교체한다.
- 왜 202 probe뿐 아니라 101 alternate probe도 필요한가?
- BEGIN/ROLLBACK과 random schema는 어떤 data를 격리할까?
- owned=true를 compose up 전에 두면 startup failure가 어떻게 달라질까?
- cleanup failure와 learner failure가 함께 있으면 무엇이 먼저 표면화될까?
- same-directory tmp→Move-Item은 무엇을 개선하고 무엇까지는 보장하지 않을까?
baseline=EMPTYprimary=202|82|75|7primary restored=EMPTYalternate=101|111|100|11alternate restored=EMPTYcleanup=1 after confirmed downSTEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 같은 대사식을 계좌 202와 101에 번갈아 적용해 특정 id만 외운 답을 걸러낸다.
두 계좌로 찾는 hardcoding
정상 baseline은 EMPTY이고 202를 7 올리면 202|82|75|7 한 줄이 나와야 한다.
복구 뒤 101을 11 올려 101|111|100|11도 확인해야 계좌 하나에 고정한 query를 잡을 수 있다.
딱 여기까지만 한계: 두 fixture sentinel 통과는 모든 production 계좌·동시성·성능이나 regex의 완전한 SQL parsing을 증명하지 않는다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
먼저 오래된 증거 제거
runner는 source 검사 전에 기존 final evidence를 지운다.
- 코드 연결
36~39줄- 비유
- 새 시험 전에 어제 합격표를 서랍에서 뺀다.
- 비유의 끝
- 실패 뒤 evidence가 없다는 것과 failure 원인을 기록했다는 것은 다르다.
한 query 모양
comment·placeholder·meta-command·semicolon·금지어·required pattern을 regex로 본다.
- 코드 연결
51~112줄- 비유
- 봉투 겉면의 필수 칸과 금지 단어를 검사한다.
- 비유의 끝
- SQL parser가 아니어서 quoted string과 grammar를 완전히 이해하지 않는다.
두 savepoint probe
202 +7과 101 +11을 각각 주입하고 rollback해 EMPTY로 돌아오는지 본다.
- 코드 연결
145~198줄- 비유
- 두 장부 칸을 따로 틀렸다가 원상복구한다.
- 비유의 끝
- fixture에 없는 account id와 복잡한 data 분포는 다루지 않는다.
정리 뒤 공개
down 성공과 failure 부재를 확인한 다음 tmp를 final evidence로 옮긴다.
- 코드 연결
245~282줄- 비유
- 실험실 철거 확인 뒤 완성 도장을 공개함에 붙인다.
- 비유의 끝
- same-directory move가 signature·fsync·writer lock까지 제공하지는 않는다.
왜 계좌가 둘인가히토리 → 니지카 → 료 → 키타
-
히토리
202 mismatch만 맞으면 query가 일반적인가요?
-
니지카
WHERE account_id=202로 외운 답도 그 한 번은 맞을 수 있어.
-
료
그래서 101에 +11을 주입해 101|111|100|11을 별도로 요구한다.
-
키타
primary와 alternate oracle을 둘 다 설명하겠습니다.
regex의 경계히토리 → 니지카 → 료 → 키타
-
히토리
금지어 목록이면 SQL parser와 같나요?
-
니지카
아니, comment를 regex로 지우고 단어 모양을 보는 정적 근사야.
-
료
quoted string에 든 단어에도 반응할 수 있어.
-
키타
fail-closed guard와 grammar proof를 구분하겠습니다.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 259줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F05-L01 | param( |
격리 장부 CTE 격리 validator의 validator header·일 좌표 절차 카드는 ‘isolated CTE validator parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다’라고 읽는다. | CTE 격리 validator의 validator header·일 좌표의 실제 뜻: isolated CTE validator parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C01 원문 〔param(〕다.
|
| 2줄F05-L02 | [ |
증거 포장대의 CTE 격리 validator의 validator header·이 좌표 봉인 공정은 parameter binder에 $ProjectRoot 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. | CTE 격리 validator의 validator header·이 좌표의 실제 뜻: parameter binder에 $ProjectRoot 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. 근거 원문은 F05-C01 원문 〔[Parameter(Mandatory = $true)][string]$ProjectRoot,〕다.
|
| 3줄F05-L03 | [ |
실패 폐쇄형 통로에서 CTE 격리 validator의 validator header·삼 좌표 문턱은 ‘parameter binder에 $ComposeProject 선언과 기본값 ("w17-cte-retrieval-" + [guid]::NewGuid().ToString("N").Substring(0, 8)) 계약을 추가한다’ 역할이다. | CTE 격리 validator의 validator header·삼 좌표의 실제 뜻: parameter binder에 $ComposeProject 선언과 기본값 ("w17-cte-retrieval-" + [guid]::NewGuid().ToString("N").Substring(0, 8)) 계약을 추가한다. 근거 원문은 F05-C01 원문 〔[string]$ComposeProject = ("w17-cte-retrieval-" + [guid]::NewGuid().ToString("N").Substring(0…〕다.
|
| 4줄F05-L04 | ) |
컨테이너 실험실 CTE 격리 validator의 validator header·사 좌표 안내는 ‘script parameter list의 마지막 delimiter를 닫는다’ 작업만 지시한다. | CTE 격리 validator의 validator header·사 좌표의 실제 뜻: script parameter list의 마지막 delimiter를 닫는다. 근거 원문은 F05-C01 원문 〔)〕다.
|
| 6줄F05-L06 | Set-StrictMode -Version Latest |
원장 대사 시뮬레이터 CTE 격리 validator의 validator header·육 좌표 단추는 PowerShell StrictMode Latest를 활성화한다. | CTE 격리 validator의 validator header·육 좌표의 실제 뜻: PowerShell StrictMode Latest를 활성화한다. 근거 원문은 F05-C01 원문 〔Set-StrictMode -Version Latest〕다.
|
| 7줄F05-L07 | $ErrorActionPreference = |
파일 증거 조립선 CTE 격리 validator의 validator header·칠 좌표 공정이 맡은 일은 PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. | CTE 격리 validator의 validator header·칠 좌표의 실제 뜻: PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. 근거 원문은 F05-C01 원문 〔$ErrorActionPreference = "Stop"〕다.
|
| 9줄F05-L09 | function Restore-EnvironmentValue { |
STARRY 운영실의 CTE 격리 validator의 environment helper·구 좌표 스위치는 ‘environment restoration function header function Restore-EnvironmentValue {가 child 범위를 연다. body는 아직 실행되지 않았다’라는 현재 동작만 맡는다. | CTE 격리 validator의 environment helper·구 좌표의 실제 뜻: environment restoration function header function Restore-EnvironmentValue {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔function Restore-EnvironmentValue {〕다.
|
| 10줄F05-L10 | param( |
대사 실험대 CTE 격리 validator의 environment helper·십 좌표 레버를 당기면 helper parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 environment helper·십 좌표의 실제 뜻: helper parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔param(〕다.
|
| 11줄F05-L11 | [ |
검증 관제판의 CTE 격리 validator의 environment helper·십일 좌표 표식은 ‘Restore-EnvironmentValue helper의 mandatory string Name parameter를 선언한다’ 상태 전환을 가리킨다. | CTE 격리 validator의 environment helper·십일 좌표의 실제 뜻: Restore-EnvironmentValue helper의 mandatory string Name parameter를 선언한다. 근거 원문은 F05-C02 원문 〔[Parameter(Mandatory = $true)][string]$Name,〕다.
|
| 12줄F05-L12 | [ |
격리 장부 CTE 격리 validator의 environment helper·십이 좌표 절차 카드는 ‘Restore-EnvironmentValue helper의 mandatory boolean Existed parameter를 선언한다’라고 읽는다. | CTE 격리 validator의 environment helper·십이 좌표의 실제 뜻: Restore-EnvironmentValue helper의 mandatory boolean Existed parameter를 선언한다. 근거 원문은 F05-C02 원문 〔[Parameter(Mandatory = $true)][bool]$Existed,〕다.
|
| 13줄F05-L13 | [ |
증거 포장대의 CTE 격리 validator의 environment helper·십삼 좌표 봉인 공정은 parameter binder에 $Value 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. | CTE 격리 validator의 environment helper·십삼 좌표의 실제 뜻: parameter binder에 $Value 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. 근거 원문은 F05-C02 원문 〔[AllowNull()][string]$Value〕다.
|
| 14줄F05-L14 | ) |
실패 폐쇄형 통로에서 CTE 격리 validator의 environment helper·십사 좌표 문턱은 ‘helper parameter list의 마지막 delimiter를 닫는다’ 역할이다. | CTE 격리 validator의 environment helper·십사 좌표의 실제 뜻: helper parameter list의 마지막 delimiter를 닫는다. 근거 원문은 F05-C02 원문 〔)〕다.
|
| 15줄F05-L15 | if ( |
컨테이너 실험실 CTE 격리 validator의 environment helper·십오 좌표 안내는 ‘prior environment value existed condition header if ($Existed) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 environment helper·십오 좌표의 실제 뜻: prior environment value existed condition header if ($Existed) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔if ($Existed) {〕다.
|
| 16줄F05-L16 | Set-Item -LiteralPath "Env: |
SQL 검수대의 CTE 격리 validator의 environment helper·십육 좌표 한 동작은 PowerShell statement Set-Item -LiteralPath "Env:$Name" -Value $Value의 현재 연산을 평가한다. | CTE 격리 validator의 environment helper·십육 좌표의 실제 뜻: PowerShell statement Set-Item -LiteralPath "Env:$Name" -Value $Value의 현재 연산을 평가한다. 근거 원문은 F05-C02 원문 〔Set-Item -LiteralPath "Env:$Name" -Value $Value〕다.
|
| 17줄F05-L17 | } else { |
원장 대사 시뮬레이터 CTE 격리 validator의 environment helper·십칠 좌표 단추는 prior environment value absent branch header } else {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 environment helper·십칠 좌표의 실제 뜻: prior environment value absent branch header } else {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔} else {〕다.
|
| 18줄F05-L18 | Remove-Item -LiteralPath "Env: |
파일 증거 조립선 CTE 격리 validator의 environment helper·십팔 좌표 공정이 맡은 일은 PowerShell statement Remove-Item -LiteralPath "Env:$Name" -ErrorAction SilentlyContinue의 현재 연산을 평가한다. | CTE 격리 validator의 environment helper·십팔 좌표의 실제 뜻: PowerShell statement Remove-Item -LiteralPath "Env:$Name" -ErrorAction SilentlyContinue의 현재 연산을 평가한다. 근거 원문은 F05-C02 원문 〔Remove-Item -LiteralPath "Env:$Name" -ErrorAction SilentlyContinue〕다.
|
| 19줄F05-L19 | } |
CTE 격리 validator의 environment helper·십구 좌표는 환경 변수 원상복구 helper 점검표에서 ‘restore-or-remove environment branch의 마지막 delimiter를 닫는다’ 봉투에 대응한다. | CTE 격리 validator의 environment helper·십구 좌표의 실제 뜻: restore-or-remove environment branch의 마지막 delimiter를 닫는다. 근거 원문은 F05-C02 원문 〔}〕다.
|
| 20줄F05-L20 | } |
STARRY 운영실의 CTE 격리 validator의 environment helper·이십 좌표 스위치는 ‘Restore-EnvironmentValue function의 마지막 delimiter를 닫는다’라는 현재 동작만 맡는다. | CTE 격리 validator의 environment helper·이십 좌표의 실제 뜻: Restore-EnvironmentValue function의 마지막 delimiter를 닫는다. 근거 원문은 F05-C02 원문 〔}〕다.
|
| 22줄F05-L22 | if ( |
검증 관제판의 CTE 격리 validator의 ProjectRoot absolute guard·이십이 좌표 표식은 ‘ProjectRoot absolute-path rejection condition header if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 상태 전환을 가리킨다. | CTE 격리 validator의 ProjectRoot absolute guard·이십이 좌표의 실제 뜻: ProjectRoot absolute-path rejection condition header if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C03 원문 〔if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {〕다.
|
| 23줄F05-L23 | throw "ProjectRoot must be an absolute learner project path" |
격리 장부 CTE 격리 validator의 ProjectRoot absolute guard·이십삼 좌표 절차 카드는 ‘현재 failure branch를 "ProjectRoot must be an absolute learner project path" 예외로 중단한다’라고 읽는다. | CTE 격리 validator의 ProjectRoot absolute guard·이십삼 좌표의 실제 뜻: 현재 failure branch를 "ProjectRoot must be an absolute learner project path" 예외로 중단한다. 근거 원문은 F05-C03 원문 〔throw "ProjectRoot must be an absolute learner project path"〕다.
|
| 24줄F05-L24 | } |
증거 포장대의 CTE 격리 validator의 ProjectRoot absolute guard·이십사 좌표 봉인 공정은 absolute ProjectRoot rejection의 마지막 delimiter를 닫는다. | CTE 격리 validator의 ProjectRoot absolute guard·이십사 좌표의 실제 뜻: absolute ProjectRoot rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C03 원문 〔}〕다.
|
| 25줄F05-L25 | if ( |
실패 폐쇄형 통로에서 CTE 격리 validator의 ComposeProject name guard·이십오 좌표 문턱은 ‘ComposeProject name rejection condition header if ($ComposeProject -cnotmatch "^[a-z0-9][a-z0-9_-]{0,62}$") {가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 ComposeProject name guard·이십오 좌표의 실제 뜻: ComposeProject name rejection condition header if ($ComposeProject -cnotmatch "^[a-z0-9][a-z0-9_-]{0,62}$") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C03 원문 〔if ($ComposeProject -cnotmatch "^[a-z0-9][a-z0-9_-]{0,62}$") {〕다.
|
| 26줄F05-L26 | throw "ComposeProject must contain only lowercase letters, |
컨테이너 실험실 CTE 격리 validator의 ComposeProject name guard·이십육 좌표 안내는 ‘현재 failure branch를 "ComposeProject must contain only lowercase letters, digits, underscore, or hyphen" 예외로 중단한다’ 작업만 지시한다. | CTE 격리 validator의 ComposeProject name guard·이십육 좌표의 실제 뜻: 현재 failure branch를 "ComposeProject must contain only lowercase letters, digits, underscore, or hyphen" 예외로 중단한다. 근거 원문은 F05-C03 원문 〔throw "ComposeProject must contain only lowercase letters, digits, underscore, or hyphen"〕다.
|
| 27줄F05-L27 | } |
SQL 검수대의 CTE 격리 validator의 ComposeProject name guard·이십칠 좌표 한 동작은 ComposeProject syntax rejection의 마지막 delimiter를 닫는다. | CTE 격리 validator의 ComposeProject name guard·이십칠 좌표의 실제 뜻: ComposeProject syntax rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C03 원문 〔}〕다.
|
| 29줄F05-L29 | $project = |
파일 증거 조립선 CTE 격리 validator의 fixed path derivation·이십구 좌표 공정이 맡은 일은 $project에 현재 식 (Resolve-Path -LiteralPath $ProjectRoot).Path의 평가값을 할당한다. | CTE 격리 validator의 fixed path derivation·이십구 좌표의 실제 뜻: $project에 현재 식 (Resolve-Path -LiteralPath $ProjectRoot).Path의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$project = (Resolve-Path -LiteralPath $ProjectRoot).Path〕다.
|
| 30줄F05-L30 | $referenceRoot = |
CTE 격리 validator의 fixed path derivation·삼십 좌표는 프로젝트 경로와 stale evidence 선삭제 점검표에서 ‘$referenceRoot에 현재 식 Split-Path -Parent $PSScriptRoot의 평가값을 할당한다’ 봉투에 대응한다. | CTE 격리 validator의 fixed path derivation·삼십 좌표의 실제 뜻: $referenceRoot에 현재 식 Split-Path -Parent $PSScriptRoot의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$referenceRoot = Split-Path -Parent $PSScriptRoot〕다.
|
| 31줄F05-L31 | $compose = |
STARRY 운영실의 CTE 격리 validator의 fixed path derivation·삼십일 좌표 스위치는 ‘$compose에 현재 식 Join-Path $referenceRoot "compose.yaml"의 평가값을 할당한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 fixed path derivation·삼십일 좌표의 실제 뜻: $compose에 현재 식 Join-Path $referenceRoot "compose.yaml"의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$compose = Join-Path $referenceRoot "compose.yaml"〕다.
|
| 32줄F05-L32 | $sourcePath = |
대사 실험대 CTE 격리 validator의 fixed path derivation·삼십이 좌표 레버를 당기면 $sourcePath에 현재 식 Join-Path $project "evidence\w17\reconcile-cte.sql"의 평가값을 할당한다. | CTE 격리 validator의 fixed path derivation·삼십이 좌표의 실제 뜻: $sourcePath에 현재 식 Join-Path $project "evidence\w17\reconcile-cte.sql"의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$sourcePath = Join-Path $project "evidence\w17\reconcile-cte.sql"〕다.
|
| 33줄F05-L33 | $evidenceDir = |
검증 관제판의 CTE 격리 validator의 fixed path derivation·삼십삼 좌표 표식은 ‘$evidenceDir에 현재 식 Join-Path $project "evidence\w17"의 평가값을 할당한다’ 상태 전환을 가리킨다. | CTE 격리 validator의 fixed path derivation·삼십삼 좌표의 실제 뜻: $evidenceDir에 현재 식 Join-Path $project "evidence\w17"의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$evidenceDir = Join-Path $project "evidence\w17"〕다.
|
| 34줄F05-L34 | $evidencePath = |
격리 장부 CTE 격리 validator의 fixed path derivation·삼십사 좌표 절차 카드는 ‘$evidencePath에 현재 식 Join-Path $evidenceDir "reconcile-cte-run.txt"의 평가값을 할당한다’라고 읽는다. | CTE 격리 validator의 fixed path derivation·삼십사 좌표의 실제 뜻: $evidencePath에 현재 식 Join-Path $evidenceDir "reconcile-cte-run.txt"의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$evidencePath = Join-Path $evidenceDir "reconcile-cte-run.txt"〕다.
|
| 36줄F05-L36 | New-Item -ItemType Directory -Force -Path $evidenceDir | Out-Null |
실패 폐쇄형 통로에서 CTE 격리 validator의 stale evidence removal·삼십육 좌표 문턱은 ‘learner evidence/w17 directory가 없으면 만들고 있으면 유지한다’ 역할이다. | CTE 격리 validator의 stale evidence removal·삼십육 좌표의 실제 뜻: learner evidence/w17 directory가 없으면 만들고 있으면 유지한다. 근거 원문은 F05-C03 원문 〔New-Item -ItemType Directory -Force -Path $evidenceDir | Out-Null〕다.
|
| 37줄F05-L37 | if ( |
컨테이너 실험실 CTE 격리 validator의 stale evidence removal·삼십칠 좌표 안내는 ‘stale evidence existence condition header if (Test-Path -LiteralPath $evidencePath) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 stale evidence removal·삼십칠 좌표의 실제 뜻: stale evidence existence condition header if (Test-Path -LiteralPath $evidencePath) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C03 원문 〔if (Test-Path -LiteralPath $evidencePath) {〕다.
|
| 38줄F05-L38 | Remove-Item -LiteralPath $evidencePath -Force |
SQL 검수대의 CTE 격리 validator의 stale evidence removal·삼십팔 좌표 한 동작은 기존 reconcile-cte-run.txt를 실행 전에 강제로 삭제한다. | CTE 격리 validator의 stale evidence removal·삼십팔 좌표의 실제 뜻: 기존 reconcile-cte-run.txt를 실행 전에 강제로 삭제한다. 근거 원문은 F05-C03 원문 〔Remove-Item -LiteralPath $evidencePath -Force〕다.
|
| 39줄F05-L39 | } |
원장 대사 시뮬레이터 CTE 격리 validator의 stale evidence removal·삼십구 좌표 단추는 stale evidence removal condition의 마지막 delimiter를 닫는다. | CTE 격리 validator의 stale evidence removal·삼십구 좌표의 실제 뜻: stale evidence removal condition의 마지막 delimiter를 닫는다. 근거 원문은 F05-C03 원문 〔}〕다.
|
| 41줄F05-L41 | if ( |
CTE 격리 validator의 source leaf existence guard·사십일 좌표는 learner SQL 존재·containment·placeholder 검사 점검표에서 ‘learner SQL missing-file condition header if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | CTE 격리 validator의 source leaf existence guard·사십일 좌표의 실제 뜻: learner SQL missing-file condition header if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {〕다.
|
| 42줄F05-L42 | throw "canonical learner SQL is missing: |
STARRY 운영실의 CTE 격리 validator의 source leaf existence guard·사십이 좌표 스위치는 ‘현재 failure branch를 "canonical learner SQL is missing: evidence/w17/reconcile-cte.sql" 예외로 중단한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 source leaf existence guard·사십이 좌표의 실제 뜻: 현재 failure branch를 "canonical learner SQL is missing: evidence/w17/reconcile-cte.sql" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "canonical learner SQL is missing: evidence/w17/reconcile-cte.sql"〕다.
|
| 43줄F05-L43 | } |
대사 실험대 CTE 격리 validator의 source leaf existence guard·사십삼 좌표 레버를 당기면 canonical learner source missing-file rejection 범위를 닫는다. | CTE 격리 validator의 source leaf existence guard·사십삼 좌표의 실제 뜻: canonical learner source missing-file rejection 범위를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다.
|
| 45줄F05-L45 | $resolvedSource = |
격리 장부 CTE 격리 validator의 resolved source containment guard·사십오 좌표 절차 카드는 ‘$resolvedSource에 현재 식 (Resolve-Path -LiteralPath $sourcePath).Path의 평가값을 할당한다’라고 읽는다. | CTE 격리 validator의 resolved source containment guard·사십오 좌표의 실제 뜻: $resolvedSource에 현재 식 (Resolve-Path -LiteralPath $sourcePath).Path의 평가값을 할당한다. 근거 원문은 F05-C04 원문 〔$resolvedSource = (Resolve-Path -LiteralPath $sourcePath).Path〕다.
|
| 46줄F05-L46 | $projectPrefix = |
증거 포장대의 CTE 격리 validator의 resolved source containment guard·사십육 좌표 봉인 공정은 $projectPrefix에 현재 식 $project.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) + […의 평가값을 할당한다. | CTE 격리 validator의 resolved source containment guard·사십육 좌표의 실제 뜻: $projectPrefix에 현재 식 $project.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) + […의 평가값을 할당한다. 근거 원문은 F05-C04 원문 〔$projectPrefix = $project.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectoryS…〕다.
|
| 47줄F05-L47 | if ( |
실패 폐쇄형 통로에서 CTE 격리 validator의 resolved source containment guard·사십칠 좌표 문턱은 ‘ProjectRoot containment rejection condition header if (-not $resolvedSource.StartsWith($projectPrefix, [StringComparison]::OrdinalIgnoreCase)) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 resolved source containment guard·사십칠 좌표의 실제 뜻: ProjectRoot containment rejection condition header if (-not $resolvedSource.StartsWith($projectPrefix, [StringComparison]::OrdinalIgnoreCase)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if (-not $resolvedSource.StartsWith($projectPrefix, [StringComparison]::OrdinalIgnoreCase)) {〕다.
|
| 48줄F05-L48 | throw "learner SQL must remain below ProjectRoot" |
컨테이너 실험실 CTE 격리 validator의 resolved source containment guard·사십팔 좌표 안내는 ‘현재 failure branch를 "learner SQL must remain below ProjectRoot" 예외로 중단한다’ 작업만 지시한다. | CTE 격리 validator의 resolved source containment guard·사십팔 좌표의 실제 뜻: 현재 failure branch를 "learner SQL must remain below ProjectRoot" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "learner SQL must remain below ProjectRoot"〕다.
|
| 49줄F05-L49 | } |
SQL 검수대의 CTE 격리 validator의 resolved source containment guard·사십구 좌표 한 동작은 resolved source containment rejection 범위를 닫는다. | CTE 격리 validator의 resolved source containment guard·사십구 좌표의 실제 뜻: resolved source containment rejection 범위를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다.
|
| 51줄F05-L51 | $learnerSql = |
파일 증거 조립선 CTE 격리 validator의 raw source empty guard·오십일 좌표 공정이 맡은 일은 $learnerSql에 현재 식 Get-Content -Raw -LiteralPath $resolvedSource의 평가값을 할당한다. | CTE 격리 validator의 raw source empty guard·오십일 좌표의 실제 뜻: $learnerSql에 현재 식 Get-Content -Raw -LiteralPath $resolvedSource의 평가값을 할당한다. 근거 원문은 F05-C04 원문 〔$learnerSql = Get-Content -Raw -LiteralPath $resolvedSource〕다.
|
| 52줄F05-L52 | if ( |
CTE 격리 validator의 raw source empty guard·오십이 좌표는 learner SQL 존재·containment·placeholder 검사 점검표에서 ‘empty learner source condition header if ([string]::IsNullOrWhiteSpace($learnerSql)) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | CTE 격리 validator의 raw source empty guard·오십이 좌표의 실제 뜻: empty learner source condition header if ([string]::IsNullOrWhiteSpace($learnerSql)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if ([string]::IsNullOrWhiteSpace($learnerSql)) {〕다.
|
| 53줄F05-L53 | throw "reconcile-cte. |
STARRY 운영실의 CTE 격리 validator의 raw source empty guard·오십삼 좌표 스위치는 ‘현재 failure branch를 "reconcile-cte.sql is empty" 예외로 중단한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 raw source empty guard·오십삼 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql is empty" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "reconcile-cte.sql is empty"〕다.
|
| 54줄F05-L54 | } |
대사 실험대 CTE 격리 validator의 raw source empty guard·오십사 좌표 레버를 당기면 empty raw source rejection의 마지막 delimiter를 닫는다. | CTE 격리 validator의 raw source empty guard·오십사 좌표의 실제 뜻: empty raw source rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다.
|
| 56줄F05-L56 | $inspection = |
격리 장부 CTE 격리 validator의 comment stripping guard·오십육 좌표 절차 카드는 ‘block comment 구간을 inspection 문자열에서 공백으로 치환한다’라고 읽는다. | CTE 격리 validator의 comment stripping guard·오십육 좌표의 실제 뜻: block comment 구간을 inspection 문자열에서 공백으로 치환한다. 근거 원문은 F05-C04 원문 〔$inspection = [regex]::Replace($learnerSql, "(?s)/\*.*?\*/", " ")〕다.
|
| 57줄F05-L57 | $inspection = |
증거 포장대의 CTE 격리 validator의 comment stripping guard·오십칠 좌표 봉인 공정은 line comment tail을 inspection 문자열에서 공백으로 치환한다. | CTE 격리 validator의 comment stripping guard·오십칠 좌표의 실제 뜻: line comment tail을 inspection 문자열에서 공백으로 치환한다. 근거 원문은 F05-C04 원문 〔$inspection = [regex]::Replace($inspection, "(?m)--.*$", " ")〕다.
|
| 58줄F05-L58 | $inspection = |
실패 폐쇄형 통로에서 CTE 격리 validator의 comment stripping guard·오십팔 좌표 문턱은 ‘$inspection에 현재 식 $inspection.Trim()의 평가값을 할당한다’ 역할이다. | CTE 격리 validator의 comment stripping guard·오십팔 좌표의 실제 뜻: $inspection에 현재 식 $inspection.Trim()의 평가값을 할당한다. 근거 원문은 F05-C04 원문 〔$inspection = $inspection.Trim()〕다.
|
| 59줄F05-L59 | if ( |
컨테이너 실험실 CTE 격리 validator의 comment stripping guard·오십구 좌표 안내는 ‘comments-only source condition header if ([string]::IsNullOrWhiteSpace($inspection)) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 comment stripping guard·오십구 좌표의 실제 뜻: comments-only source condition header if ([string]::IsNullOrWhiteSpace($inspection)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if ([string]::IsNullOrWhiteSpace($inspection)) {〕다.
|
| 60줄F05-L60 | throw "reconcile-cte. |
SQL 검수대의 CTE 격리 validator의 comment stripping guard·육십 좌표 한 동작은 현재 failure branch를 "reconcile-cte.sql contains comments only" 예외로 중단한다. | CTE 격리 validator의 comment stripping guard·육십 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql contains comments only" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "reconcile-cte.sql contains comments only"〕다.
|
| 61줄F05-L61 | } |
원장 대사 시뮬레이터 CTE 격리 validator의 comment stripping guard·육십일 좌표 단추는 comments-only rejection의 마지막 delimiter를 닫는다. | CTE 격리 validator의 comment stripping guard·육십일 좌표의 실제 뜻: comments-only rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다.
|
| 62줄F05-L62 | if ( |
파일 증거 조립선 CTE 격리 validator의 placeholder guard·육십이 좌표 공정이 맡은 일은 placeholder rejection condition header if ($inspection -match "(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER|YOUR_QUERY|WRITE_QUERY|REPLACE_ME…가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 placeholder guard·육십이 좌표의 실제 뜻: placeholder rejection condition header if ($inspection -match "(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER|YOUR_QUERY|WRITE_QUERY|REPLACE_ME…가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if ($inspection -match "(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER|YOUR_QUERY|WRITE_QUERY|REPLACE_ME…〕다.
|
| 63줄F05-L63 | throw "reconcile-cte. |
CTE 격리 validator의 placeholder guard·육십삼 좌표는 learner SQL 존재·containment·placeholder 검사 점검표에서 ‘현재 failure branch를 "reconcile-cte.sql contains an unresolved placeholder" 예외로 중단한다’ 봉투에 대응한다. | CTE 격리 validator의 placeholder guard·육십삼 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql contains an unresolved placeholder" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "reconcile-cte.sql contains an unresolved placeholder"〕다.
|
| 64줄F05-L64 | } |
STARRY 운영실의 CTE 격리 validator의 placeholder guard·육십사 좌표 스위치는 ‘placeholder rejection의 마지막 delimiter를 닫는다’라는 현재 동작만 맡는다. | CTE 격리 validator의 placeholder guard·육십사 좌표의 실제 뜻: placeholder rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다.
|
| 65줄F05-L65 | if ( |
대사 실험대 CTE 격리 validator의 meta-command guard·육십오 좌표 레버를 당기면 psql meta-command rejection condition header if ($inspection -match "(?m)^\s*\\") {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 meta-command guard·육십오 좌표의 실제 뜻: psql meta-command rejection condition header if ($inspection -match "(?m)^\s*\\") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if ($inspection -match "(?m)^\s*\\") {〕다.
|
| 66줄F05-L66 | throw "psql meta-commands are forbidden in learner SQL" |
검증 관제판의 CTE 격리 validator의 meta-command guard·육십육 좌표 표식은 ‘현재 failure branch를 "psql meta-commands are forbidden in learner SQL" 예외로 중단한다’ 상태 전환을 가리킨다. | CTE 격리 validator의 meta-command guard·육십육 좌표의 실제 뜻: 현재 failure branch를 "psql meta-commands are forbidden in learner SQL" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "psql meta-commands are forbidden in learner SQL"〕다.
|
| 67줄F05-L67 | } |
격리 장부 CTE 격리 validator의 meta-command guard·육십칠 좌표 절차 카드는 ‘meta-command rejection의 마지막 delimiter를 닫는다’라고 읽는다. | CTE 격리 validator의 meta-command guard·육십칠 좌표의 실제 뜻: meta-command rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다.
|
| 69줄F05-L69 | $query = |
실패 폐쇄형 통로에서 CTE 격리 validator의 semicolon cardinality guard·육십구 좌표 문턱은 ‘$query에 현재 식 $inspection.Trim()의 평가값을 할당한다’ 역할이다. | CTE 격리 validator의 semicolon cardinality guard·육십구 좌표의 실제 뜻: $query에 현재 식 $inspection.Trim()의 평가값을 할당한다. 근거 원문은 F05-C05 원문 〔$query = $inspection.Trim()〕다.
|
| 70줄F05-L70 | if ( |
컨테이너 실험실 CTE 격리 validator의 semicolon cardinality guard·칠십 좌표 안내는 ‘trailing semicolon normalization condition header if ($query.EndsWith(";")) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 semicolon cardinality guard·칠십 좌표의 실제 뜻: trailing semicolon normalization condition header if ($query.EndsWith(";")) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($query.EndsWith(";")) {〕다.
|
| 71줄F05-L71 | $query = |
SQL 검수대의 CTE 격리 validator의 semicolon cardinality guard·칠십일 좌표 한 동작은 $query에 현재 식 $query.Substring(0, $query.Length - 1).TrimEnd()의 평가값을 할당한다. | CTE 격리 validator의 semicolon cardinality guard·칠십일 좌표의 실제 뜻: $query에 현재 식 $query.Substring(0, $query.Length - 1).TrimEnd()의 평가값을 할당한다. 근거 원문은 F05-C05 원문 〔$query = $query.Substring(0, $query.Length - 1).TrimEnd()〕다.
|
| 72줄F05-L72 | } |
원장 대사 시뮬레이터 CTE 격리 validator의 semicolon cardinality guard·칠십이 좌표 단추는 one trailing semicolon trim의 마지막 delimiter를 닫는다. | CTE 격리 validator의 semicolon cardinality guard·칠십이 좌표의 실제 뜻: one trailing semicolon trim의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다.
|
| 73줄F05-L73 | if ( |
파일 증거 조립선 CTE 격리 validator의 semicolon cardinality guard·칠십삼 좌표 공정이 맡은 일은 additional semicolon rejection condition header if ($query.Contains(";")) {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 semicolon cardinality guard·칠십삼 좌표의 실제 뜻: additional semicolon rejection condition header if ($query.Contains(";")) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($query.Contains(";")) {〕다.
|
| 74줄F05-L74 | throw "reconcile-cte. |
CTE 격리 validator의 semicolon cardinality guard·칠십사 좌표는 단일 read-only CTE SELECT 검사 점검표에서 ‘현재 failure branch를 "reconcile-cte.sql must contain exactly one SELECT statement" 예외로 중단한다’ 봉투에 대응한다. | CTE 격리 validator의 semicolon cardinality guard·칠십사 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql must contain exactly one SELECT statement" 예외로 중단한다. 근거 원문은 F05-C05 원문 〔throw "reconcile-cte.sql must contain exactly one SELECT statement"〕다.
|
| 75줄F05-L75 | } |
STARRY 운영실의 CTE 격리 validator의 semicolon cardinality guard·칠십오 좌표 스위치는 ‘internal semicolon rejection의 마지막 delimiter를 닫는다’라는 현재 동작만 맡는다. | CTE 격리 validator의 semicolon cardinality guard·칠십오 좌표의 실제 뜻: internal semicolon rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다.
|
| 77줄F05-L77 | $inspectQuery = |
검증 관제판의 CTE 격리 validator의 WITH prefix guard·칠십칠 좌표 표식은 ‘query에서 block-comment 모양을 한 번 더 공백 치환해 inspectQuery를 만든다’ 상태 전환을 가리킨다. | CTE 격리 validator의 WITH prefix guard·칠십칠 좌표의 실제 뜻: query에서 block-comment 모양을 한 번 더 공백 치환해 inspectQuery를 만든다. 근거 원문은 F05-C05 원문 〔$inspectQuery = [regex]::Replace($query, "(?s)/\*.*?\*/", " ")〕다.
|
| 78줄F05-L78 | $inspectQuery = |
격리 장부 CTE 격리 validator의 WITH prefix guard·칠십팔 좌표 절차 카드는 ‘inspectQuery에서 line-comment tail을 다시 공백 치환한다’라고 읽는다. | CTE 격리 validator의 WITH prefix guard·칠십팔 좌표의 실제 뜻: inspectQuery에서 line-comment tail을 다시 공백 치환한다. 근거 원문은 F05-C05 원문 〔$inspectQuery = [regex]::Replace($inspectQuery, "(?m)--.*$", " ")〕다.
|
| 79줄F05-L79 | if ( |
증거 포장대의 CTE 격리 validator의 WITH prefix guard·칠십구 좌표 봉인 공정은 WITH-prefix rejection condition header if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 WITH prefix guard·칠십구 좌표의 실제 뜻: WITH-prefix rejection condition header if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {〕다.
|
| 80줄F05-L80 | throw "reconcile-cte. |
실패 폐쇄형 통로에서 CTE 격리 validator의 WITH prefix guard·팔십 좌표 문턱은 ‘현재 failure branch를 "reconcile-cte.sql must start with a CTE (WITH)" 예외로 중단한다’ 역할이다. | CTE 격리 validator의 WITH prefix guard·팔십 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql must start with a CTE (WITH)" 예외로 중단한다. 근거 원문은 F05-C05 원문 〔throw "reconcile-cte.sql must start with a CTE (WITH)"〕다.
|
| 81줄F05-L81 | } |
컨테이너 실험실 CTE 격리 validator의 WITH prefix guard·팔십일 좌표 안내는 ‘WITH-prefix rejection의 마지막 delimiter를 닫는다’ 작업만 지시한다. | CTE 격리 validator의 WITH prefix guard·팔십일 좌표의 실제 뜻: WITH-prefix rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다.
|
| 82줄F05-L82 | if ( |
SQL 검수대의 CTE 격리 validator의 mutation keyword guard·팔십이 좌표 한 동작은 mutating/control keyword rejection condition header if ($inspectQuery -match "(?i)\b(INSERT|UPDATE|DELETE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|…가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 mutation keyword guard·팔십이 좌표의 실제 뜻: mutating/control keyword rejection condition header if ($inspectQuery -match "(?i)\b(INSERT|UPDATE|DELETE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|…가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($inspectQuery -match "(?i)\b(INSERT|UPDATE|DELETE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|…〕다.
|
| 83줄F05-L83 | throw "reconcile-cte. |
원장 대사 시뮬레이터 CTE 격리 validator의 mutation keyword guard·팔십삼 좌표 단추는 현재 failure branch를 "reconcile-cte.sql may contain only a read-only CTE SELECT" 예외로 중단한다. | CTE 격리 validator의 mutation keyword guard·팔십삼 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql may contain only a read-only CTE SELECT" 예외로 중단한다. 근거 원문은 F05-C05 원문 〔throw "reconcile-cte.sql may contain only a read-only CTE SELECT"〕다.
|
| 84줄F05-L84 | } |
파일 증거 조립선 CTE 격리 validator의 mutation keyword guard·팔십사 좌표 공정이 맡은 일은 read-only keyword rejection의 마지막 delimiter를 닫는다. | CTE 격리 validator의 mutation keyword guard·팔십사 좌표의 실제 뜻: read-only keyword rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다.
|
| 85줄F05-L85 | if ( |
CTE 격리 validator의 unsafe function guard·팔십오 좌표는 단일 read-only CTE SELECT 검사 점검표에서 ‘unsafe function rejection condition header if ($inspectQuery -match "(?i)\b(pg_sleep|dblink|lo_import|lo_export)\b") {가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | CTE 격리 validator의 unsafe function guard·팔십오 좌표의 실제 뜻: unsafe function rejection condition header if ($inspectQuery -match "(?i)\b(pg_sleep|dblink|lo_import|lo_export)\b") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($inspectQuery -match "(?i)\b(pg_sleep|dblink|lo_import|lo_export)\b") {〕다.
|
| 86줄F05-L86 | throw "unsafe PostgreSQL function is forbidden in learner SQL" |
STARRY 운영실의 CTE 격리 validator의 unsafe function guard·팔십육 좌표 스위치는 ‘현재 failure branch를 "unsafe PostgreSQL function is forbidden in learner SQL" 예외로 중단한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 unsafe function guard·팔십육 좌표의 실제 뜻: 현재 failure branch를 "unsafe PostgreSQL function is forbidden in learner SQL" 예외로 중단한다. 근거 원문은 F05-C05 원문 〔throw "unsafe PostgreSQL function is forbidden in learner SQL"〕다.
|
| 87줄F05-L87 | } |
대사 실험대 CTE 격리 validator의 unsafe function guard·팔십칠 좌표 레버를 당기면 unsafe function rejection의 마지막 delimiter를 닫는다. | CTE 격리 validator의 unsafe function guard·팔십칠 좌표의 실제 뜻: unsafe function rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다.
|
| 89줄F05-L89 | $requiredPatterns = |
격리 장부 CTE 격리 validator의 required-pattern definition·팔십구 좌표 절차 카드는 ‘required-pattern ordered map header $requiredPatterns = [ordered]@{가 child 범위를 연다. body는 아직 실행되지 않았다’라고 읽는다. | CTE 격리 validator의 required-pattern definition·팔십구 좌표의 실제 뜻: required-pattern ordered map header $requiredPatterns = [ordered]@{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔$requiredPatterns = [ordered]@{〕다.
|
| 90줄F05-L90 | "ledger_sum CTE" = |
증거 포장대의 CTE 격리 validator의 required-pattern definition·구십 좌표 봉인 공정은 현재 success/failure summary literal "ledger_sum CTE" = "(?i)\bledger_sum\s+AS\s*\("을 output stream에 보낸다. | CTE 격리 validator의 required-pattern definition·구십 좌표의 실제 뜻: 현재 success/failure summary literal "ledger_sum CTE" = "(?i)\bledger_sum\s+AS\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"ledger_sum CTE" = "(?i)\bledger_sum\s+AS\s*\("〕다.
|
| 91줄F05-L91 | "compared CTE" = |
실패 폐쇄형 통로에서 CTE 격리 validator의 required-pattern definition·구십일 좌표 문턱은 ‘현재 success/failure summary literal "compared CTE" = "(?i)\bcompared\s+AS\s*\("을 output stream에 보낸다’ 역할이다. | CTE 격리 validator의 required-pattern definition·구십일 좌표의 실제 뜻: 현재 success/failure summary literal "compared CTE" = "(?i)\bcompared\s+AS\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"compared CTE" = "(?i)\bcompared\s+AS\s*\("〕다.
|
| 92줄F05-L92 | "mismatch CTE" = |
컨테이너 실험실 CTE 격리 validator의 required-pattern definition·구십이 좌표 안내는 ‘현재 success/failure summary literal "mismatch CTE" = "(?i)\bmismatch\s+AS\s*\("을 output stream에 보낸다’ 작업만 지시한다. | CTE 격리 validator의 required-pattern definition·구십이 좌표의 실제 뜻: 현재 success/failure summary literal "mismatch CTE" = "(?i)\bmismatch\s+AS\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"mismatch CTE" = "(?i)\bmismatch\s+AS\s*\("〕다.
|
| 93줄F05-L93 | "account source" = |
SQL 검수대의 CTE 격리 validator의 required-pattern definition·구십삼 좌표 한 동작은 현재 success/failure summary literal "account source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?account\b"을 output stream에 보낸다. | CTE 격리 validator의 required-pattern definition·구십삼 좌표의 실제 뜻: 현재 success/failure summary literal "account source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?account\b"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"account source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?account\b"〕다.
|
| 94줄F05-L94 | "ledger source" = |
원장 대사 시뮬레이터 CTE 격리 validator의 required-pattern definition·구십사 좌표 단추는 현재 success/failure summary literal "ledger source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?ledger_entry\b"을 output stream에 보낸다. | CTE 격리 validator의 required-pattern definition·구십사 좌표의 실제 뜻: 현재 success/failure summary literal "ledger source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?ledger_entry\b"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"ledger source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?ledger_entry\b"〕다.
|
| 95줄F05-L95 | "ledger aggregation" = |
파일 증거 조립선 CTE 격리 validator의 required-pattern definition·구십오 좌표 공정이 맡은 일은 현재 success/failure summary literal "ledger aggregation" = "(?i)\bSUM\s*\("을 output stream에 보낸다. | CTE 격리 validator의 required-pattern definition·구십오 좌표의 실제 뜻: 현재 success/failure summary literal "ledger aggregation" = "(?i)\bSUM\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"ledger aggregation" = "(?i)\bSUM\s*\("〕다.
|
| 96줄F05-L96 | "account grain" = |
CTE 격리 validator의 required-pattern definition·구십육 좌표는 필수 CTE 모양과 signed total 검사 점검표에서 ‘현재 success/failure summary literal "account grain" = "(?is)\bGROUP\s+BY\b.*?\baccount_id\b"을 output stream에 보낸다’ 봉투에 대응한다. | CTE 격리 validator의 required-pattern definition·구십육 좌표의 실제 뜻: 현재 success/failure summary literal "account grain" = "(?is)\bGROUP\s+BY\b.*?\baccount_id\b"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"account grain" = "(?is)\bGROUP\s+BY\b.*?\baccount_id\b"〕다.
|
| 97줄F05-L97 | "account-to-ledger join" = |
STARRY 운영실의 CTE 격리 validator의 required-pattern definition·구십칠 좌표 스위치는 ‘현재 success/failure summary literal "account-to-ledger join" = "(?i)\b(?:LEFT\s+)?JOIN\b"을 output stream에 보낸다’라는 현재 동작만 맡는다. | CTE 격리 validator의 required-pattern definition·구십칠 좌표의 실제 뜻: 현재 success/failure summary literal "account-to-ledger join" = "(?i)\b(?:LEFT\s+)?JOIN\b"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"account-to-ledger join" = "(?i)\b(?:LEFT\s+)?JOIN\b"〕다.
|
| 98줄F05-L98 | "missing-ledger handling" = |
대사 실험대 CTE 격리 validator의 required-pattern definition·구십팔 좌표 레버를 당기면 현재 success/failure summary literal "missing-ledger handling" = "(?i)\bCOALESCE\s*\("을 output stream에 보낸다. | CTE 격리 validator의 required-pattern definition·구십팔 좌표의 실제 뜻: 현재 success/failure summary literal "missing-ledger handling" = "(?i)\bCOALESCE\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"missing-ledger handling" = "(?i)\bCOALESCE\s*\("〕다.
|
| 99줄F05-L99 | "mismatch predicate" = |
검증 관제판의 CTE 격리 validator의 required-pattern definition·구십구 좌표 표식은 ‘현재 success/failure summary literal "mismatch predicate" = "(?i)(?:<>|!=|\bIS\s+DISTINCT\s+FROM\b)"을 output stream에 보낸다’ 상태 전환을 가리킨다. | CTE 격리 validator의 required-pattern definition·구십구 좌표의 실제 뜻: 현재 success/failure summary literal "mismatch predicate" = "(?i)(?:<>|!=|\bIS\s+DISTINCT\s+FROM\b)"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"mismatch predicate" = "(?i)(?:<>|!=|\bIS\s+DISTINCT\s+FROM\b)"〕다.
|
| 100줄F05-L100 | } |
격리 장부 CTE 격리 validator의 required-pattern definition·백 좌표 절차 카드는 ‘열 개 required CTE-shape regex를 담은 ordered map을 닫는다’라고 읽는다. | CTE 격리 validator의 required-pattern definition·백 좌표의 실제 뜻: 열 개 required CTE-shape regex를 담은 ordered map을 닫는다. 근거 원문은 F05-C06 원문 〔}〕다.
|
| 101줄F05-L101 | foreach ( |
증거 포장대의 CTE 격리 validator의 required-pattern consumption·백일 좌표 봉인 공정은 required-pattern iteration header foreach ($entry in $requiredPatterns.GetEnumerator()) {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 required-pattern consumption·백일 좌표의 실제 뜻: required-pattern iteration header foreach ($entry in $requiredPatterns.GetEnumerator()) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔foreach ($entry in $requiredPatterns.GetEnumerator()) {〕다.
|
| 102줄F05-L102 | if ( |
실패 폐쇄형 통로에서 CTE 격리 validator의 required-pattern consumption·백이 좌표 문턱은 ‘missing required construct condition header if ($inspectQuery -cnotmatch $entry.Value) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 required-pattern consumption·백이 좌표의 실제 뜻: missing required construct condition header if ($inspectQuery -cnotmatch $entry.Value) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔if ($inspectQuery -cnotmatch $entry.Value) {〕다.
|
| 103줄F05-L103 | throw "reconcile-cte. |
컨테이너 실험실 CTE 격리 validator의 required-pattern consumption·백삼 좌표 안내는 ‘현재 failure branch를 "reconcile-cte.sql is missing required construct: $($entry.Key)" 예외로 중단한다’ 작업만 지시한다. | CTE 격리 validator의 required-pattern consumption·백삼 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql is missing required construct: $($entry.Key)" 예외로 중단한다. 근거 원문은 F05-C06 원문 〔throw "reconcile-cte.sql is missing required construct: $($entry.Key)"〕다.
|
| 104줄F05-L104 | } |
SQL 검수대의 CTE 격리 validator의 required-pattern consumption·백사 좌표 한 동작은 one missing-pattern rejection의 마지막 delimiter를 닫는다. | CTE 격리 validator의 required-pattern consumption·백사 좌표의 실제 뜻: one missing-pattern rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C06 원문 〔}〕다.
|
| 105줄F05-L105 | } |
원장 대사 시뮬레이터 CTE 격리 validator의 required-pattern consumption·백오 좌표 단추는 각 required-pattern 누락을 검사하는 foreach 범위를 닫는다. | CTE 격리 validator의 required-pattern consumption·백오 좌표의 실제 뜻: 각 required-pattern 누락을 검사하는 foreach 범위를 닫는다. 근거 원문은 F05-C06 원문 〔}〕다.
|
| 106줄F05-L106 | $usesSignedAmount = |
파일 증거 조립선 CTE 격리 validator의 signed-total choice·백육 좌표 공정이 맡은 일은 $usesSignedAmount에 현재 식 $inspectQuery -cmatch "(?i)\bsigned_amount\b"의 평가값을 할당한다. | CTE 격리 validator의 signed-total choice·백육 좌표의 실제 뜻: $usesSignedAmount에 현재 식 $inspectQuery -cmatch "(?i)\bsigned_amount\b"의 평가값을 할당한다. 근거 원문은 F05-C06 원문 〔$usesSignedAmount = $inspectQuery -cmatch "(?i)\bsigned_amount\b"〕다.
|
| 107줄F05-L107 | $usesCaseAmount = |
CTE 격리 validator의 signed-total choice·백칠 좌표는 필수 CTE 모양과 signed total 검사 점검표에서 ‘$usesCaseAmount에 현재 식 ($inspectQuery -cmatch "(?i)\bCASE\b") -and의 평가값을 할당한다’ 봉투에 대응한다. | CTE 격리 validator의 signed-total choice·백칠 좌표의 실제 뜻: $usesCaseAmount에 현재 식 ($inspectQuery -cmatch "(?i)\bCASE\b") -and의 평가값을 할당한다. 근거 원문은 F05-C06 원문 〔$usesCaseAmount = ($inspectQuery -cmatch "(?i)\bCASE\b") -and〕다.
|
| 108줄F05-L108 | ( |
STARRY 운영실의 CTE 격리 validator의 signed-total choice·백팔 좌표 스위치는 ‘CASE 대안이 entry_type token도 사용하는지를 AND 조건으로 잇는다’라는 현재 동작만 맡는다. | CTE 격리 validator의 signed-total choice·백팔 좌표의 실제 뜻: CASE 대안이 entry_type token도 사용하는지를 AND 조건으로 잇는다. 근거 원문은 F05-C06 원문 〔($inspectQuery -cmatch "(?i)\bentry_type\b") -and〕다.
|
| 109줄F05-L109 | ( |
대사 실험대 CTE 격리 validator의 signed-total choice·백구 좌표 레버를 당기면 CASE 대안이 amount token까지 사용하는지를 마지막 AND 조건으로 잇는다. | CTE 격리 validator의 signed-total choice·백구 좌표의 실제 뜻: CASE 대안이 amount token까지 사용하는지를 마지막 AND 조건으로 잇는다. 근거 원문은 F05-C06 원문 〔($inspectQuery -cmatch "(?i)\bamount\b")〕다.
|
| 110줄F05-L110 | if ( |
검증 관제판의 CTE 격리 validator의 signed-total choice·백십 좌표 표식은 ‘missing signed-total condition header if (-not ($usesSignedAmount -or $usesCaseAmount)) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 상태 전환을 가리킨다. | CTE 격리 validator의 signed-total choice·백십 좌표의 실제 뜻: missing signed-total condition header if (-not ($usesSignedAmount -or $usesCaseAmount)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔if (-not ($usesSignedAmount -or $usesCaseAmount)) {〕다.
|
| 111줄F05-L111 | throw "reconcile-cte. |
격리 장부 CTE 격리 validator의 signed-total choice·백십일 좌표 절차 카드는 ‘현재 failure branch를 "reconcile-cte.sql must derive the signed ledger total" 예외로 중단한다’라고 읽는다. | CTE 격리 validator의 signed-total choice·백십일 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql must derive the signed ledger total" 예외로 중단한다. 근거 원문은 F05-C06 원문 〔throw "reconcile-cte.sql must derive the signed ledger total"〕다.
|
| 112줄F05-L112 | } |
증거 포장대의 CTE 격리 validator의 signed-total choice·백십이 좌표 봉인 공정은 signed-total representation gate의 마지막 delimiter를 닫는다. | CTE 격리 validator의 signed-total choice·백십이 좌표의 실제 뜻: signed-total representation gate의 마지막 delimiter를 닫는다. 근거 원문은 F05-C06 원문 〔}〕다.
|
| 114줄F05-L114 | $sourceHash = |
컨테이너 실험실 CTE 격리 validator의 hash and transaction header·백십사 좌표 안내는 ‘resolved learner SQL의 SHA-256을 소문자로 계산한다’ 작업만 지시한다. | CTE 격리 validator의 hash and transaction header·백십사 좌표의 실제 뜻: resolved learner SQL의 SHA-256을 소문자로 계산한다. 근거 원문은 F05-C07 원문 〔$sourceHash = (Get-FileHash -LiteralPath $resolvedSource -Algorithm SHA256).Hash.ToLowerInvar…〕다.
|
| 115줄F05-L115 | $schema = |
SQL 검수대의 CTE 격리 validator의 hash and transaction header·백십오 좌표 한 동작은 12자 GUID suffix를 붙여 격리 schema 이름을 만든다. | CTE 격리 validator의 hash and transaction header·백십오 좌표의 실제 뜻: 12자 GUID suffix를 붙여 격리 schema 이름을 만든다. 근거 원문은 F05-C07 원문 〔$schema = "w17_cte_" + [guid]::NewGuid().ToString("N").Substring(0, 12)〕다.
|
| 116줄F05-L116 | $nativeSql = |
원장 대사 시뮬레이터 CTE 격리 validator의 hash and transaction header·백십육 좌표 단추는 native SQL here-string header $nativeSql = @"가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 hash and transaction header·백십육 좌표의 실제 뜻: native SQL here-string header $nativeSql = @"가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔$nativeSql = @"〕다.
|
| 117줄F05-L117 | \set ON_ERROR_STOP on |
파일 증거 조립선 CTE 격리 validator의 hash and transaction header·백십칠 좌표 공정이 맡은 일은 native psql session에서 ON_ERROR_STOP을 켠다. | CTE 격리 validator의 hash and transaction header·백십칠 좌표의 실제 뜻: native psql session에서 ON_ERROR_STOP을 켠다. 근거 원문은 F05-C07 원문 〔\set ON_ERROR_STOP on〕다.
|
| 118줄F05-L118 | BEGIN; |
CTE 격리 validator의 hash and transaction header·백십팔 좌표는 source hash·격리 schema·fixture 점검표에서 ‘native SQL transaction을 BEGIN으로 연다’ 봉투에 대응한다. | CTE 격리 validator의 hash and transaction header·백십팔 좌표의 실제 뜻: native SQL transaction을 BEGIN으로 연다. 근거 원문은 F05-C07 원문 〔BEGIN;〕다.
|
| 119줄F05-L119 | SET LOCAL statement_timeout = |
STARRY 운영실의 CTE 격리 validator의 hash and transaction header·백십구 좌표 스위치는 ‘현재 transaction에 10초 statement timeout을 설정한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 hash and transaction header·백십구 좌표의 실제 뜻: 현재 transaction에 10초 statement timeout을 설정한다. 근거 원문은 F05-C07 원문 〔SET LOCAL statement_timeout = '10s';〕다.
|
| 120줄F05-L120 | CREATE SCHEMA $schema; |
대사 실험대 CTE 격리 validator의 hash and transaction header·백이십 좌표 레버를 당기면 GUID로 만든 random schema를 current transaction 안에 생성한다. | CTE 격리 validator의 hash and transaction header·백이십 좌표의 실제 뜻: GUID로 만든 random schema를 current transaction 안에 생성한다. 근거 원문은 F05-C07 원문 〔CREATE SCHEMA $schema;〕다.
|
| 121줄F05-L121 | SET LOCAL search_path TO $schema, |
검증 관제판의 CTE 격리 validator의 hash and transaction header·백이십일 좌표 표식은 ‘random schema와 pg_catalog를 transaction-local search_path로 둔다’ 상태 전환을 가리킨다. | CTE 격리 validator의 hash and transaction header·백이십일 좌표의 실제 뜻: random schema와 pg_catalog를 transaction-local search_path로 둔다. 근거 원문은 F05-C07 원문 〔SET LOCAL search_path TO $schema, pg_catalog;〕다.
|
| 123줄F05-L123 | CREATE TABLE account ( |
증거 포장대의 CTE 격리 validator의 account table·백이십삼 좌표 봉인 공정은 account table definition header CREATE TABLE account (가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 account table·백이십삼 좌표의 실제 뜻: account table definition header CREATE TABLE account (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔CREATE TABLE account (〕다.
|
| 124줄F05-L124 | id BIGINT PRIMARY KEY, |
실패 폐쇄형 통로에서 CTE 격리 validator의 account table·백이십사 좌표 문턱은 ‘account fixture의 id를 BIGINT PRIMARY KEY로 선언한다’ 역할이다. | CTE 격리 validator의 account table·백이십사 좌표의 실제 뜻: account fixture의 id를 BIGINT PRIMARY KEY로 선언한다. 근거 원문은 F05-C07 원문 〔id BIGINT PRIMARY KEY,〕다.
|
| 125줄F05-L125 | balance BIGINT NOT NULL CHECK ( |
컨테이너 실험실 CTE 격리 validator의 account table·백이십오 좌표 안내는 ‘fixture column balance의 type·constraint fragment를 선언한다’ 작업만 지시한다. | CTE 격리 validator의 account table·백이십오 좌표의 실제 뜻: fixture column balance의 type·constraint fragment를 선언한다. 근거 원문은 F05-C07 원문 〔balance BIGINT NOT NULL CHECK (balance >= 0)〕다.
|
| 126줄F05-L126 | ); |
SQL 검수대의 CTE 격리 validator의 account table·백이십육 좌표 한 동작은 balance check를 포함한 account table definition을 닫는다. | CTE 격리 validator의 account table·백이십육 좌표의 실제 뜻: balance check를 포함한 account table definition을 닫는다. 근거 원문은 F05-C07 원문 〔);〕다.
|
| 127줄F05-L127 | CREATE TABLE ledger_entry ( |
원장 대사 시뮬레이터 CTE 격리 validator의 ledger table·백이십칠 좌표 단추는 ledger_entry table definition header CREATE TABLE ledger_entry (가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 ledger table·백이십칠 좌표의 실제 뜻: ledger_entry table definition header CREATE TABLE ledger_entry (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔CREATE TABLE ledger_entry (〕다.
|
| 128줄F05-L128 | id BIGINT PRIMARY KEY, |
파일 증거 조립선 CTE 격리 validator의 ledger table·백이십팔 좌표 공정이 맡은 일은 ledger_entry fixture의 자체 id를 BIGINT PRIMARY KEY로 선언한다. | CTE 격리 validator의 ledger table·백이십팔 좌표의 실제 뜻: ledger_entry fixture의 자체 id를 BIGINT PRIMARY KEY로 선언한다. 근거 원문은 F05-C07 원문 〔id BIGINT PRIMARY KEY,〕다.
|
| 129줄F05-L129 | account_id BIGINT NOT NULL REFERENCES account( |
CTE 격리 validator의 ledger table·백이십구 좌표는 source hash·격리 schema·fixture 점검표에서 ‘ledger_entry.account_id를 NOT NULL account(id) foreign key로 선언한다’ 봉투에 대응한다. | CTE 격리 validator의 ledger table·백이십구 좌표의 실제 뜻: ledger_entry.account_id를 NOT NULL account(id) foreign key로 선언한다. 근거 원문은 F05-C07 원문 〔account_id BIGINT NOT NULL REFERENCES account(id),〕다.
|
| 130줄F05-L130 | entry_type VARCHAR( |
STARRY 운영실의 CTE 격리 validator의 ledger table·백삼십 좌표 스위치는 ‘fixture column entry_type의 type·constraint fragment를 선언한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 ledger table·백삼십 좌표의 실제 뜻: fixture column entry_type의 type·constraint fragment를 선언한다. 근거 원문은 F05-C07 원문 〔entry_type VARCHAR(32) NOT NULL,〕다.
|
| 131줄F05-L131 | amount BIGINT NOT NULL CHECK ( |
대사 실험대 CTE 격리 validator의 ledger table·백삼십일 좌표 레버를 당기면 ledger_entry.amount를 positive BIGINT로 제한한다. | CTE 격리 validator의 ledger table·백삼십일 좌표의 실제 뜻: ledger_entry.amount를 positive BIGINT로 제한한다. 근거 원문은 F05-C07 원문 〔amount BIGINT NOT NULL CHECK (amount > 0),〕다.
|
| 132줄F05-L132 | signed_amount BIGINT NOT NULL, |
검증 관제판의 CTE 격리 validator의 ledger table·백삼십이 좌표 표식은 ‘ledger_entry.signed_amount를 부호 있는 BIGINT로 선언한다’ 상태 전환을 가리킨다. | CTE 격리 validator의 ledger table·백삼십이 좌표의 실제 뜻: ledger_entry.signed_amount를 부호 있는 BIGINT로 선언한다. 근거 원문은 F05-C07 원문 〔signed_amount BIGINT NOT NULL,〕다.
|
| 133줄F05-L133 | created_at TIMESTAMPTZ NOT NULL |
격리 장부 CTE 격리 validator의 ledger table·백삼십삼 좌표 절차 카드는 ‘fixture column created_at의 type·constraint fragment를 선언한다’라고 읽는다. | CTE 격리 validator의 ledger table·백삼십삼 좌표의 실제 뜻: fixture column created_at의 type·constraint fragment를 선언한다. 근거 원문은 F05-C07 원문 〔created_at TIMESTAMPTZ NOT NULL〕다.
|
| 134줄F05-L134 | ); |
증거 포장대의 CTE 격리 validator의 ledger table·백삼십사 좌표 봉인 공정은 created_at까지 포함한 ledger_entry table definition을 닫는다. | CTE 격리 validator의 ledger table·백삼십사 좌표의 실제 뜻: created_at까지 포함한 ledger_entry table definition을 닫는다. 근거 원문은 F05-C07 원문 〔);〕다.
|
| 136줄F05-L136 | INSERT INTO account( |
컨테이너 실험실 CTE 격리 validator의 account fixture header·백삼십육 좌표 안내는 ‘account fixture VALUES list header INSERT INTO account(id, balance) VALUES가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 account fixture header·백삼십육 좌표의 실제 뜻: account fixture VALUES list header INSERT INTO account(id, balance) VALUES가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔INSERT INTO account(id, balance) VALUES〕다.
|
| 137줄F05-L137 | ( |
SQL 검수대의 CTE 격리 validator의 alternate account 101 baseline·백삼십칠 좌표 한 동작은 account 101을 stored balance 100으로 fixture에 넣는다. | CTE 격리 validator의 alternate account 101 baseline·백삼십칠 좌표의 실제 뜻: account 101을 stored balance 100으로 fixture에 넣는다. 근거 원문은 F05-C07 원문 〔(101, 100),〕다.
|
| 138줄F05-L138 | ( |
원장 대사 시뮬레이터 CTE 격리 validator의 primary account 202 baseline·백삼십팔 좌표 단추는 account 202를 stored balance 75로 fixture에 넣는다. | CTE 격리 validator의 primary account 202 baseline·백삼십팔 좌표의 실제 뜻: account 202를 stored balance 75로 fixture에 넣는다. 근거 원문은 F05-C07 원문 〔(202, 75),〕다.
|
| 139줄F05-L139 | ( |
파일 증거 조립선 CTE 격리 validator의 no-ledger account 303 baseline·백삼십구 좌표 공정이 맡은 일은 account 303을 balance 0으로 넣고 account VALUES statement를 끝낸다. | CTE 격리 validator의 no-ledger account 303 baseline·백삼십구 좌표의 실제 뜻: account 303을 balance 0으로 넣고 account VALUES statement를 끝낸다. 근거 원문은 F05-C07 원문 〔(303, 0);〕다.
|
| 140줄F05-L140 | INSERT INTO ledger_entry( |
CTE 격리 validator의 ledger fixture·백사십 좌표는 source hash·격리 schema·fixture 점검표에서 ‘ledger fixture VALUES list header INSERT INTO ledger_entry(id, account_id, entry_type, amount, signed_amount, created_at) VALUES가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | CTE 격리 validator의 ledger fixture·백사십 좌표의 실제 뜻: ledger fixture VALUES list header INSERT INTO ledger_entry(id, account_id, entry_type, amount, signed_amount, created_at) VALUES가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔INSERT INTO ledger_entry(id, account_id, entry_type, amount, signed_amount, created_at) VALUES〕다.
|
| 141줄F05-L141 | ( |
STARRY 운영실의 CTE 격리 validator의 ledger fixture·백사십일 좌표 스위치는 ‘account 101에 DEPOSIT +120 ledger row를 넣는다’라는 현재 동작만 맡는다. | CTE 격리 validator의 ledger fixture·백사십일 좌표의 실제 뜻: account 101에 DEPOSIT +120 ledger row를 넣는다. 근거 원문은 F05-C07 원문 〔(1001, 101, 'DEPOSIT', 120, 120, '2027-01-01T00:00:00Z'),〕다.
|
| 142줄F05-L142 | ( |
대사 실험대 CTE 격리 validator의 ledger fixture·백사십이 좌표 레버를 당기면 account 101에 WITHDRAW signed_amount -20 row를 넣는다. | CTE 격리 validator의 ledger fixture·백사십이 좌표의 실제 뜻: account 101에 WITHDRAW signed_amount -20 row를 넣는다. 근거 원문은 F05-C07 원문 〔(1002, 101, 'WITHDRAW', 20, -20, '2027-01-02T00:00:00Z'),〕다.
|
| 143줄F05-L143 | ( |
검증 관제판의 CTE 격리 validator의 ledger fixture·백사십삼 좌표 표식은 ‘account 202에 +75 ledger row를 넣고 ledger INSERT를 끝낸다’ 상태 전환을 가리킨다. | CTE 격리 validator의 ledger fixture·백사십삼 좌표의 실제 뜻: account 202에 +75 ledger row를 넣고 ledger INSERT를 끝낸다. 근거 원문은 F05-C07 원문 〔(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');〕다.
|
| 145줄F05-L145 | SELECT 'W17_BASELINE= |
증거 포장대의 CTE 격리 validator의 baseline marker expression head·백사십오 좌표 봉인 공정은 baseline marker SELECT expression header SELECT 'W17_BASELINE=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 baseline marker expression head·백사십오 좌표의 실제 뜻: baseline marker SELECT expression header SELECT 'W17_BASELINE=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔SELECT 'W17_BASELINE=' || COALESCE(〕다.
|
| 146줄F05-L146 | string_agg( |
실패 폐쇄형 통로에서 CTE 격리 validator의 baseline EMPTY marker·백사십육 좌표 문턱은 ‘baseline string_agg call header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 baseline EMPTY marker·백사십육 좌표의 실제 뜻: baseline string_agg call header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔string_agg(〕다.
|
| 147줄F05-L147 | account_id: |
컨테이너 실험실 CTE 격리 validator의 baseline EMPTY marker·백사십칠 좌표 안내는 ‘첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다’ 작업만 지시한다. | CTE 격리 validator의 baseline EMPTY marker·백사십칠 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C08 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다.
|
| 148줄F05-L148 | ', |
SQL 검수대의 CTE 격리 validator의 baseline EMPTY marker·백사십팔 좌표 한 동작은 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. | CTE 격리 validator의 baseline EMPTY marker·백사십팔 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C08 원문 〔',' ORDER BY account_id〕다.
|
| 149줄F05-L149 | ), |
원장 대사 시뮬레이터 CTE 격리 validator의 baseline EMPTY marker·백사십구 좌표 단추는 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. | CTE 격리 validator의 baseline EMPTY marker·백사십구 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C08 원문 〔),〕다.
|
| 150줄F05-L150 | 'EMPTY' |
파일 증거 조립선 CTE 격리 validator의 baseline EMPTY marker·백오십 좌표 공정이 맡은 일은 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. | CTE 격리 validator의 baseline EMPTY marker·백오십 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C08 원문 〔'EMPTY'〕다.
|
| 151줄F05-L151 | ) FROM ( |
CTE 격리 validator의 baseline EMPTY marker·백오십일 좌표는 baseline과 202 mismatch 왕복 점검표에서 ‘baseline learner-result subquery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | CTE 격리 validator의 baseline EMPTY marker·백오십일 좌표의 실제 뜻: baseline learner-result subquery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔) FROM (〕다.
|
| 152줄F05-L152 | $query |
STARRY 운영실의 CTE 격리 validator의 baseline EMPTY marker·백오십이 좌표 스위치는 ‘baseline wrapper 안에 inspected learner query text를 삽입한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 baseline EMPTY marker·백오십이 좌표의 실제 뜻: baseline wrapper 안에 inspected learner query text를 삽입한다. 근거 원문은 F05-C08 원문 〔$query〕다.
|
| 153줄F05-L153 | ) AS learner_result; |
대사 실험대 CTE 격리 validator의 baseline EMPTY marker·백오십삼 좌표 레버를 당기면 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. | CTE 격리 validator의 baseline EMPTY marker·백오십삼 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C08 원문 〔) AS learner_result;〕다.
|
| 155줄F05-L155 | SAVEPOINT primary_mismatch; |
격리 장부 CTE 격리 validator의 primary mutation setup·백오십오 좌표 절차 카드는 ‘primary_mismatch savepoint를 만든다’라고 읽는다. | CTE 격리 validator의 primary mutation setup·백오십오 좌표의 실제 뜻: primary_mismatch savepoint를 만든다. 근거 원문은 F05-C08 원문 〔SAVEPOINT primary_mismatch;〕다.
|
| 156줄F05-L156 | UPDATE account SET balance = |
증거 포장대의 CTE 격리 validator의 primary mutation setup·백오십육 좌표 봉인 공정은 account 202 balance를 75에서 82로 7 올린다. | CTE 격리 validator의 primary mutation setup·백오십육 좌표의 실제 뜻: account 202 balance를 75에서 82로 7 올린다. 근거 원문은 F05-C08 원문 〔UPDATE account SET balance = balance + 7 WHERE id = 202;〕다.
|
| 157줄F05-L157 | SELECT 'W17_INJECTED= |
실패 폐쇄형 통로에서 CTE 격리 validator의 post-update anomaly report head·백오십칠 좌표 문턱은 ‘primary injected marker SELECT expression header SELECT 'W17_INJECTED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 post-update anomaly report head·백오십칠 좌표의 실제 뜻: primary injected marker SELECT expression header SELECT 'W17_INJECTED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔SELECT 'W17_INJECTED=' || COALESCE(〕다.
|
| 158줄F05-L158 | string_agg( |
컨테이너 실험실 CTE 격리 validator의 post-update aggregation opener·백오십팔 좌표 안내는 ‘aggregation after account 202 gained seven units header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 post-update aggregation opener·백오십팔 좌표의 실제 뜻: aggregation after account 202 gained seven units header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔string_agg(〕다.
|
| 159줄F05-L159 | account_id: |
SQL 검수대의 CTE 격리 validator의 primary 202-82-75-7 marker·백오십구 좌표 한 동작은 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. | CTE 격리 validator의 primary 202-82-75-7 marker·백오십구 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C08 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다.
|
| 160줄F05-L160 | ', |
원장 대사 시뮬레이터 CTE 격리 validator의 primary 202-82-75-7 marker·백육십 좌표 단추는 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. | CTE 격리 validator의 primary 202-82-75-7 marker·백육십 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C08 원문 〔',' ORDER BY account_id〕다.
|
| 161줄F05-L161 | ), |
파일 증거 조립선 CTE 격리 validator의 primary 202-82-75-7 marker·백육십일 좌표 공정이 맡은 일은 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. | CTE 격리 validator의 primary 202-82-75-7 marker·백육십일 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C08 원문 〔),〕다.
|
| 162줄F05-L162 | 'EMPTY' |
CTE 격리 validator의 primary 202-82-75-7 marker·백육십이 좌표는 baseline과 202 mismatch 왕복 점검표에서 ‘202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다’ 봉투에 대응한다. | CTE 격리 validator의 primary 202-82-75-7 marker·백육십이 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C08 원문 〔'EMPTY'〕다.
|
| 163줄F05-L163 | ) FROM ( |
STARRY 운영실의 CTE 격리 validator의 primary 202-82-75-7 marker·백육십삼 좌표 스위치는 ‘learner-result subquery under the 202 fault header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다’라는 현재 동작만 맡는다. | CTE 격리 validator의 primary 202-82-75-7 marker·백육십삼 좌표의 실제 뜻: learner-result subquery under the 202 fault header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔) FROM (〕다.
|
| 164줄F05-L164 | $query |
대사 실험대 CTE 격리 validator의 primary 202-82-75-7 marker·백육십사 좌표 레버를 당기면 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. | CTE 격리 validator의 primary 202-82-75-7 marker·백육십사 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. 근거 원문은 F05-C08 원문 〔$query〕다.
|
| 165줄F05-L165 | ) AS learner_result; |
검증 관제판의 CTE 격리 validator의 primary 202-82-75-7 marker·백육십오 좌표 표식은 ‘202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다’ 상태 전환을 가리킨다. | CTE 격리 validator의 primary 202-82-75-7 marker·백육십오 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C08 원문 〔) AS learner_result;〕다.
|
| 166줄F05-L166 | ROLLBACK TO SAVEPOINT primary_mismatch; |
격리 장부 CTE 격리 validator의 primary rollback command·백육십육 좌표 절차 카드는 ‘primary_mismatch savepoint로 rollback한다’라고 읽는다. | CTE 격리 validator의 primary rollback command·백육십육 좌표의 실제 뜻: primary_mismatch savepoint로 rollback한다. 근거 원문은 F05-C08 원문 〔ROLLBACK TO SAVEPOINT primary_mismatch;〕다.
|
| 167줄F05-L167 | SELECT 'W17_RESTORED= |
증거 포장대의 CTE 격리 validator의 primary restored marker expression head·백육십칠 좌표 봉인 공정은 primary restored marker SELECT expression header SELECT 'W17_RESTORED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 primary restored marker expression head·백육십칠 좌표의 실제 뜻: primary restored marker SELECT expression header SELECT 'W17_RESTORED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔SELECT 'W17_RESTORED=' || COALESCE(〕다.
|
| 168줄F05-L168 | string_agg( |
실패 폐쇄형 통로에서 CTE 격리 validator의 post-primary-rollback aggregation opener·백육십팔 좌표 문턱은 ‘recovery aggregation after primary savepoint rewind header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 post-primary-rollback aggregation opener·백육십팔 좌표의 실제 뜻: recovery aggregation after primary savepoint rewind header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔string_agg(〕다.
|
| 169줄F05-L169 | account_id: |
컨테이너 실험실 CTE 격리 validator의 primary 202 rollback EMPTY marker·백육십구 좌표 안내는 ‘첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다’ 작업만 지시한다. | CTE 격리 validator의 primary 202 rollback EMPTY marker·백육십구 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C08 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다.
|
| 170줄F05-L170 | ', |
SQL 검수대의 CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십 좌표 한 동작은 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C08 원문 〔',' ORDER BY account_id〕다.
|
| 171줄F05-L171 | ), |
원장 대사 시뮬레이터 CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십일 좌표 단추는 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십일 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C08 원문 〔),〕다.
|
| 172줄F05-L172 | 'EMPTY' |
파일 증거 조립선 CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십이 좌표 공정이 맡은 일은 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십이 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C08 원문 〔'EMPTY'〕다.
|
| 173줄F05-L173 | ) FROM ( |
CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십삼 좌표는 baseline과 202 mismatch 왕복 점검표에서 ‘learner-result subquery after the first recovery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십삼 좌표의 실제 뜻: learner-result subquery after the first recovery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔) FROM (〕다.
|
| 174줄F05-L174 | $query |
STARRY 운영실의 CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십사 좌표 스위치는 ‘첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십사 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. 근거 원문은 F05-C08 원문 〔$query〕다.
|
| 175줄F05-L175 | ) AS learner_result; |
대사 실험대 CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십오 좌표 레버를 당기면 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십오 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C08 원문 〔) AS learner_result;〕다.
|
| 177줄F05-L177 | SAVEPOINT alternate_account_mismatch; |
격리 장부 CTE 격리 validator의 alternate mutation setup·백칠십칠 좌표 절차 카드는 ‘alternate_account_mismatch savepoint를 만든다’라고 읽는다. | CTE 격리 validator의 alternate mutation setup·백칠십칠 좌표의 실제 뜻: alternate_account_mismatch savepoint를 만든다. 근거 원문은 F05-C09 원문 〔SAVEPOINT alternate_account_mismatch;〕다.
|
| 178줄F05-L178 | UPDATE account SET balance = |
증거 포장대의 CTE 격리 validator의 alternate mutation setup·백칠십팔 좌표 봉인 공정은 account 101 balance를 100에서 111로 11 올린다. | CTE 격리 validator의 alternate mutation setup·백칠십팔 좌표의 실제 뜻: account 101 balance를 100에서 111로 11 올린다. 근거 원문은 F05-C09 원문 〔UPDATE account SET balance = balance + 11 WHERE id = 101;〕다.
|
| 179줄F05-L179 | SELECT 'W17_ALTERNATE_INJECTED= |
실패 폐쇄형 통로에서 CTE 격리 validator의 hardcoding probe report head·백칠십구 좌표 문턱은 ‘alternate injected marker SELECT expression header SELECT 'W17_ALTERNATE_INJECTED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 hardcoding probe report head·백칠십구 좌표의 실제 뜻: alternate injected marker SELECT expression header SELECT 'W17_ALTERNATE_INJECTED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔SELECT 'W17_ALTERNATE_INJECTED=' || COALESCE(〕다.
|
| 180줄F05-L180 | string_agg( |
컨테이너 실험실 CTE 격리 validator의 post-alternate-update aggregation opener·백팔십 좌표 안내는 ‘hardcoding-challenge aggregation after account 101 gained eleven units header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 post-alternate-update aggregation opener·백팔십 좌표의 실제 뜻: hardcoding-challenge aggregation after account 101 gained eleven units header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔string_agg(〕다.
|
| 181줄F05-L181 | account_id: |
SQL 검수대의 CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십일 좌표 한 동작은 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십일 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C09 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다.
|
| 182줄F05-L182 | ', |
원장 대사 시뮬레이터 CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십이 좌표 단추는 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십이 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C09 원문 〔',' ORDER BY account_id〕다.
|
| 183줄F05-L183 | ), |
파일 증거 조립선 CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십삼 좌표 공정이 맡은 일은 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십삼 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C09 원문 〔),〕다.
|
| 184줄F05-L184 | 'EMPTY' |
CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십사 좌표는 101 alternate mismatch와 rollback 점검표에서 ‘202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다’ 봉투에 대응한다. | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십사 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C09 원문 〔'EMPTY'〕다.
|
| 185줄F05-L185 | ) FROM ( |
STARRY 운영실의 CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십오 좌표 스위치는 ‘learner-result subquery under the alternate 101 fault header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다’라는 현재 동작만 맡는다. | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십오 좌표의 실제 뜻: learner-result subquery under the alternate 101 fault header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔) FROM (〕다.
|
| 186줄F05-L186 | $query |
대사 실험대 CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십육 좌표 레버를 당기면 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십육 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. 근거 원문은 F05-C09 원문 〔$query〕다.
|
| 187줄F05-L187 | ) AS learner_result; |
검증 관제판의 CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십칠 좌표 표식은 ‘202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다’ 상태 전환을 가리킨다. | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십칠 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C09 원문 〔) AS learner_result;〕다.
|
| 188줄F05-L188 | ROLLBACK TO SAVEPOINT alternate_account_mismatch; |
격리 장부 CTE 격리 validator의 alternate rollback command·백팔십팔 좌표 절차 카드는 ‘alternate_account_mismatch savepoint로 rollback한다’라고 읽는다. | CTE 격리 validator의 alternate rollback command·백팔십팔 좌표의 실제 뜻: alternate_account_mismatch savepoint로 rollback한다. 근거 원문은 F05-C09 원문 〔ROLLBACK TO SAVEPOINT alternate_account_mismatch;〕다.
|
| 189줄F05-L189 | SELECT 'W17_ALTERNATE_RESTORED= |
증거 포장대의 CTE 격리 validator의 second recovery report head·백팔십구 좌표 봉인 공정은 alternate restored marker SELECT expression header SELECT 'W17_ALTERNATE_RESTORED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 second recovery report head·백팔십구 좌표의 실제 뜻: alternate restored marker SELECT expression header SELECT 'W17_ALTERNATE_RESTORED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔SELECT 'W17_ALTERNATE_RESTORED=' || COALESCE(〕다.
|
| 190줄F05-L190 | string_agg( |
실패 폐쇄형 통로에서 CTE 격리 validator의 post-alternate-rollback aggregation opener·백구십 좌표 문턱은 ‘final recovery aggregation after alternate savepoint rewind header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 post-alternate-rollback aggregation opener·백구십 좌표의 실제 뜻: final recovery aggregation after alternate savepoint rewind header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔string_agg(〕다.
|
| 191줄F05-L191 | account_id: |
컨테이너 실험실 CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십일 좌표 안내는 ‘두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다’ 작업만 지시한다. | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십일 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C09 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다.
|
| 192줄F05-L192 | ', |
SQL 검수대의 CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십이 좌표 한 동작은 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십이 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C09 원문 〔',' ORDER BY account_id〕다.
|
| 193줄F05-L193 | ), |
원장 대사 시뮬레이터 CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십삼 좌표 단추는 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십삼 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C09 원문 〔),〕다.
|
| 194줄F05-L194 | 'EMPTY' |
파일 증거 조립선 CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십사 좌표 공정이 맡은 일은 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십사 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C09 원문 〔'EMPTY'〕다.
|
| 195줄F05-L195 | ) FROM ( |
CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십오 좌표는 101 alternate mismatch와 rollback 점검표에서 ‘learner-result subquery after the second recovery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다’ 봉투에 대응한다. | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십오 좌표의 실제 뜻: learner-result subquery after the second recovery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔) FROM (〕다.
|
| 196줄F05-L196 | $query |
STARRY 운영실의 CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십육 좌표 스위치는 ‘두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십육 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. 근거 원문은 F05-C09 원문 〔$query〕다.
|
| 197줄F05-L197 | ) AS learner_result; |
대사 실험대 CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십칠 좌표 레버를 당기면 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십칠 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C09 원문 〔) AS learner_result;〕다.
|
| 198줄F05-L198 | ROLLBACK; |
검증 관제판의 CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십팔 좌표 표식은 ‘native SQL transaction 전체를 rollback한다’ 상태 전환을 가리킨다. | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십팔 좌표의 실제 뜻: native SQL transaction 전체를 rollback한다. 근거 원문은 F05-C09 원문 〔ROLLBACK;〕다.
|
| 199줄F05-L199 | "@ |
격리 장부 CTE 격리 validator의 native template closure·백구십구 좌표 절차 카드는 ‘native SQL here-string의 마지막 delimiter를 닫는다’라고 읽는다. | CTE 격리 validator의 native template closure·백구십구 좌표의 실제 뜻: native SQL here-string의 마지막 delimiter를 닫는다. 근거 원문은 F05-C09 원문 〔"@〕다.
|
| 201줄F05-L201 | $hadPassword = |
실패 폐쇄형 통로에서 CTE 격리 validator의 password environment snapshot·이백일 좌표 문턱은 ‘FCL_DB_PASSWORD 환경 변수가 원래 존재했는지 기록한다’ 역할이다. | CTE 격리 validator의 password environment snapshot·이백일 좌표의 실제 뜻: FCL_DB_PASSWORD 환경 변수가 원래 존재했는지 기록한다. 근거 원문은 F05-C10 원문 〔$hadPassword = Test-Path -LiteralPath "Env:FCL_DB_PASSWORD"〕다.
|
| 202줄F05-L202 | $oldPassword = |
컨테이너 실험실 CTE 격리 validator의 password environment snapshot·이백이 좌표 안내는 ‘run 전 FCL_DB_PASSWORD 문자열을 oldPassword에 캡처한다’ 작업만 지시한다. | CTE 격리 validator의 password environment snapshot·이백이 좌표의 실제 뜻: run 전 FCL_DB_PASSWORD 문자열을 oldPassword에 캡처한다. 근거 원문은 F05-C10 원문 〔$oldPassword = $env:FCL_DB_PASSWORD〕다.
|
| 203줄F05-L203 | $hadPort = |
SQL 검수대의 CTE 격리 validator의 port environment snapshot·이백삼 좌표 한 동작은 $hadPort에 현재 식 Test-Path -LiteralPath "Env:FCL_DB_PORT"의 평가값을 할당한다. | CTE 격리 validator의 port environment snapshot·이백삼 좌표의 실제 뜻: $hadPort에 현재 식 Test-Path -LiteralPath "Env:FCL_DB_PORT"의 평가값을 할당한다. 근거 원문은 F05-C10 원문 〔$hadPort = Test-Path -LiteralPath "Env:FCL_DB_PORT"〕다.
|
| 204줄F05-L204 | $oldPort = |
원장 대사 시뮬레이터 CTE 격리 validator의 port environment snapshot·이백사 좌표 단추는 run 전 FCL_DB_PORT 문자열을 oldPort에 캡처한다. | CTE 격리 validator의 port environment snapshot·이백사 좌표의 실제 뜻: run 전 FCL_DB_PORT 문자열을 oldPort에 캡처한다. 근거 원문은 F05-C10 원문 〔$oldPort = $env:FCL_DB_PORT〕다.
|
| 205줄F05-L205 | $owned = |
파일 증거 조립선 CTE 격리 validator의 cleanup lifecycle flags·이백오 좌표 공정이 맡은 일은 Compose ownership flag를 false로 초기화한다. | CTE 격리 validator의 cleanup lifecycle flags·이백오 좌표의 실제 뜻: Compose ownership flag를 false로 초기화한다. 근거 원문은 F05-C10 원문 〔$owned = $false〕다.
|
| 206줄F05-L206 | $cleanup = |
CTE 격리 validator의 cleanup lifecycle flags·이백육 좌표는 환경과 lifecycle 상태 캡처 점검표에서 ‘$cleanup에 현재 식 $false의 평가값을 할당한다’ 봉투에 대응한다. | CTE 격리 validator의 cleanup lifecycle flags·이백육 좌표의 실제 뜻: $cleanup에 현재 식 $false의 평가값을 할당한다. 근거 원문은 F05-C10 원문 〔$cleanup = $false〕다.
|
| 207줄F05-L207 | $failure = |
STARRY 운영실의 CTE 격리 validator의 cleanup lifecycle flags·이백칠 좌표 스위치는 ‘$failure에 현재 식 $null의 평가값을 할당한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 cleanup lifecycle flags·이백칠 좌표의 실제 뜻: $failure에 현재 식 $null의 평가값을 할당한다. 근거 원문은 F05-C10 원문 〔$failure = $null〕다.
|
| 208줄F05-L208 | $nativeExit = |
대사 실험대 CTE 격리 validator의 native result sentinels·이백팔 좌표 레버를 당기면 nativeExit sentinel을 실행 전 -1로 초기화한다. | CTE 격리 validator의 native result sentinels·이백팔 좌표의 실제 뜻: nativeExit sentinel을 실행 전 -1로 초기화한다. 근거 원문은 F05-C10 원문 〔$nativeExit = -1〕다.
|
| 209줄F05-L209 | $nativeOutput = |
검증 관제판의 CTE 격리 validator의 native result sentinels·이백구 좌표 표식은 ‘nativeOutput을 빈 PowerShell array로 초기화한다’ 상태 전환을 가리킨다. | CTE 격리 validator의 native result sentinels·이백구 좌표의 실제 뜻: nativeOutput을 빈 PowerShell array로 초기화한다. 근거 원문은 F05-C10 원문 〔$nativeOutput = @()〕다.
|
| 211줄F05-L211 | try { |
증거 포장대의 CTE 격리 validator의 Compose startup·이백십일 좌표 봉인 공정은 native runner try scope header try {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 Compose startup·이백십일 좌표의 실제 뜻: native runner try scope header try {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔try {〕다.
|
| 212줄F05-L212 | $env: |
실패 폐쇄형 통로에서 CTE 격리 validator의 Compose startup·이백십이 좌표 문턱은 ‘PowerShell statement $env:FCL_DB_PASSWORD = "w17-disposable-" + [guid]::NewGuid().ToString("N")의 현재 연산을 평가한다’ 역할이다. | CTE 격리 validator의 Compose startup·이백십이 좌표의 실제 뜻: PowerShell statement $env:FCL_DB_PASSWORD = "w17-disposable-" + [guid]::NewGuid().ToString("N")의 현재 연산을 평가한다. 근거 원문은 F05-C11 원문 〔$env:FCL_DB_PASSWORD = "w17-disposable-" + [guid]::NewGuid().ToString("N")〕다.
|
| 213줄F05-L213 | $env: |
컨테이너 실험실 CTE 격리 validator의 Compose startup·이백십삼 좌표 안내는 ‘PowerShell statement $env:FCL_DB_PORT = "0"의 현재 연산을 평가한다’ 작업만 지시한다. | CTE 격리 validator의 Compose startup·이백십삼 좌표의 실제 뜻: PowerShell statement $env:FCL_DB_PORT = "0"의 현재 연산을 평가한다. 근거 원문은 F05-C11 원문 〔$env:FCL_DB_PORT = "0"〕다.
|
| 214줄F05-L214 | $owned = |
SQL 검수대의 CTE 격리 validator의 Compose startup·이백십사 좌표 한 동작은 compose up을 호출하기 전에 owned를 true로 바꾼다. | CTE 격리 validator의 Compose startup·이백십사 좌표의 실제 뜻: compose up을 호출하기 전에 owned를 true로 바꾼다. 근거 원문은 F05-C11 원문 〔$owned = $true〕다.
|
| 215줄F05-L215 | & docker compose -f $compose -p $ComposeProject up -d --wait db |
원장 대사 시뮬레이터 CTE 격리 validator의 Compose startup·이백십오 좌표 단추는 native Compose command & docker compose -f $compose -p $ComposeProject up -d --wait db를 호출한다. | CTE 격리 validator의 Compose startup·이백십오 좌표의 실제 뜻: native Compose command & docker compose -f $compose -p $ComposeProject up -d --wait db를 호출한다. 근거 원문은 F05-C11 원문 〔& docker compose -f $compose -p $ComposeProject up -d --wait db〕다.
|
| 216줄F05-L216 | if ( |
파일 증거 조립선 CTE 격리 validator의 Compose startup·이백십육 좌표 공정이 맡은 일은 Compose startup failure condition header if ($LASTEXITCODE -ne 0) {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 Compose startup·이백십육 좌표의 실제 뜻: Compose startup failure condition header if ($LASTEXITCODE -ne 0) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔if ($LASTEXITCODE -ne 0) {〕다.
|
| 217줄F05-L217 | throw "W17 CTE disposable PostgreSQL startup exit= |
CTE 격리 validator의 Compose startup·이백십칠 좌표는 Compose 기동과 native 실행 점검표에서 ‘현재 failure branch를 "W17 CTE disposable PostgreSQL startup exit=$LASTEXITCODE" 예외로 중단한다’ 봉투에 대응한다. | CTE 격리 validator의 Compose startup·이백십칠 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE disposable PostgreSQL startup exit=$LASTEXITCODE" 예외로 중단한다. 근거 원문은 F05-C11 원문 〔throw "W17 CTE disposable PostgreSQL startup exit=$LASTEXITCODE"〕다.
|
| 218줄F05-L218 | } |
STARRY 운영실의 CTE 격리 validator의 Compose startup·이백십팔 좌표 스위치는 ‘Compose startup failure guard의 마지막 delimiter를 닫는다’라는 현재 동작만 맡는다. | CTE 격리 validator의 Compose startup·이백십팔 좌표의 실제 뜻: Compose startup failure guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C11 원문 〔}〕다.
|
| 219줄F05-L219 | $container = |
대사 실험대 CTE 격리 validator의 container resolution·이백십구 좌표 레버를 당기면 $container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. | CTE 격리 validator의 container resolution·이백십구 좌표의 실제 뜻: $container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. 근거 원문은 F05-C11 원문 〔$container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()〕다.
|
| 220줄F05-L220 | if ( |
검증 관제판의 CTE 격리 validator의 container resolution·이백이십 좌표 표식은 ‘container resolution failure condition header if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($container)) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 상태 전환을 가리킨다. | CTE 격리 validator의 container resolution·이백이십 좌표의 실제 뜻: container resolution failure condition header if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($container)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($container)) {〕다.
|
| 221줄F05-L221 | throw "W17 CTE disposable PostgreSQL container resolution failed" |
격리 장부 CTE 격리 validator의 container resolution·이백이십일 좌표 절차 카드는 ‘현재 failure branch를 "W17 CTE disposable PostgreSQL container resolution failed" 예외로 중단한다’라고 읽는다. | CTE 격리 validator의 container resolution·이백이십일 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE disposable PostgreSQL container resolution failed" 예외로 중단한다. 근거 원문은 F05-C11 원문 〔throw "W17 CTE disposable PostgreSQL container resolution failed"〕다.
|
| 222줄F05-L222 | } |
증거 포장대의 CTE 격리 validator의 container resolution·이백이십이 좌표 봉인 공정은 container resolution guard의 마지막 delimiter를 닫는다. | CTE 격리 validator의 container resolution·이백이십이 좌표의 실제 뜻: container resolution guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C11 원문 〔}〕다.
|
| 224줄F05-L224 | $nativeOutput = |
컨테이너 실험실 CTE 격리 validator의 native psql execution·이백이십사 좌표 안내는 ‘native SQL here-string을 disposable PostgreSQL psql에 pipe하고 output을 배열로 모은다’ 작업만 지시한다. | CTE 격리 validator의 native psql execution·이백이십사 좌표의 실제 뜻: native SQL here-string을 disposable PostgreSQL psql에 pipe하고 output을 배열로 모은다. 근거 원문은 F05-C11 원문 〔$nativeOutput = @($nativeSql | docker exec -i $container psql -X -q -A -t -v ON_ERROR_STOP=1 …〕다.
|
| 225줄F05-L225 | $nativeExit = |
SQL 검수대의 CTE 격리 validator의 native psql execution·이백이십오 좌표 한 동작은 $nativeExit에 현재 식 $LASTEXITCODE의 평가값을 할당한다. | CTE 격리 validator의 native psql execution·이백이십오 좌표의 실제 뜻: $nativeExit에 현재 식 $LASTEXITCODE의 평가값을 할당한다. 근거 원문은 F05-C11 원문 〔$nativeExit = $LASTEXITCODE〕다.
|
| 226줄F05-L226 | if ( |
원장 대사 시뮬레이터 CTE 격리 validator의 native psql execution·이백이십육 좌표 단추는 native psql failure condition header if ($nativeExit -ne 0) {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 native psql execution·이백이십육 좌표의 실제 뜻: native psql failure condition header if ($nativeExit -ne 0) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔if ($nativeExit -ne 0) {〕다.
|
| 227줄F05-L227 | throw "W17 CTE learner SQL native exit= |
파일 증거 조립선 CTE 격리 validator의 native psql execution·이백이십칠 좌표 공정이 맡은 일은 현재 failure branch를 "W17 CTE learner SQL native exit=$nativeExitˋn$($nativeOutput -join "ˋn")" 예외로 중단한다. | CTE 격리 validator의 native psql execution·이백이십칠 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE learner SQL native exit=$nativeExitˋn$($nativeOutput -join "ˋn")" 예외로 중단한다. 근거 원문은 F05-C11 원문 〔throw "W17 CTE learner SQL native exit=$nativeExitˋn$($nativeOutput -join "ˋn")"〕다.
|
| 228줄F05-L228 | } |
CTE 격리 validator의 native psql execution·이백이십팔 좌표는 Compose 기동과 native 실행 점검표에서 ‘native psql failure guard의 마지막 delimiter를 닫는다’ 봉투에 대응한다. | CTE 격리 validator의 native psql execution·이백이십팔 좌표의 실제 뜻: native psql failure guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C11 원문 〔}〕다.
|
| 230줄F05-L230 | $markers = |
대사 실험대 CTE 격리 validator의 observed marker filter·이백삼십 좌표 레버를 당기면 observed marker array pipeline header $markers = @(가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 observed marker filter·이백삼십 좌표의 실제 뜻: observed marker array pipeline header $markers = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C12 원문 〔$markers = @(〕다.
|
| 231줄F05-L231 | $nativeOutput | |
검증 관제판의 CTE 격리 validator의 observed marker filter·이백삼십일 좌표 표식은 ‘pipeline stage $nativeOutput |로 왼쪽 값을 오른쪽 command에 전달한다’ 상태 전환을 가리킨다. | CTE 격리 validator의 observed marker filter·이백삼십일 좌표의 실제 뜻: pipeline stage $nativeOutput |로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F05-C12 원문 〔$nativeOutput |〕다.
|
| 232줄F05-L232 | ForEach-Object { |
격리 장부 CTE 격리 validator의 observed marker filter·이백삼십이 좌표 절차 카드는 ‘collection을 순회할 foreach header ForEach-Object { ([string]$_).Trim() } |를 선언한다’라고 읽는다. | CTE 격리 validator의 observed marker filter·이백삼십이 좌표의 실제 뜻: collection을 순회할 foreach header ForEach-Object { ([string]$_).Trim() } |를 선언한다. 근거 원문은 F05-C12 원문 〔ForEach-Object { ([string]$_).Trim() } |〕다.
|
| 233줄F05-L233 | Where-Object { |
증거 포장대의 CTE 격리 validator의 observed marker filter·이백삼십삼 좌표 봉인 공정은 pipeline stage Where-Object { $_ -cmatch "^W17_(BASELINE|INJECTED|RESTORED|ALTERNATE_INJECTED|ALTERNATE_REST…로 왼쪽 값을 오른쪽 command에 전달한다. | CTE 격리 validator의 observed marker filter·이백삼십삼 좌표의 실제 뜻: pipeline stage Where-Object { $_ -cmatch "^W17_(BASELINE|INJECTED|RESTORED|ALTERNATE_INJECTED|ALTERNATE_REST…로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F05-C12 원문 〔Where-Object { $_ -cmatch "^W17_(BASELINE|INJECTED|RESTORED|ALTERNATE_INJECTED|ALTERNATE_REST…〕다.
|
| 234줄F05-L234 | ) |
실패 폐쇄형 통로에서 CTE 격리 validator의 observed marker filter·이백삼십사 좌표 문턱은 ‘observed marker pipeline array의 마지막 delimiter를 닫는다’ 역할이다. | CTE 격리 validator의 observed marker filter·이백삼십사 좌표의 실제 뜻: observed marker pipeline array의 마지막 delimiter를 닫는다. 근거 원문은 F05-C12 원문 〔)〕다.
|
| 235줄F05-L235 | $expectedMarkers = |
컨테이너 실험실 CTE 격리 validator의 expected marker array head·이백삼십오 좌표 안내는 ‘expected marker array header $expectedMarkers = @(가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 expected marker array head·이백삼십오 좌표의 실제 뜻: expected marker array header $expectedMarkers = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C12 원문 〔$expectedMarkers = @(〕다.
|
| 236줄F05-L236 | "W17_BASELINE= |
SQL 검수대의 CTE 격리 validator의 expected balanced baseline·이백삼십육 좌표 한 동작은 expected sequence의 첫 값으로 balanced W17_BASELINE=EMPTY를 둔다. | CTE 격리 validator의 expected balanced baseline·이백삼십육 좌표의 실제 뜻: expected sequence의 첫 값으로 balanced W17_BASELINE=EMPTY를 둔다. 근거 원문은 F05-C12 원문 〔"W17_BASELINE=EMPTY",〕다.
|
| 237줄F05-L237 | "W17_INJECTED= |
원장 대사 시뮬레이터 CTE 격리 validator의 expected primary anomaly·이백삼십칠 좌표 단추는 expected sequence의 둘째 값으로 W17_INJECTED=202|82|75|7을 둔다. | CTE 격리 validator의 expected primary anomaly·이백삼십칠 좌표의 실제 뜻: expected sequence의 둘째 값으로 W17_INJECTED=202|82|75|7을 둔다. 근거 원문은 F05-C12 원문 〔"W17_INJECTED=202|82|75|7",〕다.
|
| 238줄F05-L238 | "W17_RESTORED= |
파일 증거 조립선 CTE 격리 validator의 expected first recovery·이백삼십팔 좌표 공정이 맡은 일은 expected sequence의 셋째 값으로 W17_RESTORED=EMPTY를 둔다. | CTE 격리 validator의 expected first recovery·이백삼십팔 좌표의 실제 뜻: expected sequence의 셋째 값으로 W17_RESTORED=EMPTY를 둔다. 근거 원문은 F05-C12 원문 〔"W17_RESTORED=EMPTY",〕다.
|
| 239줄F05-L239 | "W17_ALTERNATE_INJECTED= |
CTE 격리 validator의 expected alternate hardcoding probe·이백삼십구 좌표는 다섯 marker의 exact sequence gate 점검표에서 ‘expected sequence의 넷째 값으로 W17_ALTERNATE_INJECTED=101|111|100|11을 둔다’ 봉투에 대응한다. | CTE 격리 validator의 expected alternate hardcoding probe·이백삼십구 좌표의 실제 뜻: expected sequence의 넷째 값으로 W17_ALTERNATE_INJECTED=101|111|100|11을 둔다. 근거 원문은 F05-C12 원문 〔"W17_ALTERNATE_INJECTED=101|111|100|11",〕다.
|
| 240줄F05-L240 | "W17_ALTERNATE_RESTORED= |
STARRY 운영실의 CTE 격리 validator의 expected second recovery·이백사십 좌표 스위치는 ‘expected sequence의 마지막 값으로 W17_ALTERNATE_RESTORED=EMPTY를 둔다’라는 현재 동작만 맡는다. | CTE 격리 validator의 expected second recovery·이백사십 좌표의 실제 뜻: expected sequence의 마지막 값으로 W17_ALTERNATE_RESTORED=EMPTY를 둔다. 근거 원문은 F05-C12 원문 〔"W17_ALTERNATE_RESTORED=EMPTY"〕다.
|
| 241줄F05-L241 | ) |
대사 실험대 CTE 격리 validator의 expected array closure·이백사십일 좌표 레버를 당기면 expected five-marker array의 마지막 delimiter를 닫는다. | CTE 격리 validator의 expected array closure·이백사십일 좌표의 실제 뜻: expected five-marker array의 마지막 delimiter를 닫는다. 근거 원문은 F05-C12 원문 〔)〕다.
|
| 242줄F05-L242 | if ( |
검증 관제판의 CTE 격리 validator의 exact joined marker comparison·이백사십이 좌표 표식은 ‘exact sequence mismatch condition header if (($markers -join "ˋn") -cne ($expectedMarkers -join "ˋn")) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 상태 전환을 가리킨다. | CTE 격리 validator의 exact joined marker comparison·이백사십이 좌표의 실제 뜻: exact sequence mismatch condition header if (($markers -join "ˋn") -cne ($expectedMarkers -join "ˋn")) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C12 원문 〔if (($markers -join "ˋn") -cne ($expectedMarkers -join "ˋn")) {〕다.
|
| 243줄F05-L243 | throw "W17 CTE exact account/ |
격리 장부 CTE 격리 validator의 exact joined marker comparison·이백사십삼 좌표 절차 카드는 ‘현재 failure branch를 "W17 CTE exact account/balance/ledger/difference sentinel check failed; actual=$($markers -jo… 예외로 중단한다’라고 읽는다. | CTE 격리 validator의 exact joined marker comparison·이백사십삼 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE exact account/balance/ledger/difference sentinel check failed; actual=$($markers -jo… 예외로 중단한다. 근거 원문은 F05-C12 원문 〔throw "W17 CTE exact account/balance/ledger/difference sentinel check failed; actual=$($marke…〕다.
|
| 244줄F05-L244 | } |
증거 포장대의 CTE 격리 validator의 exact joined marker comparison·이백사십사 좌표 봉인 공정은 exact marker sequence guard의 마지막 delimiter를 닫는다. | CTE 격리 validator의 exact joined marker comparison·이백사십사 좌표의 실제 뜻: exact marker sequence guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C12 원문 〔}〕다.
|
| 245줄F05-L245 | } catch { |
실패 폐쇄형 통로에서 CTE 격리 validator의 catch finally cleanup·이백사십오 좌표 문턱은 ‘failure capture catch scope header } catch {가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 catch finally cleanup·이백사십오 좌표의 실제 뜻: failure capture catch scope header } catch {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔} catch {〕다.
|
| 246줄F05-L246 | $failure = |
컨테이너 실험실 CTE 격리 validator의 catch finally cleanup·이백사십육 좌표 안내는 ‘$failure에 현재 식 $_의 평가값을 할당한다’ 작업만 지시한다. | CTE 격리 validator의 catch finally cleanup·이백사십육 좌표의 실제 뜻: $failure에 현재 식 $_의 평가값을 할당한다. 근거 원문은 F05-C13 원문 〔$failure = $_〕다.
|
| 247줄F05-L247 | } finally { |
SQL 검수대의 CTE 격리 validator의 catch finally cleanup·이백사십칠 좌표 한 동작은 cleanup and restoration finally scope header } finally {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 catch finally cleanup·이백사십칠 좌표의 실제 뜻: cleanup and restoration finally scope header } finally {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔} finally {〕다.
|
| 248줄F05-L248 | if ( |
원장 대사 시뮬레이터 CTE 격리 validator의 catch finally cleanup·이백사십팔 좌표 단추는 owned Compose cleanup condition header if ($owned) {가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 catch finally cleanup·이백사십팔 좌표의 실제 뜻: owned Compose cleanup condition header if ($owned) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔if ($owned) {〕다.
|
| 249줄F05-L249 | & docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null |
파일 증거 조립선 CTE 격리 validator의 catch finally cleanup·이백사십구 좌표 공정이 맡은 일은 owned Compose project에 down -v --remove-orphans를 요청한다. | CTE 격리 validator의 catch finally cleanup·이백사십구 좌표의 실제 뜻: owned Compose project에 down -v --remove-orphans를 요청한다. 근거 원문은 F05-C13 원문 〔& docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null〕다.
|
| 250줄F05-L250 | $cleanup = |
CTE 격리 validator의 catch finally cleanup·이백오십 좌표는 cleanup 우선 판정과 환경 복구 점검표에서 ‘cleanup bool을 compose down exit==0 결과로 설정한다’ 봉투에 대응한다. | CTE 격리 validator의 catch finally cleanup·이백오십 좌표의 실제 뜻: cleanup bool을 compose down exit==0 결과로 설정한다. 근거 원문은 F05-C13 원문 〔$cleanup = ($LASTEXITCODE -eq 0)〕다.
|
| 251줄F05-L251 | } |
STARRY 운영실의 CTE 격리 validator의 catch finally cleanup·이백오십일 좌표 스위치는 ‘PowerShell statement }의 현재 연산을 평가한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 catch finally cleanup·이백오십일 좌표의 실제 뜻: PowerShell statement }의 현재 연산을 평가한다. 근거 원문은 F05-C13 원문 〔}〕다.
|
| 252줄F05-L252 | Restore-EnvironmentValue -Name "FCL_DB_PASSWORD" -Existed $hadPassword -Value $oldPassword |
대사 실험대 CTE 격리 validator의 catch finally cleanup·이백오십이 좌표 레버를 당기면 FCL_DB_PASSWORD의 존재 여부와 이전 값을 helper로 복원한다. | CTE 격리 validator의 catch finally cleanup·이백오십이 좌표의 실제 뜻: FCL_DB_PASSWORD의 존재 여부와 이전 값을 helper로 복원한다. 근거 원문은 F05-C13 원문 〔Restore-EnvironmentValue -Name "FCL_DB_PASSWORD" -Existed $hadPassword -Value $oldPassword〕다.
|
| 253줄F05-L253 | Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort |
검증 관제판의 CTE 격리 validator의 catch finally cleanup·이백오십삼 좌표 표식은 ‘helper 호출 Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort로 한 환경 변수를 run 전 상태로 복구한다’ 상태 전환을 가리킨다. | CTE 격리 validator의 catch finally cleanup·이백오십삼 좌표의 실제 뜻: helper 호출 Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort로 한 환경 변수를 run 전 상태로 복구한다. 근거 원문은 F05-C13 원문 〔Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort〕다.
|
| 254줄F05-L254 | } |
격리 장부 CTE 격리 validator의 catch finally cleanup·이백오십사 좌표 절차 카드는 ‘try/catch/finally lifecycle의 마지막 delimiter를 닫는다’라고 읽는다. | CTE 격리 validator의 catch finally cleanup·이백오십사 좌표의 실제 뜻: try/catch/finally lifecycle의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다.
|
| 256줄F05-L256 | if ( |
실패 폐쇄형 통로에서 CTE 격리 validator의 cleanup confirmation outer gate·이백오십육 좌표 문턱은 ‘cleanup-not-confirmed condition header if (-not $cleanup) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 역할이다. | CTE 격리 validator의 cleanup confirmation outer gate·이백오십육 좌표의 실제 뜻: cleanup-not-confirmed condition header if (-not $cleanup) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔if (-not $cleanup) {〕다.
|
| 257줄F05-L257 | if ( |
컨테이너 실험실 CTE 격리 validator의 combined run-cleanup failure·이백오십칠 좌표 안내는 ‘dual run-and-cleanup failure condition header if ($null -ne $failure) {가 child 범위를 연다. body는 아직 실행되지 않았다’ 작업만 지시한다. | CTE 격리 validator의 combined run-cleanup failure·이백오십칠 좌표의 실제 뜻: dual run-and-cleanup failure condition header if ($null -ne $failure) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔if ($null -ne $failure) {〕다.
|
| 258줄F05-L258 | throw "W17 CTE run failed and disposable cleanup was not confirmed: |
SQL 검수대의 CTE 격리 validator의 combined run-cleanup failure·이백오십팔 좌표 한 동작은 run failure와 cleanup failure가 함께 있으면 결합 message로 throw한다. | CTE 격리 validator의 combined run-cleanup failure·이백오십팔 좌표의 실제 뜻: run failure와 cleanup failure가 함께 있으면 결합 message로 throw한다. 근거 원문은 F05-C13 원문 〔throw "W17 CTE run failed and disposable cleanup was not confirmed: $($failure.Exception.Mess…〕다.
|
| 259줄F05-L259 | } |
원장 대사 시뮬레이터 CTE 격리 validator의 combined run-cleanup failure·이백오십구 좌표 단추는 combined run-and-cleanup failure branch의 마지막 delimiter를 닫는다. | CTE 격리 validator의 combined run-cleanup failure·이백오십구 좌표의 실제 뜻: combined run-and-cleanup failure branch의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다.
|
| 260줄F05-L260 | throw "W17 CTE disposable cleanup was not confirmed" |
파일 증거 조립선 CTE 격리 validator의 cleanup-only failure·이백육십 좌표 공정이 맡은 일은 현재 failure branch를 "W17 CTE disposable cleanup was not confirmed" 예외로 중단한다. | CTE 격리 validator의 cleanup-only failure·이백육십 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE disposable cleanup was not confirmed" 예외로 중단한다. 근거 원문은 F05-C13 원문 〔throw "W17 CTE disposable cleanup was not confirmed"〕다.
|
| 261줄F05-L261 | } |
CTE 격리 validator의 cleanup-only failure·이백육십일 좌표는 cleanup 우선 판정과 환경 복구 점검표에서 ‘cleanup confirmation gate의 마지막 delimiter를 닫는다’ 봉투에 대응한다. | CTE 격리 validator의 cleanup-only failure·이백육십일 좌표의 실제 뜻: cleanup confirmation gate의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다.
|
| 262줄F05-L262 | if ( |
STARRY 운영실의 CTE 격리 validator의 captured run failure rethrow·이백육십이 좌표 스위치는 ‘captured run failure condition header if ($null -ne $failure) {가 child 범위를 연다. body는 아직 실행되지 않았다’라는 현재 동작만 맡는다. | CTE 격리 validator의 captured run failure rethrow·이백육십이 좌표의 실제 뜻: captured run failure condition header if ($null -ne $failure) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔if ($null -ne $failure) {〕다.
|
| 263줄F05-L263 | throw $failure |
대사 실험대 CTE 격리 validator의 captured run failure rethrow·이백육십삼 좌표 레버를 당기면 cleanup은 성공했지만 captured run failure가 있으면 그 failure를 다시 던진다. | CTE 격리 validator의 captured run failure rethrow·이백육십삼 좌표의 실제 뜻: cleanup은 성공했지만 captured run failure가 있으면 그 failure를 다시 던진다. 근거 원문은 F05-C13 원문 〔throw $failure〕다.
|
| 264줄F05-L264 | } |
검증 관제판의 CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표 표식은 ‘captured native failure rethrow gate의 마지막 delimiter를 닫는다’ 상태 전환을 가리킨다. | CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표의 실제 뜻: captured native failure rethrow gate의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다.
|
| 266줄F05-L266 | $evidence = |
증거 포장대의 CTE 격리 validator의 evidence identity and provenance·이백육십육 좌표 봉인 공정은 final evidence line array header $evidence = @(가 child 범위를 연다. body는 아직 실행되지 않았다. | CTE 격리 validator의 evidence identity and provenance·이백육십육 좌표의 실제 뜻: final evidence line array header $evidence = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C14 원문 〔$evidence = @(〕다.
|
| 267줄F05-L267 | "W17_CTE_RETRIEVAL_GREEN", |
실패 폐쇄형 통로에서 CTE 격리 validator의 evidence identity and provenance·이백육십칠 좌표 문턱은 ‘array 또는 map에 literal element "W17_CTE_RETRIEVAL_GREEN",를 추가한다’ 역할이다. | CTE 격리 validator의 evidence identity and provenance·이백육십칠 좌표의 실제 뜻: array 또는 map에 literal element "W17_CTE_RETRIEVAL_GREEN",를 추가한다. 근거 원문은 F05-C14 원문 〔"W17_CTE_RETRIEVAL_GREEN",〕다.
|
| 268줄F05-L268 | "source_path= |
컨테이너 실험실 CTE 격리 validator의 evidence identity and provenance·이백육십팔 좌표 안내는 ‘array 또는 map에 literal element "source_path=evidence/w17/reconcile-cte.sql",를 추가한다’ 작업만 지시한다. | CTE 격리 validator의 evidence identity and provenance·이백육십팔 좌표의 실제 뜻: array 또는 map에 literal element "source_path=evidence/w17/reconcile-cte.sql",를 추가한다. 근거 원문은 F05-C14 원문 〔"source_path=evidence/w17/reconcile-cte.sql",〕다.
|
| 269줄F05-L269 | "source_sha256= |
SQL 검수대의 CTE 격리 validator의 evidence identity and provenance·이백육십구 좌표 한 동작은 evidence에 learner source SHA-256 line을 넣는다. | CTE 격리 validator의 evidence identity and provenance·이백육십구 좌표의 실제 뜻: evidence에 learner source SHA-256 line을 넣는다. 근거 원문은 F05-C14 원문 〔"source_sha256=$sourceHash",〕다.
|
| 270줄F05-L270 | "native_engine= |
원장 대사 시뮬레이터 CTE 격리 validator의 evidence identity and provenance·이백칠십 좌표 단추는 native_engine=postgresql-17-container literal을 evidence에 넣는다. | CTE 격리 validator의 evidence identity and provenance·이백칠십 좌표의 실제 뜻: native_engine=postgresql-17-container literal을 evidence에 넣는다. 근거 원문은 F05-C14 원문 〔"native_engine=postgresql-17-container",〕다.
|
| 271줄F05-L271 | "native_exit= |
파일 증거 조립선 CTE 격리 validator의 evidence identity and provenance·이백칠십일 좌표 공정이 맡은 일은 array 또는 map에 literal element "native_exit=0",를 추가한다. | CTE 격리 validator의 evidence identity and provenance·이백칠십일 좌표의 실제 뜻: array 또는 map에 literal element "native_exit=0",를 추가한다. 근거 원문은 F05-C14 원문 〔"native_exit=0",〕다.
|
| 272줄F05-L272 | "W17_BASELINE= |
CTE 격리 validator의 published baseline sentinel·이백칠십이 좌표는 hash-bound evidence payload 점검표에서 ‘final evidence에 exact balanced baseline W17_BASELINE=EMPTY를 넣는다’ 봉투에 대응한다. | CTE 격리 validator의 published baseline sentinel·이백칠십이 좌표의 실제 뜻: final evidence에 exact balanced baseline W17_BASELINE=EMPTY를 넣는다. 근거 원문은 F05-C14 원문 〔"W17_BASELINE=EMPTY",〕다.
|
| 273줄F05-L273 | "W17_INJECTED= |
STARRY 운영실의 CTE 격리 validator의 published primary anomaly·이백칠십삼 좌표 스위치는 ‘final evidence에 primary anomaly W17_INJECTED=202|82|75|7을 넣는다’라는 현재 동작만 맡는다. | CTE 격리 validator의 published primary anomaly·이백칠십삼 좌표의 실제 뜻: final evidence에 primary anomaly W17_INJECTED=202|82|75|7을 넣는다. 근거 원문은 F05-C14 원문 〔"W17_INJECTED=202|82|75|7",〕다.
|
| 274줄F05-L274 | "W17_RESTORED= |
대사 실험대 CTE 격리 validator의 published first recovery·이백칠십사 좌표 레버를 당기면 final evidence에 primary rollback 결과 W17_RESTORED=EMPTY를 넣는다. | CTE 격리 validator의 published first recovery·이백칠십사 좌표의 실제 뜻: final evidence에 primary rollback 결과 W17_RESTORED=EMPTY를 넣는다. 근거 원문은 F05-C14 원문 〔"W17_RESTORED=EMPTY",〕다.
|
| 275줄F05-L275 | "W17_ALTERNATE_INJECTED= |
검증 관제판의 CTE 격리 validator의 published hardcoding challenge·이백칠십오 좌표 표식은 ‘final evidence에 hardcoding probe W17_ALTERNATE_INJECTED=101|111|100|11을 넣는다’ 상태 전환을 가리킨다. | CTE 격리 validator의 published hardcoding challenge·이백칠십오 좌표의 실제 뜻: final evidence에 hardcoding probe W17_ALTERNATE_INJECTED=101|111|100|11을 넣는다. 근거 원문은 F05-C14 원문 〔"W17_ALTERNATE_INJECTED=101|111|100|11",〕다.
|
| 276줄F05-L276 | "W17_ALTERNATE_RESTORED= |
격리 장부 CTE 격리 validator의 published final recovery·이백칠십육 좌표 절차 카드는 ‘final evidence에 alternate rollback 결과 W17_ALTERNATE_RESTORED=EMPTY를 넣는다’라고 읽는다. | CTE 격리 validator의 published final recovery·이백칠십육 좌표의 실제 뜻: final evidence에 alternate rollback 결과 W17_ALTERNATE_RESTORED=EMPTY를 넣는다. 근거 원문은 F05-C14 원문 〔"W17_ALTERNATE_RESTORED=EMPTY",〕다.
|
| 277줄F05-L277 | "schema_scope= |
증거 포장대의 CTE 격리 validator의 published isolation and cleanup claims·이백칠십칠 좌표 봉인 공정은 array 또는 map에 literal element "schema_scope=isolated-transaction",를 추가한다. | CTE 격리 validator의 published isolation and cleanup claims·이백칠십칠 좌표의 실제 뜻: array 또는 map에 literal element "schema_scope=isolated-transaction",를 추가한다. 근거 원문은 F05-C14 원문 〔"schema_scope=isolated-transaction",〕다.
|
| 278줄F05-L278 | "cleanup= |
실패 폐쇄형 통로에서 CTE 격리 validator의 published isolation and cleanup claims·이백칠십팔 좌표 문턱은 ‘현재 success/failure summary literal "cleanup=1"을 output stream에 보낸다’ 역할이다. | CTE 격리 validator의 published isolation and cleanup claims·이백칠십팔 좌표의 실제 뜻: 현재 success/failure summary literal "cleanup=1"을 output stream에 보낸다. 근거 원문은 F05-C14 원문 〔"cleanup=1"〕다.
|
| 279줄F05-L279 | ) |
컨테이너 실험실 CTE 격리 validator의 published isolation and cleanup claims·이백칠십구 좌표 안내는 ‘final evidence line array의 마지막 delimiter를 닫는다’ 작업만 지시한다. | CTE 격리 validator의 published isolation and cleanup claims·이백칠십구 좌표의 실제 뜻: final evidence line array의 마지막 delimiter를 닫는다. 근거 원문은 F05-C14 원문 〔)〕다.
|
| 280줄F05-L280 | $temporaryEvidence = |
SQL 검수대의 CTE 격리 validator의 atomic-ish publisher·이백팔십 좌표 한 동작은 final evidence path 옆의 .tmp 경로를 정한다. | CTE 격리 validator의 atomic-ish publisher·이백팔십 좌표의 실제 뜻: final evidence path 옆의 .tmp 경로를 정한다. 근거 원문은 F05-C15 원문 〔$temporaryEvidence = "$evidencePath.tmp"〕다.
|
| 281줄F05-L281 | $evidence | Set-Content -LiteralPath $temporaryEvidence -Encoding utf8 |
원장 대사 시뮬레이터 CTE 격리 validator의 atomic-ish publisher·이백팔십일 좌표 단추는 evidence line array를 same-directory temporary file에 UTF-8로 쓴다. | CTE 격리 validator의 atomic-ish publisher·이백팔십일 좌표의 실제 뜻: evidence line array를 same-directory temporary file에 UTF-8로 쓴다. 근거 원문은 F05-C15 원문 〔$evidence | Set-Content -LiteralPath $temporaryEvidence -Encoding utf8〕다.
|
| 282줄F05-L282 | Move-Item -LiteralPath $temporaryEvidence -Destination $evidencePath -Force |
파일 증거 조립선 CTE 격리 validator의 atomic-ish publisher·이백팔십이 좌표 공정이 맡은 일은 temporary evidence를 final path로 Force move한다. | CTE 격리 validator의 atomic-ish publisher·이백팔십이 좌표의 실제 뜻: temporary evidence를 final path로 Force move한다. 근거 원문은 F05-C15 원문 〔Move-Item -LiteralPath $temporaryEvidence -Destination $evidencePath -Force〕다.
|
| 284줄F05-L284 | Write-Output "W17_CTE_RETRIEVAL_GREEN baseline= |
STARRY 운영실의 CTE 격리 validator의 atomic-ish publisher·이백팔십사 좌표 스위치는 ‘exact sentinels·source hash·native exit·cleanup 값을 담은 Green summary를 출력한다’라는 현재 동작만 맡는다. | CTE 격리 validator의 atomic-ish publisher·이백팔십사 좌표의 실제 뜻: exact sentinels·source hash·native exit·cleanup 값을 담은 Green summary를 출력한다. 근거 원문은 F05-C15 원문 〔Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|1…〕다.
|
세 번의 되돌리기히토리 → 니지카 → 료 → 키타
-
히토리
primary rollback에서 schema도 없어지나요?
-
니지카
ROLLBACK TO는 +7만 취소하고 transaction은 열린 채야.
-
료
alternate +11도 되돌린 뒤 마지막 ROLLBACK이 schema와 fixture를 없앤다.
-
키타
checkpoint 두 개와 final boundary를 그려 보겠습니다.
STEP 05 / 13
원본 코드 조각
원본을 15개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 hash로 고정한 native 정본 source에서 그대로 잘랐습니다.
param(
[Parameter(Mandatory = $true)][string]$ProjectRoot,
[string]$ComposeProject = ("w17-cte-retrieval-" + [guid]::NewGuid().ToString("N").Substring(0, 8))
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Restore-EnvironmentValue {
param(
[Parameter(Mandatory = $true)][string]$Name,
[Parameter(Mandatory = $true)][bool]$Existed,
[AllowNull()][string]$Value
)
if ($Existed) {
Set-Item -LiteralPath "Env:$Name" -Value $Value
} else {
Remove-Item -LiteralPath "Env:$Name" -ErrorAction SilentlyContinue
}
}
if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {
throw "ProjectRoot must be an absolute learner project path"
}
if ($ComposeProject -cnotmatch "^[a-z0-9][a-z0-9_-]{0,62}$") {
throw "ComposeProject must contain only lowercase letters, digits, underscore, or hyphen"
}
$project = (Resolve-Path -LiteralPath $ProjectRoot).Path
$referenceRoot = Split-Path -Parent $PSScriptRoot
$compose = Join-Path $referenceRoot "compose.yaml"
$sourcePath = Join-Path $project "evidence\w17\reconcile-cte.sql"
$evidenceDir = Join-Path $project "evidence\w17"
$evidencePath = Join-Path $evidenceDir "reconcile-cte-run.txt"
New-Item -ItemType Directory -Force -Path $evidenceDir | Out-Null
if (Test-Path -LiteralPath $evidencePath) {
Remove-Item -LiteralPath $evidencePath -Force
}
if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
throw "canonical learner SQL is missing: evidence/w17/reconcile-cte.sql"
}
$resolvedSource = (Resolve-Path -LiteralPath $sourcePath).Path
$projectPrefix = $project.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
if (-not $resolvedSource.StartsWith($projectPrefix, [StringComparison]::OrdinalIgnoreCase)) {
throw "learner SQL must remain below ProjectRoot"
}
$learnerSql = Get-Content -Raw -LiteralPath $resolvedSource
if ([string]::IsNullOrWhiteSpace($learnerSql)) {
throw "reconcile-cte.sql is empty"
}
$inspection = [regex]::Replace($learnerSql, "(?s)/\*.*?\*/", " ")
$inspection = [regex]::Replace($inspection, "(?m)--.*$", " ")
$inspection = $inspection.Trim()
if ([string]::IsNullOrWhiteSpace($inspection)) {
throw "reconcile-cte.sql contains comments only"
}
if ($inspection -match "(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER|YOUR_QUERY|WRITE_QUERY|REPLACE_ME)\b|<\s*(QUERY|SQL|ANSWER|IMPLEMENTATION)\s*>") {
throw "reconcile-cte.sql contains an unresolved placeholder"
}
if ($inspection -match "(?m)^\s*\\") {
throw "psql meta-commands are forbidden in learner SQL"
}
$query = $inspection.Trim()
if ($query.EndsWith(";")) {
$query = $query.Substring(0, $query.Length - 1).TrimEnd()
}
if ($query.Contains(";")) {
throw "reconcile-cte.sql must contain exactly one SELECT statement"
}
$inspectQuery = [regex]::Replace($query, "(?s)/\*.*?\*/", " ")
$inspectQuery = [regex]::Replace($inspectQuery, "(?m)--.*$", " ")
if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {
throw "reconcile-cte.sql must start with a CTE (WITH)"
}
if ($inspectQuery -match "(?i)\b(INSERT|UPDATE|DELETE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|REVOKE|COPY|CALL|DO|BEGIN|COMMIT|ROLLBACK|SAVEPOINT|SET|RESET|VACUUM|ANALYZE|EXPLAIN)\b") {
throw "reconcile-cte.sql may contain only a read-only CTE SELECT"
}
if ($inspectQuery -match "(?i)\b(pg_sleep|dblink|lo_import|lo_export)\b") {
throw "unsafe PostgreSQL function is forbidden in learner SQL"
}
$requiredPatterns = [ordered]@{
"ledger_sum CTE" = "(?i)\bledger_sum\s+AS\s*\("
"compared CTE" = "(?i)\bcompared\s+AS\s*\("
"mismatch CTE" = "(?i)\bmismatch\s+AS\s*\("
"account source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?account\b"
"ledger source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?ledger_entry\b"
"ledger aggregation" = "(?i)\bSUM\s*\("
"account grain" = "(?is)\bGROUP\s+BY\b.*?\baccount_id\b"
"account-to-ledger join" = "(?i)\b(?:LEFT\s+)?JOIN\b"
"missing-ledger handling" = "(?i)\bCOALESCE\s*\("
"mismatch predicate" = "(?i)(?:<>|!=|\bIS\s+DISTINCT\s+FROM\b)"
}
foreach ($entry in $requiredPatterns.GetEnumerator()) {
if ($inspectQuery -cnotmatch $entry.Value) {
throw "reconcile-cte.sql is missing required construct: $($entry.Key)"
}
}
$usesSignedAmount = $inspectQuery -cmatch "(?i)\bsigned_amount\b"
$usesCaseAmount = ($inspectQuery -cmatch "(?i)\bCASE\b") -and
($inspectQuery -cmatch "(?i)\bentry_type\b") -and
($inspectQuery -cmatch "(?i)\bamount\b")
if (-not ($usesSignedAmount -or $usesCaseAmount)) {
throw "reconcile-cte.sql must derive the signed ledger total"
}
$sourceHash = (Get-FileHash -LiteralPath $resolvedSource -Algorithm SHA256).Hash.ToLowerInvariant()
$schema = "w17_cte_" + [guid]::NewGuid().ToString("N").Substring(0, 12)
$nativeSql = @"
\set ON_ERROR_STOP on
BEGIN;
SET LOCAL statement_timeout = '10s';
CREATE SCHEMA $schema;
SET LOCAL search_path TO $schema, pg_catalog;
CREATE TABLE account (
id BIGINT PRIMARY KEY,
balance BIGINT NOT NULL CHECK (balance >= 0)
);
CREATE TABLE ledger_entry (
id BIGINT PRIMARY KEY,
account_id BIGINT NOT NULL REFERENCES account(id),
entry_type VARCHAR(32) NOT NULL,
amount BIGINT NOT NULL CHECK (amount > 0),
signed_amount BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL
);
INSERT INTO account(id, balance) VALUES
(101, 100),
(202, 75),
(303, 0);
INSERT INTO ledger_entry(id, account_id, entry_type, amount, signed_amount, created_at) VALUES
(1001, 101, 'DEPOSIT', 120, 120, '2027-01-01T00:00:00Z'),
(1002, 101, 'WITHDRAW', 20, -20, '2027-01-02T00:00:00Z'),
(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');
SELECT 'W17_BASELINE=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
SAVEPOINT primary_mismatch;
UPDATE account SET balance = balance + 7 WHERE id = 202;
SELECT 'W17_INJECTED=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
ROLLBACK TO SAVEPOINT primary_mismatch;
SELECT 'W17_RESTORED=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
SAVEPOINT alternate_account_mismatch;
UPDATE account SET balance = balance + 11 WHERE id = 101;
SELECT 'W17_ALTERNATE_INJECTED=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
ROLLBACK TO SAVEPOINT alternate_account_mismatch;
SELECT 'W17_ALTERNATE_RESTORED=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
ROLLBACK;
"@
$hadPassword = Test-Path -LiteralPath "Env:FCL_DB_PASSWORD"
$oldPassword = $env:FCL_DB_PASSWORD
$hadPort = Test-Path -LiteralPath "Env:FCL_DB_PORT"
$oldPort = $env:FCL_DB_PORT
$owned = $false
$cleanup = $false
$failure = $null
$nativeExit = -1
$nativeOutput = @()
try {
$env:FCL_DB_PASSWORD = "w17-disposable-" + [guid]::NewGuid().ToString("N")
$env:FCL_DB_PORT = "0"
$owned = $true
& docker compose -f $compose -p $ComposeProject up -d --wait db
if ($LASTEXITCODE -ne 0) {
throw "W17 CTE disposable PostgreSQL startup exit=$LASTEXITCODE"
}
$container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($container)) {
throw "W17 CTE disposable PostgreSQL container resolution failed"
}
$nativeOutput = @($nativeSql | docker exec -i $container psql -X -q -A -t -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)
$nativeExit = $LASTEXITCODE
if ($nativeExit -ne 0) {
throw "W17 CTE learner SQL native exit=$nativeExit`n$($nativeOutput -join "`n")"
}
$markers = @(
$nativeOutput |
ForEach-Object { ([string]$_).Trim() } |
Where-Object { $_ -cmatch "^W17_(BASELINE|INJECTED|RESTORED|ALTERNATE_INJECTED|ALTERNATE_RESTORED)=" }
)
$expectedMarkers = @(
"W17_BASELINE=EMPTY",
"W17_INJECTED=202|82|75|7",
"W17_RESTORED=EMPTY",
"W17_ALTERNATE_INJECTED=101|111|100|11",
"W17_ALTERNATE_RESTORED=EMPTY"
)
if (($markers -join "`n") -cne ($expectedMarkers -join "`n")) {
throw "W17 CTE exact account/balance/ledger/difference sentinel check failed; actual=$($markers -join ',')"
}
} catch {
$failure = $_
} finally {
if ($owned) {
& docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null
$cleanup = ($LASTEXITCODE -eq 0)
}
Restore-EnvironmentValue -Name "FCL_DB_PASSWORD" -Existed $hadPassword -Value $oldPassword
Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort
}
if (-not $cleanup) {
if ($null -ne $failure) {
throw "W17 CTE run failed and disposable cleanup was not confirmed: $($failure.Exception.Message)"
}
throw "W17 CTE disposable cleanup was not confirmed"
}
if ($null -ne $failure) {
throw $failure
}
$evidence = @(
"W17_CTE_RETRIEVAL_GREEN",
"source_path=evidence/w17/reconcile-cte.sql",
"source_sha256=$sourceHash",
"native_engine=postgresql-17-container",
"native_exit=0",
"W17_BASELINE=EMPTY",
"W17_INJECTED=202|82|75|7",
"W17_RESTORED=EMPTY",
"W17_ALTERNATE_INJECTED=101|111|100|11",
"W17_ALTERNATE_RESTORED=EMPTY",
"schema_scope=isolated-transaction",
"cleanup=1"
)
$temporaryEvidence = "$evidencePath.tmp"
$evidence | Set-Content -LiteralPath $temporaryEvidence -Encoding utf8
Move-Item -LiteralPath $temporaryEvidence -Destination $evidencePath -Force
Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|100|11 restored=EMPTY source_sha256=$sourceHash native_exit=0 cleanup=1"
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 259줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | param( | CTE 격리 validator의 validator header·일 좌표의 실제 뜻: isolated CTE validator parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C01 원문 〔param(〕다. |
| 2 | [Parameter(Mandatory = $true)][string]$ProjectRoot, | CTE 격리 validator의 validator header·이 좌표의 실제 뜻: parameter binder에 $ProjectRoot 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. 근거 원문은 F05-C01 원문 〔[Parameter(Mandatory = $true)][string]$ProjectRoot,〕다. |
| 3 | [string]$ComposeProject = ("w17-cte-retrieval-" + [guid]::NewGuid().ToString("N").Substring(0, 8)) | CTE 격리 validator의 validator header·삼 좌표의 실제 뜻: parameter binder에 $ComposeProject 선언과 기본값 ("w17-cte-retrieval-" + [guid]::NewGuid().ToString("N").Substring(0, 8)) 계약을 추가한다. 근거 원문은 F05-C01 원문 〔[string]$ComposeProject = ("w17-cte-retrieval-" + [guid]::NewGuid().ToString("N").Substring(0…〕다. |
| 4 | ) | CTE 격리 validator의 validator header·사 좌표의 실제 뜻: script parameter list의 마지막 delimiter를 닫는다. 근거 원문은 F05-C01 원문 〔)〕다. |
| 6 | Set-StrictMode -Version Latest | CTE 격리 validator의 validator header·육 좌표의 실제 뜻: PowerShell StrictMode Latest를 활성화한다. 근거 원문은 F05-C01 원문 〔Set-StrictMode -Version Latest〕다. |
| 7 | $ErrorActionPreference = "Stop" | CTE 격리 validator의 validator header·칠 좌표의 실제 뜻: PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. 근거 원문은 F05-C01 원문 〔$ErrorActionPreference = "Stop"〕다. |
| 9 | function Restore-EnvironmentValue { | CTE 격리 validator의 environment helper·구 좌표의 실제 뜻: environment restoration function header function Restore-EnvironmentValue {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔function Restore-EnvironmentValue {〕다. |
| 10 | param( | CTE 격리 validator의 environment helper·십 좌표의 실제 뜻: helper parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔param(〕다. |
| 11 | [Parameter(Mandatory = $true)][string]$Name, | CTE 격리 validator의 environment helper·십일 좌표의 실제 뜻: Restore-EnvironmentValue helper의 mandatory string Name parameter를 선언한다. 근거 원문은 F05-C02 원문 〔[Parameter(Mandatory = $true)][string]$Name,〕다. |
| 12 | [Parameter(Mandatory = $true)][bool]$Existed, | CTE 격리 validator의 environment helper·십이 좌표의 실제 뜻: Restore-EnvironmentValue helper의 mandatory boolean Existed parameter를 선언한다. 근거 원문은 F05-C02 원문 〔[Parameter(Mandatory = $true)][bool]$Existed,〕다. |
| 13 | [AllowNull()][string]$Value | CTE 격리 validator의 environment helper·십삼 좌표의 실제 뜻: parameter binder에 $Value 선언과 mandatory 또는 caller supplied 값 계약을 추가한다. 근거 원문은 F05-C02 원문 〔[AllowNull()][string]$Value〕다. |
| 14 | ) | CTE 격리 validator의 environment helper·십사 좌표의 실제 뜻: helper parameter list의 마지막 delimiter를 닫는다. 근거 원문은 F05-C02 원문 〔)〕다. |
| 15 | if ($Existed) { | CTE 격리 validator의 environment helper·십오 좌표의 실제 뜻: prior environment value existed condition header if ($Existed) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔if ($Existed) {〕다. |
| 16 | Set-Item -LiteralPath "Env:$Name" -Value $Value | CTE 격리 validator의 environment helper·십육 좌표의 실제 뜻: PowerShell statement Set-Item -LiteralPath "Env:$Name" -Value $Value의 현재 연산을 평가한다. 근거 원문은 F05-C02 원문 〔Set-Item -LiteralPath "Env:$Name" -Value $Value〕다. |
| 17 | } else { | CTE 격리 validator의 environment helper·십칠 좌표의 실제 뜻: prior environment value absent branch header } else {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔} else {〕다. |
| 18 | Remove-Item -LiteralPath "Env:$Name" -ErrorAction SilentlyContinue | CTE 격리 validator의 environment helper·십팔 좌표의 실제 뜻: PowerShell statement Remove-Item -LiteralPath "Env:$Name" -ErrorAction SilentlyContinue의 현재 연산을 평가한다. 근거 원문은 F05-C02 원문 〔Remove-Item -LiteralPath "Env:$Name" -ErrorAction SilentlyContinue〕다. |
| 19 | } | CTE 격리 validator의 environment helper·십구 좌표의 실제 뜻: restore-or-remove environment branch의 마지막 delimiter를 닫는다. 근거 원문은 F05-C02 원문 〔}〕다. |
| 20 | } | CTE 격리 validator의 environment helper·이십 좌표의 실제 뜻: Restore-EnvironmentValue function의 마지막 delimiter를 닫는다. 근거 원문은 F05-C02 원문 〔}〕다. |
| 22 | if (-not [IO.Path]::IsPathRooted($ProjectRoot)) { | CTE 격리 validator의 ProjectRoot absolute guard·이십이 좌표의 실제 뜻: ProjectRoot absolute-path rejection condition header if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C03 원문 〔if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {〕다. |
| 23 | throw "ProjectRoot must be an absolute learner project path" | CTE 격리 validator의 ProjectRoot absolute guard·이십삼 좌표의 실제 뜻: 현재 failure branch를 "ProjectRoot must be an absolute learner project path" 예외로 중단한다. 근거 원문은 F05-C03 원문 〔throw "ProjectRoot must be an absolute learner project path"〕다. |
| 24 | } | CTE 격리 validator의 ProjectRoot absolute guard·이십사 좌표의 실제 뜻: absolute ProjectRoot rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C03 원문 〔}〕다. |
| 25 | if ($ComposeProject -cnotmatch "^[a-z0-9][a-z0-9_-]{0,62}$") { | CTE 격리 validator의 ComposeProject name guard·이십오 좌표의 실제 뜻: ComposeProject name rejection condition header if ($ComposeProject -cnotmatch "^[a-z0-9][a-z0-9_-]{0,62}$") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C03 원문 〔if ($ComposeProject -cnotmatch "^[a-z0-9][a-z0-9_-]{0,62}$") {〕다. |
| 26 | throw "ComposeProject must contain only lowercase letters, digits, underscore, or hyphen" | CTE 격리 validator의 ComposeProject name guard·이십육 좌표의 실제 뜻: 현재 failure branch를 "ComposeProject must contain only lowercase letters, digits, underscore, or hyphen" 예외로 중단한다. 근거 원문은 F05-C03 원문 〔throw "ComposeProject must contain only lowercase letters, digits, underscore, or hyphen"〕다. |
| 27 | } | CTE 격리 validator의 ComposeProject name guard·이십칠 좌표의 실제 뜻: ComposeProject syntax rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C03 원문 〔}〕다. |
| 29 | $project = (Resolve-Path -LiteralPath $ProjectRoot).Path | CTE 격리 validator의 fixed path derivation·이십구 좌표의 실제 뜻: $project에 현재 식 (Resolve-Path -LiteralPath $ProjectRoot).Path의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$project = (Resolve-Path -LiteralPath $ProjectRoot).Path〕다. |
| 30 | $referenceRoot = Split-Path -Parent $PSScriptRoot | CTE 격리 validator의 fixed path derivation·삼십 좌표의 실제 뜻: $referenceRoot에 현재 식 Split-Path -Parent $PSScriptRoot의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$referenceRoot = Split-Path -Parent $PSScriptRoot〕다. |
| 31 | $compose = Join-Path $referenceRoot "compose.yaml" | CTE 격리 validator의 fixed path derivation·삼십일 좌표의 실제 뜻: $compose에 현재 식 Join-Path $referenceRoot "compose.yaml"의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$compose = Join-Path $referenceRoot "compose.yaml"〕다. |
| 32 | $sourcePath = Join-Path $project "evidence\w17\reconcile-cte.sql" | CTE 격리 validator의 fixed path derivation·삼십이 좌표의 실제 뜻: $sourcePath에 현재 식 Join-Path $project "evidence\w17\reconcile-cte.sql"의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$sourcePath = Join-Path $project "evidence\w17\reconcile-cte.sql"〕다. |
| 33 | $evidenceDir = Join-Path $project "evidence\w17" | CTE 격리 validator의 fixed path derivation·삼십삼 좌표의 실제 뜻: $evidenceDir에 현재 식 Join-Path $project "evidence\w17"의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$evidenceDir = Join-Path $project "evidence\w17"〕다. |
| 34 | $evidencePath = Join-Path $evidenceDir "reconcile-cte-run.txt" | CTE 격리 validator의 fixed path derivation·삼십사 좌표의 실제 뜻: $evidencePath에 현재 식 Join-Path $evidenceDir "reconcile-cte-run.txt"의 평가값을 할당한다. 근거 원문은 F05-C03 원문 〔$evidencePath = Join-Path $evidenceDir "reconcile-cte-run.txt"〕다. |
| 36 | New-Item -ItemType Directory -Force -Path $evidenceDir | Out-Null | CTE 격리 validator의 stale evidence removal·삼십육 좌표의 실제 뜻: learner evidence/w17 directory가 없으면 만들고 있으면 유지한다. 근거 원문은 F05-C03 원문 〔New-Item -ItemType Directory -Force -Path $evidenceDir | Out-Null〕다. |
| 37 | if (Test-Path -LiteralPath $evidencePath) { | CTE 격리 validator의 stale evidence removal·삼십칠 좌표의 실제 뜻: stale evidence existence condition header if (Test-Path -LiteralPath $evidencePath) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C03 원문 〔if (Test-Path -LiteralPath $evidencePath) {〕다. |
| 38 | Remove-Item -LiteralPath $evidencePath -Force | CTE 격리 validator의 stale evidence removal·삼십팔 좌표의 실제 뜻: 기존 reconcile-cte-run.txt를 실행 전에 강제로 삭제한다. 근거 원문은 F05-C03 원문 〔Remove-Item -LiteralPath $evidencePath -Force〕다. |
| 39 | } | CTE 격리 validator의 stale evidence removal·삼십구 좌표의 실제 뜻: stale evidence removal condition의 마지막 delimiter를 닫는다. 근거 원문은 F05-C03 원문 〔}〕다. |
| 41 | if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) { | CTE 격리 validator의 source leaf existence guard·사십일 좌표의 실제 뜻: learner SQL missing-file condition header if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {〕다. |
| 42 | throw "canonical learner SQL is missing: evidence/w17/reconcile-cte.sql" | CTE 격리 validator의 source leaf existence guard·사십이 좌표의 실제 뜻: 현재 failure branch를 "canonical learner SQL is missing: evidence/w17/reconcile-cte.sql" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "canonical learner SQL is missing: evidence/w17/reconcile-cte.sql"〕다. |
| 43 | } | CTE 격리 validator의 source leaf existence guard·사십삼 좌표의 실제 뜻: canonical learner source missing-file rejection 범위를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다. |
| 45 | $resolvedSource = (Resolve-Path -LiteralPath $sourcePath).Path | CTE 격리 validator의 resolved source containment guard·사십오 좌표의 실제 뜻: $resolvedSource에 현재 식 (Resolve-Path -LiteralPath $sourcePath).Path의 평가값을 할당한다. 근거 원문은 F05-C04 원문 〔$resolvedSource = (Resolve-Path -LiteralPath $sourcePath).Path〕다. |
| 46 | $projectPrefix = $project.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar | CTE 격리 validator의 resolved source containment guard·사십육 좌표의 실제 뜻: $projectPrefix에 현재 식 $project.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) + […의 평가값을 할당한다. 근거 원문은 F05-C04 원문 〔$projectPrefix = $project.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectoryS…〕다. |
| 47 | if (-not $resolvedSource.StartsWith($projectPrefix, [StringComparison]::OrdinalIgnoreCase)) { | CTE 격리 validator의 resolved source containment guard·사십칠 좌표의 실제 뜻: ProjectRoot containment rejection condition header if (-not $resolvedSource.StartsWith($projectPrefix, [StringComparison]::OrdinalIgnoreCase)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if (-not $resolvedSource.StartsWith($projectPrefix, [StringComparison]::OrdinalIgnoreCase)) {〕다. |
| 48 | throw "learner SQL must remain below ProjectRoot" | CTE 격리 validator의 resolved source containment guard·사십팔 좌표의 실제 뜻: 현재 failure branch를 "learner SQL must remain below ProjectRoot" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "learner SQL must remain below ProjectRoot"〕다. |
| 49 | } | CTE 격리 validator의 resolved source containment guard·사십구 좌표의 실제 뜻: resolved source containment rejection 범위를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다. |
| 51 | $learnerSql = Get-Content -Raw -LiteralPath $resolvedSource | CTE 격리 validator의 raw source empty guard·오십일 좌표의 실제 뜻: $learnerSql에 현재 식 Get-Content -Raw -LiteralPath $resolvedSource의 평가값을 할당한다. 근거 원문은 F05-C04 원문 〔$learnerSql = Get-Content -Raw -LiteralPath $resolvedSource〕다. |
| 52 | if ([string]::IsNullOrWhiteSpace($learnerSql)) { | CTE 격리 validator의 raw source empty guard·오십이 좌표의 실제 뜻: empty learner source condition header if ([string]::IsNullOrWhiteSpace($learnerSql)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if ([string]::IsNullOrWhiteSpace($learnerSql)) {〕다. |
| 53 | throw "reconcile-cte.sql is empty" | CTE 격리 validator의 raw source empty guard·오십삼 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql is empty" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "reconcile-cte.sql is empty"〕다. |
| 54 | } | CTE 격리 validator의 raw source empty guard·오십사 좌표의 실제 뜻: empty raw source rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다. |
| 56 | $inspection = [regex]::Replace($learnerSql, "(?s)/\*.*?\*/", " ") | CTE 격리 validator의 comment stripping guard·오십육 좌표의 실제 뜻: block comment 구간을 inspection 문자열에서 공백으로 치환한다. 근거 원문은 F05-C04 원문 〔$inspection = [regex]::Replace($learnerSql, "(?s)/\*.*?\*/", " ")〕다. |
| 57 | $inspection = [regex]::Replace($inspection, "(?m)--.*$", " ") | CTE 격리 validator의 comment stripping guard·오십칠 좌표의 실제 뜻: line comment tail을 inspection 문자열에서 공백으로 치환한다. 근거 원문은 F05-C04 원문 〔$inspection = [regex]::Replace($inspection, "(?m)--.*$", " ")〕다. |
| 58 | $inspection = $inspection.Trim() | CTE 격리 validator의 comment stripping guard·오십팔 좌표의 실제 뜻: $inspection에 현재 식 $inspection.Trim()의 평가값을 할당한다. 근거 원문은 F05-C04 원문 〔$inspection = $inspection.Trim()〕다. |
| 59 | if ([string]::IsNullOrWhiteSpace($inspection)) { | CTE 격리 validator의 comment stripping guard·오십구 좌표의 실제 뜻: comments-only source condition header if ([string]::IsNullOrWhiteSpace($inspection)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if ([string]::IsNullOrWhiteSpace($inspection)) {〕다. |
| 60 | throw "reconcile-cte.sql contains comments only" | CTE 격리 validator의 comment stripping guard·육십 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql contains comments only" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "reconcile-cte.sql contains comments only"〕다. |
| 61 | } | CTE 격리 validator의 comment stripping guard·육십일 좌표의 실제 뜻: comments-only rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다. |
| 62 | if ($inspection -match "(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER|YOUR_QUERY|WRITE_QUERY|REPLACE_ME)\b|<\s*(QUERY|SQL|ANSWER|IMPLEMENTATION)\s*>") { | CTE 격리 validator의 placeholder guard·육십이 좌표의 실제 뜻: placeholder rejection condition header if ($inspection -match "(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER|YOUR_QUERY|WRITE_QUERY|REPLACE_ME…가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if ($inspection -match "(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER|YOUR_QUERY|WRITE_QUERY|REPLACE_ME…〕다. |
| 63 | throw "reconcile-cte.sql contains an unresolved placeholder" | CTE 격리 validator의 placeholder guard·육십삼 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql contains an unresolved placeholder" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "reconcile-cte.sql contains an unresolved placeholder"〕다. |
| 64 | } | CTE 격리 validator의 placeholder guard·육십사 좌표의 실제 뜻: placeholder rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다. |
| 65 | if ($inspection -match "(?m)^\s*\\") { | CTE 격리 validator의 meta-command guard·육십오 좌표의 실제 뜻: psql meta-command rejection condition header if ($inspection -match "(?m)^\s*\\") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if ($inspection -match "(?m)^\s*\\") {〕다. |
| 66 | throw "psql meta-commands are forbidden in learner SQL" | CTE 격리 validator의 meta-command guard·육십육 좌표의 실제 뜻: 현재 failure branch를 "psql meta-commands are forbidden in learner SQL" 예외로 중단한다. 근거 원문은 F05-C04 원문 〔throw "psql meta-commands are forbidden in learner SQL"〕다. |
| 67 | } | CTE 격리 validator의 meta-command guard·육십칠 좌표의 실제 뜻: meta-command rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다. |
| 69 | $query = $inspection.Trim() | CTE 격리 validator의 semicolon cardinality guard·육십구 좌표의 실제 뜻: $query에 현재 식 $inspection.Trim()의 평가값을 할당한다. 근거 원문은 F05-C05 원문 〔$query = $inspection.Trim()〕다. |
| 70 | if ($query.EndsWith(";")) { | CTE 격리 validator의 semicolon cardinality guard·칠십 좌표의 실제 뜻: trailing semicolon normalization condition header if ($query.EndsWith(";")) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($query.EndsWith(";")) {〕다. |
| 71 | $query = $query.Substring(0, $query.Length - 1).TrimEnd() | CTE 격리 validator의 semicolon cardinality guard·칠십일 좌표의 실제 뜻: $query에 현재 식 $query.Substring(0, $query.Length - 1).TrimEnd()의 평가값을 할당한다. 근거 원문은 F05-C05 원문 〔$query = $query.Substring(0, $query.Length - 1).TrimEnd()〕다. |
| 72 | } | CTE 격리 validator의 semicolon cardinality guard·칠십이 좌표의 실제 뜻: one trailing semicolon trim의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다. |
| 73 | if ($query.Contains(";")) { | CTE 격리 validator의 semicolon cardinality guard·칠십삼 좌표의 실제 뜻: additional semicolon rejection condition header if ($query.Contains(";")) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($query.Contains(";")) {〕다. |
| 74 | throw "reconcile-cte.sql must contain exactly one SELECT statement" | CTE 격리 validator의 semicolon cardinality guard·칠십사 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql must contain exactly one SELECT statement" 예외로 중단한다. 근거 원문은 F05-C05 원문 〔throw "reconcile-cte.sql must contain exactly one SELECT statement"〕다. |
| 75 | } | CTE 격리 validator의 semicolon cardinality guard·칠십오 좌표의 실제 뜻: internal semicolon rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다. |
| 77 | $inspectQuery = [regex]::Replace($query, "(?s)/\*.*?\*/", " ") | CTE 격리 validator의 WITH prefix guard·칠십칠 좌표의 실제 뜻: query에서 block-comment 모양을 한 번 더 공백 치환해 inspectQuery를 만든다. 근거 원문은 F05-C05 원문 〔$inspectQuery = [regex]::Replace($query, "(?s)/\*.*?\*/", " ")〕다. |
| 78 | $inspectQuery = [regex]::Replace($inspectQuery, "(?m)--.*$", " ") | CTE 격리 validator의 WITH prefix guard·칠십팔 좌표의 실제 뜻: inspectQuery에서 line-comment tail을 다시 공백 치환한다. 근거 원문은 F05-C05 원문 〔$inspectQuery = [regex]::Replace($inspectQuery, "(?m)--.*$", " ")〕다. |
| 79 | if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") { | CTE 격리 validator의 WITH prefix guard·칠십구 좌표의 실제 뜻: WITH-prefix rejection condition header if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {〕다. |
| 80 | throw "reconcile-cte.sql must start with a CTE (WITH)" | CTE 격리 validator의 WITH prefix guard·팔십 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql must start with a CTE (WITH)" 예외로 중단한다. 근거 원문은 F05-C05 원문 〔throw "reconcile-cte.sql must start with a CTE (WITH)"〕다. |
| 81 | } | CTE 격리 validator의 WITH prefix guard·팔십일 좌표의 실제 뜻: WITH-prefix rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다. |
| 82 | if ($inspectQuery -match "(?i)\b(INSERT|UPDATE|DELETE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|REVOKE|COPY|CALL|DO|BEGIN|COMMIT|ROLLBACK|SAVEPOINT|SET|RESET|VACUUM|ANALYZE|EXPLAIN)\b") { | CTE 격리 validator의 mutation keyword guard·팔십이 좌표의 실제 뜻: mutating/control keyword rejection condition header if ($inspectQuery -match "(?i)\b(INSERT|UPDATE|DELETE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|…가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($inspectQuery -match "(?i)\b(INSERT|UPDATE|DELETE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|…〕다. |
| 83 | throw "reconcile-cte.sql may contain only a read-only CTE SELECT" | CTE 격리 validator의 mutation keyword guard·팔십삼 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql may contain only a read-only CTE SELECT" 예외로 중단한다. 근거 원문은 F05-C05 원문 〔throw "reconcile-cte.sql may contain only a read-only CTE SELECT"〕다. |
| 84 | } | CTE 격리 validator의 mutation keyword guard·팔십사 좌표의 실제 뜻: read-only keyword rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다. |
| 85 | if ($inspectQuery -match "(?i)\b(pg_sleep|dblink|lo_import|lo_export)\b") { | CTE 격리 validator의 unsafe function guard·팔십오 좌표의 실제 뜻: unsafe function rejection condition header if ($inspectQuery -match "(?i)\b(pg_sleep|dblink|lo_import|lo_export)\b") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($inspectQuery -match "(?i)\b(pg_sleep|dblink|lo_import|lo_export)\b") {〕다. |
| 86 | throw "unsafe PostgreSQL function is forbidden in learner SQL" | CTE 격리 validator의 unsafe function guard·팔십육 좌표의 실제 뜻: 현재 failure branch를 "unsafe PostgreSQL function is forbidden in learner SQL" 예외로 중단한다. 근거 원문은 F05-C05 원문 〔throw "unsafe PostgreSQL function is forbidden in learner SQL"〕다. |
| 87 | } | CTE 격리 validator의 unsafe function guard·팔십칠 좌표의 실제 뜻: unsafe function rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다. |
| 89 | $requiredPatterns = [ordered]@{ | CTE 격리 validator의 required-pattern definition·팔십구 좌표의 실제 뜻: required-pattern ordered map header $requiredPatterns = [ordered]@{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔$requiredPatterns = [ordered]@{〕다. |
| 90 | "ledger_sum CTE" = "(?i)\bledger_sum\s+AS\s*\(" | CTE 격리 validator의 required-pattern definition·구십 좌표의 실제 뜻: 현재 success/failure summary literal "ledger_sum CTE" = "(?i)\bledger_sum\s+AS\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"ledger_sum CTE" = "(?i)\bledger_sum\s+AS\s*\("〕다. |
| 91 | "compared CTE" = "(?i)\bcompared\s+AS\s*\(" | CTE 격리 validator의 required-pattern definition·구십일 좌표의 실제 뜻: 현재 success/failure summary literal "compared CTE" = "(?i)\bcompared\s+AS\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"compared CTE" = "(?i)\bcompared\s+AS\s*\("〕다. |
| 92 | "mismatch CTE" = "(?i)\bmismatch\s+AS\s*\(" | CTE 격리 validator의 required-pattern definition·구십이 좌표의 실제 뜻: 현재 success/failure summary literal "mismatch CTE" = "(?i)\bmismatch\s+AS\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"mismatch CTE" = "(?i)\bmismatch\s+AS\s*\("〕다. |
| 93 | "account source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?account\b" | CTE 격리 validator의 required-pattern definition·구십삼 좌표의 실제 뜻: 현재 success/failure summary literal "account source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?account\b"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"account source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?account\b"〕다. |
| 94 | "ledger source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?ledger_entry\b" | CTE 격리 validator의 required-pattern definition·구십사 좌표의 실제 뜻: 현재 success/failure summary literal "ledger source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?ledger_entry\b"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"ledger source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?ledger_entry\b"〕다. |
| 95 | "ledger aggregation" = "(?i)\bSUM\s*\(" | CTE 격리 validator의 required-pattern definition·구십오 좌표의 실제 뜻: 현재 success/failure summary literal "ledger aggregation" = "(?i)\bSUM\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"ledger aggregation" = "(?i)\bSUM\s*\("〕다. |
| 96 | "account grain" = "(?is)\bGROUP\s+BY\b.*?\baccount_id\b" | CTE 격리 validator의 required-pattern definition·구십육 좌표의 실제 뜻: 현재 success/failure summary literal "account grain" = "(?is)\bGROUP\s+BY\b.*?\baccount_id\b"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"account grain" = "(?is)\bGROUP\s+BY\b.*?\baccount_id\b"〕다. |
| 97 | "account-to-ledger join" = "(?i)\b(?:LEFT\s+)?JOIN\b" | CTE 격리 validator의 required-pattern definition·구십칠 좌표의 실제 뜻: 현재 success/failure summary literal "account-to-ledger join" = "(?i)\b(?:LEFT\s+)?JOIN\b"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"account-to-ledger join" = "(?i)\b(?:LEFT\s+)?JOIN\b"〕다. |
| 98 | "missing-ledger handling" = "(?i)\bCOALESCE\s*\(" | CTE 격리 validator의 required-pattern definition·구십팔 좌표의 실제 뜻: 현재 success/failure summary literal "missing-ledger handling" = "(?i)\bCOALESCE\s*\("을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"missing-ledger handling" = "(?i)\bCOALESCE\s*\("〕다. |
| 99 | "mismatch predicate" = "(?i)(?:<>|!=|\bIS\s+DISTINCT\s+FROM\b)" | CTE 격리 validator의 required-pattern definition·구십구 좌표의 실제 뜻: 현재 success/failure summary literal "mismatch predicate" = "(?i)(?:<>|!=|\bIS\s+DISTINCT\s+FROM\b)"을 output stream에 보낸다. 근거 원문은 F05-C06 원문 〔"mismatch predicate" = "(?i)(?:<>|!=|\bIS\s+DISTINCT\s+FROM\b)"〕다. |
| 100 | } | CTE 격리 validator의 required-pattern definition·백 좌표의 실제 뜻: 열 개 required CTE-shape regex를 담은 ordered map을 닫는다. 근거 원문은 F05-C06 원문 〔}〕다. |
| 101 | foreach ($entry in $requiredPatterns.GetEnumerator()) { | CTE 격리 validator의 required-pattern consumption·백일 좌표의 실제 뜻: required-pattern iteration header foreach ($entry in $requiredPatterns.GetEnumerator()) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔foreach ($entry in $requiredPatterns.GetEnumerator()) {〕다. |
| 102 | if ($inspectQuery -cnotmatch $entry.Value) { | CTE 격리 validator의 required-pattern consumption·백이 좌표의 실제 뜻: missing required construct condition header if ($inspectQuery -cnotmatch $entry.Value) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔if ($inspectQuery -cnotmatch $entry.Value) {〕다. |
| 103 | throw "reconcile-cte.sql is missing required construct: $($entry.Key)" | CTE 격리 validator의 required-pattern consumption·백삼 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql is missing required construct: $($entry.Key)" 예외로 중단한다. 근거 원문은 F05-C06 원문 〔throw "reconcile-cte.sql is missing required construct: $($entry.Key)"〕다. |
| 104 | } | CTE 격리 validator의 required-pattern consumption·백사 좌표의 실제 뜻: one missing-pattern rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C06 원문 〔}〕다. |
| 105 | } | CTE 격리 validator의 required-pattern consumption·백오 좌표의 실제 뜻: 각 required-pattern 누락을 검사하는 foreach 범위를 닫는다. 근거 원문은 F05-C06 원문 〔}〕다. |
| 106 | $usesSignedAmount = $inspectQuery -cmatch "(?i)\bsigned_amount\b" | CTE 격리 validator의 signed-total choice·백육 좌표의 실제 뜻: $usesSignedAmount에 현재 식 $inspectQuery -cmatch "(?i)\bsigned_amount\b"의 평가값을 할당한다. 근거 원문은 F05-C06 원문 〔$usesSignedAmount = $inspectQuery -cmatch "(?i)\bsigned_amount\b"〕다. |
| 107 | $usesCaseAmount = ($inspectQuery -cmatch "(?i)\bCASE\b") -and | CTE 격리 validator의 signed-total choice·백칠 좌표의 실제 뜻: $usesCaseAmount에 현재 식 ($inspectQuery -cmatch "(?i)\bCASE\b") -and의 평가값을 할당한다. 근거 원문은 F05-C06 원문 〔$usesCaseAmount = ($inspectQuery -cmatch "(?i)\bCASE\b") -and〕다. |
| 108 | ($inspectQuery -cmatch "(?i)\bentry_type\b") -and | CTE 격리 validator의 signed-total choice·백팔 좌표의 실제 뜻: CASE 대안이 entry_type token도 사용하는지를 AND 조건으로 잇는다. 근거 원문은 F05-C06 원문 〔($inspectQuery -cmatch "(?i)\bentry_type\b") -and〕다. |
| 109 | ($inspectQuery -cmatch "(?i)\bamount\b") | CTE 격리 validator의 signed-total choice·백구 좌표의 실제 뜻: CASE 대안이 amount token까지 사용하는지를 마지막 AND 조건으로 잇는다. 근거 원문은 F05-C06 원문 〔($inspectQuery -cmatch "(?i)\bamount\b")〕다. |
| 110 | if (-not ($usesSignedAmount -or $usesCaseAmount)) { | CTE 격리 validator의 signed-total choice·백십 좌표의 실제 뜻: missing signed-total condition header if (-not ($usesSignedAmount -or $usesCaseAmount)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔if (-not ($usesSignedAmount -or $usesCaseAmount)) {〕다. |
| 111 | throw "reconcile-cte.sql must derive the signed ledger total" | CTE 격리 validator의 signed-total choice·백십일 좌표의 실제 뜻: 현재 failure branch를 "reconcile-cte.sql must derive the signed ledger total" 예외로 중단한다. 근거 원문은 F05-C06 원문 〔throw "reconcile-cte.sql must derive the signed ledger total"〕다. |
| 112 | } | CTE 격리 validator의 signed-total choice·백십이 좌표의 실제 뜻: signed-total representation gate의 마지막 delimiter를 닫는다. 근거 원문은 F05-C06 원문 〔}〕다. |
| 114 | $sourceHash = (Get-FileHash -LiteralPath $resolvedSource -Algorithm SHA256).Hash.ToLowerInvariant() | CTE 격리 validator의 hash and transaction header·백십사 좌표의 실제 뜻: resolved learner SQL의 SHA-256을 소문자로 계산한다. 근거 원문은 F05-C07 원문 〔$sourceHash = (Get-FileHash -LiteralPath $resolvedSource -Algorithm SHA256).Hash.ToLowerInvar…〕다. |
| 115 | $schema = "w17_cte_" + [guid]::NewGuid().ToString("N").Substring(0, 12) | CTE 격리 validator의 hash and transaction header·백십오 좌표의 실제 뜻: 12자 GUID suffix를 붙여 격리 schema 이름을 만든다. 근거 원문은 F05-C07 원문 〔$schema = "w17_cte_" + [guid]::NewGuid().ToString("N").Substring(0, 12)〕다. |
| 116 | $nativeSql = @" | CTE 격리 validator의 hash and transaction header·백십육 좌표의 실제 뜻: native SQL here-string header $nativeSql = @"가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔$nativeSql = @"〕다. |
| 117 | \set ON_ERROR_STOP on | CTE 격리 validator의 hash and transaction header·백십칠 좌표의 실제 뜻: native psql session에서 ON_ERROR_STOP을 켠다. 근거 원문은 F05-C07 원문 〔\set ON_ERROR_STOP on〕다. |
| 118 | BEGIN; | CTE 격리 validator의 hash and transaction header·백십팔 좌표의 실제 뜻: native SQL transaction을 BEGIN으로 연다. 근거 원문은 F05-C07 원문 〔BEGIN;〕다. |
| 119 | SET LOCAL statement_timeout = '10s'; | CTE 격리 validator의 hash and transaction header·백십구 좌표의 실제 뜻: 현재 transaction에 10초 statement timeout을 설정한다. 근거 원문은 F05-C07 원문 〔SET LOCAL statement_timeout = '10s';〕다. |
| 120 | CREATE SCHEMA $schema; | CTE 격리 validator의 hash and transaction header·백이십 좌표의 실제 뜻: GUID로 만든 random schema를 current transaction 안에 생성한다. 근거 원문은 F05-C07 원문 〔CREATE SCHEMA $schema;〕다. |
| 121 | SET LOCAL search_path TO $schema, pg_catalog; | CTE 격리 validator의 hash and transaction header·백이십일 좌표의 실제 뜻: random schema와 pg_catalog를 transaction-local search_path로 둔다. 근거 원문은 F05-C07 원문 〔SET LOCAL search_path TO $schema, pg_catalog;〕다. |
| 123 | CREATE TABLE account ( | CTE 격리 validator의 account table·백이십삼 좌표의 실제 뜻: account table definition header CREATE TABLE account (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔CREATE TABLE account (〕다. |
| 124 | id BIGINT PRIMARY KEY, | CTE 격리 validator의 account table·백이십사 좌표의 실제 뜻: account fixture의 id를 BIGINT PRIMARY KEY로 선언한다. 근거 원문은 F05-C07 원문 〔id BIGINT PRIMARY KEY,〕다. |
| 125 | balance BIGINT NOT NULL CHECK (balance >= 0) | CTE 격리 validator의 account table·백이십오 좌표의 실제 뜻: fixture column balance의 type·constraint fragment를 선언한다. 근거 원문은 F05-C07 원문 〔balance BIGINT NOT NULL CHECK (balance >= 0)〕다. |
| 126 | ); | CTE 격리 validator의 account table·백이십육 좌표의 실제 뜻: balance check를 포함한 account table definition을 닫는다. 근거 원문은 F05-C07 원문 〔);〕다. |
| 127 | CREATE TABLE ledger_entry ( | CTE 격리 validator의 ledger table·백이십칠 좌표의 실제 뜻: ledger_entry table definition header CREATE TABLE ledger_entry (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔CREATE TABLE ledger_entry (〕다. |
| 128 | id BIGINT PRIMARY KEY, | CTE 격리 validator의 ledger table·백이십팔 좌표의 실제 뜻: ledger_entry fixture의 자체 id를 BIGINT PRIMARY KEY로 선언한다. 근거 원문은 F05-C07 원문 〔id BIGINT PRIMARY KEY,〕다. |
| 129 | account_id BIGINT NOT NULL REFERENCES account(id), | CTE 격리 validator의 ledger table·백이십구 좌표의 실제 뜻: ledger_entry.account_id를 NOT NULL account(id) foreign key로 선언한다. 근거 원문은 F05-C07 원문 〔account_id BIGINT NOT NULL REFERENCES account(id),〕다. |
| 130 | entry_type VARCHAR(32) NOT NULL, | CTE 격리 validator의 ledger table·백삼십 좌표의 실제 뜻: fixture column entry_type의 type·constraint fragment를 선언한다. 근거 원문은 F05-C07 원문 〔entry_type VARCHAR(32) NOT NULL,〕다. |
| 131 | amount BIGINT NOT NULL CHECK (amount > 0), | CTE 격리 validator의 ledger table·백삼십일 좌표의 실제 뜻: ledger_entry.amount를 positive BIGINT로 제한한다. 근거 원문은 F05-C07 원문 〔amount BIGINT NOT NULL CHECK (amount > 0),〕다. |
| 132 | signed_amount BIGINT NOT NULL, | CTE 격리 validator의 ledger table·백삼십이 좌표의 실제 뜻: ledger_entry.signed_amount를 부호 있는 BIGINT로 선언한다. 근거 원문은 F05-C07 원문 〔signed_amount BIGINT NOT NULL,〕다. |
| 133 | created_at TIMESTAMPTZ NOT NULL | CTE 격리 validator의 ledger table·백삼십삼 좌표의 실제 뜻: fixture column created_at의 type·constraint fragment를 선언한다. 근거 원문은 F05-C07 원문 〔created_at TIMESTAMPTZ NOT NULL〕다. |
| 134 | ); | CTE 격리 validator의 ledger table·백삼십사 좌표의 실제 뜻: created_at까지 포함한 ledger_entry table definition을 닫는다. 근거 원문은 F05-C07 원문 〔);〕다. |
| 136 | INSERT INTO account(id, balance) VALUES | CTE 격리 validator의 account fixture header·백삼십육 좌표의 실제 뜻: account fixture VALUES list header INSERT INTO account(id, balance) VALUES가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔INSERT INTO account(id, balance) VALUES〕다. |
| 137 | (101, 100), | CTE 격리 validator의 alternate account 101 baseline·백삼십칠 좌표의 실제 뜻: account 101을 stored balance 100으로 fixture에 넣는다. 근거 원문은 F05-C07 원문 〔(101, 100),〕다. |
| 138 | (202, 75), | CTE 격리 validator의 primary account 202 baseline·백삼십팔 좌표의 실제 뜻: account 202를 stored balance 75로 fixture에 넣는다. 근거 원문은 F05-C07 원문 〔(202, 75),〕다. |
| 139 | (303, 0); | CTE 격리 validator의 no-ledger account 303 baseline·백삼십구 좌표의 실제 뜻: account 303을 balance 0으로 넣고 account VALUES statement를 끝낸다. 근거 원문은 F05-C07 원문 〔(303, 0);〕다. |
| 140 | INSERT INTO ledger_entry(id, account_id, entry_type, amount, signed_amount, created_at) VALUES | CTE 격리 validator의 ledger fixture·백사십 좌표의 실제 뜻: ledger fixture VALUES list header INSERT INTO ledger_entry(id, account_id, entry_type, amount, signed_amount, created_at) VALUES가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C07 원문 〔INSERT INTO ledger_entry(id, account_id, entry_type, amount, signed_amount, created_at) VALUES〕다. |
| 141 | (1001, 101, 'DEPOSIT', 120, 120, '2027-01-01T00:00:00Z'), | CTE 격리 validator의 ledger fixture·백사십일 좌표의 실제 뜻: account 101에 DEPOSIT +120 ledger row를 넣는다. 근거 원문은 F05-C07 원문 〔(1001, 101, 'DEPOSIT', 120, 120, '2027-01-01T00:00:00Z'),〕다. |
| 142 | (1002, 101, 'WITHDRAW', 20, -20, '2027-01-02T00:00:00Z'), | CTE 격리 validator의 ledger fixture·백사십이 좌표의 실제 뜻: account 101에 WITHDRAW signed_amount -20 row를 넣는다. 근거 원문은 F05-C07 원문 〔(1002, 101, 'WITHDRAW', 20, -20, '2027-01-02T00:00:00Z'),〕다. |
| 143 | (2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z'); | CTE 격리 validator의 ledger fixture·백사십삼 좌표의 실제 뜻: account 202에 +75 ledger row를 넣고 ledger INSERT를 끝낸다. 근거 원문은 F05-C07 원문 〔(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');〕다. |
| 145 | SELECT 'W17_BASELINE=' || COALESCE( | CTE 격리 validator의 baseline marker expression head·백사십오 좌표의 실제 뜻: baseline marker SELECT expression header SELECT 'W17_BASELINE=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔SELECT 'W17_BASELINE=' || COALESCE(〕다. |
| 146 | string_agg( | CTE 격리 validator의 baseline EMPTY marker·백사십육 좌표의 실제 뜻: baseline string_agg call header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔string_agg(〕다. |
| 147 | account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text, | CTE 격리 validator의 baseline EMPTY marker·백사십칠 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C08 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다. |
| 148 | ',' ORDER BY account_id | CTE 격리 validator의 baseline EMPTY marker·백사십팔 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C08 원문 〔',' ORDER BY account_id〕다. |
| 149 | ), | CTE 격리 validator의 baseline EMPTY marker·백사십구 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C08 원문 〔),〕다. |
| 150 | 'EMPTY' | CTE 격리 validator의 baseline EMPTY marker·백오십 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C08 원문 〔'EMPTY'〕다. |
| 151 | ) FROM ( | CTE 격리 validator의 baseline EMPTY marker·백오십일 좌표의 실제 뜻: baseline learner-result subquery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔) FROM (〕다. |
| 152 | $query | CTE 격리 validator의 baseline EMPTY marker·백오십이 좌표의 실제 뜻: baseline wrapper 안에 inspected learner query text를 삽입한다. 근거 원문은 F05-C08 원문 〔$query〕다. |
| 153 | ) AS learner_result; | CTE 격리 validator의 baseline EMPTY marker·백오십삼 좌표의 실제 뜻: 첫 정상 대조표에서 불필요한 mismatch가 없는지 찾는다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C08 원문 〔) AS learner_result;〕다. |
| 155 | SAVEPOINT primary_mismatch; | CTE 격리 validator의 primary mutation setup·백오십오 좌표의 실제 뜻: primary_mismatch savepoint를 만든다. 근거 원문은 F05-C08 원문 〔SAVEPOINT primary_mismatch;〕다. |
| 156 | UPDATE account SET balance = balance + 7 WHERE id = 202; | CTE 격리 validator의 primary mutation setup·백오십육 좌표의 실제 뜻: account 202 balance를 75에서 82로 7 올린다. 근거 원문은 F05-C08 원문 〔UPDATE account SET balance = balance + 7 WHERE id = 202;〕다. |
| 157 | SELECT 'W17_INJECTED=' || COALESCE( | CTE 격리 validator의 post-update anomaly report head·백오십칠 좌표의 실제 뜻: primary injected marker SELECT expression header SELECT 'W17_INJECTED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔SELECT 'W17_INJECTED=' || COALESCE(〕다. |
| 158 | string_agg( | CTE 격리 validator의 post-update aggregation opener·백오십팔 좌표의 실제 뜻: aggregation after account 202 gained seven units header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔string_agg(〕다. |
| 159 | account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text, | CTE 격리 validator의 primary 202-82-75-7 marker·백오십구 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C08 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다. |
| 160 | ',' ORDER BY account_id | CTE 격리 validator의 primary 202-82-75-7 marker·백육십 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C08 원문 〔',' ORDER BY account_id〕다. |
| 161 | ), | CTE 격리 validator의 primary 202-82-75-7 marker·백육십일 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C08 원문 〔),〕다. |
| 162 | 'EMPTY' | CTE 격리 validator의 primary 202-82-75-7 marker·백육십이 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C08 원문 〔'EMPTY'〕다. |
| 163 | ) FROM ( | CTE 격리 validator의 primary 202-82-75-7 marker·백육십삼 좌표의 실제 뜻: learner-result subquery under the 202 fault header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔) FROM (〕다. |
| 164 | $query | CTE 격리 validator의 primary 202-82-75-7 marker·백육십사 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. 근거 원문은 F05-C08 원문 〔$query〕다. |
| 165 | ) AS learner_result; | CTE 격리 validator의 primary 202-82-75-7 marker·백육십오 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C08 원문 〔) AS learner_result;〕다. |
| 166 | ROLLBACK TO SAVEPOINT primary_mismatch; | CTE 격리 validator의 primary rollback command·백육십육 좌표의 실제 뜻: primary_mismatch savepoint로 rollback한다. 근거 원문은 F05-C08 원문 〔ROLLBACK TO SAVEPOINT primary_mismatch;〕다. |
| 167 | SELECT 'W17_RESTORED=' || COALESCE( | CTE 격리 validator의 primary restored marker expression head·백육십칠 좌표의 실제 뜻: primary restored marker SELECT expression header SELECT 'W17_RESTORED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔SELECT 'W17_RESTORED=' || COALESCE(〕다. |
| 168 | string_agg( | CTE 격리 validator의 post-primary-rollback aggregation opener·백육십팔 좌표의 실제 뜻: recovery aggregation after primary savepoint rewind header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔string_agg(〕다. |
| 169 | account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text, | CTE 격리 validator의 primary 202 rollback EMPTY marker·백육십구 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C08 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다. |
| 170 | ',' ORDER BY account_id | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C08 원문 〔',' ORDER BY account_id〕다. |
| 171 | ), | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십일 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C08 원문 〔),〕다. |
| 172 | 'EMPTY' | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십이 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C08 원문 〔'EMPTY'〕다. |
| 173 | ) FROM ( | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십삼 좌표의 실제 뜻: learner-result subquery after the first recovery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔) FROM (〕다. |
| 174 | $query | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십사 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. 근거 원문은 F05-C08 원문 〔$query〕다. |
| 175 | ) AS learner_result; | CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십오 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C08 원문 〔) AS learner_result;〕다. |
| 177 | SAVEPOINT alternate_account_mismatch; | CTE 격리 validator의 alternate mutation setup·백칠십칠 좌표의 실제 뜻: alternate_account_mismatch savepoint를 만든다. 근거 원문은 F05-C09 원문 〔SAVEPOINT alternate_account_mismatch;〕다. |
| 178 | UPDATE account SET balance = balance + 11 WHERE id = 101; | CTE 격리 validator의 alternate mutation setup·백칠십팔 좌표의 실제 뜻: account 101 balance를 100에서 111로 11 올린다. 근거 원문은 F05-C09 원문 〔UPDATE account SET balance = balance + 11 WHERE id = 101;〕다. |
| 179 | SELECT 'W17_ALTERNATE_INJECTED=' || COALESCE( | CTE 격리 validator의 hardcoding probe report head·백칠십구 좌표의 실제 뜻: alternate injected marker SELECT expression header SELECT 'W17_ALTERNATE_INJECTED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔SELECT 'W17_ALTERNATE_INJECTED=' || COALESCE(〕다. |
| 180 | string_agg( | CTE 격리 validator의 post-alternate-update aggregation opener·백팔십 좌표의 실제 뜻: hardcoding-challenge aggregation after account 101 gained eleven units header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔string_agg(〕다. |
| 181 | account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text, | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십일 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C09 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다. |
| 182 | ',' ORDER BY account_id | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십이 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C09 원문 〔',' ORDER BY account_id〕다. |
| 183 | ), | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십삼 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C09 원문 〔),〕다. |
| 184 | 'EMPTY' | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십사 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C09 원문 〔'EMPTY'〕다. |
| 185 | ) FROM ( | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십오 좌표의 실제 뜻: learner-result subquery under the alternate 101 fault header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔) FROM (〕다. |
| 186 | $query | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십육 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. 근거 원문은 F05-C09 원문 〔$query〕다. |
| 187 | ) AS learner_result; | CTE 격리 validator의 alternate 101-111-100-11 marker·백팔십칠 좌표의 실제 뜻: 202 hardcoding을 들추려고 다른 101번 계좌의 11-unit fault를 관찰한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C09 원문 〔) AS learner_result;〕다. |
| 188 | ROLLBACK TO SAVEPOINT alternate_account_mismatch; | CTE 격리 validator의 alternate rollback command·백팔십팔 좌표의 실제 뜻: alternate_account_mismatch savepoint로 rollback한다. 근거 원문은 F05-C09 원문 〔ROLLBACK TO SAVEPOINT alternate_account_mismatch;〕다. |
| 189 | SELECT 'W17_ALTERNATE_RESTORED=' || COALESCE( | CTE 격리 validator의 second recovery report head·백팔십구 좌표의 실제 뜻: alternate restored marker SELECT expression header SELECT 'W17_ALTERNATE_RESTORED=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔SELECT 'W17_ALTERNATE_RESTORED=' || COALESCE(〕다. |
| 190 | string_agg( | CTE 격리 validator의 post-alternate-rollback aggregation opener·백구십 좌표의 실제 뜻: final recovery aggregation after alternate savepoint rewind header string_agg(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔string_agg(〕다. |
| 191 | account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text, | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십일 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 발견 row를 account|stored|ledger|difference 네 field로 직렬화한다. 근거 원문은 F05-C09 원문 〔account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || diff…〕다. |
| 192 | ',' ORDER BY account_id | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십이 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 그 marker 안의 mismatch rows를 account_id 순서로 정렬한다. 근거 원문은 F05-C09 원문 〔',' ORDER BY account_id〕다. |
| 193 | ), | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십삼 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C09 원문 〔),〕다. |
| 194 | 'EMPTY' | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십사 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; learner mismatch set이 0행일 때 쓸 EMPTY fallback을 제공한다. 근거 원문은 F05-C09 원문 〔'EMPTY'〕다. |
| 195 | ) FROM ( | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십오 좌표의 실제 뜻: learner-result subquery after the second recovery header ) FROM (가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C09 원문 〔) FROM (〕다. |
| 196 | $query | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십육 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; 정적 검사를 통과한 learner query를 해당 fixture state에 삽입한다. 근거 원문은 F05-C09 원문 〔$query〕다. |
| 197 | ) AS learner_result; | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십칠 좌표의 실제 뜻: 두 번째 checkpoint가 alternate anomaly까지 제거했는지 최종 확인한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C09 원문 〔) AS learner_result;〕다. |
| 198 | ROLLBACK; | CTE 격리 validator의 alternate 101 rollback EMPTY marker·백구십팔 좌표의 실제 뜻: native SQL transaction 전체를 rollback한다. 근거 원문은 F05-C09 원문 〔ROLLBACK;〕다. |
| 199 | "@ | CTE 격리 validator의 native template closure·백구십구 좌표의 실제 뜻: native SQL here-string의 마지막 delimiter를 닫는다. 근거 원문은 F05-C09 원문 〔"@〕다. |
| 201 | $hadPassword = Test-Path -LiteralPath "Env:FCL_DB_PASSWORD" | CTE 격리 validator의 password environment snapshot·이백일 좌표의 실제 뜻: FCL_DB_PASSWORD 환경 변수가 원래 존재했는지 기록한다. 근거 원문은 F05-C10 원문 〔$hadPassword = Test-Path -LiteralPath "Env:FCL_DB_PASSWORD"〕다. |
| 202 | $oldPassword = $env:FCL_DB_PASSWORD | CTE 격리 validator의 password environment snapshot·이백이 좌표의 실제 뜻: run 전 FCL_DB_PASSWORD 문자열을 oldPassword에 캡처한다. 근거 원문은 F05-C10 원문 〔$oldPassword = $env:FCL_DB_PASSWORD〕다. |
| 203 | $hadPort = Test-Path -LiteralPath "Env:FCL_DB_PORT" | CTE 격리 validator의 port environment snapshot·이백삼 좌표의 실제 뜻: $hadPort에 현재 식 Test-Path -LiteralPath "Env:FCL_DB_PORT"의 평가값을 할당한다. 근거 원문은 F05-C10 원문 〔$hadPort = Test-Path -LiteralPath "Env:FCL_DB_PORT"〕다. |
| 204 | $oldPort = $env:FCL_DB_PORT | CTE 격리 validator의 port environment snapshot·이백사 좌표의 실제 뜻: run 전 FCL_DB_PORT 문자열을 oldPort에 캡처한다. 근거 원문은 F05-C10 원문 〔$oldPort = $env:FCL_DB_PORT〕다. |
| 205 | $owned = $false | CTE 격리 validator의 cleanup lifecycle flags·이백오 좌표의 실제 뜻: Compose ownership flag를 false로 초기화한다. 근거 원문은 F05-C10 원문 〔$owned = $false〕다. |
| 206 | $cleanup = $false | CTE 격리 validator의 cleanup lifecycle flags·이백육 좌표의 실제 뜻: $cleanup에 현재 식 $false의 평가값을 할당한다. 근거 원문은 F05-C10 원문 〔$cleanup = $false〕다. |
| 207 | $failure = $null | CTE 격리 validator의 cleanup lifecycle flags·이백칠 좌표의 실제 뜻: $failure에 현재 식 $null의 평가값을 할당한다. 근거 원문은 F05-C10 원문 〔$failure = $null〕다. |
| 208 | $nativeExit = -1 | CTE 격리 validator의 native result sentinels·이백팔 좌표의 실제 뜻: nativeExit sentinel을 실행 전 -1로 초기화한다. 근거 원문은 F05-C10 원문 〔$nativeExit = -1〕다. |
| 209 | $nativeOutput = @() | CTE 격리 validator의 native result sentinels·이백구 좌표의 실제 뜻: nativeOutput을 빈 PowerShell array로 초기화한다. 근거 원문은 F05-C10 원문 〔$nativeOutput = @()〕다. |
| 211 | try { | CTE 격리 validator의 Compose startup·이백십일 좌표의 실제 뜻: native runner try scope header try {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔try {〕다. |
| 212 | $env:FCL_DB_PASSWORD = "w17-disposable-" + [guid]::NewGuid().ToString("N") | CTE 격리 validator의 Compose startup·이백십이 좌표의 실제 뜻: PowerShell statement $env:FCL_DB_PASSWORD = "w17-disposable-" + [guid]::NewGuid().ToString("N")의 현재 연산을 평가한다. 근거 원문은 F05-C11 원문 〔$env:FCL_DB_PASSWORD = "w17-disposable-" + [guid]::NewGuid().ToString("N")〕다. |
| 213 | $env:FCL_DB_PORT = "0" | CTE 격리 validator의 Compose startup·이백십삼 좌표의 실제 뜻: PowerShell statement $env:FCL_DB_PORT = "0"의 현재 연산을 평가한다. 근거 원문은 F05-C11 원문 〔$env:FCL_DB_PORT = "0"〕다. |
| 214 | $owned = $true | CTE 격리 validator의 Compose startup·이백십사 좌표의 실제 뜻: compose up을 호출하기 전에 owned를 true로 바꾼다. 근거 원문은 F05-C11 원문 〔$owned = $true〕다. |
| 215 | & docker compose -f $compose -p $ComposeProject up -d --wait db | CTE 격리 validator의 Compose startup·이백십오 좌표의 실제 뜻: native Compose command & docker compose -f $compose -p $ComposeProject up -d --wait db를 호출한다. 근거 원문은 F05-C11 원문 〔& docker compose -f $compose -p $ComposeProject up -d --wait db〕다. |
| 216 | if ($LASTEXITCODE -ne 0) { | CTE 격리 validator의 Compose startup·이백십육 좌표의 실제 뜻: Compose startup failure condition header if ($LASTEXITCODE -ne 0) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔if ($LASTEXITCODE -ne 0) {〕다. |
| 217 | throw "W17 CTE disposable PostgreSQL startup exit=$LASTEXITCODE" | CTE 격리 validator의 Compose startup·이백십칠 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE disposable PostgreSQL startup exit=$LASTEXITCODE" 예외로 중단한다. 근거 원문은 F05-C11 원문 〔throw "W17 CTE disposable PostgreSQL startup exit=$LASTEXITCODE"〕다. |
| 218 | } | CTE 격리 validator의 Compose startup·이백십팔 좌표의 실제 뜻: Compose startup failure guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C11 원문 〔}〕다. |
| 219 | $container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim() | CTE 격리 validator의 container resolution·이백십구 좌표의 실제 뜻: $container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. 근거 원문은 F05-C11 원문 〔$container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()〕다. |
| 220 | if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($container)) { | CTE 격리 validator의 container resolution·이백이십 좌표의 실제 뜻: container resolution failure condition header if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($container)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($container)) {〕다. |
| 221 | throw "W17 CTE disposable PostgreSQL container resolution failed" | CTE 격리 validator의 container resolution·이백이십일 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE disposable PostgreSQL container resolution failed" 예외로 중단한다. 근거 원문은 F05-C11 원문 〔throw "W17 CTE disposable PostgreSQL container resolution failed"〕다. |
| 222 | } | CTE 격리 validator의 container resolution·이백이십이 좌표의 실제 뜻: container resolution guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C11 원문 〔}〕다. |
| 224 | $nativeOutput = @($nativeSql | docker exec -i $container psql -X -q -A -t -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1) | CTE 격리 validator의 native psql execution·이백이십사 좌표의 실제 뜻: native SQL here-string을 disposable PostgreSQL psql에 pipe하고 output을 배열로 모은다. 근거 원문은 F05-C11 원문 〔$nativeOutput = @($nativeSql | docker exec -i $container psql -X -q -A -t -v ON_ERROR_STOP=1 …〕다. |
| 225 | $nativeExit = $LASTEXITCODE | CTE 격리 validator의 native psql execution·이백이십오 좌표의 실제 뜻: $nativeExit에 현재 식 $LASTEXITCODE의 평가값을 할당한다. 근거 원문은 F05-C11 원문 〔$nativeExit = $LASTEXITCODE〕다. |
| 226 | if ($nativeExit -ne 0) { | CTE 격리 validator의 native psql execution·이백이십육 좌표의 실제 뜻: native psql failure condition header if ($nativeExit -ne 0) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔if ($nativeExit -ne 0) {〕다. |
| 227 | throw "W17 CTE learner SQL native exit=$nativeExit`n$($nativeOutput -join "`n")" | CTE 격리 validator의 native psql execution·이백이십칠 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE learner SQL native exit=$nativeExitˋn$($nativeOutput -join "ˋn")" 예외로 중단한다. 근거 원문은 F05-C11 원문 〔throw "W17 CTE learner SQL native exit=$nativeExitˋn$($nativeOutput -join "ˋn")"〕다. |
| 228 | } | CTE 격리 validator의 native psql execution·이백이십팔 좌표의 실제 뜻: native psql failure guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C11 원문 〔}〕다. |
| 230 | $markers = @( | CTE 격리 validator의 observed marker filter·이백삼십 좌표의 실제 뜻: observed marker array pipeline header $markers = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C12 원문 〔$markers = @(〕다. |
| 231 | $nativeOutput | | CTE 격리 validator의 observed marker filter·이백삼십일 좌표의 실제 뜻: pipeline stage $nativeOutput |로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F05-C12 원문 〔$nativeOutput |〕다. |
| 232 | ForEach-Object { ([string]$_).Trim() } | | CTE 격리 validator의 observed marker filter·이백삼십이 좌표의 실제 뜻: collection을 순회할 foreach header ForEach-Object { ([string]$_).Trim() } |를 선언한다. 근거 원문은 F05-C12 원문 〔ForEach-Object { ([string]$_).Trim() } |〕다. |
| 233 | Where-Object { $_ -cmatch "^W17_(BASELINE|INJECTED|RESTORED|ALTERNATE_INJECTED|ALTERNATE_RESTORED)=" } | CTE 격리 validator의 observed marker filter·이백삼십삼 좌표의 실제 뜻: pipeline stage Where-Object { $_ -cmatch "^W17_(BASELINE|INJECTED|RESTORED|ALTERNATE_INJECTED|ALTERNATE_REST…로 왼쪽 값을 오른쪽 command에 전달한다. 근거 원문은 F05-C12 원문 〔Where-Object { $_ -cmatch "^W17_(BASELINE|INJECTED|RESTORED|ALTERNATE_INJECTED|ALTERNATE_REST…〕다. |
| 234 | ) | CTE 격리 validator의 observed marker filter·이백삼십사 좌표의 실제 뜻: observed marker pipeline array의 마지막 delimiter를 닫는다. 근거 원문은 F05-C12 원문 〔)〕다. |
| 235 | $expectedMarkers = @( | CTE 격리 validator의 expected marker array head·이백삼십오 좌표의 실제 뜻: expected marker array header $expectedMarkers = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C12 원문 〔$expectedMarkers = @(〕다. |
| 236 | "W17_BASELINE=EMPTY", | CTE 격리 validator의 expected balanced baseline·이백삼십육 좌표의 실제 뜻: expected sequence의 첫 값으로 balanced W17_BASELINE=EMPTY를 둔다. 근거 원문은 F05-C12 원문 〔"W17_BASELINE=EMPTY",〕다. |
| 237 | "W17_INJECTED=202|82|75|7", | CTE 격리 validator의 expected primary anomaly·이백삼십칠 좌표의 실제 뜻: expected sequence의 둘째 값으로 W17_INJECTED=202|82|75|7을 둔다. 근거 원문은 F05-C12 원문 〔"W17_INJECTED=202|82|75|7",〕다. |
| 238 | "W17_RESTORED=EMPTY", | CTE 격리 validator의 expected first recovery·이백삼십팔 좌표의 실제 뜻: expected sequence의 셋째 값으로 W17_RESTORED=EMPTY를 둔다. 근거 원문은 F05-C12 원문 〔"W17_RESTORED=EMPTY",〕다. |
| 239 | "W17_ALTERNATE_INJECTED=101|111|100|11", | CTE 격리 validator의 expected alternate hardcoding probe·이백삼십구 좌표의 실제 뜻: expected sequence의 넷째 값으로 W17_ALTERNATE_INJECTED=101|111|100|11을 둔다. 근거 원문은 F05-C12 원문 〔"W17_ALTERNATE_INJECTED=101|111|100|11",〕다. |
| 240 | "W17_ALTERNATE_RESTORED=EMPTY" | CTE 격리 validator의 expected second recovery·이백사십 좌표의 실제 뜻: expected sequence의 마지막 값으로 W17_ALTERNATE_RESTORED=EMPTY를 둔다. 근거 원문은 F05-C12 원문 〔"W17_ALTERNATE_RESTORED=EMPTY"〕다. |
| 241 | ) | CTE 격리 validator의 expected array closure·이백사십일 좌표의 실제 뜻: expected five-marker array의 마지막 delimiter를 닫는다. 근거 원문은 F05-C12 원문 〔)〕다. |
| 242 | if (($markers -join "`n") -cne ($expectedMarkers -join "`n")) { | CTE 격리 validator의 exact joined marker comparison·이백사십이 좌표의 실제 뜻: exact sequence mismatch condition header if (($markers -join "ˋn") -cne ($expectedMarkers -join "ˋn")) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C12 원문 〔if (($markers -join "ˋn") -cne ($expectedMarkers -join "ˋn")) {〕다. |
| 243 | throw "W17 CTE exact account/balance/ledger/difference sentinel check failed; actual=$($markers -join ',')" | CTE 격리 validator의 exact joined marker comparison·이백사십삼 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE exact account/balance/ledger/difference sentinel check failed; actual=$($markers -jo… 예외로 중단한다. 근거 원문은 F05-C12 원문 〔throw "W17 CTE exact account/balance/ledger/difference sentinel check failed; actual=$($marke…〕다. |
| 244 | } | CTE 격리 validator의 exact joined marker comparison·이백사십사 좌표의 실제 뜻: exact marker sequence guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C12 원문 〔}〕다. |
| 245 | } catch { | CTE 격리 validator의 catch finally cleanup·이백사십오 좌표의 실제 뜻: failure capture catch scope header } catch {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔} catch {〕다. |
| 246 | $failure = $_ | CTE 격리 validator의 catch finally cleanup·이백사십육 좌표의 실제 뜻: $failure에 현재 식 $_의 평가값을 할당한다. 근거 원문은 F05-C13 원문 〔$failure = $_〕다. |
| 247 | } finally { | CTE 격리 validator의 catch finally cleanup·이백사십칠 좌표의 실제 뜻: cleanup and restoration finally scope header } finally {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔} finally {〕다. |
| 248 | if ($owned) { | CTE 격리 validator의 catch finally cleanup·이백사십팔 좌표의 실제 뜻: owned Compose cleanup condition header if ($owned) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔if ($owned) {〕다. |
| 249 | & docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null | CTE 격리 validator의 catch finally cleanup·이백사십구 좌표의 실제 뜻: owned Compose project에 down -v --remove-orphans를 요청한다. 근거 원문은 F05-C13 원문 〔& docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null〕다. |
| 250 | $cleanup = ($LASTEXITCODE -eq 0) | CTE 격리 validator의 catch finally cleanup·이백오십 좌표의 실제 뜻: cleanup bool을 compose down exit==0 결과로 설정한다. 근거 원문은 F05-C13 원문 〔$cleanup = ($LASTEXITCODE -eq 0)〕다. |
| 251 | } | CTE 격리 validator의 catch finally cleanup·이백오십일 좌표의 실제 뜻: PowerShell statement }의 현재 연산을 평가한다. 근거 원문은 F05-C13 원문 〔}〕다. |
| 252 | Restore-EnvironmentValue -Name "FCL_DB_PASSWORD" -Existed $hadPassword -Value $oldPassword | CTE 격리 validator의 catch finally cleanup·이백오십이 좌표의 실제 뜻: FCL_DB_PASSWORD의 존재 여부와 이전 값을 helper로 복원한다. 근거 원문은 F05-C13 원문 〔Restore-EnvironmentValue -Name "FCL_DB_PASSWORD" -Existed $hadPassword -Value $oldPassword〕다. |
| 253 | Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort | CTE 격리 validator의 catch finally cleanup·이백오십삼 좌표의 실제 뜻: helper 호출 Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort로 한 환경 변수를 run 전 상태로 복구한다. 근거 원문은 F05-C13 원문 〔Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort〕다. |
| 254 | } | CTE 격리 validator의 catch finally cleanup·이백오십사 좌표의 실제 뜻: try/catch/finally lifecycle의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다. |
| 256 | if (-not $cleanup) { | CTE 격리 validator의 cleanup confirmation outer gate·이백오십육 좌표의 실제 뜻: cleanup-not-confirmed condition header if (-not $cleanup) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔if (-not $cleanup) {〕다. |
| 257 | if ($null -ne $failure) { | CTE 격리 validator의 combined run-cleanup failure·이백오십칠 좌표의 실제 뜻: dual run-and-cleanup failure condition header if ($null -ne $failure) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔if ($null -ne $failure) {〕다. |
| 258 | throw "W17 CTE run failed and disposable cleanup was not confirmed: $($failure.Exception.Message)" | CTE 격리 validator의 combined run-cleanup failure·이백오십팔 좌표의 실제 뜻: run failure와 cleanup failure가 함께 있으면 결합 message로 throw한다. 근거 원문은 F05-C13 원문 〔throw "W17 CTE run failed and disposable cleanup was not confirmed: $($failure.Exception.Mess…〕다. |
| 259 | } | CTE 격리 validator의 combined run-cleanup failure·이백오십구 좌표의 실제 뜻: combined run-and-cleanup failure branch의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다. |
| 260 | throw "W17 CTE disposable cleanup was not confirmed" | CTE 격리 validator의 cleanup-only failure·이백육십 좌표의 실제 뜻: 현재 failure branch를 "W17 CTE disposable cleanup was not confirmed" 예외로 중단한다. 근거 원문은 F05-C13 원문 〔throw "W17 CTE disposable cleanup was not confirmed"〕다. |
| 261 | } | CTE 격리 validator의 cleanup-only failure·이백육십일 좌표의 실제 뜻: cleanup confirmation gate의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다. |
| 262 | if ($null -ne $failure) { | CTE 격리 validator의 captured run failure rethrow·이백육십이 좌표의 실제 뜻: captured run failure condition header if ($null -ne $failure) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔if ($null -ne $failure) {〕다. |
| 263 | throw $failure | CTE 격리 validator의 captured run failure rethrow·이백육십삼 좌표의 실제 뜻: cleanup은 성공했지만 captured run failure가 있으면 그 failure를 다시 던진다. 근거 원문은 F05-C13 원문 〔throw $failure〕다. |
| 264 | } | CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표의 실제 뜻: captured native failure rethrow gate의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다. |
| 266 | $evidence = @( | CTE 격리 validator의 evidence identity and provenance·이백육십육 좌표의 실제 뜻: final evidence line array header $evidence = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C14 원문 〔$evidence = @(〕다. |
| 267 | "W17_CTE_RETRIEVAL_GREEN", | CTE 격리 validator의 evidence identity and provenance·이백육십칠 좌표의 실제 뜻: array 또는 map에 literal element "W17_CTE_RETRIEVAL_GREEN",를 추가한다. 근거 원문은 F05-C14 원문 〔"W17_CTE_RETRIEVAL_GREEN",〕다. |
| 268 | "source_path=evidence/w17/reconcile-cte.sql", | CTE 격리 validator의 evidence identity and provenance·이백육십팔 좌표의 실제 뜻: array 또는 map에 literal element "source_path=evidence/w17/reconcile-cte.sql",를 추가한다. 근거 원문은 F05-C14 원문 〔"source_path=evidence/w17/reconcile-cte.sql",〕다. |
| 269 | "source_sha256=$sourceHash", | CTE 격리 validator의 evidence identity and provenance·이백육십구 좌표의 실제 뜻: evidence에 learner source SHA-256 line을 넣는다. 근거 원문은 F05-C14 원문 〔"source_sha256=$sourceHash",〕다. |
| 270 | "native_engine=postgresql-17-container", | CTE 격리 validator의 evidence identity and provenance·이백칠십 좌표의 실제 뜻: native_engine=postgresql-17-container literal을 evidence에 넣는다. 근거 원문은 F05-C14 원문 〔"native_engine=postgresql-17-container",〕다. |
| 271 | "native_exit=0", | CTE 격리 validator의 evidence identity and provenance·이백칠십일 좌표의 실제 뜻: array 또는 map에 literal element "native_exit=0",를 추가한다. 근거 원문은 F05-C14 원문 〔"native_exit=0",〕다. |
| 272 | "W17_BASELINE=EMPTY", | CTE 격리 validator의 published baseline sentinel·이백칠십이 좌표의 실제 뜻: final evidence에 exact balanced baseline W17_BASELINE=EMPTY를 넣는다. 근거 원문은 F05-C14 원문 〔"W17_BASELINE=EMPTY",〕다. |
| 273 | "W17_INJECTED=202|82|75|7", | CTE 격리 validator의 published primary anomaly·이백칠십삼 좌표의 실제 뜻: final evidence에 primary anomaly W17_INJECTED=202|82|75|7을 넣는다. 근거 원문은 F05-C14 원문 〔"W17_INJECTED=202|82|75|7",〕다. |
| 274 | "W17_RESTORED=EMPTY", | CTE 격리 validator의 published first recovery·이백칠십사 좌표의 실제 뜻: final evidence에 primary rollback 결과 W17_RESTORED=EMPTY를 넣는다. 근거 원문은 F05-C14 원문 〔"W17_RESTORED=EMPTY",〕다. |
| 275 | "W17_ALTERNATE_INJECTED=101|111|100|11", | CTE 격리 validator의 published hardcoding challenge·이백칠십오 좌표의 실제 뜻: final evidence에 hardcoding probe W17_ALTERNATE_INJECTED=101|111|100|11을 넣는다. 근거 원문은 F05-C14 원문 〔"W17_ALTERNATE_INJECTED=101|111|100|11",〕다. |
| 276 | "W17_ALTERNATE_RESTORED=EMPTY", | CTE 격리 validator의 published final recovery·이백칠십육 좌표의 실제 뜻: final evidence에 alternate rollback 결과 W17_ALTERNATE_RESTORED=EMPTY를 넣는다. 근거 원문은 F05-C14 원문 〔"W17_ALTERNATE_RESTORED=EMPTY",〕다. |
| 277 | "schema_scope=isolated-transaction", | CTE 격리 validator의 published isolation and cleanup claims·이백칠십칠 좌표의 실제 뜻: array 또는 map에 literal element "schema_scope=isolated-transaction",를 추가한다. 근거 원문은 F05-C14 원문 〔"schema_scope=isolated-transaction",〕다. |
| 278 | "cleanup=1" | CTE 격리 validator의 published isolation and cleanup claims·이백칠십팔 좌표의 실제 뜻: 현재 success/failure summary literal "cleanup=1"을 output stream에 보낸다. 근거 원문은 F05-C14 원문 〔"cleanup=1"〕다. |
| 279 | ) | CTE 격리 validator의 published isolation and cleanup claims·이백칠십구 좌표의 실제 뜻: final evidence line array의 마지막 delimiter를 닫는다. 근거 원문은 F05-C14 원문 〔)〕다. |
| 280 | $temporaryEvidence = "$evidencePath.tmp" | CTE 격리 validator의 atomic-ish publisher·이백팔십 좌표의 실제 뜻: final evidence path 옆의 .tmp 경로를 정한다. 근거 원문은 F05-C15 원문 〔$temporaryEvidence = "$evidencePath.tmp"〕다. |
| 281 | $evidence | Set-Content -LiteralPath $temporaryEvidence -Encoding utf8 | CTE 격리 validator의 atomic-ish publisher·이백팔십일 좌표의 실제 뜻: evidence line array를 same-directory temporary file에 UTF-8로 쓴다. 근거 원문은 F05-C15 원문 〔$evidence | Set-Content -LiteralPath $temporaryEvidence -Encoding utf8〕다. |
| 282 | Move-Item -LiteralPath $temporaryEvidence -Destination $evidencePath -Force | CTE 격리 validator의 atomic-ish publisher·이백팔십이 좌표의 실제 뜻: temporary evidence를 final path로 Force move한다. 근거 원문은 F05-C15 원문 〔Move-Item -LiteralPath $temporaryEvidence -Destination $evidencePath -Force〕다. |
| 284 | Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|100|11 restored=EMPTY source_sha256=$sourceHash native_exit=0 cleanup=1" | CTE 격리 validator의 atomic-ish publisher·이백팔십사 좌표의 실제 뜻: exact sentinels·source hash·native exit·cleanup 값을 담은 Green summary를 출력한다. 근거 원문은 F05-C15 원문 〔Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|1…〕다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기static regex shape gate와 isolated two-account native oracle, fail-closed cleanup, cleanup 이후 atomic-ish evidence promotion을 결합한 CTE retrieval validator다.
문법 해부
- source는 fixed ProjectRoot/evidence/w17/reconcile-cte.sql이고 resolved path prefix containment를 확인한다.
- one optional trailing semicolon만 떼고 내부 semicolon·DML/DDL/control·unsafe function을 거절하지만 full SQL parser는 아니다.
- expected five-marker array와 observed filtered marker array를 newline join해 case-sensitive exact 비교하므로 순서·중복도 닫는다.
- owned=true before up, finally down exit→cleanup bool, cleanup failure 우선, captured failure rethrow 순서로 fail closed한다.
- evidence는 cleanup/failure gates 뒤 같은 directory .tmp에 쓴 후 Force move한다.
실행 순서
- paths and stale evidence removal
- source containment/static contract
- hash and random transaction fixture
- baseline/202/restore/101/restore
- exact five-marker sequence
- down and environment restore
- cleanup/failure gates
- tmp write and final move
원래 W6 수준의 조각별 정밀 해설
F05-C01 · parameters and strict failure mode
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 CTE 격리 validator의 validator header·일 좌표의 실제 뜻: 격리된 CTE validator parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C01 원문 〔param(〕다. 끝에서 CTE 격리 validator의 validator header·칠 좌표의 실제 뜻: PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. 근거 원문은 F05-C01 원문 〔$ErrorActionPreference = "Stop"〕다.
- 실제 값 추적
- 시작 조건 CTE 격리 validator의 validator header·일 좌표 입력: 격리된 CTE validator parameter declaration header param(가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 매개변수와 엄격 실패 모드 직전 state와 〔param(〕의 operand만 받는다; 미래 child 산출은 제외한다.에서 범위를 통과하면 중간에 CTE 격리 validator의 validator header·사 좌표 직후 상태: parser와 PowerShell 제어가 script parameter list 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔)〕이며 이 변화는 F05-C01 안에 머문다. 마지막에 CTE 격리 validator의 validator header·칠 좌표 직후 상태: 뒤 cmdlet 실패가 terminating 경로로 이어질 기본 정책이 생긴다. source 단서는 〔$ErrorActionPreference = "Stop"〕이며 이 변화는 F05-C01 안에 머문다.
- 정상 예
- 원본 `param(`를 정확히 유지하고 이 범위를 실행·해석했을 때 CTE 격리 validator의 validator header·칠 좌표 직후 상태: 뒤 cmdlet 실패가 terminating 경로로 이어질 기본 정책이 생긴다. source 단서는 〔$ErrorActionPreference = "Stop"〕이며 이 변화는 F05-C01 안에 머문다.
- 틀린 예·반례
- parameter validation과 strict preference만 보고 아직 source·container·증거가 유효하다고 선언할 수 없다.
- 착각 방지
- CTE 격리 validator의 validator header·칠 좌표 책임 경계: 외부 명령 종료 코드를 자동 예외로 바꾸지는 않는다. 현재 operation은 PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. 확인 근거는 〔$ErrorActionPreference = "Stop"〕다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `매개변수와 엄격 실패 모드`의 source state만 다루며 CTE 격리 validator의 validator header·칠 좌표 책임 경계: 외부 명령 종료 코드를 자동 예외로 바꾸지는 않는다. 현재 operation은 PowerShell cmdlet 오류를 Stop으로 승격하는 전역 선호값을 설정한다. 확인 근거는 〔$ErrorActionPreference = "Stop"〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 validator header·칠 좌표 직후 상태: 뒤 cmdlet failure가 terminating path로 이어질 기본 정책이 생긴다. source 단서는 〔$ErrorActionPreference = "Stop"〕이며 이 변화는 F05-C01 안에 머문다. 이어지는 `environment restoration helper` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C02 · environment restoration helper
- 문법 해부
- 이 source slice의 문법 축은 CTE 격리 validator의 environment helper·십오 좌표의 실제 뜻: prior environment value existed condition header if ($Existed) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔if ($Existed) {〕다. 앞뒤로 CTE 격리 validator의 environment helper·구 좌표의 실제 뜻: environment restoration function header function Restore-EnvironmentValue {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C02 원문 〔function Restore-EnvironmentValue {〕다. 및 CTE 격리 validator의 environment helper·이십 좌표의 실제 뜻: Restore-EnvironmentValue function의 마지막 delimiter를 닫는다. 근거 원문은 F05-C02 원문 〔}〕다.
- 실제 값 추적
- CTE 격리 validator의 environment helper·구 좌표 입력: environment restoration function header function Restore-EnvironmentValue {가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 환경 변수 원상복구 helper 직전 state와 〔function Restore-EnvironmentValue {〕의 operand만 받는다; 미래 child 산출은 제외한다. 그 상태가 진행되면 CTE 격리 validator의 environment helper·이십 좌표 직후 상태: parser와 PowerShell 제어가 Restore-EnvironmentValue function 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C02 안에 머문다.
- 정상 예
- 유효한 예는 'function Restore-EnvironmentValue {' bytes를 보존해 CTE 격리 validator의 environment helper·십오 좌표 직후 상태: 환경 변수 원상복구 helper에서 prior environment value existed condition의 빈 scope가 생겨 바로 뒤 child를 받을 준비만 한다. source 단서는 〔if ($Existed) {〕이며 이 변화는 F05-C02 안에 머문다.
- 틀린 예·반례
- environment 복원 helper가 실행된다는 사실을 정리이나 첫 예외이 항상 성공한다는 보장으로 바꾸면 안 된다.
- 착각 방지
- CTE 격리 validator의 environment helper·십오 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 prior environment value existed condition header if ($Existed) {가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔if ($Existed) {〕다. 따라서 `environment restoration helper`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. CTE 격리 validator의 environment helper·십오 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 prior environment value existed condition header if ($Existed) {가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔if ($Existed) {〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 environment helper·이십 좌표 직후 상태: parser와 PowerShell 제어가 Restore-EnvironmentValue function 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C02 안에 머문다. 이어지는 `project paths and stale evidence removal` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C03 · project paths and stale evidence removal
- 문법 해부
- `project paths and stale evidence removal` 범위는 CTE 격리 validator의 ProjectRoot absolute guard·이십이 좌표의 실제 뜻: ProjectRoot absolute-path rejection condition header if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C03 원문 〔if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {〕다. 이어서 CTE 격리 validator의 stale evidence removal·삼십구 좌표의 실제 뜻: stale evidence removal condition의 마지막 delimiter를 닫는다. 근거 원문은 F05-C03 원문 〔}〕다.
- 실제 값 추적
- 구체 입력은 CTE 격리 validator의 fixed path derivation·삼십일 좌표 입력: $compose에 현재 식 Join-Path $referenceRoot "compose.yaml"의 평가값을 할당한다. 수행에 필요한 프로젝트 경로와 stale evidence 선삭제 직전 state와 〔$compose = Join-Path $referenceRoot "compose.yaml"〕의 operand만 받는다; 미래 child 산출은 제외한다. 처리 뒤 관찰 가능한 끝 상태는 CTE 격리 validator의 stale evidence removal·삼십구 좌표 직후 상태: parser와 PowerShell 제어가 stale evidence removal condition 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C03 안에 머문다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 CTE 격리 validator의 ProjectRoot absolute guard·이십이 좌표 직후 상태: 프로젝트 경로와 stale evidence 선삭제에서 ProjectRoot absolute-path rejection condition의 빈 scope가 생겨 바로 뒤 child를 받을 준비만 한다. source 단서는 〔if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {〕이며 이 변화는 F05-C03 안에 머문다. 그리고 범위 끝에서 CTE 격리 validator의 stale evidence removal·삼십구 좌표 직후 상태: parser와 PowerShell 제어가 stale evidence removal condition 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C03 안에 머문다.
- 틀린 예·반례
- stale evidence를 지우는 경로가 있다는 이유로 모든 early 실패 전에 이전 파일이 반드시 사라진다고 일반화하지 않는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: CTE 격리 validator의 ProjectRoot absolute guard·이십이 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 ProjectRoot absolute-path rejection condition header if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {〕다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: CTE 격리 validator의 ProjectRoot absolute guard·이십이 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 ProjectRoot absolute-path rejection condition header if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 stale evidence removal·삼십구 좌표 직후 상태: parser와 PowerShell 제어가 stale evidence removal condition 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C03 안에 머문다. 이어지는 `source existence containment and placeholder guards` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C04 · source existence containment and placeholder guards
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 CTE 격리 validator의 source leaf existence guard·사십일 좌표의 실제 뜻: learner SQL missing-file condition header if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C04 원문 〔if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {〕다. 끝에서 CTE 격리 validator의 meta-command guard·육십칠 좌표의 실제 뜻: meta-command rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C04 원문 〔}〕다.
- 실제 값 추적
- 시작 조건 CTE 격리 validator의 source leaf existence guard·사십일 좌표 입력: learner SQL missing-file condition header if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 learner SQL 존재·containment·placeholder 검사 직전 state와 〔if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {〕의 operand만 받는다; 미래 child 산출은 제외한다.에서 범위를 통과하면 중간에 CTE 격리 validator의 comment stripping guard·오십육 좌표 직후 상태: 정적 검사 대상에서 slash-star comment 내용이 제거된다. source 단서는 〔$inspection = [regex]::Replace($learnerSql, "(?s)/\*.*?\*/", " ")〕이며 이 변화는 F05-C04 안에 머문다. 마지막에 CTE 격리 validator의 meta-command guard·육십칠 좌표 직후 상태: parser와 PowerShell 제어가 meta-command rejection 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C04 안에 머문다.
- 정상 예
- 원본 `if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {`를 정확히 유지하고 이 범위를 실행·해석했을 때 CTE 격리 validator의 meta-command guard·육십칠 좌표 직후 상태: parser와 PowerShell 제어가 meta-command rejection 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C04 안에 머문다.
- 틀린 예·반례
- placeholder와 containment guard를 통과한 검사 문자열가 완전한 SQL parser 관점에서도 안전하다고 말하면 regex 검사의 한계를 넘는다.
- 착각 방지
- CTE 격리 validator의 meta-command guard·육십칠 좌표 책임 경계: 닫는 기호만으로 meta-command rejection 안 명령의 성공·Green은 증명되지 않는다. 현재 operation은 meta-command rejection의 마지막 delimiter를 닫는다. 확인 근거는 〔}〕다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `source existence containment and placeholder guards`의 source state만 다루며 CTE 격리 validator의 meta-command guard·육십칠 좌표 책임 경계: 닫는 기호만으로 meta-command rejection 안 명령의 성공·Green은 증명되지 않는다. 현재 operation은 meta-command rejection의 마지막 delimiter를 닫는다. 확인 근거는 〔}〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 meta-command guard·육십칠 좌표 직후 상태: parser와 PowerShell 제어가 meta-command rejection 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C04 안에 머문다. 이어지는 `single read-only CTE SELECT guard` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C05 · single read-only CTE SELECT guard
- 문법 해부
- 이 source slice의 문법 축은 CTE 격리 validator의 WITH prefix guard·칠십구 좌표의 실제 뜻: WITH-prefix rejection condition header if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C05 원문 〔if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {〕다. 앞뒤로 CTE 격리 validator의 semicolon cardinality guard·육십구 좌표의 실제 뜻: $query에 현재 식 $inspection.Trim()의 평가값을 할당한다. 근거 원문은 F05-C05 원문 〔$query = $inspection.Trim()〕다. 및 CTE 격리 validator의 unsafe function guard·팔십칠 좌표의 실제 뜻: unsafe function rejection의 마지막 delimiter를 닫는다. 근거 원문은 F05-C05 원문 〔}〕다.
- 실제 값 추적
- CTE 격리 validator의 semicolon cardinality guard·육십구 좌표 입력: $query에 현재 식 $inspection.Trim()의 평가값을 할당한다. 수행에 필요한 단일 read-only CTE SELECT 검사 직전 state와 〔$query = $inspection.Trim()〕의 operand만 받는다; 미래 child 산출은 제외한다. 그 상태가 진행되면 CTE 격리 validator의 unsafe function guard·팔십칠 좌표 직후 상태: parser와 PowerShell 제어가 unsafe function rejection 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C05 안에 머문다.
- 정상 예
- 유효한 예는 '$query = $inspection.Trim()' bytes를 보존해 CTE 격리 validator의 WITH prefix guard·칠십구 좌표 직후 상태: 단일 read-only CTE SELECT 검사에서 WITH-prefix rejection condition의 빈 scope가 생겨 바로 뒤 child를 받을 준비만 한다. source 단서는 〔if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {〕이며 이 변화는 F05-C05 안에 머문다.
- 틀린 예·반례
- DML keyword 부재·SELECT 한 개 검사만으로 quoted 검사 문자열와 복잡한 writable 구문를 모두 판별했다고 할 수 없다.
- 착각 방지
- CTE 격리 validator의 WITH prefix guard·칠십구 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 WITH-prefix rejection condition header if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {〕다. 따라서 `single read-only CTE SELECT guard`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. CTE 격리 validator의 WITH prefix guard·칠십구 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 WITH-prefix rejection condition header if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 unsafe function guard·팔십칠 좌표 직후 상태: parser와 PowerShell 제어가 unsafe function rejection 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C05 안에 머문다. 이어지는 `required CTE shape and signed total` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C06 · required CTE shape and signed total
- 문법 해부
- `required CTE shape and signed total` 범위는 CTE 격리 validator의 required-pattern definition·팔십구 좌표의 실제 뜻: required-pattern ordered map header $requiredPatterns = [ordered]@{가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C06 원문 〔$requiredPatterns = [ordered]@{〕다. 이어서 CTE 격리 validator의 signed-total choice·백십이 좌표의 실제 뜻: signed-total representation gate의 마지막 delimiter를 닫는다. 근거 원문은 F05-C06 원문 〔}〕다.
- 실제 값 추적
- 구체 입력은 CTE 격리 validator의 required-pattern consumption·백일 좌표 입력: required-pattern iteration header foreach ($entry in $requiredPatterns.GetEnumerator()) {가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 필수 CTE 모양과 signed total 검사 직전 state와 〔foreach ($entry in $requiredPatterns.GetEnumerator()) {〕의 operand만 받는다; 미래 child 산출은 제외한다. 처리 뒤 관찰 가능한 끝 상태는 CTE 격리 validator의 signed-total choice·백십이 좌표 직후 상태: parser와 PowerShell 제어가 signed-total representation gate 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C06 안에 머문다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 CTE 격리 validator의 required-pattern definition·팔십구 좌표 직후 상태: 필수 CTE 모양과 signed total 검사에서 required-pattern ordered map의 빈 scope가 생겨 바로 뒤 child를 받을 준비만 한다. source 단서는 〔$requiredPatterns = [ordered]@{〕이며 이 변화는 F05-C06 안에 머문다. 그리고 범위 끝에서 CTE 격리 validator의 signed-total choice·백십이 좌표 직후 상태: parser와 PowerShell 제어가 signed-total representation gate 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C06 안에 머문다.
- 틀린 예·반례
- 세 CTE 이름과 SUM token이 있다는 사실만으로 account grain, LEFT JOIN preservation, 차이 semantics가 옳다고 단정하지 않는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: CTE 격리 validator의 required-pattern definition·팔십구 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 required-pattern ordered map header $requiredPatterns = [ordered]@{가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔$requiredPatterns = [ordered]@{〕다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: CTE 격리 validator의 required-pattern definition·팔십구 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 required-pattern ordered map header $requiredPatterns = [ordered]@{가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔$requiredPatterns = [ordered]@{〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 signed-total choice·백십이 좌표 직후 상태: parser와 PowerShell 제어가 signed-total representation gate 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C06 안에 머문다. 이어지는 `source hash isolated schema and fixture` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C07 · source hash isolated schema and fixture
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 CTE 격리 validator의 hash and transaction header·백십사 좌표의 실제 뜻: resolved learner SQL의 SHA-256을 소문자로 계산한다. 근거 원문은 F05-C07 원문 〔$sourceHash = (Get-FileHash -LiteralPath $resolvedSource -Algorithm SHA256).Hash.ToLowerInvar…〕다. 끝에서 CTE 격리 validator의 ledger fixture·백사십삼 좌표의 실제 뜻: account 202에 +75 ledger row를 넣고 ledger INSERT를 끝낸다. 근거 원문은 F05-C07 원문 〔(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');〕다.
- 실제 값 추적
- 시작 조건 CTE 격리 validator의 hash and transaction header·백십사 좌표 입력: resolved learner SQL의 SHA-256을 소문자로 계산한다. 수행에 필요한 source hash·격리 schema·fixture 직전 state와 〔$sourceHash = (Get-FileHash -LiteralPath $resolvedSource -Algorithm SHA256).Hash.ToLowerInvar…〕의 operand만 받는다; 미래 child 산출은 제외한다.에서 범위를 통과하면 중간에 CTE 격리 validator의 ledger table·백이십구 좌표 직후 상태: 각 fixture ledger row가 존재하는 101 또는 202 account grain에 연결된다. source 단서는 〔account_id BIGINT NOT NULL REFERENCES account(id),〕이며 이 변화는 F05-C07 안에 머문다. 마지막에 CTE 격리 validator의 ledger fixture·백사십삼 좌표 직후 상태: 101 net 100·202 net 75·303 no-row 기준 fixture가 완성된다. source 단서는 〔(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');〕이며 이 변화는 F05-C07 안에 머문다.
- 정상 예
- 원본 `$sourceHash = (Get-FileHash -LiteralPath $resolvedSource -Algorithm SHA256).Hash.ToLowerInv…`를 정확히 유지하고 이 범위를 실행·해석했을 때 CTE 격리 validator의 ledger fixture·백사십삼 좌표 직후 상태: 101 net 100·202 net 75·303 no-row 기준 fixture가 완성된다. source 단서는 〔(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');〕이며 이 변화는 F05-C07 안에 머문다.
- 틀린 예·반례
- 격리된 schema와 source SHA 기록을 production data 무변경 또는 image digest 고정 증명으로 확대하면 범위를 벗어난다.
- 착각 방지
- CTE 격리 validator의 ledger fixture·백사십삼 좌표 책임 경계: production ledger completeness나 double-entry balance는 이 세 행이 증명하지 않는다. 현재 operation은 account 202에 +75 ledger row를 넣고 ledger INSERT를 끝낸다. 확인 근거는 〔(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');〕다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `source hash·격리 schema·fixture`의 source state만 다루며 CTE 격리 validator의 ledger fixture·백사십삼 좌표 책임 경계: production ledger completeness나 double-entry balance는 이 세 행이 증명하지 않는다. 현재 operation은 account 202에 +75 ledger row를 넣고 ledger INSERT를 끝낸다. 확인 근거는 〔(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 ledger fixture·백사십삼 좌표 직후 상태: 101 net 100·202 net 75·303 no-row baseline fixture가 완성된다. source 단서는 〔(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');〕이며 이 변화는 F05-C07 안에 머문다. 이어지는 `baseline and primary mismatch cycle` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C08 · baseline and primary mismatch cycle
- 문법 해부
- 이 source slice의 문법 축은 CTE 격리 validator의 첫 불일치 marker·백육십일 좌표의 실제 뜻: 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 근거 원문은 F05-C08 원문 〔),〕다. 앞뒤로 CTE 격리 validator의 기준 marker expression head·백사십오 좌표의 실제 뜻: 기준 marker SELECT expression header SELECT 'W17_BASELINE=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C08 원문 〔SELECT 'W17_BASELINE=' || COALESCE(〕다. 및 CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십오 좌표의 실제 뜻: 첫 checkpoint 복구가 mismatch를 깨끗이 없앴는지 반례 row로 감시한다; learner subquery를 alias로 닫아 marker aggregate에 넘긴다. 근거 원문은 F05-C08 원문 〔) AS learner_result;〕다.
- 실제 값 추적
- CTE 격리 validator의 기준 marker expression head·백사십오 좌표 입력: 기준 marker SELECT expression header SELECT 'W17_BASELINE=' || COALESCE(가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 기준과 202 mismatch 왕복 직전 state와 〔SELECT 'W17_BASELINE=' || COALESCE(〕의 operand만 받는다; 미래 child 산출은 제외한다. 그 상태가 진행되면 CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십오 좌표 직후 상태: primary savepoint rollback 뒤 202가 75로 복귀한 상태의 four-column relation이 바깥 SELECT에 연결되어 W17_RESTORED=EMPTY 후보 계산이 끝난다. source 단서는 〔) AS learner_result;〕이며 이 변화는 F05-C08 안에 머문다.
- 정상 예
- 유효한 예는 "SELECT 'W17_BASELINE=' || COALESCE(" bytes를 보존해 CTE 격리 validator의 첫 불일치 marker·백육십일 좌표 직후 상태: account 202의 저장값과 ledger 75 사이 양의 차이에서 aggregate text 또는 NULL이 fallback 선택 지점에 도착한다. source 단서는 〔),〕이며 이 변화는 F05-C08 안에 머문다.
- 틀린 예·반례
- 202 검산 표식 +7 한 건을 통과했다고 hardcoded account filter가 없다고 결론 내리면 대체 cycle의 목적을 잃는다.
- 착각 방지
- CTE 격리 validator의 첫 불일치 marker·백육십일 좌표 책임 경계: delimiter closure만으로 주입 결과 marker와 실제 equality가 성립하지 않는다. 현재 operation은 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 확인 근거는 〔),〕다. 따라서 `기준 상태와 첫 불일치 왕복`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. CTE 격리 validator의 첫 불일치 marker·백육십일 좌표 책임 경계: delimiter closure만으로 주입 결과 marker와 실제 equality가 성립하지 않는다. 현재 operation은 202번 계좌에 만든 7-unit fault를 한 행으로 포착한다; string_agg argument list를 닫고 COALESCE 첫 operand로 넘긴다. 확인 근거는 〔),〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 primary 202 rollback EMPTY marker·백칠십오 좌표 직후 상태: primary savepoint rollback 뒤 202가 75로 복귀한 상태의 four-column relation이 바깥 SELECT에 연결되어 W17_RESTORED=EMPTY 후보 계산이 끝난다. source 단서는 〔) AS learner_result;〕이며 이 변화는 F05-C08 안에 머문다. 이어지는 `alternate mismatch cycle and rollback` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C09 · alternate mismatch cycle and rollback
- 문법 해부
- `대체 불일치 왕복과 복구` 범위는 CTE 격리 validator의 대체 mutation setup·백칠십칠 좌표의 실제 뜻: alternate_account_mismatch savepoint를 만든다. 근거 원문은 F05-C09 원문 〔SAVEPOINT alternate_account_mismatch;〕다. 이어서 CTE 격리 validator의 외부 명령 template closure·백구십구 좌표의 실제 뜻: 외부 명령 SQL here-string의 마지막 delimiter를 닫는다. 근거 원문은 F05-C09 원문 〔"@〕다.
- 실제 값 추적
- 구체 입력은 CTE 격리 validator의 대체 rollback command·백팔십팔 좌표 입력: alternate_account_mismatch savepoint로 rollback한다. 수행에 필요한 101 대체 mismatch와 rollback 직전 state와 〔ROLLBACK TO SAVEPOINT alternate_account_mismatch;〕의 operand만 받는다; 미래 child 산출은 제외한다. 처리 뒤 관찰 가능한 끝 상태는 CTE 격리 validator의 외부 명령 template closure·백구십구 좌표 직후 상태: parser와 PowerShell 제어가 외부 명령 SQL here-string 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔"@〕이며 이 변화는 F05-C09 안에 머문다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 CTE 격리 validator의 대체 mutation setup·백칠십칠 좌표 직후 상태: 101 +11 probe를 되돌릴 두 번째 checkpoint가 생긴다. source 단서는 〔SAVEPOINT alternate_account_mismatch;〕이며 이 변화는 F05-C09 안에 머문다. 그리고 범위 끝에서 CTE 격리 validator의 외부 명령 template closure·백구십구 좌표 직후 상태: parser와 PowerShell 제어가 외부 명령 SQL here-string 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔"@〕이며 이 변화는 F05-C09 안에 머문다.
- 틀린 예·반례
- 101 대체 +11까지 맞아도 모든 account·amount·multi-row mismatch에 일반적으로 정확하다고 보장되지는 않는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: CTE 격리 validator의 대체 mutation setup·백칠십칠 좌표 책임 경계: primary savepoint의 이름이나 query source를 바꾸지는 않는다. 현재 operation은 alternate_account_mismatch savepoint를 만든다. 확인 근거는 〔SAVEPOINT alternate_account_mismatch;〕다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: CTE 격리 validator의 대체 mutation setup·백칠십칠 좌표 책임 경계: primary savepoint의 이름이나 query source를 바꾸지는 않는다. 현재 operation은 alternate_account_mismatch savepoint를 만든다. 확인 근거는 〔SAVEPOINT alternate_account_mismatch;〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 native template closure·백구십구 좌표 직후 상태: parser와 PowerShell 제어가 native SQL here-string 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔"@〕이며 이 변화는 F05-C09 안에 머문다. 이어지는 `environment and lifecycle state capture` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C10 · environment and lifecycle state capture
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 CTE 격리 validator의 password environment snapshot·이백일 좌표의 실제 뜻: FCL_DB_PASSWORD 환경 변수가 원래 존재했는지 기록한다. 근거 원문은 F05-C10 원문 〔$hadPassword = Test-Path -LiteralPath "Env:FCL_DB_PASSWORD"〕다. 끝에서 CTE 격리 validator의 외부 명령 result sentinels·이백구 좌표의 실제 뜻: nativeOutput을 빈 PowerShell array로 초기화한다. 근거 원문은 F05-C10 원문 〔$nativeOutput = @()〕다.
- 실제 값 추적
- 시작 조건 CTE 격리 validator의 password environment snapshot·이백일 좌표 입력: FCL_DB_PASSWORD 환경 변수가 원래 존재했는지 기록한다. 수행에 필요한 환경과 lifecycle 상태 캡처 직전 state와 〔$hadPassword = Test-Path -LiteralPath "Env:FCL_DB_PASSWORD"〕의 operand만 받는다; 미래 child 산출은 제외한다.에서 범위를 통과하면 중간에 CTE 격리 validator의 cleanup lifecycle flags·이백오 좌표 직후 상태: 구동 전 lifecycle은 아직 cleanup 대상 아님으로 표시된다. source 단서는 〔$owned = $false〕이며 이 변화는 F05-C10 안에 머문다. 마지막에 CTE 격리 validator의 외부 명령 result sentinels·이백구 좌표 직후 상태: psql transcript를 받기 전 output collection이 0개 element 상태가 된다. source 단서는 〔$nativeOutput = @()〕이며 이 변화는 F05-C10 안에 머문다.
- 정상 예
- 원본 `$hadPassword = Test-Path -LiteralPath "Env:FCL_DB_PASSWORD"`를 정확히 유지하고 이 범위를 실행·해석했을 때 CTE 격리 validator의 외부 명령 result sentinels·이백구 좌표 직후 상태: psql transcript를 받기 전 output collection이 0개 element 상태가 된다. source 단서는 〔$nativeOutput = @()〕이며 이 변화는 F05-C10 안에 머문다.
- 틀린 예·반례
- lifecycle state를 변수에 담는 것과 실제 Docker resource ownership·cleanup 성공은 같은 사건이 아니다.
- 착각 방지
- CTE 격리 validator의 외부 명령 result sentinels·이백구 좌표 책임 경계: 빈 초기 array를 W17_BASELINE=EMPTY SQL marker와 혼동하면 안 된다. 현재 operation은 nativeOutput을 빈 PowerShell array로 초기화한다. 확인 근거는 〔$nativeOutput = @()〕다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `environment and lifecycle state capture`의 source state만 다루며 CTE 격리 validator의 외부 명령 result sentinels·이백구 좌표 책임 경계: 빈 초기 array를 W17_BASELINE=EMPTY SQL marker와 혼동하면 안 된다. 현재 operation은 nativeOutput을 빈 PowerShell array로 초기화한다. 확인 근거는 〔$nativeOutput = @()〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 native result sentinels·이백구 좌표 직후 상태: psql transcript를 받기 전 output collection이 0개 element 상태가 된다. source 단서는 〔$nativeOutput = @()〕이며 이 변화는 F05-C10 안에 머문다. 이어지는 `Compose startup and native execution` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C11 · Compose startup and native execution
- 문법 해부
- 이 source slice의 문법 축은 CTE 격리 validator의 container resolution·이백십구 좌표의 실제 뜻: $container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. 근거 원문은 F05-C11 원문 〔$container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()〕다. 앞뒤로 CTE 격리 validator의 Compose startup·이백십일 좌표의 실제 뜻: native runner try scope header try {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C11 원문 〔try {〕다. 및 CTE 격리 validator의 native psql execution·이백이십팔 좌표의 실제 뜻: native psql failure guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C11 원문 〔}〕다.
- 실제 값 추적
- CTE 격리 validator의 Compose startup·이백십일 좌표 입력: native runner try scope header try {가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 Compose 기동과 native 실행 직전 state와 〔try {〕의 operand만 받는다; 미래 child 산출은 제외한다. 그 상태가 진행되면 CTE 격리 validator의 native psql execution·이백이십팔 좌표 직후 상태: parser와 PowerShell 제어가 native psql failure guard 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C11 안에 머문다.
- 정상 예
- 유효한 예는 'try {' bytes를 보존해 CTE 격리 validator의 container resolution·이백십구 좌표 직후 상태: 뒤 sibling statement가 $container의 새 값을 읽을 수 있는 state가 된다. source 단서는 〔$container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()〕이며 이 변화는 F05-C11 안에 머문다.
- 틀린 예·반례
- mutable image tag와 compose wait 성공을 immutable runtime bytes·application query Green으로 읽을 수 없다.
- 착각 방지
- CTE 격리 validator의 container resolution·이백십구 좌표 책임 경계: 이 assignment 하나는 $container이 가리키는 외부 file·container·SQL 의미를 검증하지 않는다. 현재 operation은 $container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. 확인 근거는 〔$container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()〕다. 따라서 `Compose 구동과 외부 명령 실행`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. CTE 격리 validator의 container resolution·이백십구 좌표 책임 경계: 이 assignment 하나는 $container이 가리키는 외부 file·container·SQL 의미를 검증하지 않는다. 현재 operation은 $container에 현재 식 (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()의 평가값을 할당한다. 확인 근거는 〔$container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 native psql execution·이백이십팔 좌표 직후 상태: parser와 PowerShell 제어가 native psql failure guard 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C11 안에 머문다. 이어지는 `exact five-marker sequence check` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C12 · exact five-marker sequence check
- 문법 해부
- `exact five-marker sequence check` 범위는 CTE 격리 validator의 observed marker filter·이백삼십 좌표의 실제 뜻: observed marker array pipeline header $markers = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C12 원문 〔$markers = @(〕다. 이어서 CTE 격리 validator의 exact joined marker comparison·이백사십사 좌표의 실제 뜻: exact marker sequence guard의 마지막 delimiter를 닫는다. 근거 원문은 F05-C12 원문 〔}〕다.
- 실제 값 추적
- 구체 입력은 CTE 격리 validator의 expected primary anomaly·이백삼십칠 좌표 입력: expected sequence의 둘째 값으로 주입 결과 marker을 둔다. 수행에 필요한 다섯 marker의 exact sequence gate 직전 state와 〔"주입 결과 marker",〕의 operand만 받는다; 미래 child 산출은 제외한다. 처리 뒤 관찰 가능한 끝 상태는 CTE 격리 validator의 exact joined marker comparison·이백사십사 좌표 직후 상태: parser와 PowerShell 제어가 exact marker sequence guard 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C12 안에 머문다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 CTE 격리 validator의 observed marker filter·이백삼십 좌표 직후 상태: 다섯 marker의 exact sequence gate에서 observed marker array pipeline의 빈 scope가 생겨 바로 뒤 child를 받을 준비만 한다. source 단서는 〔$markers = @(〕이며 이 변화는 F05-C12 안에 머문다. 그리고 범위 끝에서 CTE 격리 validator의 exact joined marker comparison·이백사십사 좌표 직후 상태: parser와 PowerShell 제어가 exact marker sequence guard 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C12 안에 머문다.
- 틀린 예·반례
- 202 sentinel을 포함한 five markers가 있다는 것과 정확히 한 번씩 지정 순서로 나타난다는 것을 구분하지 않으면 false Green이 생긴다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: CTE 격리 validator의 observed marker filter·이백삼십 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 observed marker array pipeline header $markers = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔$markers = @(〕다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: CTE 격리 validator의 observed marker filter·이백삼십 좌표 책임 경계: 이 opener는 현재 header만 해석하며 child의 값·오류·Green 결과를 아직 확정하지 않는다. 현재 operation은 observed marker array pipeline header $markers = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 확인 근거는 〔$markers = @(〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 exact joined marker comparison·이백사십사 좌표 직후 상태: parser와 PowerShell 제어가 exact marker sequence guard 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C12 안에 머문다. 이어지는 `cleanup error precedence and environment restore` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C13 · cleanup error precedence and environment restore
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 CTE 격리 validator의 catch finally cleanup·이백사십오 좌표의 실제 뜻: failure capture catch scope header } catch {가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C13 원문 〔} catch {〕다. 끝에서 CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표의 실제 뜻: captured native failure rethrow gate의 마지막 delimiter를 닫는다. 근거 원문은 F05-C13 원문 〔}〕다.
- 실제 값 추적
- 시작 조건 CTE 격리 validator의 catch finally cleanup·이백사십오 좌표 입력: failure capture catch scope header } catch {가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 cleanup 우선 판정과 환경 복구 직전 state와 〔} catch {〕의 operand만 받는다; 미래 child 산출은 제외한다.에서 범위를 통과하면 중간에 CTE 격리 validator의 catch finally cleanup·이백오십사 좌표 직후 상태: parser와 PowerShell 제어가 try/catch/finally lifecycle 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C13 안에 머문다. 마지막에 CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표 직후 상태: parser와 PowerShell 제어가 captured native failure rethrow gate 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C13 안에 머문다.
- 정상 예
- 원본 `} catch {`를 정확히 유지하고 이 범위를 실행·해석했을 때 CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표 직후 상태: parser와 PowerShell 제어가 captured native failure rethrow gate 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C13 안에 머문다.
- 틀린 예·반례
- partial cleanup error가 primary error를 덮지 않는다고 환경 복원·resource 제거가 반드시 성공했다고 말할 수 없다.
- 착각 방지
- CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표 책임 경계: 닫는 기호만으로 captured native failure rethrow gate 안 명령의 성공·Green은 증명되지 않는다. 현재 operation은 captured native failure rethrow gate의 마지막 delimiter를 닫는다. 확인 근거는 〔}〕다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `cleanup error precedence and environment restore`의 source state만 다루며 CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표 책임 경계: 닫는 기호만으로 captured native failure rethrow gate 안 명령의 성공·Green은 증명되지 않는다. 현재 operation은 captured native failure rethrow gate의 마지막 delimiter를 닫는다. 확인 근거는 〔}〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 captured run failure rethrow·이백육십사 좌표 직후 상태: parser와 PowerShell 제어가 captured native failure rethrow gate 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔}〕이며 이 변화는 F05-C13 안에 머문다. 이어지는 `hash-bound evidence payload` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C14 · hash-bound evidence payload
- 문법 해부
- 이 source slice의 문법 축은 CTE 격리 validator의 published primary anomaly·이백칠십삼 좌표의 실제 뜻: final evidence에 primary anomaly 주입 결과 marker을 넣는다. 근거 원문은 F05-C14 원문 〔"주입 결과 marker",〕다. 앞뒤로 CTE 격리 validator의 evidence identity and provenance·이백육십육 좌표의 실제 뜻: final evidence line array header $evidence = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 근거 원문은 F05-C14 원문 〔$evidence = @(〕다. 및 CTE 격리 validator의 published isolation and cleanup claims·이백칠십구 좌표의 실제 뜻: final evidence line array의 마지막 delimiter를 닫는다. 근거 원문은 F05-C14 원문 〔)〕다.
- 실제 값 추적
- CTE 격리 validator의 evidence identity and provenance·이백육십육 좌표 입력: final evidence line array header $evidence = @(가 child 범위를 연다. body는 아직 실행되지 않았다. 수행에 필요한 hash-bound evidence payload 직전 state와 〔$evidence = @(〕의 operand만 받는다; 미래 child 산출은 제외한다. 그 상태가 진행되면 CTE 격리 validator의 published isolation and cleanup claims·이백칠십구 좌표 직후 상태: parser와 PowerShell 제어가 final evidence line array 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔)〕이며 이 변화는 F05-C14 안에 머문다.
- 정상 예
- 유효한 예는 '$evidence = @(' bytes를 보존해 CTE 격리 validator의 published primary anomaly·이백칠십삼 좌표 직후 상태: 공개 payload가 202 stored·ledger·difference 네 값을 고정한다. source 단서는 〔"주입 결과 marker",〕이며 이 변화는 F05-C14 안에 머문다.
- 틀린 예·반례
- evidence JSON의 source hash는 learner query bytes를 결속하지만 DB image digest나 production result까지 인증하지 않는다.
- 착각 방지
- CTE 격리 validator의 published primary anomaly·이백칠십삼 좌표 책임 경계: 대체 101 hardcoding probe의 통과는 별도 evidence line이 담당한다. 현재 operation은 final evidence에 primary anomaly 주입 결과 marker을 넣는다. 확인 근거는 〔"주입 결과 marker",〕다. 따라서 `hash-bound evidence payload`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. CTE 격리 validator의 published primary anomaly·이백칠십삼 좌표 책임 경계: 대체 101 hardcoding probe의 통과는 별도 evidence line이 담당한다. 현재 operation은 final evidence에 primary anomaly 주입 결과 marker을 넣는다. 확인 근거는 〔"주입 결과 marker",〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 published isolation and cleanup claims·이백칠십구 좌표 직후 상태: parser와 PowerShell 제어가 final evidence line array 밖의 sibling 단계로 이동할 수 있게 된다. source 단서는 〔)〕이며 이 변화는 F05-C14 안에 머문다. 이어지는 `temporary write atomic move and Green output` 범위에서 이 상태의 입력 경계를 확인한다.
F05-C15 · temporary write atomic move and Green output
- 문법 해부
- `temporary write atomic move and Green output` 범위는 CTE 격리 validator의 atomic-ish publisher·이백팔십 좌표의 실제 뜻: final evidence path 옆의 .tmp 경로를 정한다. 근거 원문은 F05-C15 원문 〔$temporaryEvidence = "$evidencePath.tmp"〕다. 이어서 CTE 격리 validator의 atomic-ish publisher·이백팔십사 좌표의 실제 뜻: exact sentinels·source hash·native exit·cleanup 값을 담은 Green summary를 출력한다. 근거 원문은 F05-C15 원문 〔Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|1…〕다.
- 실제 값 추적
- 구체 입력은 CTE 격리 validator의 atomic-ish publisher·이백팔십이 좌표 입력: temporary evidence를 final path로 Force move한다. 수행에 필요한 임시 쓰기·교체·Green 출력 직전 state와 〔Move-Item -LiteralPath $temporaryEvidence -Destination $evidencePath -Force〕의 operand만 받는다; 미래 child 산출은 제외한다. 처리 뒤 관찰 가능한 끝 상태는 CTE 격리 validator의 atomic-ish publisher·이백팔십사 좌표 직후 상태: caller가 성공 run의 한 줄 요약을 받는다. source 단서는 〔Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|1…〕이며 이 변화는 F05-C15 안에 머문다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 CTE 격리 validator의 atomic-ish publisher·이백팔십 좌표 직후 상태: 완성 전 bytes를 별도 이름에 쓸 staging target이 생긴다. source 단서는 〔$temporaryEvidence = "$evidencePath.tmp"〕이며 이 변화는 F05-C15 안에 머문다. 그리고 범위 끝에서 CTE 격리 validator의 atomic-ish publisher·이백팔십사 좌표 직후 상태: caller가 성공 run의 한 줄 요약을 받는다. source 단서는 〔Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|1…〕이며 이 변화는 F05-C15 안에 머문다.
- 틀린 예·반례
- temporary file의 atomic move와 101 alternate 표기가 내용의 의미적 정확성이나 외부 filesystem의 모든 crash durability를 보장하지 않는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: CTE 격리 validator의 atomic-ish publisher·이백팔십 좌표 책임 경계: 다른 process와의 locking이나 fsync durability는 제공하지 않는다. 현재 operation은 final evidence path 옆의 .tmp 경로를 정한다. 확인 근거는 〔$temporaryEvidence = "$evidencePath.tmp"〕다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: CTE 격리 validator의 atomic-ish publisher·이백팔십 좌표 책임 경계: 다른 process와의 locking이나 fsync durability는 제공하지 않는다. 현재 operation은 final evidence path 옆의 .tmp 경로를 정한다. 확인 근거는 〔$temporaryEvidence = "$evidencePath.tmp"〕다.
- 다음 연결
- 끝 상태를 기록한다: CTE 격리 validator의 atomic-ish publisher·이백팔십사 좌표 직후 상태: caller가 성공 run의 한 줄 요약을 받는다. source 단서는 〔Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|1…〕이며 이 변화는 F05-C15 안에 머문다. 이어지는 `provenance and runner contract` 범위에서 이 상태의 입력 경계를 확인한다.
정리가 먼저인 이유히토리 → 니지카 → 료 → 키타
-
히토리
psql이 성공하면 바로 evidence를 써도 되죠?
-
니지카
이 runner는 down 성공과 captured failure 부재를 먼저 확인해.
-
료
cleanup이 실패하면 Green file을 쓰지 않고 실패를 우선 표면화한다.
-
키타
evidence publish 전 gates를 순서대로 적겠습니다.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| 1 | accounts 101=100, 202=75, 303=0; ledger totals 101=100, 202=75 | learner query를 baseline wrapper에 넣는다. | W17_BASELINE=EMPTY가 exact first marker다. | EMPTY는 mismatch set 0행이지 table row 0건이 아니다. |
| 2 | SAVEPOINT primary_mismatch; account 202 +7 | 같은 learner query를 실행한다. | W17_INJECTED=202|82|75|7 뒤 rollback과 W17_RESTORED=EMPTY가 온다. | 202 hardcoding은 아직 들키지 않을 수 있다. |
| 3 | SAVEPOINT alternate_account_mismatch; account 101 +11 | alternate account에서 query를 다시 실행한다. | W17_ALTERNATE_INJECTED=101|111|100|11 뒤 EMPTY로 복구된다. | fixture 두 계정 밖의 일반성은 별도 test 책임이다. |
| 4 | native success 또는 captured failure와 owned=true | finally에서 down -v --remove-orphans와 환경 복구를 실행한다. | cleanup exit 0일 때만 original failure rethrow 또는 evidence 단계로 간다. | cleanup failure가 있으면 final evidence를 쓰지 않는다. |
| 5 | cleanup=true, failure=null, exact markers | source hash와 sentinels를 .tmp에 쓰고 final path로 move한다. | reconcile-cte-run.txt가 검증 완료 payload로 교체된다. | native_engine은 literal이며 Compose image digest attestation이 아니다. |
tmp 이동의 정확한 말히토리 → 니지카 → 료 → 키타
-
히토리
Move-Item이면 완전한 원자 transaction인가요?
-
니지카
같은 directory tmp를 완성한 뒤 final name으로 바꿔 partial final write를 줄여.
-
료
하지만 digest attestation, fsync, writer lock까지 생기는 건 아니야.
-
키타
atomic-ish replacement라는 한계를 붙이겠습니다.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
fixed source path와 ProjectRoot prefix를 확인하고 stale final evidence를 제거한다.
path containment는 source authenticity allowlist가 아니다.comments/placeholder/meta/semicolon/keywords/CTE shape/signed total을 검사한다.
quoted strings와 complete PostgreSQL grammar를 이해하는 parser가 아니다.random schema에 fixture를 만들고 두 savepoint mutation을 final rollback 안에서 수행한다.
PowerShell environment와 Docker lifecycle은 transaction 밖이다.202와 101 두 계정 mismatch의 exact four-field marker를 요구한다.
production cardinality·performance·all account ids는 증명하지 않는다.filtered marker 다섯 줄을 expected array와 exact joined string으로 비교한다.
marker 아닌 stdout 전체는 equality 대상이 아니다.startup 전 owned=true를 두고 finally down exit를 cleanup bool로 만든다.
exit 0 뒤 resource absence enumeration까지 하지는 않는다.all gates 뒤 same-directory tmp write와 Force move로 final file을 교체한다.
cryptographic signature·fsync·concurrent writer lock은 없다.STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ 금지어 regex를 통과하면 SQL은 확실히 read-only다.
왜 틀리나 regex는 full lexer/parser가 아니고 quoted literal에도 반응할 수 있다.
바르게 읽기 fail-closed static approximation과 native isolated execution을 두 층으로 설명한다.
반례 문자열 속 UPDATE 단어는 실행 DML이 아니어도 gate에 걸릴 수 있다.
❌ 202 sentinel 하나면 account_id hardcoding도 잡힌다.
왜 틀리나 202만 반환하도록 쓴 query가 primary probe를 통과할 수 있다.
바르게 읽기 101 alternate mismatch를 독립 exact oracle로 유지한다.
반례 WHERE account_id=202인 query는 101|111|100|11을 만들지 못한다.
❌ SAVEPOINT rollback이 random schema까지 즉시 지운다.
왜 틀리나 ROLLBACK TO는 probe mutation만 되돌리고 transaction을 열린 채 유지한다.
바르게 읽기 두 savepoint rollback과 final ROLLBACK의 범위를 분리한다.
반례 primary 복구 뒤 같은 account table로 alternate probe를 계속 실행한다.
❌ learner failure가 있으면 그 오류가 항상 최우선으로 던져진다.
왜 틀리나 cleanup=false면 결합 cleanup 오류 branch가 먼저 평가된다.
바르게 읽기 cleanup confirmation을 evidence와 original rethrow 앞의 필수 gate로 읽는다.
반례 psql 실패와 down 실패가 함께 나면 run failed and cleanup not confirmed 문구가 나온다.
❌ native_engine line은 PostgreSQL image digest 증거다.
왜 틀리나 evidence array의 고정 literal일 뿐 실제 image digest를 읽지 않는다.
바르게 읽기 intended engine label과 artifact attestation을 구분한다.
반례 Compose tag가 같은 다른 digest로 이동해도 literal은 바뀌지 않는다.
❌ Move-Item이면 evidence는 완전한 database transaction이다.
왜 틀리나 same-directory staging은 partial final write를 줄이지만 fsync·locking·signature를 제공하지 않는다.
바르게 읽기 atomic-ish replacement라고 범위를 제한한다.
반례 동시 writer 또는 storage crash durability는 이 script가 serialize하지 않는다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
complete PostgreSQL parse와 모든 side effect 부재
이 책임을 맡는 곳: AST parser, restricted role, and transaction isolation모든 account/data distribution에서 일반화
이 책임을 맡는 곳: broader property and integration suitesCompose image digest 또는 binary attestation
이 책임을 맡는 곳: digest-pinned image and runtime inspectionexit 0 뒤 Docker resource absence enumeration
이 책임을 맡는 곳: post-cleanup resource queryfsync, signature, concurrent writer lock
이 책임을 맡는 곳: durable signed evidence storesource audit가 Docker/runner를 실제 실행함
이 책임을 맡는 곳: separate authorized runtime QA evidenceSTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
stale 제거→static contract→hash/random fixture→두 account probe→exact sequence→cleanup/environment→evidence promotion 순서로 말한다.
2단계 · 코드 조각 재조립
- resolved containment
- regex not full parser
- baseline EMPTY
- 202|82|75|7
- 101|111|100|11
- owned before up
- cleanup failure precedence
- same-directory tmp move
3단계 · 파일 전체 다시 쓰기
284개 물리 줄과 259개 nonblank mapping을 canonical SHA-256 9a8fc9bc...eaa와 대조한다.
자가 점검
- regex를 parser라고 부르지 않는다.
- 두 account와 두 restored EMPTY를 모두 적는다.
- savepoint와 final rollback 범위를 구분한다.
- cleanup gate가 evidence보다 앞임을 확인한다.
- native_engine literal을 digest proof로 과장하지 않는다.
- source audit의 non-execution boundary를 유지한다.
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
정본 전체 코드 확인하기
param(
[Parameter(Mandatory = $true)][string]$ProjectRoot,
[string]$ComposeProject = ("w17-cte-retrieval-" + [guid]::NewGuid().ToString("N").Substring(0, 8))
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Restore-EnvironmentValue {
param(
[Parameter(Mandatory = $true)][string]$Name,
[Parameter(Mandatory = $true)][bool]$Existed,
[AllowNull()][string]$Value
)
if ($Existed) {
Set-Item -LiteralPath "Env:$Name" -Value $Value
} else {
Remove-Item -LiteralPath "Env:$Name" -ErrorAction SilentlyContinue
}
}
if (-not [IO.Path]::IsPathRooted($ProjectRoot)) {
throw "ProjectRoot must be an absolute learner project path"
}
if ($ComposeProject -cnotmatch "^[a-z0-9][a-z0-9_-]{0,62}$") {
throw "ComposeProject must contain only lowercase letters, digits, underscore, or hyphen"
}
$project = (Resolve-Path -LiteralPath $ProjectRoot).Path
$referenceRoot = Split-Path -Parent $PSScriptRoot
$compose = Join-Path $referenceRoot "compose.yaml"
$sourcePath = Join-Path $project "evidence\w17\reconcile-cte.sql"
$evidenceDir = Join-Path $project "evidence\w17"
$evidencePath = Join-Path $evidenceDir "reconcile-cte-run.txt"
New-Item -ItemType Directory -Force -Path $evidenceDir | Out-Null
if (Test-Path -LiteralPath $evidencePath) {
Remove-Item -LiteralPath $evidencePath -Force
}
if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
throw "canonical learner SQL is missing: evidence/w17/reconcile-cte.sql"
}
$resolvedSource = (Resolve-Path -LiteralPath $sourcePath).Path
$projectPrefix = $project.TrimEnd([IO.Path]::DirectorySeparatorChar, [IO.Path]::AltDirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
if (-not $resolvedSource.StartsWith($projectPrefix, [StringComparison]::OrdinalIgnoreCase)) {
throw "learner SQL must remain below ProjectRoot"
}
$learnerSql = Get-Content -Raw -LiteralPath $resolvedSource
if ([string]::IsNullOrWhiteSpace($learnerSql)) {
throw "reconcile-cte.sql is empty"
}
$inspection = [regex]::Replace($learnerSql, "(?s)/\*.*?\*/", " ")
$inspection = [regex]::Replace($inspection, "(?m)--.*$", " ")
$inspection = $inspection.Trim()
if ([string]::IsNullOrWhiteSpace($inspection)) {
throw "reconcile-cte.sql contains comments only"
}
if ($inspection -match "(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER|YOUR_QUERY|WRITE_QUERY|REPLACE_ME)\b|<\s*(QUERY|SQL|ANSWER|IMPLEMENTATION)\s*>") {
throw "reconcile-cte.sql contains an unresolved placeholder"
}
if ($inspection -match "(?m)^\s*\\") {
throw "psql meta-commands are forbidden in learner SQL"
}
$query = $inspection.Trim()
if ($query.EndsWith(";")) {
$query = $query.Substring(0, $query.Length - 1).TrimEnd()
}
if ($query.Contains(";")) {
throw "reconcile-cte.sql must contain exactly one SELECT statement"
}
$inspectQuery = [regex]::Replace($query, "(?s)/\*.*?\*/", " ")
$inspectQuery = [regex]::Replace($inspectQuery, "(?m)--.*$", " ")
if ($inspectQuery -cnotmatch "(?is)^\s*WITH\b") {
throw "reconcile-cte.sql must start with a CTE (WITH)"
}
if ($inspectQuery -match "(?i)\b(INSERT|UPDATE|DELETE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|REVOKE|COPY|CALL|DO|BEGIN|COMMIT|ROLLBACK|SAVEPOINT|SET|RESET|VACUUM|ANALYZE|EXPLAIN)\b") {
throw "reconcile-cte.sql may contain only a read-only CTE SELECT"
}
if ($inspectQuery -match "(?i)\b(pg_sleep|dblink|lo_import|lo_export)\b") {
throw "unsafe PostgreSQL function is forbidden in learner SQL"
}
$requiredPatterns = [ordered]@{
"ledger_sum CTE" = "(?i)\bledger_sum\s+AS\s*\("
"compared CTE" = "(?i)\bcompared\s+AS\s*\("
"mismatch CTE" = "(?i)\bmismatch\s+AS\s*\("
"account source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?account\b"
"ledger source" = "(?i)\bFROM\s+(?:[a-z_][a-z0-9_]*\.)?ledger_entry\b"
"ledger aggregation" = "(?i)\bSUM\s*\("
"account grain" = "(?is)\bGROUP\s+BY\b.*?\baccount_id\b"
"account-to-ledger join" = "(?i)\b(?:LEFT\s+)?JOIN\b"
"missing-ledger handling" = "(?i)\bCOALESCE\s*\("
"mismatch predicate" = "(?i)(?:<>|!=|\bIS\s+DISTINCT\s+FROM\b)"
}
foreach ($entry in $requiredPatterns.GetEnumerator()) {
if ($inspectQuery -cnotmatch $entry.Value) {
throw "reconcile-cte.sql is missing required construct: $($entry.Key)"
}
}
$usesSignedAmount = $inspectQuery -cmatch "(?i)\bsigned_amount\b"
$usesCaseAmount = ($inspectQuery -cmatch "(?i)\bCASE\b") -and
($inspectQuery -cmatch "(?i)\bentry_type\b") -and
($inspectQuery -cmatch "(?i)\bamount\b")
if (-not ($usesSignedAmount -or $usesCaseAmount)) {
throw "reconcile-cte.sql must derive the signed ledger total"
}
$sourceHash = (Get-FileHash -LiteralPath $resolvedSource -Algorithm SHA256).Hash.ToLowerInvariant()
$schema = "w17_cte_" + [guid]::NewGuid().ToString("N").Substring(0, 12)
$nativeSql = @"
\set ON_ERROR_STOP on
BEGIN;
SET LOCAL statement_timeout = '10s';
CREATE SCHEMA $schema;
SET LOCAL search_path TO $schema, pg_catalog;
CREATE TABLE account (
id BIGINT PRIMARY KEY,
balance BIGINT NOT NULL CHECK (balance >= 0)
);
CREATE TABLE ledger_entry (
id BIGINT PRIMARY KEY,
account_id BIGINT NOT NULL REFERENCES account(id),
entry_type VARCHAR(32) NOT NULL,
amount BIGINT NOT NULL CHECK (amount > 0),
signed_amount BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL
);
INSERT INTO account(id, balance) VALUES
(101, 100),
(202, 75),
(303, 0);
INSERT INTO ledger_entry(id, account_id, entry_type, amount, signed_amount, created_at) VALUES
(1001, 101, 'DEPOSIT', 120, 120, '2027-01-01T00:00:00Z'),
(1002, 101, 'WITHDRAW', 20, -20, '2027-01-02T00:00:00Z'),
(2001, 202, 'DEPOSIT', 75, 75, '2027-01-03T00:00:00Z');
SELECT 'W17_BASELINE=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
SAVEPOINT primary_mismatch;
UPDATE account SET balance = balance + 7 WHERE id = 202;
SELECT 'W17_INJECTED=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
ROLLBACK TO SAVEPOINT primary_mismatch;
SELECT 'W17_RESTORED=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
SAVEPOINT alternate_account_mismatch;
UPDATE account SET balance = balance + 11 WHERE id = 101;
SELECT 'W17_ALTERNATE_INJECTED=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
ROLLBACK TO SAVEPOINT alternate_account_mismatch;
SELECT 'W17_ALTERNATE_RESTORED=' || COALESCE(
string_agg(
account_id::text || '|' || stored_balance::text || '|' || ledger_balance::text || '|' || difference::text,
',' ORDER BY account_id
),
'EMPTY'
) FROM (
$query
) AS learner_result;
ROLLBACK;
"@
$hadPassword = Test-Path -LiteralPath "Env:FCL_DB_PASSWORD"
$oldPassword = $env:FCL_DB_PASSWORD
$hadPort = Test-Path -LiteralPath "Env:FCL_DB_PORT"
$oldPort = $env:FCL_DB_PORT
$owned = $false
$cleanup = $false
$failure = $null
$nativeExit = -1
$nativeOutput = @()
try {
$env:FCL_DB_PASSWORD = "w17-disposable-" + [guid]::NewGuid().ToString("N")
$env:FCL_DB_PORT = "0"
$owned = $true
& docker compose -f $compose -p $ComposeProject up -d --wait db
if ($LASTEXITCODE -ne 0) {
throw "W17 CTE disposable PostgreSQL startup exit=$LASTEXITCODE"
}
$container = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($container)) {
throw "W17 CTE disposable PostgreSQL container resolution failed"
}
$nativeOutput = @($nativeSql | docker exec -i $container psql -X -q -A -t -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)
$nativeExit = $LASTEXITCODE
if ($nativeExit -ne 0) {
throw "W17 CTE learner SQL native exit=$nativeExit`n$($nativeOutput -join "`n")"
}
$markers = @(
$nativeOutput |
ForEach-Object { ([string]$_).Trim() } |
Where-Object { $_ -cmatch "^W17_(BASELINE|INJECTED|RESTORED|ALTERNATE_INJECTED|ALTERNATE_RESTORED)=" }
)
$expectedMarkers = @(
"W17_BASELINE=EMPTY",
"W17_INJECTED=202|82|75|7",
"W17_RESTORED=EMPTY",
"W17_ALTERNATE_INJECTED=101|111|100|11",
"W17_ALTERNATE_RESTORED=EMPTY"
)
if (($markers -join "`n") -cne ($expectedMarkers -join "`n")) {
throw "W17 CTE exact account/balance/ledger/difference sentinel check failed; actual=$($markers -join ',')"
}
} catch {
$failure = $_
} finally {
if ($owned) {
& docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null
$cleanup = ($LASTEXITCODE -eq 0)
}
Restore-EnvironmentValue -Name "FCL_DB_PASSWORD" -Existed $hadPassword -Value $oldPassword
Restore-EnvironmentValue -Name "FCL_DB_PORT" -Existed $hadPort -Value $oldPort
}
if (-not $cleanup) {
if ($null -ne $failure) {
throw "W17 CTE run failed and disposable cleanup was not confirmed: $($failure.Exception.Message)"
}
throw "W17 CTE disposable cleanup was not confirmed"
}
if ($null -ne $failure) {
throw $failure
}
$evidence = @(
"W17_CTE_RETRIEVAL_GREEN",
"source_path=evidence/w17/reconcile-cte.sql",
"source_sha256=$sourceHash",
"native_engine=postgresql-17-container",
"native_exit=0",
"W17_BASELINE=EMPTY",
"W17_INJECTED=202|82|75|7",
"W17_RESTORED=EMPTY",
"W17_ALTERNATE_INJECTED=101|111|100|11",
"W17_ALTERNATE_RESTORED=EMPTY",
"schema_scope=isolated-transaction",
"cleanup=1"
)
$temporaryEvidence = "$evidencePath.tmp"
$evidence | Set-Content -LiteralPath $temporaryEvidence -Encoding utf8
Move-Item -LiteralPath $temporaryEvidence -Destination $evidencePath -Force
Write-Output "W17_CTE_RETRIEVAL_GREEN baseline=EMPTY injected=202|82|75|7 alternate=101|111|100|11 restored=EMPTY source_sha256=$sourceHash native_exit=0 cleanup=1"
06동률에서 달라지는 세 가지 순위
illustrative/sql/W17-ranking.sql
학습용 SQL 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W17-F0610줄 연결10줄 번역3 chunks
동률에서 달라지는 세 가지 순위
illustrative/sql/W17-ranking.sql
학습용 SQL 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W17-F06STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
같은 점수가 있을 때 ROW_NUMBER, RANK, DENSE_RANK가 서로 다른 숫자를 만드는 이유를 네 행으로 추적한다.
- ROW_NUMBER는 왜 100점 두 행을 1과 2로 나누는가?
- RANK 다음 순위가 3인 반면 DENSE_RANK는 2인 이유는 무엇인가?
- window ORDER BY와 최종 ORDER BY는 어떤 역할 차이가 있는가?
score=(1,100),(2,100),(3,80),(4,70)row_no=1,2,3,4rank=1,1,3,4dense=1,1,2,3STEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 같은 점수 두 장을 서로 다른 세 가지 순위 규칙으로 정리한다.
동점 선수 네 명의 세 순위표
네 행의 점수를 세 window 함수에 넣으면 동점을 다루는 방식이 숫자로 드러난다.
ROW_NUMBER만 account_id로 동점을 깨고 RANK는 틈을, DENSE_RANK는 연속 등수를 만든다.
딱 여기까지만 PARTITION BY가 없는 네 행 전역 fixture이며 audit 작성 학습용 예시일 뿐 account별 top-N 정본 답안이 아니다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
줄 세우기
ROW_NUMBER는 모두에게 다른 번호를 준다.
- 코드 연결
ROW_NUMBER() OVER(ORDER BY amount DESC, account_id)- 비유
- 동점이면 선수 번호로 앞뒤를 정한다.
- 비유의 끝
- 번호 순서는 업무상 tie policy가 아니라 이 fixture의 결정 규칙이다.
공동 등수
RANK는 공동 1등 뒤에 3등을 둔다.
- 코드 연결
RANK() OVER(ORDER BY amount DESC)- 비유
- 1등 자리를 두 명이 차지해 2등 칸이 비었다.
- 비유의 끝
- peer 내부 행 순서는 이 expression이 정하지 않는다.
촘촘한 등수
DENSE_RANK는 다음 distinct 점수에 2를 준다.
- 코드 연결
DENSE_RANK() OVER(ORDER BY amount DESC)- 비유
- 빈 등수 칸을 남기지 않는다.
- 비유의 끝
- 행마다 유일 번호가 필요한 경우와 목적이 다르다.
같은 100점히토리 → 니지카 → 료 → 키타
-
히토리
100점이 둘이면 ROW_NUMBER도 둘 다 1 아닌가요?
-
니지카
아니, 그 함수는 account_id로 동점을 깨서 유일 번호를 줘.
-
료
공동 순위가 필요하면 RANK 계열을 골라야 한다.
-
키타
5줄과 6줄의 ORDER BY 열부터 비교하겠습니다.
빠진 2등히토리 → 니지카 → 료 → 키타
-
히토리
RANK에서 80점이 왜 2등이 아니죠?
-
니지카
앞에 100점 행이 두 개라 다음 ordinal position이 3이야.
-
료
peer group size가 gap으로 나타난다.
-
키타
1,1 다음 값을 표로 계산해 보겠습니다.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 10줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F06-L01 | -- W17-RANKING illustrative learner source; |
STARRY가 연습 카드에 비정본 도장을 찍는다. | 파일의 provenance를 illustrative learner source로 제한하는 주석이다.
|
| 2줄F06-L02 | -- The packaged runner enforces exact rows for this four-row fixture. |
STARRY가 검산대에 네 줄짜리 정답표가 있음을 적는다. | runner acceptance가 four-row fixture의 exact rows에 묶인다고 선언한다.
|
| 3줄F06-L03 | WITH score( |
STARRY가 네 선수의 번호와 점수를 출발선에 놓는다. | VALUES table constructor를 score(account_id, amount) CTE로 이름 붙인다.
|
| 4줄F06-L04 | SELECT account_id, |
STARRY가 선수표의 번호와 점수 칸을 먼저 복사한다. | main SELECT가 base columns 두 개의 projection을 시작한다.
|
| 5줄F06-L05 | ROW_NUMBER( |
STARRY가 동점이면 번호가 작은 선수부터 한 줄로 세운다. | ROW_NUMBER window가 total order를 이용해 1부터 연속 번호를 부여한다.
|
| 6줄F06-L06 | RANK( |
STARRY가 같은 점수 둘에게 같은 등수를 주고 다음 칸을 건너뛴다. | RANK window가 peer group 크기만큼 다음 ordinal을 벌린다.
|
| 7줄F06-L07 | DENSE_RANK( |
STARRY가 공동 1등 뒤에 바로 2등 표찰을 붙인다. | DENSE_RANK window가 distinct ordering value마다 연속 rank를 준다.
|
| 8줄F06-L08 | FROM score |
STARRY가 출발선에 만든 네 선수표를 계산대로 가져온다. | FROM clause가 main query의 driving rows를 score에 결속한다.
|
| 9줄F06-L09 | ORDER BY account_id; |
STARRY가 계산이 끝난 표를 선수 번호순으로 다시 진열한다. | outer ORDER BY가 반환 행의 presentation order를 안정화한다.
|
| 10줄F06-L10 | -- Oracle: |
STARRY가 마지막 검산표에 다섯 칸짜리 네 줄을 적는다. | 고정 fixture가 기대하는 account|amount|세 순위 값을 문서화한다.
|
DENSE의 뜻히토리 → 니지카 → 료 → 키타
-
히토리
DENSE_RANK의 dense는 무엇이 촘촘한 건가요?
-
니지카
distinct 점수 level마다 1,2,3을 연속으로 붙인다는 뜻이야.
-
료
행 수가 아니라 서로 다른 ordering value를 센다.
-
키타
100·80·70 세 level을 표시할게요.
STEP 05 / 13
원본 코드 조각
원본을 3개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.
-- W17-RANKING illustrative learner source; not a shipped answer.
-- The packaged runner enforces exact rows for this four-row fixture.
WITH score(account_id, amount) AS (VALUES (1,100),(2,100),(3,80),(4,70))
SELECT account_id, amount,
ROW_NUMBER() OVER(ORDER BY amount DESC, account_id) AS row_no,
RANK() OVER(ORDER BY amount DESC) AS rank_with_gap,
DENSE_RANK() OVER(ORDER BY amount DESC) AS dense_rank_no_gap
FROM score
ORDER BY account_id;
-- Oracle: 1|100|1|1|1; 2|100|2|1|1; 3|80|3|3|2; 4|70|4|4|3.
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 10줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | -- W17-RANKING illustrative learner source; not a shipped answer. | W17 ranking 학습 예시이며 배포된 정본 답안이 아님을 밝힌다. |
| 2 | -- The packaged runner enforces exact rows for this four-row fixture. | 패키지 runner가 이 네 행 fixture의 정확한 결과를 확인한다고 알린다. |
| 3 | WITH score(account_id, amount) AS (VALUES (1,100),(2,100),(3,80),(4,70)) | score CTE에 (1,100),(2,100),(3,80),(4,70) 네 행을 만든다. |
| 4 | SELECT account_id, amount, | 각 score 행에서 account_id와 amount를 결과 앞 두 열로 고른다. |
| 5 | ROW_NUMBER() OVER(ORDER BY amount DESC, account_id) AS row_no, | amount 내림차순, account_id 오름차순으로 각 행에 고유 순번을 붙인다. |
| 6 | RANK() OVER(ORDER BY amount DESC) AS rank_with_gap, | amount만 내림차순으로 공동 순위를 매기고 다음 순위에는 틈을 둔다. |
| 7 | DENSE_RANK() OVER(ORDER BY amount DESC) AS dense_rank_no_gap | amount 동점은 같은 순위로 두되 다음 순위의 번호를 건너뛰지 않는다. |
| 8 | FROM score | 세 window expression이 읽을 source relation을 score CTE로 지정한다. |
| 9 | ORDER BY account_id; | 최종 표시를 account_id 오름차순으로 정렬한다. |
| 10 | -- Oracle: 1|100|1|1|1; 2|100|2|1|1; 3|80|3|3|2; 4|70|4|4|3. | 네 행의 row_no, RANK, DENSE_RANK 정확한 oracle을 주석으로 기록한다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기VALUES 네 행에서 tie-breaker 유무와 peer-group numbering을 분리해 세 window rank를 비교하는 비정본 fixture query다.
문법 해부
- OVER 안 ORDER BY는 window value를 계산하고 바깥 ORDER BY는 반환 행 표시만 정렬한다.
- RANK와 DENSE_RANK는 amount만 보므로 두 100 rows가 peers지만 ROW_NUMBER는 account_id까지 본다.
실행 순서
- score CTE VALUES
- FROM score
- window ordering
- three ranking values
- outer account_id sort
- runner oracle comparison
원래 W6 수준의 조각별 정밀 해설
F06-C01 · provenance and runner contract
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 파일의 provenance를 illustrative learner source로 제한하는 주석이다. 끝에서 runner acceptance가 four-row fixture의 exact rows에 묶인다고 선언한다.
- 실제 값 추적
- 시작 조건 독자는 실행 전에 첫 주석의 분류 문구를 읽는다.에서 범위를 통과하면 중간에 결과 비교가 단순 설명이 아니라 외부 검산 대상임이 공개된다. 마지막에 결과 비교가 단순 설명이 아니라 외부 검산 대상임이 공개된다.
- 정상 예
- 원본 `-- W17-RANKING illustrative learner source; not a shipped answer.`를 정확히 유지하고 이 범위를 실행·해석했을 때 결과 비교가 단순 설명이 아니라 외부 검산 대상임이 공개된다.
- 틀린 예·반례
- 학습용 주석과 runner 계약이 있다고 SQL이 shipped canonical answer이거나 arbitrary output을 엄격히 거부한다고 해석하면 안 된다.
- 착각 방지
- 현재 runner는 numeric 행만 남겨 unordered multiset으로 비교하고 ranking-result.txt를 사전 삭제하지 않아 failed rerun 뒤 stale success evidence가 남을 수 있다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `provenance and runner contract`의 source state만 다루며 현재 runner는 numeric 행만 남겨 unordered multiset으로 비교하고 ranking-result.txt를 사전 삭제하지 않아 failed rerun 뒤 stale success evidence가 남을 수 있다.
- 다음 연결
- 끝 상태를 기록한다: 결과 비교가 단순 설명이 아니라 외부 검산 대상임이 공개된다. 이어지는 `fixture and three ranking functions` 범위에서 이 상태의 입력 경계를 확인한다.
F06-C02 · fixture and three ranking functions
- 문법 해부
- 이 source slice의 문법 축은 ROW_NUMBER window가 total order를 이용해 1부터 연속 번호를 부여한다. 앞뒤로 VALUES table constructor를 score(account_id, amount) CTE로 이름 붙인다. 및 DENSE_RANK window가 distinct ordering value마다 연속 rank를 준다.
- 실제 값 추적
- 서로 다른 account_id 네 개와 100,100,80,70 금액을 받는다. 그 상태가 진행되면 dense_rank_no_gap 값은 1,1,2,3이 된다.
- 정상 예
- 유효한 예는 'WITH score(account_id, amount) AS (VALUES (1,100),(2,100),(3,80),(4,70))' bytes를 보존해 100점 두 행도 각각 row_no 1과 2라는 다른 번호를 얻는다.
- 틀린 예·반례
- ROW_NUMBER, RANK, DENSE_RANK가 네 행에서 맞았다는 결과를 PARTITION BY가 있는 account별 순위로 일반화하지 않는다.
- 착각 방지
- 동점 공동 순위를 표현하는 함수가 아니며 outer 표시 순서도 아니다. 따라서 `fixture and three ranking functions`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. 동점 공동 순위를 표현하는 함수가 아니며 outer 표시 순서도 아니다.
- 다음 연결
- 끝 상태를 기록한다: dense_rank_no_gap 값은 1,1,2,3이 된다. 이어지는 `stable display order and exact oracle` 범위에서 이 상태의 입력 경계를 확인한다.
F06-C03 · stable display order and exact oracle
- 문법 해부
- `stable display order and exact oracle` 범위는 FROM clause가 main query의 driving rows를 score에 결속한다. 이어서 고정 fixture가 기대하는 account|amount|세 순위 값을 문서화한다.
- 실제 값 추적
- 구체 입력은 window 계산 뒤 각 행의 account_id를 sort key로 쓴다. 처리 뒤 관찰 가능한 끝 상태는 oracle은 1|100|1|1|1; 2|100|2|1|1; 3|80|3|3|2; 4|70|4|4|3이다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 projection과 세 window 함수가 네 candidate row에 적용된다. 그리고 범위 끝에서 oracle은 1|100|1|1|1; 2|100|2|1|1; 3|80|3|3|2; 4|70|4|4|3이다.
- 틀린 예·반례
- outer account_id 정렬이 window rank를 계산하거나 runner의 unordered Compare-Object를 ordered check로 바꾸지는 않는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: filter나 grouping을 추가하지 않아 source cardinality를 바꾸지 않는다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: filter나 grouping을 추가하지 않아 source cardinality를 바꾸지 않는다.
- 다음 연결
- 끝 상태를 기록한다: oracle은 1|100|1|1|1; 2|100|2|1|1; 3|80|3|3|2; 4|70|4|4|3이다. 이어지는 `provenance and validator contract` 범위에서 이 상태의 입력 경계를 확인한다.
두 ORDER BY히토리 → 니지카 → 료 → 키타
-
히토리
9줄 정렬을 지우면 순위 값도 달라지나요?
-
니지카
window 안 ordering은 그대로라 row별 값은 유지돼.
-
료
다만 반환 순서가 보장되지 않아 oracle 표시가 흔들릴 수 있다.
-
키타
계산 규칙과 presentation을 두 칸에 나누겠습니다.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| tie input | account 1=100, account 2=100 | 세 window ordering을 평가한다 | row_no 1/2, rank 1/1, dense 1/1 | ROW_NUMBER만 account_id tie-breaker를 갖는다 |
| next score | account 3=80 | 앞 peer group 크기를 반영한다 | row_no 3, rank 3, dense 2 | RANK는 gap, DENSE_RANK는 distinct level을 센다 |
| display | 계산 완료 네 rows | account_id로 outer sort | 1,2,3,4 순서 | 표시 정렬은 rank를 다시 계산하지 않는다 |
runner의 빈틈히토리 → 니지카 → 료 → 키타
-
히토리
실패한 재실행이면 ranking-result.txt도 실패 상태로 항상 바뀌나요?
-
니지카
아니, 그 파일을 사전 삭제하지 않아서 failed rerun 뒤 이전 성공 내용이 남을 수 있어.
-
료
그 stale success evidence와 numeric-only·unordered comparison을 함께 경계해야 해.
-
키타
실행 Green과 현재 결과 파일의 생성 시점을 분리해 확인하겠습니다.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
VALUES CTE와 세 window specifications를 parse한다
source가 read-only 한 statement인지 runner가 완전히 검사하지 않는다amount ordering에서 peer groups와 ordinal positions를 계산한다
작은 fixture는 sort memory·parallel plan 일반성을 보여 주지 않는다numeric five-field lines를 남겨 expected multiset과 비교한다
nonnumeric output과 position order는 acceptance 밖에 있고 ranking-result.txt를 사전 삭제하지 않아 failed rerun 뒤 stale success evidence가 남을 수 있다STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ 세 함수는 이름만 다르고 항상 같은 순위다.
왜 틀리나 동점 다음 80점에서 3과 2가 갈린다.
바르게 읽기 row uniqueness, gap, dense level이라는 목적을 구분한다.
반례 100,100,80에서 RANK=1,1,3이고 DENSE_RANK=1,1,2다.
❌ 마지막 ORDER BY가 window rank를 결정한다.
왜 틀리나 rank는 OVER 내부 ordering으로 먼저 계산된다.
바르게 읽기 window ordering과 result presentation을 별도로 읽는다.
반례 outer sort를 amount로 바꿔도 row별 계산값은 같다.
❌ RANK의 동점 행 순서도 안정적이다.
왜 틀리나 RANK OVER에는 account_id tie-breaker가 없다.
바르게 읽기 동점 내 표시 안정성이 필요하면 명시적 outer order를 둔다.
반례 100점 두 rows는 같은 rank라 executor가 어느 peer를 먼저 내도 rank contract는 만족한다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
shipped workbook canonical answer
이 책임을 맡는 곳: approved workbook solutionaccount별 PARTITION과 top-N 업무 규칙
이 책임을 맡는 곳: query requirementsnonnumeric extra output와 row position의 엄격한 거부; ranking-result.txt 사전 삭제와 failed rerun 뒤 stale success evidence 제거
이 책임을 맡는 곳: ordered exact-output validator with result preclearSTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
fixture→window ordering→peer rule→outer display→oracle 경계를 말한다.
2단계 · 코드 조각 재조립
- VALUES four rows
- ROW_NUMBER tie-breaker
- RANK gap
- DENSE_RANK no gap
- outer ORDER BY
3단계 · 파일 전체 다시 쓰기
원문 10줄을 줄바꿈과 주석까지 그대로 다시 쓰고 source SHA와 비교한다.
자가 점검
- 세 함수의 네 결과를 모두 적었는가?
- OVER와 outer ORDER BY를 분리했는가?
- 비정본·global fixture 한계를 썼는가?
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
학습용 예시 전체 확인하기 · 정본 답안 아님
-- W17-RANKING illustrative learner source; not a shipped answer.
-- The packaged runner enforces exact rows for this four-row fixture.
WITH score(account_id, amount) AS (VALUES (1,100),(2,100),(3,80),(4,70))
SELECT account_id, amount,
ROW_NUMBER() OVER(ORDER BY amount DESC, account_id) AS row_no,
RANK() OVER(ORDER BY amount DESC) AS rank_with_gap,
DENSE_RANK() OVER(ORDER BY amount DESC) AS dense_rank_no_gap
FROM score
ORDER BY account_id;
-- Oracle: 1|100|1|1|1; 2|100|2|1|1; 3|80|3|3|2; 4|70|4|4|3.
07원장 합계와 저장 잔액을 세 CTE로 대사하기
illustrative/sql/W17-reconcile-cte.sql
학습용 SQL 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W17-F0724줄 연결24줄 번역5 chunks
원장 합계와 저장 잔액을 세 CTE로 대사하기
illustrative/sql/W17-reconcile-cte.sql
학습용 SQL 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W17-F07STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
ledger_entry 합과 account.balance를 account grain으로 비교해 불일치만 네 열로 반환한다.
- 원장 0건 계좌를 어떻게 0으로 보존하는가?
- stored-ledger difference의 부호는 무엇을 뜻하는가?
- validator가 요구하는 세 CTE와 exact sentinel은 무엇인가?
CTEs=ledger_sum,compared,mismatchbaseline/restored=EMPTY202|82|75|7101|111|100|11STEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 원장 합계표, 비교표, 불일치표를 차례로 접어 최종 경고 행을 만든다.
저장 장부와 원장 합계의 세 단계 검산
ledger_sum은 signed_amount를 account별로 더하고 compared는 모든 account를 LEFT JOIN으로 보존한다.
mismatch는 stored-ledger 차이가 있는 행만 남겨 runner의 EMPTY와 +7·+11 sentinel을 만든다.
딱 여기까지만 validator 열·CTE 계약에 맞춘 비정본 예시이며 signed_amount 회계 완전성, double-entry 균형, 운영 대사 정책은 증명하지 않는다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
합계표
계좌별 원장 금액을 먼저 더한다.
- 코드 연결
ledger_sum- 비유
- 같은 계좌 영수증을 한 묶음으로 합친다.
- 비유의 끝
- 원장 0건 계좌는 이 표에 아직 없다.
비교표
저장 잔액과 합계를 나란히 둔다.
- 코드 연결
compared LEFT JOIN- 비유
- 모든 계좌 카드를 기준으로 합계표를 붙인다.
- 비유의 끝
- COALESCE 0은 부재와 실제 합 0을 구분하지 않는다.
경고표
두 숫자가 다를 때만 difference를 낸다.
- 코드 연결
mismatch WHERE stored_balance <> ledger_balance- 비유
- 어긋난 카드만 빨간 바구니로 보낸다.
- 비유의 끝
- 차이는 원인을 분류하거나 자동 복구하지 않는다.
왜 세 CTE인가히토리 → 니지카 → 료 → 키타
-
히토리
한 SELECT에 전부 쓰면 틀린 건가요?
-
니지카
아니, 여기서는 aggregate·compare·filter grain을 이름으로 분리한 거야.
-
료
게다가 validator가 세 이름을 계약으로 요구한다.
-
키타
가독성 이유와 runner 요구를 따로 적겠습니다.
빈 원장의 0히토리 → 니지카 → 료 → 키타
-
히토리
ledger_sum에 COALESCE가 있으니 0건 계좌도 생기죠?
-
니지카
SUM group 자체가 없으면 그 CTE에는 row가 없어.
-
료
account LEFT JOIN 뒤 NULL을 다시 COALESCE해야 보존된다.
-
키타
두 COALESCE 위치의 역할을 구분하겠습니다.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 24줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F07-L01 | -- W17-CTE illustrative learner source; |
STARRY가 세 겹 계산표 위에 학습용 표찰을 붙인다. | 첫 comment가 이 SQL을 공식 산출물 밖의 교육용 CTE 예제로 분류한다.
|
| 2줄F07-L02 | -- It matches the packaged retrieval runner's required columns and three CTE names. |
STARRY가 검사기가 찾는 이름표 세 장을 미리 공개한다. | validator-specific shape와 required column contract를 설명한다.
|
| 3줄F07-L03 | WITH ledger_sum AS ( |
STARRY가 계좌별 원장 합계를 담을 첫 접이식 표를 펼친다. | WITH clause가 ledger_sum CTE scope를 시작한다.
|
| 4줄F07-L04 | SELECT account_id, |
STARRY가 원장 조각을 계좌 바구니별로 더해 합계표를 만든다. | SELECT가 grouping key와 COALESCE(SUM(...),0) aggregate를 투영한다.
|
| 5줄F07-L05 | FROM ledger_entry |
STARRY가 모든 원장 카드를 첫 계산대에 올린다. | FROM clause가 aggregate input relation을 ledger_entry에 결속한다.
|
| 6줄F07-L06 | GROUP BY account_id |
STARRY가 같은 계좌 번호의 원장 카드를 한 바구니에 모은다. | GROUP BY가 aggregate output grain을 account_id로 정한다.
|
| 7줄F07-L07 | ), |
STARRY가 합계표를 접고 저장값 비교표의 빈 면을 펼친다. | comma-separated WITH item이 compared CTE scope를 시작한다.
|
| 8줄F07-L08 | SELECT a. |
STARRY가 저장 계좌표의 번호 칸을 비교표 첫 열에 옮긴다. | alias a의 primary key를 compared output key로 projection한다.
|
| 9줄F07-L09 | a. |
STARRY가 계좌표에 적힌 저장 잔액을 두 번째 칸에 복사한다. | 저장된 balance 값을 comparison side 하나로 projection한다.
|
| 10줄F07-L10 | COALESCE( |
STARRY가 빈 원장 칸에는 계산용 0 카드를 꽂는다. | nullable l.ledger_balance 값을 COALESCE로 0에 치환한다.
|
| 11줄F07-L11 | FROM account AS a |
STARRY가 모든 계좌 카드를 비교표의 기준 줄로 삼는다. | FROM account AS a가 보존할 left-side row set을 정한다.
|
| 12줄F07-L12 | LEFT JOIN ledger_sum AS l ON l. |
STARRY가 계좌 카드 옆에 번호가 같은 원장 합계표를 붙인다. | LEFT JOIN이 account id와 aggregate key equality로 두 relation을 연결한다.
|
| 13줄F07-L13 | ), |
STARRY가 비교표를 접어 불일치 전용 목록의 표지를 연다. | WITH chain의 마지막 named CTE scope를 시작한다.
|
| 14줄F07-L14 | SELECT account_id, |
STARRY가 문제가 난 계좌의 번호표를 새 목록에 옮긴다. | 세 번째 CTE가 account identifier를 그대로 projection한다.
|
| 15줄F07-L15 | stored_balance, |
STARRY가 저장 장부 숫자를 증거 칸에 그대로 적는다. | 저장값 side를 diagnostic output column으로 전달한다.
|
| 16줄F07-L16 | ledger_balance, |
STARRY가 원장 합계 숫자도 나란히 증거 칸에 적는다. | 앞 단계에서 얻은 원장 합계 숫자를 mismatch 증거 열에 보존한다.
|
| 17줄F07-L17 | stored_balance - ledger_balance AS difference |
STARRY가 두 숫자 사이 간격을 세 번째 검산 칸에 쓴다. | BIGINT subtraction expression으로 방향 있는 차이를 만든다.
|
| 18줄F07-L18 | FROM compared |
STARRY가 완성된 비교표 전체를 불일치 선별대로 가져온다. | FROM clause가 세 번째 query의 input을 compared에 결속한다.
|
| 19줄F07-L19 | WHERE stored_balance <> ledger_balance |
STARRY가 두 숫자가 어긋난 카드만 경고 바구니에 넣는다. | WHERE inequality가 equal rows를 제거하고 mismatch rows를 선택한다.
|
| 20줄F07-L20 | ) |
STARRY가 세 번째 접이식 표의 덮개를 닫는다. | closing parenthesis가 WITH clause의 마지막 CTE body를 완결한다.
|
| 21줄F07-L21 | SELECT account_id, |
STARRY가 경고 카드의 네 증거 칸을 최종 보고서에 복사한다. | main SELECT가 validator-required output shape를 projection한다.
|
| 22줄F07-L22 | FROM mismatch |
STARRY가 경고 바구니만 최종 출력대로 옮긴다. | FROM mismatch가 filtered CTE rows를 driving input으로 쓴다.
|
| 23줄F07-L23 | ORDER BY account_id; |
STARRY가 경고 카드를 계좌 번호가 작은 순서로 진열한다. | outer ORDER BY가 diagnostic presentation을 stable하게 만든다.
|
| 24줄F07-L24 | -- Runner oracle: |
STARRY가 두 번의 고장 주입 검산표를 마지막에 붙인다. | validator fixture의 primary·alternate sentinel 결과를 주석으로 문서화한다.
|
차이의 방향히토리 → 니지카 → 료 → 키타
-
히토리
difference 7은 원장이 저장값보다 7 크다는 뜻인가요?
-
니지카
식이 stored-ledger라 저장값이 7 큰 경우야.
-
료
operand 순서를 바꾸면 같은 mismatch도 부호가 뒤집힌다.
-
키타
82-75와 111-100을 직접 적겠습니다.
STEP 05 / 13
원본 코드 조각
원본을 5개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.
-- W17-CTE illustrative learner source; not a shipped answer.
-- It matches the packaged retrieval runner's required columns and three CTE names.
WITH ledger_sum AS (
SELECT account_id, COALESCE(SUM(signed_amount), 0) AS ledger_balance
FROM ledger_entry
GROUP BY account_id
), compared AS (
SELECT a.id AS account_id,
a.balance AS stored_balance,
COALESCE(l.ledger_balance, 0) AS ledger_balance
FROM account AS a
LEFT JOIN ledger_sum AS l ON l.account_id = a.id
), mismatch AS (
SELECT account_id,
stored_balance,
ledger_balance,
stored_balance - ledger_balance AS difference
FROM compared
WHERE stored_balance <> ledger_balance
)
SELECT account_id, stored_balance, ledger_balance, difference
FROM mismatch
ORDER BY account_id;
-- Runner oracle: baseline EMPTY; injected 202|82|75|7; alternate 101|111|100|11; both restored EMPTY.
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 24줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | -- W17-CTE illustrative learner source; not a shipped answer. | W17 CTE 학습 예시이며 배포된 정본 답안이 아님을 밝힌다. |
| 2 | -- It matches the packaged retrieval runner's required columns and three CTE names. | 패키지 retrieval runner가 요구하는 열과 세 CTE 이름에 맞춘 예시라고 알린다. |
| 3 | WITH ledger_sum AS ( | ledger_sum이라는 첫 CTE 정의를 연다. |
| 4 | SELECT account_id, COALESCE(SUM(signed_amount), 0) AS ledger_balance | account_id별 existing ledger group의 signed_amount를 합하고 그 SUM이 NULL이면 0으로 바꿔 ledger_balance라 부른다. |
| 5 | FROM ledger_entry | ledger_sum 집계의 source를 ledger_entry로 지정한다. |
| 6 | GROUP BY account_id | ledger_entry를 account_id별 그룹으로 묶는다. |
| 7 | ), compared AS ( | 첫 CTE를 닫고 compared라는 두 번째 CTE를 연다. |
| 8 | SELECT a.id AS account_id, | account의 id를 account_id라는 결과 열로 고른다. |
| 9 | a.balance AS stored_balance, | account.balance를 stored_balance라는 열로 고른다. |
| 10 | COALESCE(l.ledger_balance, 0) AS ledger_balance | ledger 합이 없으면 0을 쓰고 ledger_balance라는 열로 고른다. |
| 11 | FROM account AS a | compared CTE의 driving relation을 account a로 지정한다. |
| 12 | LEFT JOIN ledger_sum AS l ON l.account_id = a.id | 같은 account_id의 ledger_sum을 LEFT JOIN한다. |
| 13 | ), mismatch AS ( | compared를 닫고 mismatch라는 세 번째 CTE를 연다. |
| 14 | SELECT account_id, | compared의 account_id를 mismatch 결과 첫 열로 고른다. |
| 15 | stored_balance, | stored_balance를 mismatch 결과에 유지한다. |
| 16 | ledger_balance, | ledger_balance를 mismatch 결과에 유지한다. |
| 17 | stored_balance - ledger_balance AS difference | stored_balance에서 ledger_balance를 빼 difference를 계산한다. |
| 18 | FROM compared | mismatch CTE가 compared relation을 읽도록 지정한다. |
| 19 | WHERE stored_balance <> ledger_balance | 저장 잔액과 원장 잔액이 다른 행만 남긴다. |
| 20 | ) | mismatch CTE 정의를 닫는다. |
| 21 | SELECT account_id, stored_balance, ledger_balance, difference | 최종 결과에 account_id, stored, ledger, difference 네 열을 고른다. |
| 22 | FROM mismatch | 최종 query의 source를 mismatch CTE로 지정한다. |
| 23 | ORDER BY account_id; | 최종 결과를 account_id 오름차순으로 정렬한다. |
| 24 | -- Runner oracle: baseline EMPTY; injected 202|82|75|7; alternate 101|111|100|11; both restored EMPTY. | runner oracle의 EMPTY, 202|82|75|7, 101|111|100|11 상태를 기록한다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기account grain aggregate를 LEFT JOIN하고 stored-ledger diagnostic difference를 세 named CTE로 분리한 validator-bound illustrative SELECT다.
문법 해부
- ledger_sum GROUP BY가 right side uniqueness를 만들고 account-driven LEFT JOIN이 zero-entry 계좌를 보존한다.
- COALESCE는 missing sum을 0으로 바꾸며 WHERE inequality가 baseline equal rows를 제거한다.
실행 순서
- ledger_sum aggregate
- account-driven compared
- COALESCE
- difference projection
- mismatch filter
- stable sort
- runner sentinel
원래 W6 수준의 조각별 정밀 해설
F07-C01 · provenance and validator contract
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 첫 comment가 이 SQL을 공식 산출물 밖의 교육용 CTE 예제로 분류한다. 끝에서 validator-specific shape와 required column contract를 설명한다.
- 실제 값 추적
- 시작 조건 독자는 첫 줄의 비정본 분류를 해석 입력으로 받는다.에서 범위를 통과하면 중간에 예시가 일반 설계보다 특정 runner interface에 맞춰졌음이 드러난다. 마지막에 예시가 일반 설계보다 특정 runner interface에 맞춰졌음이 드러난다.
- 정상 예
- 원본 `-- W17-CTE illustrative learner source; not a shipped answer.`를 정확히 유지하고 이 범위를 실행·해석했을 때 예시가 일반 설계보다 특정 runner interface에 맞춰졌음이 드러난다.
- 틀린 예·반례
- validator 열·CTE 이름에 맞춘 예시를 회계 대사의 유일한 정본 SQL로 취급할 수 없다.
- 착각 방지
- 정규 SQL parser가 아니라 regex 검사라는 구현 한계는 남는다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `provenance and validator contract`의 source state만 다루며 정규 SQL parser가 아니라 regex 검사라는 구현 한계는 남는다.
- 다음 연결
- 끝 상태를 기록한다: 예시가 일반 설계보다 특정 runner interface에 맞춰졌음이 드러난다. 이어지는 `ledger_sum account grain` 범위에서 이 상태의 입력 경계를 확인한다.
F07-C02 · ledger_sum account grain
- 문법 해부
- 이 source slice의 문법 축은 FROM clause가 aggregate input relation을 ledger_entry에 결속한다. 앞뒤로 WITH clause가 ledger_sum CTE scope를 시작한다. 및 GROUP BY가 aggregate output grain을 account_id로 정한다.
- 실제 값 추적
- parser는 이름과 AS, 여는 괄호 token을 받는다. 그 상태가 진행되면 한 계좌에 여러 entry가 있어도 ledger_sum에는 최대 한 행이 남는다.
- 정상 예
- 유효한 예는 'WITH ledger_sum AS (' bytes를 보존해 앞 SUM이 실제 signed_amount column을 읽을 수 있게 된다.
- 틀린 예·반례
- ledger_sum의 COALESCE만으로 원장 0건 account row가 생성된다고 생각하면 group 부재와 NULL aggregate를 혼동한다.
- 착각 방지
- schema provenance·row completeness·currency 일관성은 확인하지 않는다. 따라서 `ledger_sum account grain`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. schema provenance·row completeness·currency 일관성은 확인하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: 한 계좌에 여러 entry가 있어도 ledger_sum에는 최대 한 행이 남는다. 이어지는 `stored and ledger comparison` 범위에서 이 상태의 입력 경계를 확인한다.
F07-C03 · stored and ledger comparison
- 문법 해부
- `stored and ledger comparison` 범위는 comma-separated WITH item이 compared CTE scope를 시작한다. 이어서 LEFT JOIN이 account id와 aggregate key equality로 두 relation을 연결한다.
- 실제 값 추적
- 구체 입력은 현재 row scope의 ledger sum 값 또는 NULL을 받는다. 처리 뒤 관찰 가능한 끝 상태는 matching 합계는 붙고 없는 경우에도 account row와 NULL 오른쪽이 남는다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 두 번째 named relation body를 작성할 자리가 생긴다. 그리고 범위 끝에서 matching 합계는 붙고 없는 경우에도 account row와 NULL 오른쪽이 남는다.
- 틀린 예·반례
- LEFT JOIN 뒤 0은 실제 signed sum 0과 ledger row 부재를 값만으로 구별하지 못한다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: 이 줄만으로 account source나 join condition은 정해지지 않는다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: 이 줄만으로 account source나 join condition은 정해지지 않는다.
- 다음 연결
- 끝 상태를 기록한다: matching 합계는 붙고 없는 경우에도 account row와 NULL 오른쪽이 남는다. 이어지는 `mismatch projection and predicate` 범위에서 이 상태의 입력 경계를 확인한다.
F07-C04 · mismatch projection and predicate
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 WITH chain의 마지막 named CTE scope를 시작한다. 끝에서 closing parenthesis가 WITH clause의 마지막 CTE body를 완결한다.
- 실제 값 추적
- 시작 조건 앞 compared relation과 새 name/parenthesis token을 사용한다.에서 범위를 통과하면 중간에 양수이면 저장값이 원장보다 그만큼 큰 difference가 출력된다. 마지막에 main query가 mismatch라는 완성된 relation을 참조할 수 있다.
- 정상 예
- 원본 `), mismatch AS (`를 정확히 유지하고 이 범위를 실행·해석했을 때 main query가 mismatch라는 완성된 relation을 참조할 수 있다.
- 틀린 예·반례
- 양의 difference가 보이면 누락 entry 하나가 원인이라고 확정하거나 double-entry 균형까지 증명하면 안 된다.
- 착각 방지
- materialization·row order·실행 성공을 괄호가 보장하지 않는다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `mismatch projection and predicate`의 source state만 다루며 materialization·row order·실행 성공을 괄호가 보장하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: main query가 mismatch라는 완성된 relation을 참조할 수 있다. 이어지는 `stable output and runner oracle` 범위에서 이 상태의 입력 경계를 확인한다.
F07-C05 · stable output and runner oracle
- 문법 해부
- 이 source slice의 문법 축은 outer ORDER BY가 diagnostic presentation을 stable하게 만든다. 앞뒤로 main SELECT가 validator-required output shape를 projection한다. 및 validator fixture의 primary·alternate sentinel 결과를 주석으로 문서화한다.
- 실제 값 추적
- mismatch row의 네 named columns를 순서대로 받는다. 그 상태가 진행되면 baseline/restored는 EMPTY이고 injected rows는 정확한 네 값으로 알려진다.
- 정상 예
- 유효한 예는 'SELECT account_id, stored_balance, ledger_balance, difference' bytes를 보존해 여러 불일치가 있어도 반환 순서가 deterministic해진다.
- 틀린 예·반례
- baseline EMPTY와 두 sentinel 통과를 모든 production account가 정확하다는 증거로 확대할 수 없다.
- 착각 방지
- mismatch 정확성이나 marker sequence를 검증하지 않는다. 따라서 `stable output and runner oracle`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. mismatch 정확성이나 marker sequence를 검증하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: baseline/restored는 EMPTY이고 injected rows는 정확한 네 값으로 알려진다. 이어지는 `provenance assumptions and workbook schema` 범위에서 이 상태의 입력 경계를 확인한다.
EMPTY의 범위히토리 → 니지카 → 료 → 키타
-
히토리
baseline EMPTY면 데이터베이스가 완벽한가요?
-
니지카
이 query가 보는 stored와 signed sum 차이가 없다는 뜻뿐이야.
-
료
업무 누락이 양쪽에 똑같이 반영되면 EMPTY일 수도 있다.
-
키타
직접 증거와 비보장 영역을 나누겠습니다.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| baseline | stored=ledger | inequality filter | EMPTY | count zero만 보며 회계 완전성 전체를 증명하지 않는다 |
| primary injection | account 202 stored82 ledger75 | 82-75 | difference 7 | fixture-bound exact sentinel |
| alternate injection | account 101 stored111 ledger100 | 111-100 | difference 11 | hardcoded filter 우회를 검사하는 반례 |
정적 검사히토리 → 니지카 → 료 → 키타
-
히토리
세 CTE 이름이 있으면 어떤 SQL도 안전한가요?
-
니지카
validator는 regex와 native execution을 같이 쓰지만 parser 자체는 아니야.
-
료
quoted text나 복잡한 동치 표현에서 정적 판정 한계가 남는다.
-
키타
runner Green과 일반 SQL 정당성을 분리할게요.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
ledger_entry를 account_id hash/group aggregate로 축약한다
실제 plan과 memory는 statistics에 따라 달라진다account rows에 at-most-one ledger_sum row를 LEFT JOIN한다
앞 GROUP BY uniqueness와 schema types에 의존한다격리 transaction에서 두 mismatch cycle의 five markers를 exact sequence로 본다
정적 regex는 완전한 SQL parser가 아니다STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ INNER JOIN이어도 원장 없는 계좌가 0으로 나온다.
왜 틀리나 matching right row가 없으면 account 자체가 사라진다.
바르게 읽기 account에서 시작한 LEFT JOIN과 COALESCE를 함께 쓴다.
반례 ledger 0건 account 202가 inner join에서는 사라진다.
❌ difference 7이면 원인이 정확히 하나다.
왜 틀리나 저장값 오류, 누락 entry, 잘못된 부호 등 여러 원인이 같은 차이를 낸다.
바르게 읽기 이 query는 차이 상태만 관찰한다.
반례 +7 update와 -7 entry 누락은 같은 numeric gap을 만들 수 있다.
❌ signed_amount 합이 맞으면 double-entry도 맞다.
왜 틀리나 schema와 query는 pair·currency·entry type 균형을 검사하지 않는다.
바르게 읽기 대사 invariant와 회계 invariant를 분리한다.
반례 잘못된 두 entries가 우연히 저장 balance와 같은 합을 낼 수 있다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
shipped canonical retrieval answer
이 책임을 맡는 곳: approved learner solutiondouble-entry·currency·entry semantics completeness
이 책임을 맡는 곳: ledger domain constraints모든 valid SQL shape에 대한 parser-level 판정
이 책임을 맡는 곳: SQL parser and native testsSTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
aggregate→left preservation→coalesce→difference→filter→sentinel 순서를 말한다.
2단계 · 코드 조각 재조립
- ledger_sum GROUP BY
- account LEFT JOIN
- COALESCE zero
- stored-ledger
- mismatch WHERE
3단계 · 파일 전체 다시 쓰기
원문 24줄을 다시 쓰고 세 CTE 이름과 네 output 열을 validator 계약과 대조한다.
자가 점검
- 원장 0건 보존을 설명했는가?
- difference 부호를 값으로 계산했는가?
- double-entry 비보장을 적었는가?
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
학습용 예시 전체 확인하기 · 정본 답안 아님
-- W17-CTE illustrative learner source; not a shipped answer.
-- It matches the packaged retrieval runner's required columns and three CTE names.
WITH ledger_sum AS (
SELECT account_id, COALESCE(SUM(signed_amount), 0) AS ledger_balance
FROM ledger_entry
GROUP BY account_id
), compared AS (
SELECT a.id AS account_id,
a.balance AS stored_balance,
COALESCE(l.ledger_balance, 0) AS ledger_balance
FROM account AS a
LEFT JOIN ledger_sum AS l ON l.account_id = a.id
), mismatch AS (
SELECT account_id,
stored_balance,
ledger_balance,
stored_balance - ledger_balance AS difference
FROM compared
WHERE stored_balance <> ledger_balance
)
SELECT account_id, stored_balance, ledger_balance, difference
FROM mismatch
ORDER BY account_id;
-- Runner oracle: baseline EMPTY; injected 202|82|75|7; alternate 101|111|100|11; both restored EMPTY.
08거래 0건 고객까지 남기는 성공률 집계
illustrative/sql/W17-SQL-Q25.sql
학습용 SQL 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W17-F0819줄 연결19줄 번역3 chunks
거래 0건 고객까지 남기는 성공률 집계
illustrative/sql/W17-SQL-Q25.sql
학습용 SQL 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W17-F08STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
모든 customer를 보존하면서 SUCCESS 거래 수를 전체 거래 수로 나눈 비율을 안전하게 계산한다.
- COUNT(*) 대신 COUNT(t.tx_id)를 쓰는 이유는 무엇인가?
- 왜 거래 0건을 0%가 아니라 NULL로 두는가?
- SUCCESS numerator와 all-status denominator는 어디에서 드러나는가?
customer1=11/12=91.67customer2=2/7=28.57customer4/5=NULLcustomer3/6=100.00STEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 고객 명부를 출발점으로 계좌와 거래를 붙이고 성공 도장 비율을 계산한다.
빈 바구니도 남기는 고객 성공률표
customer에서 시작한 두 LEFT JOIN이 거래가 없는 고객 4·5도 결과에 남긴다.
SUCCESS 건수는 FILTER로 세고 전체 거래 0건은 NULLIF로 나눗셈 오류 대신 NULL을 만든다.
딱 여기까지만 customer grain·all-status denominator·SUCCESS numerator·0건 NULL은 prompt가 고정하지 않은 공개 가정이며 shipped workbook 정본 답안이 아니다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
모두 남기기
고객 명부에서 시작해 거래가 없어도 고객 행을 보존한다.
- 코드 연결
customer LEFT JOIN account LEFT JOIN business_tx- 비유
- 빈 바구니도 진열대에서 치우지 않는다.
- 비유의 끝
- 계좌가 여러 개면 거래는 customer group에 함께 모인다.
성공만 세기
전체 수와 SUCCESS 수를 서로 다른 COUNT로 구한다.
- 코드 연결
COUNT(t.tx_id) FILTER- 비유
- 모든 카드와 성공 도장 카드 두 계수기를 쓴다.
- 비유의 끝
- 금액 가중 성공률이 아니다.
0으로 나누지 않기
전체 건수 0을 NULL로 바꾼 뒤 나눈다.
- 코드 연결
NULLIF(COUNT(t.tx_id),0)- 비유
- 빈 바구니에는 계산 불가 표찰을 붙인다.
- 비유의 끝
- NULL을 0%와 같은 뜻으로 해석하지 않는다.
분모의 상태히토리 → 니지카 → 료 → 키타
-
히토리
성공률이면 SUCCESS와 FAILED만 세나요?
-
니지카
이 예시는 모든 business_tx row를 분모로 둬.
-
료
PROCESSING 같은 상태도 total count에 들어갈 수 있다.
-
키타
주석 2줄과 FILTER 위치를 함께 보겠습니다.
COUNT 별표히토리 → 니지카 → 료 → 키타
-
히토리
customer를 남기려면 COUNT(*)가 더 안전하지 않나요?
-
니지카
보존된 빈 join row까지 한 건으로 셀 위험이 있어.
-
료
right-side tx_id를 세야 실제 거래만 count된다.
-
키타
고객 4의 placeholder를 표로 그리겠습니다.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 19줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F08-L01 | -- W17-SQL-Q25 illustrative example; |
STARRY가 고객 비율표에 비정본 스티커를 붙인다. | 파일 provenance를 audit-authored illustrative example로 제한한다.
|
| 2줄F08-L02 | -- Assumption: |
STARRY가 성공 도장 카드 수를 전체 카드 수로 나누는 규칙표를 세운다. | customer-level numerator와 denominator 정책을 명시한다.
|
| 3줄F08-L03 | -- Customers with no transactions remain and return NULL, |
STARRY가 빈 바구니에 가짜 0% 표찰 대신 ‘계산 불가’를 붙인다. | zero-row preservation과 zero denominator semantics를 공개한다.
|
| 4줄F08-L04 | SET search_path TO : |
STARRY가 고객표를 찾을 선반 순서를 workbook부터 지정한다. | psql session의 unqualified-name resolution precedence를 바꾼다.
|
| 6줄F08-L06 | SELECT |
STARRY가 고객별 성적표의 빈 머리글을 펼친다. | main SELECT가 output expression list를 여는 keyword다.
|
| 7줄F08-L07 | c. |
STARRY가 각 성적표에 고객 번호표를 붙인다. | alias c의 customer_id를 group identifier로 projection한다.
|
| 8줄F08-L08 | COUNT( |
STARRY가 붙어 있는 실제 거래 카드만 세고 빈 자리 표시는 제외한다. | COUNT(expression)이 NULL tx_id를 세지 않는다.
|
| 9줄F08-L09 | COUNT( |
STARRY가 전체 카드 중 성공 도장 카드만 별도 계수기에 넣는다. | FILTER clause가 aggregate input을 SUCCESS rows로 제한한다.
|
| 10줄F08-L10 | ROUND( |
STARRY가 계산된 백분율을 두 자리 눈금표에 맞출 준비를 한다. | ROUND numeric function의 첫 argument expression scope를 시작한다.
|
| 11줄F08-L11 | 100. |
STARRY가 성공 카드 비중을 100칸 눈금으로 확대한다. | filtered COUNT를 numeric literal과 곱워 integer division을 피한다.
|
| 12줄F08-L12 | / |
STARRY가 빈 전체 바구니에는 나눗셈 금지 표찰을 붙인다. | NULLIF(COUNT(t.tx_id),0)가 zero divisor를 NULL로 치환한다.
|
| 13줄F08-L13 | 2 |
STARRY가 백분율 눈금을 소수점 아래 두 칸으로 고정한다. | ROUND 두 번째 argument가 decimal places를 설정한다.
|
| 14줄F08-L14 | ) AS success_rate_pct |
STARRY가 계산 칸에 ‘성공률 퍼센트’ 머리표를 붙인다. | closing parenthesis 뒤 alias가 derived expression의 output name을 정한다.
|
| 15줄F08-L15 | FROM customer AS c |
STARRY가 모든 고객 명부를 결과표의 출발 카드로 놓는다. | FROM customer AS c가 보존할 master row set을 정한다.
|
| 16줄F08-L16 | LEFT JOIN account AS a ON a. |
STARRY가 고객 카드 옆에 그 고객의 계좌 카드를 붙인다. | 첫 LEFT JOIN이 customer와 account를 ownership key로 연결한다.
|
| 17줄F08-L17 | LEFT JOIN business_tx AS t ON t. |
STARRY가 각 계좌 옆에 번호가 같은 거래 카드를 모두 붙인다. | 두 번째 LEFT JOIN이 account에서 transaction rows로 확장한다.
|
| 18줄F08-L18 | GROUP BY c. |
STARRY가 한 고객에게 붙은 모든 계좌·거래 카드를 한 바구니로 묶는다. | GROUP BY가 aggregate grain을 customer로 확정한다.
|
| 19줄F08-L19 | ORDER BY c. |
STARRY가 고객 성적표를 번호가 작은 순서로 진열한다. | outer ORDER BY가 반환 row presentation을 deterministic하게 만든다.
|
| 20줄F08-L20 | -- Oracle: |
STARRY가 마지막 검산판에 여섯 고객의 분수와 퍼센트를 적는다. | 고정 workbook seed에서 계산된 exact Q25 결과를 문서화한다.
|
0퍼센트와 NULL히토리 → 니지카 → 료 → 키타
-
히토리
거래가 없으면 성공도 없으니 0%가 맞지 않나요?
-
니지카
비율 분모가 0이라 0/0은 정의되지 않아.
-
료
NULL은 실패율 100%와 다른 정보다.
-
키타
0건과 실패만 있는 고객을 비교하겠습니다.
STEP 05 / 13
원본 코드 조각
원본을 3개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.
-- W17-SQL-Q25 illustrative example; not a shipped workbook answer.
-- Assumption: customer-level success means business_tx.status='SUCCESS' divided by all transactions.
-- Customers with no transactions remain and return NULL, not 0%, through NULLIF.
SET search_path TO :"workbook_schema", public;
SELECT
c.customer_id,
COUNT(t.tx_id) AS tx_count,
COUNT(t.tx_id) FILTER (WHERE t.status = 'SUCCESS') AS success_count,
ROUND(
100.0 * COUNT(t.tx_id) FILTER (WHERE t.status = 'SUCCESS')
/ NULLIF(COUNT(t.tx_id), 0),
2
) AS success_rate_pct
FROM customer AS c
LEFT JOIN account AS a ON a.customer_id = c.customer_id
LEFT JOIN business_tx AS t ON t.account_id = a.account_id
GROUP BY c.customer_id
ORDER BY c.customer_id;
-- Oracle: 1=11/12/91.67, 2=2/7/28.57, 3=1/1/100.00, 4=NULL, 5=NULL, 6=1/1/100.00.
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 19줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | -- W17-SQL-Q25 illustrative example; not a shipped workbook answer. | W17 Q25 학습 예시이며 배포된 workbook 정본 답안이 아님을 밝힌다. |
| 2 | -- Assumption: customer-level success means business_tx.status='SUCCESS' divided by all transactions. | 성공률을 SUCCESS 건수/전체 거래 건수로 정의한다는 가정을 적는다. |
| 3 | -- Customers with no transactions remain and return NULL, not 0%, through NULLIF. | 거래가 없는 고객도 남기고 NULLIF로 0%가 아닌 NULL을 반환한다고 적는다. |
| 4 | SET search_path TO :"workbook_schema", public; | search_path를 supplied workbook_schema와 public 순서로 설정한다. |
| 6 | SELECT | 고객별 집계 결과의 SELECT projection을 시작한다. |
| 7 | c.customer_id, | customer_id를 결과의 기준 열로 고른다. |
| 8 | COUNT(t.tx_id) AS tx_count, | NULL이 아닌 t.tx_id 수를 전체 거래 건수 tx_count로 센다. |
| 9 | COUNT(t.tx_id) FILTER (WHERE t.status = 'SUCCESS') AS success_count, | status가 SUCCESS인 tx_id만 세어 success_count를 만든다. |
| 10 | ROUND( | 성공률을 소수 둘째 자리로 반올림할 ROUND 호출을 연다. |
| 11 | 100.0 * COUNT(t.tx_id) FILTER (WHERE t.status = 'SUCCESS') | SUCCESS 건수에 numeric 100.0을 곱해 백분율 분자를 만든다. |
| 12 | / NULLIF(COUNT(t.tx_id), 0), | 전체 거래 건수가 0이면 NULL로 바꾼 값으로 나눈다. |
| 13 | 2 | ROUND의 scale을 2로 지정한다. |
| 14 | ) AS success_rate_pct | 완성된 반올림 결과에 success_rate_pct라는 이름을 붙인다. |
| 15 | FROM customer AS c | customer를 driving relation c로 읽는다. |
| 16 | LEFT JOIN account AS a ON a.customer_id = c.customer_id | 같은 customer_id의 account를 LEFT JOIN한다. |
| 17 | LEFT JOIN business_tx AS t ON t.account_id = a.account_id | 같은 account_id의 business_tx를 LEFT JOIN한다. |
| 18 | GROUP BY c.customer_id | joined rows를 customer_id별로 그룹화한다. |
| 19 | ORDER BY c.customer_id; | 결과를 customer_id 오름차순으로 정렬한다. |
| 20 | -- Oracle: 1=11/12/91.67, 2=2/7/28.57, 3=1/1/100.00, 4=NULL, 5=NULL, 6=1/1/100.00. | 고객 1·2·3·4·5·6의 fixture oracle을 주석으로 기록한다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기customer-preserving outer joins와 FILTER aggregate, numeric division, NULLIF zero guard를 결합한 fixture-bound customer-grain success-rate 예시다.
문법 해부
- COUNT(t.tx_id)는 LEFT JOIN의 NULL placeholder를 제외하지만 COUNT(*)는 customer row 자체를 셀 수 있다.
- 100.0이 numeric division을 유도하고 NULLIF는 zero denominator를 NULL result로 전파한다.
실행 순서
- customer scan
- account LEFT JOIN
- business_tx LEFT JOIN
- customer grouping
- total/success counts
- NULLIF division
- ROUND 2
- customer sort
원래 W6 수준의 조각별 정밀 해설
F08-C01 · provenance assumptions and workbook schema
- 문법 해부
- `provenance assumptions and workbook schema` 범위는 파일 provenance를 audit-authored illustrative example로 제한한다. 이어서 psql session의 unqualified-name resolution precedence를 바꾼다.
- 실제 값 추적
- 구체 입력은 customer master row와 transaction count 0 상태를 전제로 한다. 처리 뒤 관찰 가능한 끝 상태는 뒤의 unqualified relation names가 앞선 schema부터 해석될 수 있다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 뒤 집계를 공식 요구사항이 아니라 공개된 가정의 예시로 보게 된다. 그리고 범위 끝에서 뒤의 unqualified relation names가 앞선 schema부터 해석될 수 있다.
- 틀린 예·반례
- SUCCESS/전체·customer grain·0건 NULL을 prompt의 공식 요구라고 쓰면 공개된 illustrative assumption을 정본으로 바꾼다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: 주석만으로 fixture나 비율 공식의 타당성이 검증되지는 않는다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: 주석만으로 fixture나 비율 공식의 타당성이 검증되지는 않는다.
- 다음 연결
- 끝 상태를 기록한다: 뒤의 unqualified relation names가 앞선 schema부터 해석될 수 있다. 이어지는 `conditional aggregation and NULLIF division` 범위에서 이 상태의 입력 경계를 확인한다.
F08-C02 · conditional aggregation and NULLIF division
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 main SELECT가 output expression list를 여는 keyword다. 끝에서 closing parenthesis 뒤 alias가 derived expression의 output name을 정한다.
- 실제 값 추적
- 시작 조건 SQL parser가 다음 column과 aggregate expressions를 기다린다.에서 범위를 통과하면 중간에 numeric value를 반올림할 function call scope가 열린다. 마지막에 client가 success_rate_pct 열 이름으로 값을 읽을 수 있다.
- 정상 예
- 원본 `SELECT`를 정확히 유지하고 이 범위를 실행·해석했을 때 client가 success_rate_pct 열 이름으로 값을 읽을 수 있다.
- 틀린 예·반례
- COUNT(*)로 바꿔도 zero-row customer의 tx_count가 0이라고 기대하면 보존 조인의 빈자리를 한 건 세게 된다.
- 착각 방지
- alias는 비율 가정이나 NULL 의미를 강제하지 않는다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `conditional aggregation and NULLIF division`의 source state만 다루며 alias는 비율 가정이나 NULL 의미를 강제하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: client가 success_rate_pct 열 이름으로 값을 읽을 수 있다. 이어지는 `zero-row preserving joins grouping and oracle` 범위에서 이 상태의 입력 경계를 확인한다.
F08-C03 · zero-row preserving joins grouping and oracle
- 문법 해부
- 이 source slice의 문법 축은 GROUP BY가 aggregate grain을 customer로 확정한다. 앞뒤로 FROM customer AS c가 보존할 master row set을 정한다. 및 고정 workbook seed에서 계산된 exact Q25 결과를 문서화한다.
- 실제 값 추적
- workbook schema의 customer rows를 입력으로 사용한다. 그 상태가 진행되면 1=11/12/91.67, 2=2/7/28.57, 3·6=100.00, 4·5=NULL이 기대된다.
- 정상 예
- 유효한 예는 'FROM customer AS c' bytes를 보존해 각 customer master row마다 하나의 count/rate result가 생성된다.
- 틀린 예·반례
- 거래 0건 NULL을 성공률 0%와 같게 해석하거나 LEFT JOIN 결과를 account별 비율이라고 부르면 grain이 틀린다.
- 착각 방지
- account별 성공률이나 기간별 분할은 보존하지 않는다. 따라서 `zero-row preserving joins grouping and oracle`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. account별 성공률이나 기간별 분할은 보존하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: 1=11/12/91.67, 2=2/7/28.57, 3·6=100.00, 4·5=NULL이 기대된다. 이어지는 `provenance semantics and workbook schema` 범위에서 이 상태의 입력 경계를 확인한다.
100.0의 점히토리 → 니지카 → 료 → 키타
-
히토리
100 대신 100.0을 쓴 이유가 표시뿐인가요?
-
니지카
numeric arithmetic에 참여시켜 integer division 위험을 피하려는 거야.
-
료
type coercion도 결과 계약의 일부다.
-
키타
11/12 계산 타입을 확인할게요.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| customer 1 | SUCCESS 11, total 12 | 100*11/12 then ROUND | 91.67 | FAILED 한 건도 denominator에는 포함된다 |
| customer 2 | SUCCESS 2, total 7 | numeric percentage | 28.57 | status 전부가 분모다 |
| customer 4 | joined tx_id NULL, count 0 | NULLIF(0,0) | rate NULL | 0%로 치환하지 않는다 |
공식 요구인가히토리 → 니지카 → 료 → 키타
-
히토리
oracle이 정확하니 이게 정본 Q25 답이죠?
-
니지카
fixture에서는 정확하지만 query policy는 audit 작성 가정이야.
-
료
정확한 실행 결과와 요구사항 승인 여부는 다른 축이다.
-
키타
페이지에 ‘학습용 예시’ 한계를 유지하겠습니다.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
customer master rows를 보존하며 account와 tx로 확장한다
join multiplicity는 fixture foreign keys에 의존한다customer_id group별 total·filtered counts를 함께 계산한다
large tables의 memory·parallel plan을 작은 seed가 설명하지 않는다100.0 multiplication, guarded division, scale-2 rounding을 수행한다
report formatting·statistical confidence를 제공하지 않는다STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ LEFT JOIN 뒤 COUNT(*)를 써도 거래 0건은 0이다.
왜 틀리나 보존된 customer placeholder row 하나가 count될 수 있다.
바르게 읽기 nullable right-side identifier COUNT(t.tx_id)를 쓴다.
반례 customer4는 COUNT(*)=1 가능하지만 COUNT(t.tx_id)=0이다.
❌ NULL 성공률은 성공이 0건이라는 뜻이다.
왜 틀리나 분모 자체가 0이라 비율이 정의되지 않은 상태다.
바르게 읽기 0/positive와 0/0을 구분한다.
반례 실패 2건 고객은 0%, 거래 0건 고객은 NULL이다.
❌ SUCCESS 비율 공식은 prompt의 정본 요구다.
왜 틀리나 source audit가 공개한 illustrative assumption이다.
바르게 읽기 분자·분모·grain 정책을 결과와 함께 표기한다.
반례 금액 가중 또는 COMPLETED 기준이면 다른 숫자가 나온다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
shipped workbook canonical answer
이 책임을 맡는 곳: approved workbook solution업무 승인 SUCCESS 정의·denominator·grain
이 책임을 맡는 곳: reporting requirements표본 신뢰도·기간 비교·금액 가중
이 책임을 맡는 곳: analytics designSTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
master preservation→join multiplicity→two counts→zero guard→rounding 순서를 말한다.
2단계 · 코드 조각 재조립
- COUNT(t.tx_id)
- FILTER SUCCESS
- 100.0 numeric
- NULLIF zero
- ROUND scale2
- customer GROUP BY
3단계 · 파일 전체 다시 쓰기
원문 20줄을 빈 5줄까지 보존해 다시 쓰고 여섯 고객 oracle을 계산한다.
자가 점검
- COUNT(*) 반례를 설명했는가?
- NULL과 0%를 분리했는가?
- 공개 가정임을 표시했는가?
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
학습용 예시 전체 확인하기 · 정본 답안 아님
-- W17-SQL-Q25 illustrative example; not a shipped workbook answer.
-- Assumption: customer-level success means business_tx.status='SUCCESS' divided by all transactions.
-- Customers with no transactions remain and return NULL, not 0%, through NULLIF.
SET search_path TO :"workbook_schema", public;
SELECT
c.customer_id,
COUNT(t.tx_id) AS tx_count,
COUNT(t.tx_id) FILTER (WHERE t.status = 'SUCCESS') AS success_count,
ROUND(
100.0 * COUNT(t.tx_id) FILTER (WHERE t.status = 'SUCCESS')
/ NULLIF(COUNT(t.tx_id), 0),
2
) AS success_rate_pct
FROM customer AS c
LEFT JOIN account AS a ON a.customer_id = c.customer_id
LEFT JOIN business_tx AS t ON t.account_id = a.account_id
GROUP BY c.customer_id
ORDER BY c.customer_id;
-- Oracle: 1=11/12/91.67, 2=2/7/28.57, 3=1/1/100.00, 4=NULL, 5=NULL, 6=1/1/100.00.
09중복 correlation_id 후보를 묶어 찾기
illustrative/sql/W17-SQL-Q26.sql
학습용 SQL 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W17-F099줄 연결9줄 번역3 chunks
중복 correlation_id 후보를 묶어 찾기
illustrative/sql/W17-SQL-Q26.sql
학습용 SQL 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W17-F09STEP 01 / 13
오늘 이 코드에서 해결할 문제
무엇을 이해해야 하는지 질문부터 잡습니다.
business_tx를 correlation_id별로 묶고 두 행 이상인 key만 후보로 반환한다.
- WHERE가 아니라 HAVING이 필요한 이유는 무엇인가?
- duplicate candidate가 fraud를 뜻하지 않는 이유는 무엇인가?
- 왜 workbook schema와 application V001을 구분해야 하는가?
candidate=COUNT(*)>1oracle=CORR-DUP|2workbook correlation_id non-uniqueV001 correlation_id UNIQUESTEP 02 / 13
아주 짧게: 이 코드는 왜 필요할까?
웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.
STARRY가 correlation_id가 같은 카드를 묶고 두 장 이상인 바구니만 확인 선반에 놓는다.
같은 표찰이 겹친 거래 카드 찾기
GROUP BY가 correlation_id별 묶음을 만들고 HAVING이 count 1보다 큰 묶음만 남긴다.
고정 workbook seed에서는 CORR-DUP 두 행 한 묶음만 결과에 나온다.
딱 여기까지만 중복 후보는 원인·사기·동일 요청 판정이 아니며 application V001의 UNIQUE 계약에는 이 duplicate fixture가 들어갈 수 없는 비정본 예시다.
STEP 03 / 13
초등학생도 이해하는 설명
생활 비유와 실제 코드의 경계를 함께 확인합니다.
같은 표찰 묶기
correlation_id가 같은 거래를 한 그룹으로 모은다.
- 코드 연결
GROUP BY correlation_id- 비유
- 같은 이름표 카드를 한 바구니에 넣는다.
- 비유의 끝
- NULL key가 있다면 한 그룹이 될 수 있다.
두 장 이상
그룹이 만들어진 뒤 count가 2 이상인 것만 남긴다.
- 코드 연결
HAVING COUNT(*) > 1- 비유
- 한 장 바구니는 확인 선반에서 뺀다.
- 비유의 끝
- 어떤 개별 row가 잘못인지 선택하지 않는다.
후보일 뿐
반복 key를 조사 후보로 표시한다.
- 코드 연결
duplicate_count- 비유
- 경고가 아니라 확인 필요 표찰이다.
- 비유의 끝
- fraud·재시도·같은 logical request를 판정하지 않는다.
HAVING의 자리히토리 → 니지카 → 료 → 키타
-
히토리
COUNT 조건도 WHERE에서 먼저 거르면 빠르지 않나요?
-
니지카
COUNT는 group이 만들어진 뒤에야 값이 생겨.
-
료
그래서 aggregate 결과 조건은 HAVING 단계에 둔다.
-
키타
logical order를 화살표로 그리겠습니다.
두 행의 의미히토리 → 니지카 → 료 → 키타
-
히토리
CORR-DUP 두 건이면 둘 다 잘못된 거래죠?
-
니지카
query가 아는 건 같은 key가 두 번 보였다는 사실뿐이야.
-
료
사기나 재시도 판정에는 별도 증거가 필요하다.
-
키타
후보와 결론을 다른 색으로 표시할게요.
STEP 04 / 13
비유 ↔ 코드 전체 연결표
감사 규칙상 연결 대상인 원본 9줄을 빠짐없이 연결합니다.
| 줄 | 정확한 원본 줄 | STARRY 비유 | 실제 뜻·입력·결과·한계 |
|---|---|---|---|
| 1줄F09-L01 | -- W17-SQL-Q26 illustrative example; |
STARRY가 중복 후보표에 비정본 도장을 찍는다. | 파일 provenance를 illustrative example로 제한하는 주석이다.
|
| 2줄F09-L02 | -- Candidate means correlation_id appears more than once; |
STARRY가 같은 표찰이 겹친 카드에 ‘확인 필요’만 붙인다. | duplicate candidate의 의미와 부정적 경계를 명시한다.
|
| 3줄F09-L03 | SET search_path TO : |
STARRY가 중복 허용 거래표가 있는 workbook 선반을 먼저 찾는다. | psql session의 name resolution order를 변경한다.
|
| 5줄F09-L05 | SELECT correlation_id, |
STARRY가 같은 표찰별 카드 묶음 이름과 장수를 결과표에 적는다. | SELECT가 grouping key와 COUNT(*) aggregate를 projection한다.
|
| 6줄F09-L06 | FROM business_tx |
STARRY가 workbook 거래 카드 전체를 계수대로 가져온다. | FROM clause가 grouping input을 business_tx에 결속한다.
|
| 7줄F09-L07 | GROUP BY correlation_id |
STARRY가 같은 상관 표찰을 가진 카드를 한 바구니에 모은다. | GROUP BY가 aggregate grain을 correlation identifier로 정한다.
|
| 8줄F09-L08 | HAVING COUNT( |
STARRY가 카드가 두 장 이상인 바구니만 확인 선반으로 보낸다. | HAVING이 aggregate cardinality predicate를 group 결과에 적용한다.
|
| 9줄F09-L09 | ORDER BY correlation_id; |
STARRY가 확인 선반의 표찰을 글자 순서로 진열한다. | outer ORDER BY가 grouped candidate presentation을 안정화한다.
|
| 10줄F09-L10 | -- Oracle: |
STARRY가 검산판에 겹친 표찰 하나와 카드 두 장을 적는다. | 고정 workbook seed의 exact Q26 result를 주석으로 문서화한다.
|
COUNT 별표히토리 → 니지카 → 료 → 키타
-
히토리
COUNT(correlation_id)로 바꿔도 항상 같나요?
-
니지카
현재 fixture가 non-null이면 같지만 NULL 가능성에서 달라져.
-
료
COUNT(*)는 group의 물리 rows를 세겠다는 선택이다.
-
키타
column constraint를 확인하고 일반화를 제한하겠습니다.
STEP 05 / 13
원본 코드 조각
원본을 3개 의미 조각으로 나누어 그대로 확인합니다.
파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.
-- W17-SQL-Q26 illustrative example; not a shipped workbook answer.
-- Candidate means correlation_id appears more than once; neither row is thereby declared fraudulent.
SET search_path TO :"workbook_schema", public;
SELECT correlation_id, COUNT(*) AS duplicate_count
FROM business_tx
GROUP BY correlation_id
HAVING COUNT(*) > 1
ORDER BY correlation_id;
-- Oracle: exactly one row, CORR-DUP|2.
STEP 06 / 13
코드 한 줄씩 한국어로 번역
비어 있지 않은 9줄을 모두 한국어로 옮깁니다.
비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.
| 줄 | 원본 | 한국어 번역 |
|---|---|---|
| 1 | -- W17-SQL-Q26 illustrative example; not a shipped workbook answer. | W17 Q26 학습 예시이며 배포된 workbook 정본 답안이 아님을 밝힌다. |
| 2 | -- Candidate means correlation_id appears more than once; neither row is thereby declared fraudulent. | correlation_id가 한 번보다 많이, 즉 두 번 이상 나타난 묶음을 후보라 부르며 사기라고 단정하지 않는다. |
| 3 | SET search_path TO :"workbook_schema", public; | search_path를 supplied workbook_schema와 public 순서로 설정한다. |
| 5 | SELECT correlation_id, COUNT(*) AS duplicate_count | correlation_id와 각 묶음의 행 수 duplicate_count를 고른다. |
| 6 | FROM business_tx | 중복 후보를 찾을 source relation을 business_tx로 지정한다. |
| 7 | GROUP BY correlation_id | business_tx rows를 correlation_id 값별로 묶는다. |
| 8 | HAVING COUNT(*) > 1 | COUNT(*)가 1보다 큰 group만 남긴다. |
| 9 | ORDER BY correlation_id; | 후보 결과를 correlation_id 오름차순으로 정렬한다. |
| 10 | -- Oracle: exactly one row, CORR-DUP|2. | fixture oracle은 CORR-DUP|2 한 행뿐이라고 기록한다. |
STEP 07 / 13
기존 수준의 한 줄 읽기·문법 해부
쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.
한 줄로 읽기duplicate-friendly workbook relation에서 correlation_id grain aggregate와 post-aggregate HAVING을 적용하는 provenance-limited candidate query다.
문법 해부
- WHERE는 개별 input row를 거르지만 HAVING은 GROUP BY 뒤 COUNT 결과를 거른다.
- COUNT(*)>1은 frequency만 말하며 cause나 row identity를 projection하지 않는다.
실행 순서
- workbook search_path
- business_tx scan
- correlation grouping
- row count
- HAVING >1
- key sort
- fixture oracle
원래 W6 수준의 조각별 정밀 해설
F09-C01 · provenance semantics and workbook schema
- 문법 해부
- `provenance semantics and workbook schema` 범위는 파일 provenance를 illustrative example로 제한하는 주석이다. 이어서 psql session의 name resolution order를 변경한다.
- 실제 값 추적
- 구체 입력은 거래 관계 correlation_id frequency만 판단 입력으로 둔다. 처리 뒤 관찰 가능한 끝 상태는 뒤의 unqualified relation name이 workbook schema에서 먼저 resolution될 수 있다.
- 정상 예
- frozen source의 범위 시작부터 읽으면 뒤 GROUP BY를 공식 fraud rule이 아닌 학습 예시로 보게 된다. 그리고 범위 끝에서 뒤의 unqualified relation name이 workbook schema에서 먼저 resolution될 수 있다.
- 틀린 예·반례
- 중복 candidate라는 말을 fraud 판정이나 application V001에서도 가능한 fixture라는 뜻으로 넓히지 않는다.
- 착각 방지
- 오해를 막으려면 다음 경계를 유지한다: 주석 자체는 duplicate 결과나 schema 적합성을 검사하지 않는다.
- 하지 않는 일
- 현재 chunk가 직접 보장하지 않는 경계는 다음과 같다: 주석 자체는 duplicate 결과나 schema 적합성을 검사하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: 뒤의 unqualified relation name이 workbook schema에서 먼저 resolution될 수 있다. 이어지는 `grouped duplicate candidate query` 범위에서 이 상태의 입력 경계를 확인한다.
F09-C02 · grouped duplicate candidate query
- 문법 해부
- 설명 대상 줄을 한 범위로 묶으면 시작에서 SELECT가 grouping key와 COUNT(*) aggregate를 projection한다. 끝에서 outer ORDER BY가 grouped candidate presentation을 안정화한다.
- 실제 값 추적
- 시작 조건 각 eventual correlation_id group의 rows를 입력으로 쓴다.에서 범위를 통과하면 중간에 distinct key마다 COUNT를 계산할 한 group이 생성된다. 마지막에 여러 duplicate key가 있어도 deterministic order로 반환된다.
- 정상 예
- 원본 `SELECT correlation_id, COUNT(*) AS duplicate_count`를 정확히 유지하고 이 범위를 실행·해석했을 때 여러 duplicate key가 있어도 deterministic order로 반환된다.
- 틀린 예·반례
- COUNT aggregate 조건을 WHERE에 두거나 HAVING이 duplicate group의 어느 개별 row가 원인인지 고른다고 생각하면 안 된다.
- 착각 방지
- candidate 수·fraud severity·최근성 우선순위를 계산하지 않는다. 이 제한을 결과 설명에서 생략하지 않는다.
- 하지 않는 일
- 이 범위는 `grouped duplicate candidate query`의 source state만 다루며 candidate 수·fraud severity·최근성 우선순위를 계산하지 않는다.
- 다음 연결
- 끝 상태를 기록한다: 여러 duplicate key가 있어도 deterministic order로 반환된다. 이어지는 `fixture oracle` 범위에서 이 상태의 입력 경계를 확인한다.
F09-C03 · fixture oracle
- 문법 해부
- 이 source slice의 문법 축은 고정 workbook seed의 exact Q26 result를 주석으로 문서화한다. 앞뒤로 고정 workbook seed의 exact Q26 result를 주석으로 문서화한다. 및 고정 workbook seed의 exact Q26 result를 주석으로 문서화한다.
- 실제 값 추적
- duplicate-friendly workbook schema와 현재 seed bytes를 전제로 한다. 그 상태가 진행되면 expected output은 correlation_id CORR-DUP, duplicate_count 2 한 행이다.
- 정상 예
- 유효한 예는 '-- Oracle: exactly one row, CORR-DUP|2.' bytes를 보존해 expected output은 correlation_id CORR-DUP, duplicate_count 2 한 행이다.
- 틀린 예·반례
- CORR-DUP|2 한 행 oracle이 다른 singleton key의 정상성이나 반복 원인을 증명하지 않는다.
- 착각 방지
- application V001은 correlation_id UNIQUE라 같은 fixture를 수용하지 못한다. 따라서 `fixture oracle`의 직접 증거와 외부 가정을 분리한다.
- 하지 않는 일
- 책임 밖 항목은 명시적으로 남는다. application V001은 correlation_id UNIQUE라 같은 fixture를 수용하지 못한다.
- 다음 연결
- 끝 상태를 기록한다: expected output은 correlation_id CORR-DUP, duplicate_count 2 한 행이다. 이를 W17 전체 source·runner·fixture 책임표와 다시 대조한다.
두 schema히토리 → 니지카 → 료 → 키타
-
히토리
앞 V001의 business_tx에 CORR-DUP을 넣으면 되죠?
-
니지카
그 migration은 correlation_id UNIQUE라 두 번째 row가 거부돼.
-
료
Q26 oracle은 duplicate-friendly workbook schema에만 결속된다.
-
키타
source authority를 나눠 적겠습니다.
STEP 08 / 13
실제 값 따라가기
같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.
| 순서 | 들어온 값 | 코드가 하는 일 | 나온 값·상태 | 경계 |
|---|---|---|---|---|
| group | CORR-DUP rows 2 | COUNT(*) | duplicate_count 2 | 두 rows 모두 candidate group member일 뿐 fraud label이 아니다 |
| singleton | 다른 correlation key row 1 | HAVING 1>1 | filtered out | 정상임을 증명하지 않고 frequency threshold만 통과하지 못한다 |
| schema split | application V001 UNIQUE | duplicate insert attempt | 같은 fixture 불가 | Q26는 workbook schema 전용 |
한 행 oracle히토리 → 니지카 → 료 → 키타
-
히토리
결과가 한 행이면 다른 key는 모두 정상인가요?
-
니지카
그저 count threshold를 넘은 key가 하나라는 뜻이야.
-
료
singleton도 업무상 이상할 수 있고 duplicate도 합법일 수 있다.
-
키타
query가 직접 증명하는 빈도만 남기겠습니다.
STEP 09 / 13
PowerShell·SQL·DB 내부에서 벌어지는 일
PowerShell·SQL·DB에서 실제로 일어나는 일과 증명 범위를 구분합니다.
correlation_id별 hash/sort group과 count state를 만든다
large-cardinality plan과 index 사용은 이 fixture가 고정하지 않는다finalized count가 1보다 큰 groups만 통과시킨다
개별 row를 삭제하거나 수정하지 않는 read-only observation이다workbook fixture는 repeated correlation id를 허용한다
application migration의 UNIQUE constraint와 합치지 않는다STEP 10 / 13
흔한 착각과 틀린 예
그럴듯하지만 틀린 해석을 반례로 고칩니다.
❌ COUNT 조건은 WHERE에 쓰면 된다.
왜 틀리나 WHERE 단계에는 group aggregate가 아직 없다.
바르게 읽기 GROUP BY 결과의 aggregate predicate는 HAVING에 둔다.
반례 WHERE COUNT(*)>1은 일반 SQL에서 유효한 row predicate가 아니다.
❌ 중복 correlation_id면 두 거래 모두 사기다.
왜 틀리나 빈도는 원인과 의도를 제공하지 않는다.
바르게 읽기 후보를 반환하고 별도 provenance·request 조사로 판정한다.
반례 합법적 재시도나 fixture duplicate도 count 2를 만든다.
❌ 이 query를 V001 schema에 그대로 검증할 수 있다.
왜 틀리나 V001은 correlation_id UNIQUE라 duplicate seed가 거부된다.
바르게 읽기 workbook과 application schema 계약을 분리한다.
반례 CORR-DUP 두 번째 insert가 unique violation을 낸다.
STEP 11 / 13
이 코드가 보장하지 않는 것
이 코드가 책임지지 않는 일을 분리합니다.
shipped workbook canonical answer
이 책임을 맡는 곳: approved workbook solutionfraud·same request·root cause 판정
이 책임을 맡는 곳: investigation and domain policyapplication V001에서 duplicate fixture 재현
이 책임을 맡는 곳: workbook fixture contractSTEP 12 / 13
직접 다시 써보기
뜻 → 조각 → 전체 코드 순서로 다시 씁니다.
1단계 · 뜻부터 복원
source→group grain→count→HAVING→candidate boundary를 말한다.
2단계 · 코드 조각 재조립
- FROM business_tx
- GROUP BY correlation_id
- COUNT(*)
- HAVING >1
- ORDER BY
3단계 · 파일 전체 다시 쓰기
원문 10줄을 빈 4줄까지 보존해 다시 쓰고 CORR-DUP 두 rows를 손으로 묶는다.
자가 점검
- WHERE와 HAVING 단계를 구분했는가?
- candidate와 fraud를 분리했는가?
- workbook/V001 constraint 차이를 적었는가?
STEP 13 / 13
전체 원본 정답
감사로 고정한 전체 source를 가감 없이 확인합니다.
학습용 예시 전체 확인하기 · 정본 답안 아님
-- W17-SQL-Q26 illustrative example; not a shipped workbook answer.
-- Candidate means correlation_id appears more than once; neither row is thereby declared fraudulent.
SET search_path TO :"workbook_schema", public;
SELECT correlation_id, COUNT(*) AS duplicate_count
FROM business_tx
GROUP BY correlation_id
HAVING COUNT(*) > 1
ORDER BY correlation_id;
-- Oracle: exactly one row, CORR-DUP|2.