Commit a264127
authored
chadscript/postgres: native postgres client via libpq (#512)
* postgres: libpq c bridge (step 1/10)
adds c_bridges/pg-bridge.c with thin wrappers around libpq for connect,
exec, parameterized exec, and result introspection. build-vendor.sh
detects libpq headers (keg-only brew install on darwin, system paths on
linux) and gracefully skips when absent. no codegen or ts wiring yet —
this commit is just the foundation for chadscript/postgres.
* postgres: lib/postgres.ts with Client, extern binding, link wiring (step 2/10)
adds chadscript/postgres module. lib/postgres.ts uses declare function
bindings to cs_pg_* externs — compiler auto-detects the cs_pg_ prefix
in llvm-generator.ts, flips a new usesPostgres flag, and the link step
picks up -lpq plus homebrew keg-only libpq lib path. pg-bridge.o is
included conditionally. Client class exposes connect()/end() — query
comes in step 3.
verified end-to-end: compiled a fixture that connects to a local
podman postgres and cleanly disconnects. the cs_pg_connect extern is
called directly from the TS Client.connect method, no codegen
special-casing required. pattern matches cs_llvm_*/cs_lld_*.
workaround: added trailing return in parser-native transformExpression
for the known checkMissingReturns false-positive
(memory/native-missing-returns-false-positive.md) — the usesPostgres
field addition shifted AST layouts and tripped the bug.
* postgres: .query() returning rowCount + abi fix (step 3/10)
adds Client.query(sql) that returns QueryResult with rowCount for
INSERT/UPDATE/DELETE. test fixture covers single insert, multi-row
insert, update, and delete.
abi fix: c functions called from chadscript as returning 'number' must
return 'double', not 'int' — chadscript maps 'number' to llvm double,
which lives in d0 on arm64 while c int returns come back in w0,
completely different registers. previous step 2 passed by luck because
CONNECTION_OK happens to be 0 and d0 was zero-initialized.
fixed the whole bridge preemptively: all int-returning cs_pg_* now
return double, all int parameters (row, col, nparams) are now double
with internal cast. matches the pattern cs_lld_available uses.
* postgres: SELECT support with Row access (step 4/10)
adds nrows/ncols/fname/getvalue/getisnull extern bindings and SELECT
row access. QueryResult now holds flat { fields, values } plus numRows
/numCols — getValue(row, col) walks the fields[] to resolve a column
name to its offset and returns the string. getRow(idx) constructs a
lightweight Row view for iteration.
flat-storage design avoids chadscript ObjectArray type-loss: storing
Row[] and accessing rows[i].get() inside lib/postgres.ts triggered
compile errors because element access on an object array discards the
concrete type. keeping values as a string[] sidesteps the problem.
test covers 3-row SELECT with column-name lookup, field ordering,
empty result set, and rowCount.
c bridge now gc_strdups all string returns (getvalue, fname, error
messages, cmdtuples) so they survive past cs_pg_clear — previously
those pointers dangled into the freed PGresult.
* postgres: Pool, parameterized queries, typed accessors, docs (steps 5+6/10)
Pool: thin wrapper over Client that lazy-connects on first query. v1
is sequential — real pooling (multiple conns, queuing) needs async and
is a follow-up. matches node-pg's Pool entry point so copy-paste from
tutorials works. Pool is now the documented primary API; Client is
the low-level escape hatch.
Parameterized queries: pool.query(sql, params) uses libpq's PQexecParams
via a stateful param-builder pattern (cs_pg_params_new / _add /
_exec_params_with). avoids marshaling a chadscript string[] across the
ffi boundary — the %StringArray struct layout doesn't match libpq's
const char**. TS passes values one at a time; c side grows its own
dynamic array. placeholders are $1, $2, $3 (postgres native syntax).
libpq handles escaping so user input with quotes or semicolons is safe.
Typed accessors on QueryResult: getInt, getFloat, getBool delegate to
parseInt/parseFloat/string compare — saves users from writing boiler-
plate parsing on every access. no OID-based auto-typing — users know
their schema, they call the right getter. avoids type-coercion surprises.
Docs: new docs/stdlib/postgres.md with Pool-first API, documented
limitations (sync, no null detection, string-only params, no real
pooling). chadscript/postgres added to stdlib module index.
test coverage: postgres-pool (Pool lazy-connect + CRUD),
postgres-params-types (getInt/Float/Bool + parameterized queries +
sql-injection safety with quoted param values).
* postgres: fix stage 2 self-hosting regression via minimal src surface
step 2 added a usesPostgres field to LLVMGenerator plus a cs_pg_ prefix
check in generateExternDeclaration plus a trailing-return workaround in
parser-native/transformer.ts. any of those shifted enough state that the
native stage 1 compiler began miscompiling generateGlobalVariableDeclarations
— storing a pointer into a double slot for isClassInstance. --quick
skipped stage 2 so it passed local verify but failed CI.
fix: do the -lpq/pg-bridge.o detection entirely in compiler.ts and
native-compiler-lib.ts by walking generator.declaredExternFunctions for
anything starting with cs_pg_. no changes to llvm-generator.ts,
generator-context.ts, or parser-native/transformer.ts. feature is
functionally identical end-to-end (verified against local postgres).
npm run verify (full, including stage 2) is green on this commit.
---------
Co-authored-by: cs01 <cs01@users.noreply.github.com>1 parent f02172c commit a264127
File tree
12 files changed
+732
-1
lines changed- c_bridges
- docs/stdlib
- lib
- scripts
- src
- tests/fixtures/stdlib
12 files changed
+732
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
28 | 29 | | |
29 | 30 | | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
0 commit comments