Skip to content

CXH-2381: document Db2 setup, correct the supported-database list, and fix the help link - #150

Open
al-conductorone wants to merge 6 commits into
mainfrom
cxh-2381-baton-sql-document-the-db2-configuration-requirements-and
Open

CXH-2381: document Db2 setup, correct the supported-database list, and fix the help link#150
al-conductorone wants to merge 6 commits into
mainfrom
cxh-2381-baton-sql-document-the-db2-configuration-requirements-and

Conversation

@al-conductorone

Copy link
Copy Markdown
Contributor

Documents how to set up the IBM Db2 database engine for the SQL connector, corrects the list of supported databases so it matches what the connector actually supports, and fixes the connector's help link, which pointed at a dead page.

Add a "Writing a Db2 spec" section to docs/db2.md (wrap every column
reference in string(), alias columns to double-quoted lowercase), notes that
account provisioning is unavailable and group principals can't be represented,
and a "Running the Db2 tests" section with make test-db2 / make vet-db2 and
the raw CGO_CFLAGS/CGO_LDFLAGS + library-path invocation.

Add test-db2 and vet-db2 Makefile targets scoping the CGO flags to the recipe.

Reconcile the engine lists (README, docs/docs-info.md, test/README.md) so they
agree with the dispatch switch in pkg/database/database.go, and drop the
unfilled template sentence from docs-info.md.

Point the connector help URL at the live docs page (/docs/baton/baton-sql);
the old /docs/baton/sql returns 404.

Bump the ci.yaml sync-test action to @v4 and gitignore the root baton-sql
build output.
@linear-code

linear-code Bot commented Sep 2, 2026

Copy link
Copy Markdown

CXH-2381

Comment thread pkg/config/schema.go
Comment thread .github/workflows/ci.yaml
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: CXH-2381: document Db2 setup, correct the supported-database list, and fix the help link

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

Review Summary

Scanned the full PR diff — docs, the Makefile Db2 test/vet targets, the CI sync-test@v4 bump with bad-credentials, the help-URL change, and the new pkg/database/autherror.go — for security and correctness. The previous blocking finding is addressed: Validate now maps DB auth failures to a codes.Unauthenticated gRPC status before the generic fmt.Errorf wrap, exit.LogExit derives exit 16 from that status, and the test job is green on this SHA. Earlier reviewer feedback on the WordPress/engine-list mismatch, the grantable_to enforcement wording, and the "Db2-only" CEL claim also reads as addressed; two non-blocking notes remain on the new auth-error mapping.

Security Issues

None found. No secrets, injection, or credential-logging changes; the new error path emits a fixed message with no driver detail.

Correctness Issues

None found.

Suggestions

  • pkg/database/autherror.go:14-27 — the SQLState() interface probe matches pgx only; Vertica (VError.SQLState is a struct field, not a method), SQL Server (SQLErrorState()), Oracle and HANA all fall through to exit 2, so the doc comment naming Vertica is inaccurate.
  • pkg/connector/connector.go:100-102 — the auth-error early return drops the database name and the driver message, losing which DSN failed in a multi-database config.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `pkg/database/autherror.go`:
- Around lines 14-27: The doc comment claims Postgres/Redshift/Vertica surface SQLSTATE via
  a SQLState() method, but only pgx does. vertica-sql-go v1.3.6 declares SQLState as a plain
  struct field on *VError, whose only method is Error(), so errors.As against the anonymous
  SQLState() string interface never matches Vertica; microsoft/go-mssqldb exposes
  SQLErrorState() uint8 rather than SQLState(); go-ora and go-hdb expose numeric codes only.
  Net effect: only Postgres/Redshift and MySQL map to Unauthenticated. Fix the comment so it
  names only the engines actually covered, and optionally extend AuthError with explicit
  cases for *vertigo.VError (SQLState 28000), mssql.Error (Number 18456) and go-ora
  ORA-01017 so those engines exit 16 instead of 2. If cases are added, extend
  pkg/database/autherror_test.go with matching table entries.

In `pkg/connector/connector.go`:
- Around lines 100-102: The early return of authErr discards both the loop name variable and
  the underlying driver error, so an operator with several databases configured sees only
  "database authentication failed" and cannot tell which DSN failed or why. Preserve that
  context while keeping the Unauthenticated code — for example return
  status.Errorf(codes.Unauthenticated, "database %q authentication failed: %v", name, err)
  from this branch, or have database.AuthError accept and embed the context.

@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.

…h check

Add WordPress (MySQL-based) back to the README engine list so it agrees
with docs/docs-info.md, which still ships it.

Pass bad-credentials: DB_PASSWORD=invalid to sync-test@v4 so the new
auth-error check actually runs; without it the step skips (DB_PASSWORD is
not a BATON_* var, so nothing gets invalidated).

@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 .github/workflows/ci.yaml
Comment thread docs/db2.md Outdated
Comment thread docs/db2.md Outdated
Comment thread docs/docs-info.md
Comment thread README.md Outdated
- db2.md: reframe the "Writing a Db2 spec" intro. The string()-wrapping
  and lowercase-alias patterns are not Db2-only; Oracle folds unquoted
  identifiers and Redshift needs string() in CEL concatenations. Db2
  just needs both everywhere.
- db2.md: correct the group-provisioning note. grantableTo is
  spec-driven and is not filtered by engine, so a spec that declares
  group still advertises it as grantable; the group grant is dropped at
  ingest, not at grantableTo. Split the two into separate statements.
- docs-info.md: bring the "Example DSN formats" and "Configuration
  Examples" lists in line with the supported-engines list (SAP HANA,
  Vertica, Amazon Redshift, IBM DB2).
- README.md: drop the hand-maintained engine enumeration in Key
  Features that had drifted from the Supported Database Engines list on
  WordPress; link to that list instead.

@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 .gitignore Outdated

@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.

Replace os.Exit(1) in main.go with exit.LogExit(err) so an auth failure exits
with the mapped gRPC status code (Unauthenticated/PermissionDenied) instead of
a bare 1, which lets the CI sync-test auth-error check actually assert.
Comment thread cmd/baton-sql/main.go

@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.

Blocking issues found — see review comments.

exit.LogExit alone made the CI bad-credentials check hard-fail: Validate wrapped
the ping error with plain fmt.Errorf, so exit mapped it to Unknown(2) while
auth-error.sh expects Unauthenticated(16)/PermissionDenied(7). Add
database.AuthError: SQLSTATE class 28 (Postgres/Redshift/Vertica/etc.) and MySQL
1045 map to codes.Unauthenticated. Verified live: bad postgres creds now exit 16,
good creds pass Validate.
Comment thread pkg/database/autherror.go
Comment on lines +14 to +27
// AuthError returns an Unauthenticated gRPC status when err is a database
// authentication/authorization failure, or nil otherwise. SQLSTATE class 28
// ("invalid authorization") is the ANSI code drivers report on bad credentials
// (Postgres/Redshift/Vertica/etc. surface it via SQLState()); MySQL is the
// exception, reporting error 1045 with no SQLSTATE.
func AuthError(err error) error {
if err == nil {
return nil
}

var sqlState interface{ SQLState() string }
if errors.As(err, &sqlState) && strings.HasPrefix(sqlState.SQLState(), "28") {
return status.Error(codes.Unauthenticated, "database authentication failed")
}

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.

🟡 Suggestion: the SQLState() interface probe only matches pgx — Vertica is named in the comment but doesn't qualify. vertica-sql-go@v1.3.6 declares SQLState as a struct field on VError (its only method is Error()), so errors.As against interface{ SQLState() string } never matches it; same for SQL Server (mssql.Error exposes SQLErrorState() uint8, not SQLState()), Oracle and HANA. Net effect is that only Postgres/Redshift and MySQL map to Unauthenticated — worth correcting the comment to say so, and optionally adding *vertigo.VError (SQLState 28000) / mssql.Error (18456) / go-ora ORA-01017 cases so the other engines return 16 instead of 2.

Comment on lines +100 to +102
if authErr := database.AuthError(err); authErr != nil {
return nil, authErr
}

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.

🟡 Suggestion: this early return discards both the database name and the driver's message, so a multi-database config that fails auth on one connection logs only database authentication failed with no way to tell which DSN or why. Consider carrying the context through, e.g. return nil, status.Errorf(codes.Unauthenticated, "database %q authentication failed: %v", name, err) — the exit code stays 16 while the operator keeps the diagnostic detail.

@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.

4 participants