Skip to content

Retire gp-common-go-libs and sqlx; inline replacements in-repo#29

Open
adam8157 wants to merge 1 commit into
mainfrom
retire_gp-common-go-libs
Open

Retire gp-common-go-libs and sqlx; inline replacements in-repo#29
adam8157 wants to merge 1 commit into
mainfrom
retire_gp-common-go-libs

Conversation

@adam8157

@adam8157 adam8157 commented May 21, 2026

Copy link
Copy Markdown
Contributor

Replace the external gp-common-go-libs dependency (and its transitive sqlx
dep) with seven top-level packages copied/ported into the repo:
cluster/, dbconn/, gplog/, iohelper/, operating/, structmatcher/, testhelper/.
The bulk of the file churn is mechanical import-path rewrites; APIs were
preserved so call sites didn't need to change.

Zero new direct deps; the replace directive pointing at gp-common-go-libs is
gone. dbconn is rewritten on database/sql + pgx/v5 stdlib driver with a small
reflect-based scanner (db: tag mapping, embedded structs, sql.Scanner
passthrough so pq.StringArray still works) — sqlx is out. gplog is
reimplemented on stdlib log.Logger.

Internal behavior changes worth flagging:

  • dbconn.Get is now strict: returns ErrMultipleRows on >1 row instead of
    sqlx's silent first-row. Every production call site was audited and is
    1-row by construction (scalar functions, SHOW <guc>, PK-unique catalog
    lookups, cluster invariants).
  • dbconn.handleConnectionError classifies pgx errors by SQLSTATE
    (42704/3D000) instead of substring-matching lib/pq error prefixes.
  • dbconn.Begin uses BeginTx(LevelSerializable); previously BEGIN + SET
    TRANSACTION ISOLATION LEVEL SERIALIZABLE.
  • DBConn.ConnPool[i] is *sql.DB (was *sqlx.DB); Tx[i] is *sql.Tx.
  • dbconn.ParseGPVersion anchors only on the brand marker and takes the first
    X.Y.Z token after it, handling both the "(Greenplum Database <ver>)" banner
    shape and the newer shape where the closing paren precedes the version,
    without mistaking the gcc toolchain version for the product version, and
    returning an error instead of panicking on an unrecognized banner.

Cleanups: pkg/errors dropped for stdlib (errors.Wrap → fmt.Errorf("%s: %w", …)
so wrapping stays recoverable; gplog.Fatal stack capture via runtime.Callers).
pq.StringArray replaced by an in-repo sql.Scanner. tools.go removed —
ginkgo/goimports run via go tool (x/tools now indirect, needs Go 1.24+).

Tests: in-repo unit tests accompany the inlined packages — ported from the
upstream suites for cluster/structmatcher/iohelper, fresh tests for the
stdlib-log gplog, and dbconn coverage for the reflect scanner, array scanning,
and version parsing (both banner shapes + error paths).

Rebased on main; adapts cleanly to the features that landed since
(--exclude-extension, gpbackup_history columns, the CVE/dep bumps).

@adam8157

Copy link
Copy Markdown
Contributor Author
image

@adam8157
adam8157 requested a review from linwen May 26, 2026 04:17
Replace the external gp-common-go-libs dependency (and its transitive sqlx
dep) with seven top-level packages copied/ported into the repo:
cluster/, dbconn/, gplog/, iohelper/, operating/, structmatcher/, testhelper/.
The bulk of the file churn is mechanical import-path rewrites; APIs were
preserved so call sites didn't need to change.

Zero new direct deps; the replace directive pointing at warehouse-pg/gp-
common-go-libs is gone. dbconn is rewritten on database/sql + pgx/v5 stdlib
driver with a small reflect-based scanner (db: tag mapping, embedded
structs, sql.Scanner passthrough so pq.StringArray still works) — sqlx is
out. gplog is reimplemented on stdlib log.Logger.

Internal behavior changes worth flagging:
- dbconn.Get is now strict: returns ErrMultipleRows on >1 row instead of
  sqlx's silent first-row. Every production call site was audited and is
  1-row by construction (scalar functions, SHOW <guc>, PK-unique catalog
  lookups, cluster invariants).
- dbconn.handleConnectionError classifies pgx errors by SQLSTATE
  (42704/3D000) instead of substring-matching lib/pq error prefixes.
- dbconn.Begin uses BeginTx(LevelSerializable); previously BEGIN + SET
  TRANSACTION ISOLATION LEVEL SERIALIZABLE.
- DBConn.ConnPool[i] is *sql.DB (was *sqlx.DB); Tx[i] is *sql.Tx.

Version-string parsing (dbconn.ParseGPVersion) anchors only on the brand
marker and takes the first X.Y.Z token after it, so it handles both banner
shapes — version inside the "(Greenplum Database <ver>)" parens (GP6/GP7),
and the newer shape where the closing paren precedes the version
("... (Greenplum Database) <ver> build ...") — without mistaking the gcc
toolchain version for the product version, and returns an error instead of
panicking on an unrecognized banner.

pkg/errors is dropped in favor of stdlib: errors.Errorf/New/As/Is -> stdlib,
errors.Wrap -> fmt.Errorf("%s: %w", ...) so wrapping stays recoverable; the
gplog.Fatal stack capture uses runtime.Callers via an internal captureStack()
(stack still starts at Fatal's caller). pq.StringArray is replaced by an
in-repo sql.Scanner (dbconn/array.go) matching pq's strict NULL handling.
tools.go is gone; ginkgo/goimports run via `go tool` (x/tools now indirect,
needs Go 1.24+, we're on 1.25). Assorted altitude cleanups (SelectString
single-pass scan; ReplaceAll; reflect.PointerTo; stale sqlx comments).

In-repo unit tests accompany the inlined packages: ported from the upstream
suites for cluster/structmatcher/iohelper (iohelper minus the dropped
OpenFileForAppending variants), fresh tests for the stdlib-log gplog
reimplementation, and dbconn coverage for the reflect scanner, array
scanning, and version parsing (both banner shapes, the toolchain-version
trap, and the error paths).
@adam8157
adam8157 force-pushed the retire_gp-common-go-libs branch from 8d04f50 to 432ef05 Compare July 24, 2026 06:36
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