Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
244 commits
Select commit Hold shift + click to select a range
95045d8
Describe QWiP ingress in README.md
mtopolnik Apr 22, 2026
757d111
Egress step 1
mtopolnik Apr 22, 2026
ed47448
Egress step 5
mtopolnik Apr 22, 2026
fd49bdf
Egress step 6
mtopolnik Apr 22, 2026
ee39752
Egress step 7
mtopolnik Apr 22, 2026
d1bd14e
Egress step 8
mtopolnik Apr 22, 2026
2037a94
Egress step 9 -- plan complete
mtopolnik Apr 23, 2026
8b64fed
Drain dispatcher when Query/Exec ctx expires mid-wait
mtopolnik Apr 23, 2026
b01179b
Make QWP egress writes participate in shutdown
mtopolnik Apr 23, 2026
2ff39e7
Release batch buffer and drain on yield-body panic
mtopolnik Apr 23, 2026
349b7b1
Clarify a comment
mtopolnik Apr 23, 2026
58e1915
Fix data race on decimal scale and geohash precision
mtopolnik Apr 23, 2026
200e60d
Fix QwpQuery.Close racing an in-flight Batches iterator
mtopolnik Apr 23, 2026
ceb9ea0
Poison QWP egress on decoder errors so reuse is safe
mtopolnik Apr 23, 2026
68262c7
Close test coverage gaps flagged in egress review
mtopolnik Apr 23, 2026
1208ce7
Speed up Float64Array/Int64Array with memmove
mtopolnik Apr 23, 2026
17439b0
Speed up Gorilla bit reader with 8-byte LE refills
mtopolnik Apr 23, 2026
ffe170e
Inline varint fast path in symbol-id and delta-entry loops
mtopolnik Apr 23, 2026
342b38e
Fix flaky timing-sensitive test
mtopolnik Apr 23, 2026
28c9fe9
Speed up null-bitmap decoding by iterating bytes
mtopolnik Apr 23, 2026
85af5aa
Preallocate layouts slice instead of append-grow loop
mtopolnik Apr 23, 2026
1ba4c74
Add QwpColumn handle and bulk Range accessors
mtopolnik Apr 23, 2026
3c46795
Remove dead id64 < 0 branches after readVarintInt63
mtopolnik Apr 23, 2026
ac9e18e
Return decode error on Gorilla overrun
mtopolnik Apr 23, 2026
63fba4e
Add typed bind parameters to QWP query client
mtopolnik Apr 23, 2026
fa80a03
Handle server-emitted CACHE_RESET (0x17) frames
mtopolnik Apr 24, 2026
1c5e454
Cut three hot-path costs in QWP query decoder
mtopolnik Apr 24, 2026
f819d90
Address IntelliJ inspections
mtopolnik Apr 24, 2026
c84b5ec
Fix bit-order comment
mtopolnik Apr 24, 2026
c709766
More robust query cancelling
mtopolnik Apr 24, 2026
9cff988
Reject nDims=0 arrays on the QWP wire
mtopolnik Apr 24, 2026
cc0925a
Validate VARCHAR offsets on QWP decode
mtopolnik Apr 24, 2026
4282f3f
Fix test issues
mtopolnik Apr 24, 2026
b23c00e
Fix submit/shutdown race
mtopolnik Apr 24, 2026
ab94205
Seed Gorilla decode bench with real first two timestamps
mtopolnik Apr 24, 2026
fcd1d28
Match Range OOB test wire types to accessor widths
mtopolnik Apr 24, 2026
d97023f
Touch up comment
mtopolnik Apr 24, 2026
ef6e46a
Drop dead errors.As probe in decode-error helper
mtopolnik Apr 24, 2026
a12946b
Supply missing args to Eventually failure message
mtopolnik Apr 24, 2026
7fe23e6
Add QWP query example: insert 1000 rows, sum locally
mtopolnik Apr 27, 2026
ce40eaa
Add querying section to README
mtopolnik Apr 27, 2026
5032a80
Update ACK decoding
mtopolnik Apr 27, 2026
a2e2ecc
Port Java benchmarks
mtopolnik Apr 27, 2026
002cbe1
Address CodeRabbit review
mtopolnik Apr 28, 2026
4c9dbf6
Harden QWP query decode and bind paths
mtopolnik Apr 30, 2026
6ba6e1e
Port four Java QWP test contracts to Go
mtopolnik Apr 30, 2026
1fe270b
Address QWP coverage gaps and wire-format bugs
mtopolnik Apr 30, 2026
6c05deb
Address QWP egress review nits
mtopolnik Apr 30, 2026
16af461
Add QWP v2 multi-endpoint failover and SERVER_INFO
mtopolnik Apr 30, 2026
8131f73
Fix computeBackoff returning max when initial is zero
mtopolnik May 5, 2026
eac6883
Latch ioErr on every QWP transport-class fault
mtopolnik May 5, 2026
08a2e91
Skip just-failed endpoint on QWP query reconnect
mtopolnik May 5, 2026
ff0f803
Preserve typed errors on QWP failover-time faults
mtopolnik May 5, 2026
6ee305c
Expose SawV1Mismatch on QwpRoleMismatchError
mtopolnik May 5, 2026
d3986a6
Preserve transport error on QwpRoleMismatchError
mtopolnik May 5, 2026
a5bcc40
Reject zero qwp query server_info_timeout
mtopolnik May 5, 2026
7f210d6
Honour Cancel mid-walk in QWP failover reconnect
mtopolnik May 5, 2026
0498f66
Wake QWP backoff sleep on Cancel via channel
mtopolnik May 5, 2026
b162676
Surface QWP failover exhaustion as typed error
mtopolnik May 5, 2026
c988497
Cap QWP bind parameters at the spec value of 1024
mtopolnik May 5, 2026
4fdf0d6
Preflight QWP query SQL text against spec 1 MiB cap
mtopolnik May 5, 2026
8debd5a
Enforce QWP spec frame size and version checks
mtopolnik May 5, 2026
0bba9fc
Enforce QWP spec table_count on inbound frames
mtopolnik May 5, 2026
3e9eaef
Group QWP connect test with integration tests
mtopolnik May 5, 2026
994df3c
Rename QWP query example dir to basic-query
mtopolnik May 5, 2026
3c47c55
Skip protocol auto-detect in tight-timeout retry tests
mtopolnik May 5, 2026
6eedac1
Expose max_name_len in config string
mtopolnik May 6, 2026
4dae562
SaF Phase 1
mtopolnik Apr 28, 2026
9f60dcb
SaF Phase 2
mtopolnik Apr 29, 2026
e652832
S&F complete
mtopolnik Apr 28, 2026
c5ef120
Add CI check guarding against binaries in PR
mtopolnik Apr 29, 2026
fd2f313
Fix orphan-goroutine race in cursor flush
mtopolnik Apr 29, 2026
440edd7
Fix orphan-drainer goroutine + active-list leaks on pool close
mtopolnik Apr 29, 2026
49efc52
Fix send-loop ACK race and add protocol-mismatch fast-fail
mtopolnik Apr 29, 2026
7914efb
Decode QWP ACKs with per-table watermark trailer
mtopolnik Apr 29, 2026
6e5b96c
Surface close drain errors; harden QWP recovery
mtopolnik Apr 29, 2026
419add9
Add typed SenderError surface for QWP cursor SF
mtopolnik Apr 30, 2026
aec4850
Report raw wire seq on QWP rejection SenderError
mtopolnik Apr 30, 2026
4ed452e
Guard cursor walk against corrupt segment frames
mtopolnik May 6, 2026
d3a9744
Fix QWP build errors from egress rebase
mtopolnik May 6, 2026
c8d42b4
Reject duplicate keys in config string parser
mtopolnik May 6, 2026
5a6fc9b
Document OVERLAPPED lifetime in Windows flock
mtopolnik May 6, 2026
7c0f903
Split slot-lock PID into .lock.pid sidecar
mtopolnik May 6, 2026
f97026e
Pass endpointPath in SF test dial helpers
mtopolnik May 6, 2026
87515a8
Accept sync alias and async mode for initial_connect_retry
mtopolnik May 6, 2026
9b46945
Fix three pre-existing test failures on dev machines
mtopolnik May 6, 2026
8ac0e0f
Expose spec §20 observability counters on QwpSender
mtopolnik May 6, 2026
70329ad
Enrich SF backpressure error with reconnect state
mtopolnik May 6, 2026
827b4b1
Failover spec, Phase 1
mtopolnik May 11, 2026
09b351b
Failover spec, Phase 2
mtopolnik May 11, 2026
b75c6bc
Failover spec, Phase 3
mtopolnik May 11, 2026
8407c77
Failover spec, Phase 4
mtopolnik May 11, 2026
232080b
Failover spec, Phase 5
mtopolnik May 11, 2026
50670c4
Failover spec, Phase 6
mtopolnik May 11, 2026
9aa0420
Support v2 server capabilities
mtopolnik May 11, 2026
853e24a
Fix formatting
mtopolnik May 11, 2026
852d302
Fix comments
mtopolnik May 11, 2026
a907d56
Try all hosts on initial connect
mtopolnik May 12, 2026
2909958
Rewrite CLAUDE.md
mtopolnik May 14, 2026
8ced1fa
Replace AwaitAckedFsn timeout with context
mtopolnik May 14, 2026
295b375
Pre-allocate disk blocks for SF segment files
mtopolnik May 14, 2026
568a382
Fix dispatcher race losing terminal notifications
mtopolnik May 14, 2026
08bd80a
Latch terminal error before handler dispatch
mtopolnik May 14, 2026
b6f9908
Honor drain timeout in dispatcher close
mtopolnik May 14, 2026
067f436
Drop oldest on dispatcher inbox overflow
mtopolnik May 14, 2026
d36d36b
Surface terminal HALT from Table() entry
mtopolnik May 15, 2026
67158f8
Pin QWP ingress to v1 in version negotiation
mtopolnik May 15, 2026
b8a087a
Drop dead v2 branch from SF round-walk
mtopolnik May 15, 2026
aa6e057
Apply full-jitter to egress failover backoff
mtopolnik May 15, 2026
976a528
Guard cursor walk against corrupt payloadLen
mtopolnik May 15, 2026
2f58e2c
Fix data race in SF manager trim test
mtopolnik May 15, 2026
e101f41
Honour and persist QWP SF .ack-watermark
mtopolnik May 15, 2026
69084bd
Recognise durable-ack connect-string keys
mtopolnik May 15, 2026
d5ce0bc
Return (maxGen, found) from SF generation scan
mtopolnik May 15, 2026
1a84f48
Make CI Go-version matrix actually test 1.23
mtopolnik May 15, 2026
74fdc5e
Fix README drift: Go version, QWP errors, failover
mtopolnik May 15, 2026
b823d70
Emit valid geohash precision on all-null columns
mtopolnik May 15, 2026
a2cd7fd
Fix QWP send-loop spin, Close race, timer leaks
mtopolnik May 15, 2026
19163b8
Add QWP example and manifest entries for docs
mtopolnik May 15, 2026
cba5097
Add failover_max_duration_ms to QWP query client
mtopolnik May 15, 2026
82f9ab3
egress benchmarks
mtopolnik May 18, 2026
a2dbb04
Fix frame buffer GC
mtopolnik May 18, 2026
1b47a3d
Add egress-read tuning knobs and batches/op metric
mtopolnik May 18, 2026
efbc446
Add /review-pr skill
mtopolnik May 18, 2026
84fb309
Retain pending rows when flush/close append fails
mtopolnik May 18, 2026
4bca3f7
Don't replay non-idempotent Exec on conn drop
mtopolnik May 18, 2026
defbd62
Fix goroutine+conn leak on Close vs failover race
mtopolnik May 18, 2026
540f046
Fix self-join deadlock when handler calls Close
mtopolnik May 18, 2026
3462508
Cap inbound WebSocket frame size to prevent OOM
mtopolnik May 18, 2026
df479cd
Fix orphan drainer livelock on non-acking server
mtopolnik May 18, 2026
29a6f12
Drop Flush() ACK barrier on QWP cursor path
mtopolnik May 18, 2026
a0fcd61
Add deprecated QwpError compatibility shim
mtopolnik May 18, 2026
9b34c21
Close QWP test coverage gaps
mtopolnik May 18, 2026
f3f1dfd
Add gap-free replay test with payload recording
mtopolnik May 18, 2026
081f5f0
Align QWP decoder lower bounds with Java reference
mtopolnik May 18, 2026
6cb8e19
Add With* options for QWP connect-string keys
mtopolnik May 18, 2026
1ab491a
Fix flaky OnParseErrorDrop server-error assertion
mtopolnik May 18, 2026
179c11a
Emit throttled WARN when SF segment cap is full
mtopolnik May 18, 2026
02a21ce
Fix bench go.mod drift and gate it in CI
mtopolnik May 18, 2026
3a6537d
Drive QWP query failover through the host tracker
mtopolnik May 18, 2026
6addc8e
Poll for async delivery in SF walk-to-healthy test
mtopolnik May 18, 2026
1bfcf6f
Drop duplicate BenchmarkQwpEgressRead go-test
mtopolnik May 19, 2026
2bed17e
Add CI workflow to fuzz QWP against QuestDB
mtopolnik May 19, 2026
0b2d9ce
Add QWP fuzz suite: server fixture + two ports
mtopolnik May 19, 2026
f0d618b
Suppress U1000 on unused QWP fuzz fixture helpers
mtopolnik May 19, 2026
351e0a7
Fix QWP egress DATE decode framing
mtopolnik May 19, 2026
81dca57
Add Go port of QwpEgressFuzzTest
mtopolnik May 19, 2026
d3679ab
Fix stale dropAllTables suppression rationale
mtopolnik May 19, 2026
134d496
Add Go port of QwpIngressOracleFuzzTest slice
mtopolnik May 19, 2026
8d00d6b
Add QWP ingress-oracle bounce-torture fuzz test
mtopolnik May 19, 2026
dfd5105
Add QWP ingress-oracle poison-rows fuzz test
mtopolnik May 19, 2026
69a7141
Add QWP ingress-oracle restart-replay fuzz test
mtopolnik May 20, 2026
3cf0399
Add async-connect fuzz test + fixture pause
mtopolnik May 20, 2026
bff37e7
Add QWP sender fuzz test runner (testLoad slice)
mtopolnik May 20, 2026
93c6b5b
Make QWP column buffer dedup case-insensitive
mtopolnik May 20, 2026
bdf0a69
Add QWP sender fuzz S2 mechanics + 13 entry-point tests
mtopolnik May 20, 2026
74b42cb
Add QWP sender fuzz S3 ALTER thread + 12 entry-point tests
mtopolnik May 20, 2026
7a1ed7b
Port QwpIngressServerRestartFuzzTest to Go (all 5 methods)
mtopolnik May 20, 2026
eacb90a
Add sidecar fixture + QWP sender LoadSmallBuffer fuzz test
mtopolnik May 20, 2026
a9d937b
Port QwpEgressFragmentationFuzzTest to Go (all 4 methods)
mtopolnik May 20, 2026
d041cea
Route QWP integration tests through the fuzz fixture
mtopolnik May 20, 2026
740b72e
Rewire TestQwpSenderIntegration + rename helper to qwpEnsureServer
mtopolnik May 20, 2026
aa5226e
Add two failover-stickiness tests to the SF round-walk suite
mtopolnik May 20, 2026
e2638d3
Tighten low-severity fuzz-test review nits
mtopolnik May 20, 2026
7fd4486
Pin reject-host hit count in stickiness test
mtopolnik May 20, 2026
210ec4b
Make WS connect failures fatal in QWP integ tests
mtopolnik May 20, 2026
ee930b9
Guarantee fuzz ALTER loop runs at least once
mtopolnik May 20, 2026
d658487
Fail-fast on missing mandatory fuzz-assert columns
mtopolnik May 20, 2026
f36ea1b
Call qwpEnsureServer before qwpDropTable in tests
mtopolnik May 20, 2026
1b03240
Surface execSQL errors from fuzz poll helpers
mtopolnik May 20, 2026
2399a94
Add val=id*1.5 invariant to restart-fuzz tests
mtopolnik May 20, 2026
5099040
Fail-fast on non-numeric distinct-id cells
mtopolnik May 20, 2026
c54d85c
Pin category/policy in poison-handler fuzz test
mtopolnik May 20, 2026
50cbc2f
Tighten auth-timeout bound to a two-sided assertion
mtopolnik May 20, 2026
4b1aa82
Assert SF segments survive paused-server close
mtopolnik May 20, 2026
3cfb947
Use SIGKILL to leave unacked frames in restart-fuzz
mtopolnik May 20, 2026
e55a6b7
Assert >=2 retry attempts in async-connect fuzz
mtopolnik May 20, 2026
958163a
Promote initial_connect_retry on reconnect_* tune
mtopolnik May 21, 2026
7c5506b
Fix connect-string parser/spec discrepancies
mtopolnik May 21, 2026
5bbb92c
Reject retry_timeout on QWP; remove dead plumbing
mtopolnik May 21, 2026
e74f8ad
Drop close_timeout; document Java-parity QWP knobs
mtopolnik May 21, 2026
229ac3e
Drop schema-ID tracking; remove max_schemas knob
mtopolnik May 25, 2026
c8cd51d
Enforce X-QWP-Max-Batch-Size auto-flush clamp
mtopolnik May 25, 2026
00569bf
Add hard guards for server batch-size cap
mtopolnik May 25, 2026
060bddd
Fix CopyAll aliasing recycled WS frame buffer
mtopolnik May 26, 2026
29716f0
Reject non-HTTP schemas in LineSenderPool
mtopolnik May 26, 2026
bee781c
Fix AwaitAckedFsn Godoc on Flush ACK semantics
mtopolnik May 26, 2026
e6085d2
Fix fabricated DROP on QWP pre-send rejection
mtopolnik May 26, 2026
4c4c533
Unblock AwaitAckedFsn on concurrent Close
mtopolnik May 26, 2026
433a5e0
Validate WithSenderId charset to block path traversal
mtopolnik May 26, 2026
73e5056
Clear cachedDesignatedTs on cancelRow paths
mtopolnik May 26, 2026
3394437
Gate silent-drop guard on lifetime ACK history
mtopolnik May 26, 2026
de0f5a3
Fix per-row guard false reject on mid-row cap flip
mtopolnik May 26, 2026
dd5a02e
Surface latched fluent error on QWP Close
mtopolnik May 26, 2026
9adde39
Cancel mid-row on unknown designated-TS typeCode
mtopolnik May 26, 2026
903d8dc
Cancel via session in Exec for failover safety
mtopolnik May 26, 2026
5cd9dde
Skip tracker demote on ctx-cancelled QWP dial
mtopolnik May 26, 2026
0dac215
Re-issue cancel after QWP replay handoff
mtopolnik May 26, 2026
c91656c
Reset per-cat flag when WithErrorPolicy nets Auto
mtopolnik May 26, 2026
9982bc5
Align SF ingress with zone-blind spec
mtopolnik May 26, 2026
58d7307
Reject QWP-only options on HTTP/TCP sanitizers
mtopolnik May 26, 2026
74f442e
Skip *Set on zero/negative WithReconnectPolicy args
mtopolnik May 26, 2026
7d6b0b4
Treat sub-ms WithCloseTimeout as no-override
mtopolnik May 26, 2026
3da510c
Trim whitespace-only zone= as unset in host tracker
mtopolnik May 26, 2026
e401851
Document inode-bound flock hole in SF slot lock
mtopolnik May 26, 2026
4cf3686
add Enterprise e2e integration test infrastructure
ideoma May 26, 2026
7f8f526
add enterprise e2e dispatch to build workflow
ideoma May 27, 2026
f4745ac
move enterprise e2e dispatch to run in parallel with tests
ideoma May 27, 2026
b2e7ded
Surface ADO response body on enterprise e2e dispatch failure
mtopolnik May 28, 2026
13ca756
Drop empty template params from enterprise e2e dispatch body
mtopolnik May 28, 2026
f01c05a
Warm up totalAcks before closeAfterFrames drop
mtopolnik May 28, 2026
3a1cce0
Cap SF frame payloadLen at MaxInt32 on write
mtopolnik May 26, 2026
0f4b902
Stop special-casing max_schemas_per_connection
mtopolnik Jun 3, 2026
27c0802
Remove QWP schema references and protocol v2
mtopolnik Jun 3, 2026
1d31a77
Fix silent row loss on QWP SF reconnect race
mtopolnik Jun 9, 2026
d728423
Fix qwp-fuzz server build for SNAPSHOT client dep
mtopolnik Jun 10, 2026
def2292
Honor failover config in QWP memory mode
mtopolnik Jun 11, 2026
c592f5d
Fix docs teaching dropped Flush-ACK barrier
mtopolnik Jun 12, 2026
55e5f22
Require repeated silent drops before QWP SF HALT
mtopolnik Jun 12, 2026
a4d2019
Fix QWP cursor wedge on over-segment flush
mtopolnik Jun 11, 2026
274fc7a
Fix QWP sender crash on Close from error handler
mtopolnik Jun 12, 2026
3e6c2af
Fix QWP decoder OOM on cell-count amplification
mtopolnik Jun 12, 2026
fa4f66a
Fix QWP egress Close data race on transport conn
mtopolnik Jun 12, 2026
fd5ea8e
Split QWP over-cap flush per table
mtopolnik Jun 12, 2026
c7c2978
Fix QWP host crash on panicking policy resolver
mtopolnik Jun 12, 2026
0a99dd2
Fix QWP Flush double-write on post-enqueue HALT
mtopolnik Jun 12, 2026
028c9df
Fix QWP ingest connect/close storm on target!=any
mtopolnik Jun 12, 2026
d11ba9a
Remove stale QWP v1/v2 wire-version framing from comments
mtopolnik Jun 12, 2026
d9ee1ff
Document QWP SERVER_INFO as egress-only; pin it with a test
mtopolnik Jun 12, 2026
37b93cb
Fix QWP SF ACK clamp covering in-flight frame
mtopolnik Jun 12, 2026
5927bdc
Fix QWP conn + goroutine leak on upgrade reject
mtopolnik Jun 12, 2026
cc5ff03
Cut idle CPU in QWP send loop and SF manager
mtopolnik Jun 12, 2026
8d1ea04
Fix QWP dump-mode ACK race via write buffer
mtopolnik Jun 12, 2026
5b30334
Fix QWP mixed-case column lookup allocations
mtopolnik Jun 12, 2026
aa5f329
Bound QWP SF dispatcher and drainer close waits
mtopolnik Jun 12, 2026
1ce24e2
Settle QWP public API surface before tagging
mtopolnik Jun 12, 2026
0a3ee47
Close QWP test-infrastructure gaps (M14)
mtopolnik Jun 12, 2026
eb1dc5f
Fix misleading QWP symbol-dict and SF-path docs
mtopolnik Jun 12, 2026
e0ffd65
Fix QWP ACK seq, ring wakeup, and await poll
mtopolnik Jun 12, 2026
8bb3aef
Guard QWP bulk accessors; close M20 test gaps
mtopolnik Jun 12, 2026
ef6ca50
Fix QWP transport, egress, and framing gaps
mtopolnik Jun 12, 2026
1ca2fa5
Optimize QWP flush + arrays, fix watermark + tests
mtopolnik Jun 12, 2026
5a7189a
Re-tidy replace-linked modules after dep bump
mtopolnik Jun 12, 2026
67be8eb
Fix stranded QWP ACK for quiescent last frame
mtopolnik Jun 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
340 changes: 340 additions & 0 deletions .claude/skills/review-pr/SKILL.md

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions .github/workflows/binary-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Binary check

on:
pull_request:
push:
branches:
- main

jobs:
reject-binaries:
name: Reject committed executables
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Scan for executable binaries
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "pull_request" ]; then
base="${{ github.event.pull_request.base.sha }}"
head="${{ github.event.pull_request.head.sha }}"
list_cmd=(git diff --name-only --diff-filter=AMRC "$base...$head")
scope="PR diff ($base..$head)"
else
list_cmd=(git ls-files)
scope="full tree"
fi
count=0
violations=()
while IFS= read -r f; do
count=$((count + 1))
[ -f "$f" ] || continue
mime=$(file --brief --mime-type -- "$f" 2>/dev/null || true)
case "$mime" in
*application/x-mach-binary*|\
*application/x-executable*|\
*application/x-pie-executable*|\
*application/x-sharedlib*|\
*application/x-dosexec*)
summary=$(printf '%s\n' "$mime" | head -n1)
violations+=("$f — $summary")
;;
esac
done < <("${list_cmd[@]}")
echo "Scanned $scope: $count file(s)"
if [ ${#violations[@]} -gt 0 ]; then
echo "::error::Committed executable binaries detected:"
for v in "${violations[@]}"; do
echo " - $v"
done
echo
echo "Build artifacts must not be committed. For example dirs, use"
echo "'go run .' (no artifact) or 'go install' with GOBIN pointing"
echo "at a gitignored directory."
exit 1
fi
echo "OK: no committed executables."
131 changes: 130 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,88 @@ name: build
on: [push]

jobs:
# Cross-repo trigger: fire the questdb-enterprise
# build-and-test-e2e-go-client pipeline with this build's SHA so
# the go_client-marked failover tests run against an Enterprise
# primary. The Enterprise pipeline posts a status check back on the
# PR (`enterprise-e2e-go-client` context); this job fire-and-forgets.
dispatch-enterprise-e2e:
runs-on: ubuntu-latest
if: ${{ !github.event.repository.fork }}
steps:
- name: Queue enterprise go_client e2e
env:
ENT_DISPATCH_PAT: ${{ secrets.ENT_DISPATCH_PAT }}
ENT_ORG_URL: ${{ secrets.ENT_ORG_URL }}
run: |
set -euo pipefail

if [ -z "${ENT_DISPATCH_PAT:-}" ] || [ -z "${ENT_ORG_URL:-}" ]; then
echo "ENT_DISPATCH_PAT or ENT_ORG_URL not set; skipping enterprise e2e dispatch."
exit 0
fi

PROJECT="questdb-enterprise"
PIPELINE_NAME="build-and-test-e2e-go-client"

echo "Looking up '${PIPELINE_NAME}' in '${PROJECT}'..."
PIPELINES=$(curl -fsS -u ":${ENT_DISPATCH_PAT}" \
"${ENT_ORG_URL}${PROJECT}/_apis/pipelines?api-version=7.0")
PIPELINE_ID=$(echo "$PIPELINES" | jq -r --arg n "$PIPELINE_NAME" \
'.value[] | select(.name == $n) | .id' | head -1)

if [ -z "$PIPELINE_ID" ] || [ "$PIPELINE_ID" = "null" ]; then
echo "Pipeline '${PIPELINE_NAME}' not found in '${PROJECT}'; skipping."
exit 0
fi

CLIENT_BRANCH="${GITHUB_REF_NAME}"
CLIENT_PR_NUMBER=""

# Azure DevOps rejects empty-string template parameters with
# "The 'X' parameter is not a valid String." even when the
# pipeline YAML declares `type: string, default: ''`. Omitting
# the key entirely lets the YAML default kick in; the
# enterprise pipeline already handles empty goClientPrNumber
# by skipping the GitHub PR status post.
BODY=$(jq -n \
--arg commit "${GITHUB_SHA}" \
--arg pr "${CLIENT_PR_NUMBER}" \
--arg branch "${CLIENT_BRANCH}" \
'{
templateParameters: ({
goClientCommit: $commit,
goClientPrNumber: $pr,
clientBranch: $branch
} | with_entries(select(.value != ""))),
resources: { repositories: { self: { refName: "refs/heads/main" } } }
}')

echo "Dispatching enterprise e2e: commit=${GITHUB_SHA} branch=${CLIENT_BRANCH}"

# Capture status and body separately so we can surface Azure
# DevOps's error message on 4xx. With -fsS the body is dropped
# and only "curl: (22) ... error: 400" reaches the log, which
# is useless for diagnosing parameter / YAML mismatches.
RESPONSE_FILE=$(mktemp)
HTTP_STATUS=$(curl -sS -u ":${ENT_DISPATCH_PAT}" \
-H "Content-Type: application/json" \
-X POST \
-d "$BODY" \
-o "$RESPONSE_FILE" \
-w '%{http_code}' \
"${ENT_ORG_URL}${PROJECT}/_apis/pipelines/${PIPELINE_ID}/runs?api-version=7.0")

if [ "$HTTP_STATUS" -lt 200 ] || [ "$HTTP_STATUS" -ge 300 ]; then
echo "Dispatch failed with HTTP ${HTTP_STATUS}. Response body:"
cat "$RESPONSE_FILE"
echo ""
exit 1
fi

RUN_URL=$(jq -r '._links.web.href // ""' "$RESPONSE_FILE")
echo "Enterprise build queued: ${RUN_URL}"

test:
runs-on: ubuntu-latest
strategy:
Expand All @@ -21,10 +103,57 @@ jobs:
cache: true

- name: Run vet
# Pin to the matrix-installed Go. Without this, a stray
# `toolchain` line re-added to go.mod by `go mod tidy` on a
# newer box would silently switch this job off the matrix
# version; `local` makes that fail loudly instead.
env:
GOTOOLCHAIN: local
run: go vet ./...

- name: Run Staticcheck
run: go run honnef.co/go/tools/cmd/staticcheck@v0.7.0 ./...

- name: Build bench modules
# bench/* are separate Go modules with their own go.mod, so
# the root `go vet`/`go test ./...` above never touches them.
# Project convention is that bench/ builds. `go mod tidy
# -diff` fails (with an actionable diff) on go.mod/go.sum
# drift — e.g. an indirect dep pulled transitively from the
# root via `replace => ../..` but missing from the bench
# go.mod; `go build ./...` then proves they compile. The loop
# globs bench/*/go.mod so new bench modules are auto-gated.
# GOTOOLCHAIN=local pins to the matrix Go (see "Run vet"); the
# bench go.mod `go` directive is 1.23, satisfied by both
# matrix versions.
env:
GOTOOLCHAIN: local
run: |
set -euo pipefail
for mod in bench/*/go.mod; do
dir=$(dirname "$mod")
echo "::group::$dir"
( cd "$dir" && go mod tidy -diff && go build ./... )
echo "::endgroup::"
done

- name: Run zero-alloc invariant (non-race)
# The QWP hot-path 0-allocs/op pins (the Test*ZeroAllocs cases in
# qwp_bench_test.go) self-skip under -race: race instrumentation
# forces stack-allocatable values to escape and inflates
# allocs/op. The "Run tests" step below is -race only, so without
# this dedicated non-race run the headline allocation-free
# guarantee would never actually be exercised in CI. Cheap — a
# handful of testing.AllocsPerRun loops, no network or Docker.
# GOTOOLCHAIN=local pins to the matrix Go (see "Run vet").
env:
GOTOOLCHAIN: local
run: go test -run ZeroAllocs -count=1 .

- name: Run tests
run: go test -v ./...
# Pin to the matrix-installed Go (see "Run vet"). The
# Staticcheck step deliberately omits this: staticcheck@v0.7.0
# needs go1.25 to build and must stay on GOTOOLCHAIN=auto.
env:
GOTOOLCHAIN: local
run: go test -race -v ./...
127 changes: 127 additions & 0 deletions .github/workflows/qwp-fuzz.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Builds QuestDB from source and runs the Go QWP fuzz suite against it.
#
# Modelled on c-questdb-client's ci/run_fuzz_pipeline.yaml (clone questdb,
# build with Maven, point the test fixture at the built repo). The fixture
# (qwp_fuzz_fixture_test.go) then launches the SNAPSHOT jar exactly as
# system_test/fixture.py does.
#
# This job MUST actually build, start the server, and run the fuzz tests —
# never silently skip. Two guards enforce that:
# * QDB_FUZZ_STRICT=1 turns an unresolved/unstartable server from a
# green t.Skip into a red t.Fatal (see fuzzStrict in the fixture).
# * the explicit "Verify QuestDB jar" step fails the job with an
# actionable message if the build produced no server jar.
# The regular build.yml workflow is unaffected: it sets neither QDB_REPO
# nor QDB_FUZZ_STRICT, so the fuzz tests skip cleanly there.
#
# Runs on every pull request (and on demand). The QuestDB build plus
# first-time dependency download takes a few minutes; the ~/.m2 cache
# below keeps repeat runs short.
name: qwp-fuzz

on:
workflow_dispatch:
pull_request:

jobs:
qwp-fuzz:
name: QWP fuzz vs QuestDB master
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout go-questdb-client
uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Go
uses: actions/setup-go@v5
with:
go-version: "1.24.x"
cache: true

# QuestDB's maven-enforcer-plugin pins java.enforce.version=25
# (core/pom.xml); building with anything else fails the build.
# c-questdb-client uses JDK 25 for the same reason.
- name: Install JDK 25
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "25"

- name: Clone QuestDB
# Shallow clone of master. The C submodules ship prebuilt, so no
# blanket submodule init is needed; the java-questdb-client
# submodule is fetched on demand by the detect step below.
run: git clone --depth 1 https://github.com/questdb/questdb.git

- name: Detect local client profile
# core/pom.xml has a test-scoped dependency on
# org.questdb:questdb-client, and `package -DskipTests` still
# compiles tests, so Maven must resolve it. A release version
# resolves from Maven Central; a -SNAPSHOT version (server and
# client evolving in lockstep) exists only as the
# java-questdb-client submodule, built in-reactor via the
# local-client profile. Mirrors the server repo's
# .github/actions/detect-local-client composite action.
id: client
run: |
set -euo pipefail
version="$(sed -n 's/.*<questdb.client.version>\(.*\)<\/questdb.client.version>.*/\1/p' questdb/core/pom.xml | head -1)"
echo "questdb.client.version=${version:-<not found>}"
if [[ "$version" == *-SNAPSHOT ]]; then
echo "SNAPSHOT client version — building the java-questdb-client submodule via -Plocal-client"
git -C questdb submodule update --init java-questdb-client
echo "client_profile=-Plocal-client" >> "$GITHUB_OUTPUT"
else
echo "Release client version — resolving from Maven Central"
echo "client_profile=" >> "$GITHUB_OUTPUT"
fi

# QuestDB pulls a large, slow-moving dependency set; cache ~/.m2 so
# repeat runs skip the multi-minute first-time download. Key
# rotates when this workflow changes.
- name: Cache Maven repository
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: m2-questdb-${{ runner.os }}-${{ hashFiles('.github/workflows/qwp-fuzz.yml') }}
restore-keys: |
m2-questdb-${{ runner.os }}-

- name: Build QuestDB server jar
# Minimal, verified build: produces core/target/questdb-
# <ver>-SNAPSHOT.jar + core/target/classes/.../site/conf in ~30s
# (warm .m2). With local-client active, -am additionally builds
# the java-questdb-client module ahead of core (~10s). No
# -Pbuild-web-console: the embedded console UI is irrelevant to
# QWP / /exec / /ping, and skipping it removes the Node-download
# failure surface. JAVA_HOME is exported by setup-java; the
# enforcer verifies it is JDK 25.
run: mvn -B -ntp -DskipTests -pl core -am package -f questdb/pom.xml ${{ steps.client.outputs.client_profile }}

- name: Verify QuestDB jar exists
# Defense in depth: if Maven "succeeded" but emitted no server
# jar (wrong module, layout change), fail HERE with a precise
# message instead of letting the fuzz step skip/fatal opaquely.
run: |
set -euo pipefail
jar="$(ls questdb/core/target/questdb-*-SNAPSHOT.jar 2>/dev/null \
| grep -v -- '-tests.jar' | head -n1 || true)"
if [ -z "$jar" ]; then
echo "::error::No QuestDB server jar under questdb/core/target — the build did not produce it."
ls -la questdb/core/target/ || true
exit 1
fi
echo "Found server jar: $jar"

- name: Run QWP fuzz + integration tests
env:
GOTOOLCHAIN: local
QDB_REPO: ${{ github.workspace }}/questdb
# Make a missing/unstartable server a hard failure, not a skip.
# Applies to both ^TestQwpFuzz and ^TestQwpIntegration: the
# integration suite now boots the same shared fuzz fixture
# instead of probing an absent localhost:9000 server.
QDB_FUZZ_STRICT: "1"
run: go test -count=1 -timeout 30m -run '^TestQwp(Fuzz|Integration)' -v .
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,28 @@
# Test binary, built with `go test -c`
*.test

# Go build artifacts from the `package main` dirs (each `go build`
# produces a binary named after its directory). binary-check.yml is the
# CI backstop; these keep `git status` clean locally.
/bench/qwp-egress-read/qwp-egress-read
/bench/qwp-egress-read-wide/qwp-egress-read-wide
/examples/from-conf/from-conf
/examples/tcp/basic/basic
/examples/tcp/auth/auth
/examples/tcp/auth-and-tls/auth-and-tls
/examples/http/basic/basic
/examples/http/auth/auth
/examples/http/auth-and-tls/auth-and-tls
/examples/qwp/basic/basic
/examples/qwp/basic-query/basic-query
/examples/qwp/sf/sf
/system_test/enterprise_e2e/sidecar/sidecar

# Python caches from the system_test/enterprise_e2e fixtures
__pycache__/
.pytest_cache/
.venv/

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

Expand Down
Loading
Loading