Skip to content

refactor(server): drop duckdb-go from conn.go via DuckDBAppender hook#496

Merged
fuziontech merged 1 commit intomainfrom
feature/conn-appender-hook
May 1, 2026
Merged

refactor(server): drop duckdb-go from conn.go via DuckDBAppender hook#496
fuziontech merged 1 commit intomainfrom
feature/conn-appender-hook

Conversation

@fuziontech
Copy link
Copy Markdown
Member

Summary

server/conn.go's appendWithDuckDBAppender was the last block of duckdb-go references in conn.go — the COPY FROM bulk-insert path that uses the duckdb Appender API. This PR factors it out the same way PR #482 split AppendValue: server holds the registration hook, duckdbservice's init() registers the real implementation.

Changes

  • server/duckdb_appender.go (new): DuckDBAppendFunc type + RegisterDuckDBAppender + a thin (*clientConn).appendWithDuckDBAppender that dispatches to the registered implementation. Returns a sentinel errDuckDBAppenderUnavailable when nothing is registered, so callers can fall back to batchInsertRows.
  • duckdbservice/duckdb_appender.go (new): the real implementation. Registers in init() so any binary that links duckdbservice gets full Appender support. Mirrors the logic that previously lived inline in conn.go (Rawdriver.Connduckdb.NewAppender* → AppendRow loop).
  • server/conn.go: the inline implementation is removed; the unused "database/sql/driver" and "github.com/duckdb/duckdb-go/v2" imports are dropped.

After this PR

grep duckdb server/conn.go    # only an arrowmap import + SQL strings, no duckdb-go imports

The whole server package still links duckdb-go via server.go, querylog.go, and checkpoint.go, but conn.go itself is fully clean. Three down (types.go format/encode, conn.go format, conn.go appender), three to go (server.go's _ "duckdb-go" blank import + sql.Open("duckdb", ...) calls; querylog.go's sql.Open("duckdb", ...); checkpoint.go's sql.Open("duckdb", ...)).

Test plan

  • go build ./... clean
  • go build -tags kubernetes ./... clean
  • go test -short ./server/ ./duckdbservice/... — green

🤖 Generated with Claude Code

server/conn.go's appendWithDuckDBAppender was the last block of duckdb-go
references in conn.go (used for COPY FROM bulk insert via the duckdb
Appender API). This PR factors it out the same way PR #482 split
AppendValue: server holds the registration hook, duckdbservice's init()
registers the real implementation.

Changes:
  - server/duckdb_appender.go (new): DuckDBAppendFunc type +
    RegisterDuckDBAppender + a thin (*clientConn).appendWithDuckDBAppender
    that dispatches to the registered implementation. Returns a sentinel
    errDuckDBAppenderUnavailable when nothing is registered, so callers
    can fall back to batchInsertRows.
  - duckdbservice/duckdb_appender.go (new): the real implementation.
    Registers in init() so any binary that links duckdbservice gets full
    Appender support. Mirrors the logic that previously lived inline in
    conn.go (Raw → driver.Conn → duckdb.NewAppender* → AppendRow loop).
  - server/conn.go: the inline implementation is removed; the unused
    "database/sql/driver" and "github.com/duckdb/duckdb-go/v2" imports
    are dropped.

  grep duckdb server/conn.go        # only an arrowmap import + SQL strings
  go list -deps ./server/conn.go    # no duckdb-go (file-level)

The whole server package still links duckdb-go via server.go, querylog.go,
and checkpoint.go, but conn.go is fully clean of duckdb-go now.

Verified:
  - go build ./... clean
  - go build -tags kubernetes ./... clean
  - go test -short ./server/ ./duckdbservice/... — green

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fuziontech fuziontech enabled auto-merge (squash) May 1, 2026 17:55
@fuziontech fuziontech merged commit fab8eb4 into main May 1, 2026
19 of 21 checks passed
@fuziontech fuziontech deleted the feature/conn-appender-hook branch May 1, 2026 17:58
fuziontech added a commit that referenced this pull request May 1, 2026
…497)

server/server.go used to blank-import github.com/duckdb/duckdb-go/v2 to
register the "duckdb" sql/driver. The all-in-one binary already imports
duckdbservice (which itself imports duckdb-go via the appender + value
normalizer hooks added in PR #482, #494, #496), so the driver gets
registered through that chain — server.go's blank import is redundant in
production.

server/ package tests already blank-import duckdb-go in the files that
need a real DuckDB connection (bundled_extensions_test.go, catalog_test.go,
chsql_test.go, transient_test.go, session_database_metadata_test.go,
types_test.go), so removing the production blank import doesn't break the
test binaries.

The integration test binary (tests/integration/) imported `server` but not
`duckdbservice`, so it relied on server.go's blank import for driver
registration. Added a blank import of duckdbservice in
tests/integration/harness.go to compensate — same effect, just routed
through the package that's now responsible for registering all duckdb-go
hooks (driver, AppendValue handler, value normalizer, COPY appender).

After this PR, server/server.go has zero `import` statements that pull
duckdb-go into the package's import graph. server still links duckdb-go
overall via querylog.go and checkpoint.go (both call sql.Open("duckdb", ...)
directly), but that's about runtime use of an already-registered driver
rather than a Go-level package import. The follow-up PRs that move
querylog and checkpoint into server/exec/ will close out the file-level
duckdb-go references in server/.

Verified:
  - go build ./... clean
  - go build -tags kubernetes ./... clean
  - go test -short ./server/ ./duckdbservice/... ./controlplane/... ./
    — all green
  - go test -short -timeout 60s ./tests/integration/... — same failures
    as main (TestFallbackUtilityCommands etc.); confirmed pre-existing
    via stash + re-run; unrelated to this PR

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant