Wraps the v1.0 PG-wire deliverable with the two pieces operators
actually look for: a runnable example PRG and an updated CI gate
list in CLAUDE.md.
* examples/pgserver_demo.prg — full bootstrap PRG demonstrating
every HB_FUNC composed in the order a production deployment
needs:
PG_TLS_SELF_SIGNED → PG_ADD_ROLE × N → PG_ALLOW_IP × N →
PG_SERVER_START( ":5432", "md5" )
Comments cover the SHARED-DBF integration point and the SPAWN
idiom for non-blocking server startup. Builds cleanly under
the examples_build sweep (now 66/72; was 65/71).
* CLAUDE.md — the "어떤 파일이든 수정한 후" mandatory test list
goes from 3 gates → 6:
1. go test ./...
2. FiveSql2 SQL:1999 43/43
3. Harbour compat 56/56
4. std.ch 17/17 (added)
5. FRB 7/7 (added)
6. pgserver integration 6/6 (added — psql required)
Aligns the rule-of-thumb with reality. The five suites already
ran on every audit-era commit; pgserver/run.sh is new in
Phases 3-6 and now joins them.
This completes the v1.0 PostgreSQL-wire frontend. End-to-end
checklist:
Phase 1: per-session state isolation [93cf5c8]
Phase 2: SimpleQuery wire MVP [d98f5e1 7083297]
Phase 3: DML + transactions [a556764]
Phase 4: Extended Protocol (Parse/Bind/Exec) [8472928]
Phase 5: password + MD5 auth [90eafcf]
Phase 6: TLS + IP allowlist [3b2dd36]
Phase 7: example + docs [this commit]
Open follow-ups (Phase 7.x):
- hbrdd workarea per-thread isolation (audit Top-Risk #2):
≥3 concurrent connections doing in-flight INSERT/SELECT in
their own transactions can race at the workarea layer. Fix
is a separate workstream against hbrtl/database.go +
hbrdd/dbf/. Documented limitation in tests/pgserver/run.sh.
- SCRAM-SHA-256 auth (Phase 5.1).
- pg_catalog shim for BI-tool introspection (Phase 1.1+ of the
original audit plan).
- Binary parameter format for NUMERIC/TIMESTAMP (Phase 4.1).
All gates green:
go test ./... ✓
FiveSql2 SQL:1999 43/43 ✓
Harbour compat 56/56 ✓
std.ch 17/17 ✓
FRB 7/7 ✓
examples 66/72 ✓ (+1 from new pgserver_demo)
pgserver integration 6/6 ✓
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.9 KiB
5.9 KiB
Five — 개발 규칙
절대 규칙: 변경 후 반드시 검증
어떤 파일이든 수정한 후, 다음 6개 테스트를 모두 통과해야 한다. 하나라도 실패하면 해당 변경을 되돌린다.
# 1. Go 유닛 테스트
go test ./...
# 2. FiveSql2 SQL 테스트 (43/43)
./five build _FiveSql2/test/test_sql1999.prg _FiveSql2/src/*.prg -o /tmp/test_sql
cd ~/tmp && rm -f *.dbf __cte_*.dbf && /tmp/test_sql
# 3. Harbour 호환 테스트 (56/56)
./five build tests/compat_harbour.prg -o /tmp/test_compat && /tmp/test_compat
# 4. std.ch 테스트 (17/17)
bash tests/std_ch/run.sh
# 5. FRB 테스트 (7/7)
bash tests/frb/run.sh
# 6. pgserver 통합 테스트 (6/6) — psql 필요
bash tests/pgserver/run.sh
절대로 "나중에 확인" 하지 않는다. 매 변경마다 즉시.
파일별 영향 범위
수정하는 파일에 따라 어디가 깨질 수 있는지:
hbrt/ (런타임 — 가장 위험)
| 파일 | 변경 시 영향 | 주의사항 |
|---|---|---|
| thread.go | 모든 것 | Frame/EndProc/Local 수정 시 FiveSql2 전체 crash 가능. EndProc은 반드시 re-panic 방식 유지 |
| ops_arith.go | 모든 산술/FOR 루프 | LocalAdd/LocalAddInt는 byref-aware 필수 |
| ops_compare.go | 모든 비교/IF/WHILE | PopLogical은 NIL→false 유지. LocalLessEqualInt는 byref-aware 필수 |
| ops_collection.go | 배열/해시 접근 | ArrayPush/ArrayPop은 hash + string 인덱싱 지원 필수 |
| value.go | 모든 것 | Value 구조체 크기(24B) 변경 금지. HbRefCell은 ptr 필드 사용 |
| call.go | 모든 함수 호출 | Function()의 pop/push 순서 변경 금지. copy 최적화 시도 금지 (이전에 실패) |
| class.go | 모든 메서드 호출 | Send()의 pendingParams 설정 순서 유지 |
compiler/gengo/ (코드 생성 — 두 번째로 위험)
| 파일 | 변경 시 영향 | 주의사항 |
|---|---|---|
| gengo.go | 모든 생성 코드 | emitExpr의 BinaryExpr: short-circuit AND/OR 유지. emitBlock: RefCell 기반 mutable capture 유지. emitAssignExpr: 블록 내 += 처리 필수 |
| gen_class.go | 클래스/메서드 | blockSeq는 함수 간 공유됨 (reset 불필요) |
| gen_cmd.go | USE/INDEX 등 명령 | USE ALIAS (expr) 동적 별칭 유지 |
hbrtl/ (RTL 함수)
| 파일 | 변경 시 영향 | 주의사항 |
|---|---|---|
| array.go | AEval/ASort/AScan | AEval: push 순서 = index먼저, element나중 (Frame이 상단에서 가져감) |
| database.go | DB 함수 전체 | dbUseArea 실패 시 반드시 *HbError panic |
| register.go | 함수 등록 | 새 함수 추가 시 이름 충돌 확인 |
_FiveSql2/src/ (SQL 엔진 PRG)
| 파일 | 주의사항 |
|---|---|
| TSqlExecutor.prg | 세미콜론 인라인 IF...ENDIF 사용 금지 (Five 파서 미지원). ENDIF 개수 반드시 IF와 매칭 확인 |
| TSqlDDL.prg | @byref 미지원이었으나 이제 동작함. MemoRead 사용 유지 |
| TFiveSQL.prg | Query Plan Cache: parse tree가 실행 중 변경됨(aTables 등). 캐시 시 deep clone 필수 |
알려진 제약사항
| 항목 | 상태 | 비고 |
|---|---|---|
| CDX 바이너리 Harbour 호환 | ⚠️ CHAR 태그만 호환 | 숫자 키: Harbour는 IEEE double 8B, Five는 DBF ASCII. Five↔Five 완벽 동작. Harbour가 Five CDX 읽기 시 숫자 태그에서 corruption |
해결된 제약 (2026-04-11~13)
| 항목 | 커밋 |
|---|---|
| 세미콜론 IF...ENDIF | 이미 동작 확인 (2026-04-13) |
| `{ | |
| CDX compound index 쓰기 미지원 | CDX 빌더 구현 (비트팩 리프+compound root) |
| STATIC inside FUNCTION → panic | 5bfdc47 — Go 패키지 변수로 emit |
| FIELD->NAME 빈 값 반환 | e95afad — GetAliasField 반환 타입 수정 |
| OrdSetFocus(n) 무동작 | e95afad — 숫자→문자열 변환 수정 |
| Break("string") RECOVER USING panic | 3adc9d7 — BreakValue duck-type dispatch |
| SET INDEX TO a, b, c 마지막만 열림 | 3adc9d7 — 파서+gengo 다중 파일 지원 |
| PCount() 항상 0 반환 | 3adc9d7 — CallerParamCount + Frame.paramCount |
| OutStd()/OutErr() 미등록 | e95afad — RTL 등록 |
| Date + Numeric panic | 6c53747 — NumInt→Numeric 확장 |
| STATIC += / -= 단순 대입으로 처리 | 5bfdc47 — compound assign 지원 |
최적화 시 주의
- thread.go의 pop() slot clearing — 제거하면 stale 데이터 문제 가능. 현재
cachedNil로 클리어 유지 - call.go의 copy 최적화 — 이전에 시도했으나 pendingSyms desync 발생. 시도 금지
- growStack/growFrame 분리 — 가능하지만 다른 변경과 동시 적용 금지. 단독 적용 + 전체 테스트
- FiveSql2 PRG 최적화 — 한 번에 하나씩. Column Binding, CTE in-memory 등은 별도 브랜치에서
빌드 환경
/mnt/d/(NTFS 9P): 5~15x 느림. 벤치마크는 반드시~/tmp/(ext4)에서 실행- Five 컴파일러:
go build -o five ./cmd/five - FiveSql2: 다중 파일 빌드 필수
./five build test.prg src/*.prg -o output - Go 경로:
export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin
현재 지표 (2026-04-13)
- Go test: ALL PASS (14 packages)
- RTL 함수: 483개
- FiveSql2: 43/43 (100%)
- Compat: 51/51 (100%)
- Syntax test: 100/100
- RDD test: 44/44
- RTL test: 114/114
- Harbour RDD parity: diff 0 (281-line NTX+CDX comparison)
- Windows cross-compile: OK (five.exe 4.0MB)
- Linux cross-compile: OK (five_linux 3.8MB)
- @byref: 동작 (RefCell)
- Mutable closure: 동작 (RefCell + EnsureLocalRef)
- FIELD->NAME: 동작 (읽기/쓰기)
- STATIC inside FUNCTION: 동작 (패키지 변수 + 함수 스코프 격리)
- PCount(): 동작 (CallerParamCount)
- Break/RECOVER USING: 동작 (BreakValue duck-type)
- 파일 락킹: POSIX fcntl + Windows LockFileEx
- INDEX 성능: Harbour 대비 12% faster (50k records)