Skip to content

feat: opt-in IBM DB2 support behind the db2 build tag#140

Open
afalahi wants to merge 5 commits into
mainfrom
ali/db2-support
Open

feat: opt-in IBM DB2 support behind the db2 build tag#140
afalahi wants to merge 5 commits into
mainfrom
ali/db2-support

Conversation

@afalahi

@afalahi afalahi commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

  • Bug fix
  • New feature

Adds IBM DB2 as a supported engine, fully isolated behind a db2 Go build tag.

DB2 is unlike every other engine here: no pure-Go driver exists (the only two DRDA-in-Go attempts are abandoned), so the only viable driver is IBM's github.com/ibmdb/go_ibm_db — cgo, linking IBM's native ODBC/CLI driver ("clidriver"). Left unguarded, that import breaks default builds, cross-compilation, and the goreleaser release pipeline. This PR quarantines it so the cost is paid only by builds that opt in.

Default build: zero behavior change

  • make build, go test, lint, and the release pipeline stay pure Go — no IBM software, no CGO flags, no env vars, CGO_ENABLED=0 cross-compilation intact.
  • A default binary given a db2:// DSN fails fast with: baton-sql: DB2 support not compiled into this binary; rebuild with -tags db2 (see docs/db2.md).
  • DSN parsing/conversion lives in an untagged file, so it is compiled and unit-tested in every build.

What -tags db2 adds

  • pkg/database/db2: driver registration (tagged), stub Connect (!db2), URL→native DSN conversion.
  • Hardened DSN handling: credentials containing DB2 metacharacters are ODBC brace-quoted (a ; in a password would otherwise silently truncate it or inject connection keywords), URL query params are forwarded as connection keywords, and params colliding with URL-derived keywords are rejected.
  • Explicit DB2 cases for parameter placeholders and timestamp parsing in pkg/bsql.

Build & distribution

  • make build-db2 — CGO flags scoped inline to that one command (never exported), -tags db2.
  • Binaries are relocatable: they resolve the clidriver next to the executable first ($ORIGIN/clidriver/lib on Linux, @executable_path on macOS with the load command rewritten to @rpath), falling back to the build-time DB2HOME. No LD_LIBRARY_PATH/DYLD_LIBRARY_PATH at run time in either layout.
  • make package-db2 — self-contained ~55 MB tarball (binary + clidriver + IBM's license/ directory, which the redistribution terms require shipping). Customers untar and run; no installation, no root, no env vars.
  • docs/db2.md — setup, troubleshooting, Docker example, and redistribution-licensing notes (including the GSKit TLS and Db2 Connect caveats).

Verification

  • Default build with all DB2 env vars scrubbed; CGO_ENABLED=0; GOOS=linux cross-compile; full test suite; golangci-lint (no new findings); go vet -tags db2.
  • Relocatable lookup proven strictly on both platforms: macOS with the fallback rpath stripped from the binary, Linux running the bundle from an arbitrary path in a bare debian:bookworm-slim container with the fallback pointed at a nonexistent directory.
  • That Linux run surfaced the clidriver's one OS-level dependency, libxml2 — documented and added to the Docker example (it is preinstalled on full server distros, absent in slim images).

Notes for reviewers

  • Most of the diff is vendor/github.com/ibmdb + vendor/github.com/ibmruntimes; the reviewable surface is pkg/database/db2, small switch additions in pkg/database/database.go and pkg/bsql, the Makefile targets, and docs.
  • Platform limits are IBM's, not ours: no Linux ARM64 clidriver, glibc only (no Alpine/musl).
  • The DB2 variant cannot ride the standard goreleaser release (cgo); it ships as the package-db2 bundle or a Docker image until releng wants to own a DB2 artifact.

Useful links:

afalahi added 4 commits July 9, 2026 06:55
The go_ibm_db driver is cgo and links IBM's native CLI driver, so it is
excluded from default builds: make build stays pure Go (CGO_ENABLED=0,
cross-compilable, no clidriver needed) and a db2:// DSN on a default
binary returns a clear rebuild hint. make build-db2 scopes the CGO flags
to that one invocation and bakes the library path into the binary
(rpath on Linux, install_name_tool on macOS) so no LD_LIBRARY_PATH or
DYLD_LIBRARY_PATH is needed at run time.

URL-form DSNs brace-quote credentials containing DSN metacharacters and
forward query parameters as DB2 connection keywords, rejecting
collisions with URL-derived keywords.
The db2 binary now resolves the clidriver relative to itself first
($ORIGIN/clidriver/lib on Linux, @executable_path on macOS) before
falling back to the build-time DB2HOME, so make package-db2 can ship a
single archive (binary + clidriver + IBM license files) that customers
untar and run anywhere with no installation or environment variables.
Verified end-to-end on macOS and on linux/amd64 in a bare
debian:bookworm-slim container; the clidriver's one OS dependency,
libxml2, is documented and added to the Docker example.
@afalahi
afalahi requested a review from a team July 9, 2026 14:26
Comment thread pkg/database/db2/dsn.go
@linear-code

linear-code Bot commented Jul 9, 2026

Copy link
Copy Markdown

CXP-750

CXH-2046

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: feat: opt-in IBM DB2 support behind the db2 build tag

Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base c68e5c138d45.
Review mode: full
View review run

Review Summary

Full PR diff scanned for security and correctness. This adds opt-in IBM DB2 support isolated behind the db2 cgo build tag, with a !db2 stub returning a clear "not compiled in" error, so default builds stay pure-Go and CGO-free. The prior security finding (hostname not being brace-quoted in DSN conversion) is now addressed: parsedURL.Hostname() passes through quoteDB2Value (pkg/database/db2/dsn.go:75) and a regression test ("hostname with semicolon is brace-quoted") covers it. DSN construction robustly brace-quotes or rejects injection characters (semicolon, brace, equals, space) across hostname, database, credentials, and forwarded query keywords, and rejects reserved-keyword overrides. go.mod, go.sum, vendor/modules.txt and the vendored driver are consistent and match the code. No new issues found.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

None.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found.

Comment thread pkg/database/db2/dsn.go
url.Parse permits semicolons in the host component, so an unquoted
hostname could splice extra connection keywords into the DSN,
bypassing the reserved-keyword rejection. Hostname now goes through
quoteDB2Value like every other URL-derived value; IPv6 hosts are
unaffected.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found.

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.

2 participants