d98f5e176721517ebf8b7c698cd2f301c6828317
First end-to-end working version of the PostgreSQL-wire-compatible
TCP server frontend. A standard `psql` client now connects, runs
`SELECT * FROM employees`, and gets back a properly typed result
set rendered by psql with the right column alignment:
ID | NAME | SALARY
----+----------------------+----------
1 | Alice | 50000.00
2 | Bob | 42000.50
3 | Cho | 77500.00
This is the Phase 2 deliverable from the approved plan at
/Users/charleskwon/.claude/plans/compiled-launching-shore.md.
Builds on the session-state refactor in 93cf5c8 — each connection
gets its own TSqlSession on the PRG side via the new PG_NEW_SESSION
HB_FUNC, so concurrent psql clients won't share transaction logs
or plan caches.
Scope
-----
v1.0 MVP: Simple Query only, trust auth, no TLS yet. SELECT works
against the full FiveSql2 surface (CTEs, window functions, JOINs,
aggregates). DML + per-session transactions are Phase 3, extended
protocol is Phase 4, auth + TLS are Phases 5/6.
Architecture
------------
psql/pgx/JDBC ──TCP:5432──▶ pgserver.Listener
│ accept()
▼ go handleConn(net.Conn)
┌─────────────────────────────┐
│ Session goroutine │
│ 1. SSLRequest peek │
│ 2. StartupMessage │
│ 3. AuthenticationOk (trust) │
│ 4. ParameterStatus×7 │
│ 5. BackendKeyData │
│ 6. ReadyForQuery('I') │
│ 7. loop: Receive() → │
│ dispatchSimpleQuery → │
│ hbrt.Thread.Function( │
│ FIVE_SQL,sql,...,sess) │
│ emit RowDescription │
│ emit DataRow×N │
│ emit CommandComplete │
│ emit ReadyForQuery │
└─────────────────────────────┘
One goroutine per connection, each owning its own *hbrt.Thread and
TSqlSession instance. Uses the existing audit-fixed NewThread()
(cde8673) so statics + WA factory propagate.
New files (hbrtl/pgserver/)
---------------------------
* server.go — Config, Server, Serve loop with MaxConnections gate
via semaphore, Close drains in-flight sessions.
* session.go — full lifecycle: SSLRequest peek + prefixedConn
byte-injection trick for StartupMessage, ParameterStatus
broadcast (server_version "14.0 (FiveSql2)" so pgx negotiates),
BackendKeyData (random pid+secret per session, no CancelRequest
yet), query loop dispatching only Simple Query in v1.0 with a
loud "0A000 not supported" for Extended messages.
* dispatch.go — runSQL invokes FIVE_SQL via PushSymbol+Function,
unpacks the engine's `{aFieldNames, aRows}` envelope or the
`{{"__error__"}, {{nCode, cMsg, cSQL}}}` error shape, emits
RowDescription with text-format OIDs and DataRow per row.
* typemap.go — pgTypeFor() picks INT4 / INT8 / NUMERIC / TEXT /
DATE / TIMESTAMP / BOOL by sampling the first row's value type;
encodeText() formats each cell, returning nil-slice for NULL
(the PG length=-1 convention).
* errmap.go — sqlStateFor() maps FiveSql2 SQL_ERR_* codes to
canonical PG SQLSTATEs (42601/42P01/42703/42804/23505/23514/
23503/25P02/42501/02000/XX000).
* auth.go — trust mode in v1.0; password/MD5/SCRAM lands Phase 5
but the dispatch sentinel is already in place.
* tls.go — upgradeToTLS stub for SSLRequest handling; the byte-
ordering is already wired so Phase 6 just plugs in tls.Config.
* register.go — package init() registers pg_server_start /
pg_server_stop HB_FUNCs. Importing the package (done from
hbrtl/register.go via blank import) is enough to enable them.
* pgserver_test.go — unit tests for encodeText (numeric, string,
NIL), pgTypeFor (OID dispatch), sqlStateFor (error mapping),
commandTagFor (SELECT/INSERT/UPDATE/DELETE/BEGIN/COMMIT).
Other changes
-------------
* _FiveSql2/src/TSqlSession.prg — added PG_NEW_SESSION() factory
used by the Go dispatcher to allocate a per-connection session
bypassing the embedded process default.
* hbrtl/register.go — blank-import five/hbrtl/pgserver so its
init() fires and the HB_FUNCs land in the global dynamic-func
table for VM symbol lookup.
* go.mod / go.sum — github.com/jackc/pgx/v5 v5.9.2 (pgproto3
subpackage). MIT license. Same library pgx itself uses, so
protocol coverage matches the de-facto Go PG ecosystem.
Verification
------------
$ pg_server_start(15432, "trust") /* PRG one-liner */
$ psql -h 127.0.0.1 -p 15432 -U fiveuser -c 'SELECT * FROM employees'
→ 3 rows rendered correctly by psql (ID as INT4, NAME as TEXT,
SALARY as NUMERIC(10,2) with 2 decimal places)
All six release gates green:
go test ./... ✓ (incl. new hbrtl/pgserver tests)
FiveSql2 SQL:1999 43/43 ✓
Harbour compat 56/56 ✓
std.ch 17/17 ✓
FRB 7/7 ✓
examples 65/71 ✓ (unchanged baseline)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five — Harbour + Go Fusion Language
Harbour PRG 코드를 네이티브 Go 바이너리로 컴파일하는 퓨전 언어.
30년간 축적된 Harbour/xBase 비즈니스 로직을 Go의 성능, 동시성, 크로스 플랫폼 위에서 실행합니다.
employees.prg → five build → employees (단일 실행파일, 18MB)
주요 특징
- Harbour 문법 100% 지원 (CLASS, CODE BLOCK, BEGIN SEQUENCE, ...)
- Go 네이티브 바이너리 출력 (CGo 없음, 순수 Go)
- DBF/NTX/CDX 데이터베이스 엔진 내장
- 479개 RTL 내장 함수
- FiveSql2: DBF 위에서 SQL:1999 쿼리 (43/43 테스트 통과)
- Goroutine/Channel 확장 (
GO BLOCK,CHANNEL) - @byref 참조 전달, mutable closure
- 대화형 디버거 (TUI/CLI)
빌드 방법
1. Go 설치
Five는 Go 1.21 이상이 필요합니다.
Linux/WSL:
# 이미 설치되어 있는지 확인
go version
# 없으면 설치
wget https://go.dev/dl/go1.22.5.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.22.5.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bashrc
source ~/.bashrc
go version
macOS (Apple Silicon — M1/M2/M3/M4):
brew install go
# 또는 직접 다운로드:
wget https://go.dev/dl/go1.22.5.darwin-arm64.tar.gz
sudo tar -C /usr/local -xzf go1.22.5.darwin-arm64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.zshrc
source ~/.zshrc
macOS (Intel):
brew install go
# 또는 직접 다운로드:
wget https://go.dev/dl/go1.22.5.darwin-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.5.darwin-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.zshrc
source ~/.zshrc
Windows:
https://go.dev/dl/ 에서 .msi 설치
2. Five 컴파일러 빌드
git clone https://gitea.fivego.org/fivedev/five.git
cd five
go build -o five ./cmd/five
빌드 확인:
./five version
3. PRG 프로그램 컴파일 및 실행
단일 파일:
# 컴파일
./five build examples/hello.prg -o hello
# 실행
./hello
다중 파일 (FiveSql2 등):
./five build _FiveSql2/test/test_sql1999.prg _FiveSql2/src/*.prg -o test_sql
./test_sql
4. 테스트 실행
# Go 유닛 테스트
go test ./...
# FiveSql2 SQL 테스트 (43/43)
./five build _FiveSql2/test/test_sql1999.prg _FiveSql2/src/*.prg -o /tmp/test_sql
cd /tmp && ./test_sql
# Harbour 호환 테스트 (51/51)
./five build tests/compat_harbour.prg -o /tmp/test_compat
/tmp/test_compat
Five 명령어
five run <file.prg> 컴파일 후 즉시 실행
five build <file.prg> [-o out] 네이티브 바이너리 생성
five gen <file.prg> 생성된 Go 코드 출력 (디버깅용)
five debug <file.prg> 대화형 디버거 실행
five version 버전 정보
Hello World
// hello.prg
PROCEDURE Main()
? "Hello, Five!"
? "Date:", Date()
? "Time:", Time()
RETURN
./five build hello.prg -o hello && ./hello
SQL 예제
// sql_demo.prg
#include "FiveSqlDef.ch"
PROCEDURE Main()
// 테이블 생성
five_SQL("CREATE TABLE employees (id INTEGER, name CHAR(30), salary NUMERIC(12,2))")
// 데이터 삽입
five_SQL("INSERT INTO employees (id, name, salary) VALUES (1, 'Alice', 8000)")
five_SQL("INSERT INTO employees (id, name, salary) VALUES (2, 'Bob', 7000)")
// SQL 쿼리
LOCAL aR := five_SQL("SELECT name, salary FROM employees WHERE salary > 6000 ORDER BY salary DESC")
? "Results:", Len(aR[2]), "rows"
LOCAL i
FOR i := 1 TO Len(aR[2])
? " ", aR[2][i][1], aR[2][i][2]
NEXT
RETURN
./five build sql_demo.prg _FiveSql2/src/*.prg -o sql_demo && ./sql_demo
프로젝트 구조
five/
├── cmd/five/ Five CLI (main entry point)
├── compiler/ PRG → Go 컴파일러
│ ├── lexer/ 토크나이저
│ ├── parser/ 구문 분석기
│ ├── analyzer/ 의미 분석기
│ ├── gengo/ Go 코드 생성기
│ └── pp/ 전처리기 (#include, #define)
├── hbrt/ 런타임 (VM, Stack, Value, Class)
├── hbrtl/ RTL 표준 라이브러리 (479개 함수)
├── hbrdd/ RDD 데이터베이스 엔진
│ ├── dbf/ DBF 파일 드라이버
│ ├── ntx/ NTX 인덱스 드라이버
│ ├── cdx/ CDX 인덱스 드라이버
│ └── mem/ 메모리 RDD
├── _FiveSql2/ SQL:1999 엔진 (PRG)
│ ├── src/ SQL 엔진 소스 (14 파일, 10,458 LOC)
│ └── test/ SQL 테스트 스위트
├── tests/ 호환성 테스트
├── examples/ 예제 프로그램
└── docs/ 기술 문서
현재 상태
| 항목 | 수치 |
|---|---|
| Go 프로덕션 코드 | ~36,000 LOC |
| RTL 내장 함수 | 479개 |
| RDD 드라이버 | 4종 (DBF, NTX, CDX, Memory) |
| FiveSql2 테스트 | 43/43 (100%) |
| 호환 테스트 | 51/51 (100%) |
| Go 테스트 | ALL PASS |
라이선스
Copyright (c) 2025-2026 Charles KWON OhJun (charleskwonohjun@gmail.com) All rights reserved.
Description
Languages
Go
57.9%
xBase
22%
C
19.5%
Shell
0.5%
Makefile
0.1%