Skip to content

feat(kernel): SEA-via-kernel PuPr tail — advanced proxy, Geography, conn/error telemetry, token-caching docs, configurable backoff#412

Draft
mani-mathur-arch wants to merge 9 commits into
mainfrom
mani/sea-kernel-new-items
Draft

feat(kernel): SEA-via-kernel PuPr tail — advanced proxy, Geography, conn/error telemetry, token-caching docs, configurable backoff#412
mani-mathur-arch wants to merge 9 commits into
mainfrom
mani/sea-kernel-new-items

Conversation

@mani-mathur-arch

@mani-mathur-arch mani-mathur-arch commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

The genuinely-new SEA-via-kernel driver work from the new-items backlog: the short PuPr telemetry/config/Geography tail plus advanced proxy and configurable backoff, followed by a datatype-parity + decimal-perf + RSS pass. Each is re-implemented clean on main (post-#399) — the pre-#399 POC was the spec, not the source. Every commit was reviewed with Isaac Review before commit.

Commits

PuPr new-items tail

  • feat(kernel): advanced HTTP proxy via WithKernelProxy (PECOBLR-3607) — fill the username / password / bypass_hosts args into the kernel's set_proxy setter (the kernel path passed the URL only). New WithKernelProxy(url, user, pass, bypassHosts) connector option; explicit proxy takes precedence over the env-var path.
  • test(kernel): cover Geography as the WKT sibling of Geometry (PECOBLR-3620) — verify-and-close: GEOGRAPHY maps to the same Arrow Utf8/WKT shape as GEOMETRY (no renderer needed). Parity + live-e2e (skip-on-reject) coverage.
  • feat(kernel): emit connection-config telemetry + fix connection-scoped error drop (PECOBLR-3627 / 3628) — emit DriverConnectionParameters at connect (kernel-path only; mode=SEA, auth_mech/auth_flow closed enums, proxy/arrow/query-tags/metric-view) and stop silently dropping connection-scoped errors in the aggregator. Additive on top of feat(kernel): consolidated DAIS gap-closure + PuPr feature set + nightly workflows for e2e tests #399's per-statement telemetry (not duplicated).
  • docs(kernel): note token caching + client reuse are inherited from the kernel (PECOBLR-3606 / 3626) — verify-and-close, doc-only: both are handled inside the kernel below the C ABI.
  • feat(kernel): configurable HTTP retry / backoff (PECOBLR-3598) — wire WithRetries (RetryWaitMin/Max/RetryMax, incl. the disable form) into the kernel's new set_retry_config C-ABI setter, plus a kernel-only WithKernelRetryOverallTimeout.

Datatype parity + decimal perf + RSS

  • feat(kernel): report column-type metadata on the kernel Rows path (PECOBLR-3692) — kernelRows implemented only driver.Rows, so database/sql fell back to "" DatabaseTypeName / interface{} ScanType for every column vs Thrift's typed metadata (a silent regression for ORMs / typed-scan tooling that value-level tests can't see). New shared pure-Go arrowscan.ColumnTypeInfoFor maps Arrow → {DatabaseTypeName, ScanType, Length} matching Thrift for all 21 types; kernelRows now implements the 4 optional RowsColumnType* interfaces. Pure-Go guard + live TestKernelThriftColumnTypeParity.
  • perf(decimal): alloc-free exact decimal renderer (shared Thrift + kernel) (PECOBLR-3691) — rewrite decimalfmt.ExactString (on the shared render path) to allocate only the returned string: uint64 fast path renders into a stack scratch, big.Int only for true 128-bit magnitudes. Byte-identical output, pinned by an oracle-parity test (old impl kept verbatim as reference); 38.9ns/18B/1alloc → ~12ns/0B/0alloc. Live 50k-row multi-batch parity vs Thrift.
  • feat(kernel): tune CloudFetch in-memory chunks via WithKernelMaxChunksInMemory (PECOBLR-3691, RSS) — bound how many decompressed CloudFetch chunks the kernel holds in memory (default 16), the knob that trades throughput for peak RSS on large results (measured 265 MB @ chunks=4 vs 856 MB @ chunks=32 on a 3M-row query). Kernel-only option forwarded as the client-only cloudfetch_max_chunks_in_memory session conf, which the kernel folds into its result config and strips before the SEA wire — never reaching the server or the Thrift path. No new C-ABI symbol.

Kernel dependency

Two commits need new kernel behavior on the same kernel branch (PR #178):

  • set_retry_config C-ABI symbol (backoff commit), and
  • the apply_client_result_overrides reader that applies cloudfetch_max_chunks_in_memory (chunk-knob commit).

KERNEL_REV is pinned to that branch's head (ffa73c0), so the tagged CI links both. Re-pin to the squash-merge SHA once the kernel PR lands. The other commits are driver-only and need no kernel change.

Testing

Both build paths green (CGO_ENABLED=0 go test ./... + CGO_ENABLED=1 go test -tags databricks_kernel ./...), go vet clean, gofmt clean, golangci-lint run ./... 0 issues. Pure-Go tests (option wiring, field-classification guards, ColumnType mapper, decimal oracle-parity, retry/proxy/telemetry resolvers, telemetry full-loop) run under CGO_ENABLED=0; tagged tests drive the real cgo setters; live e2e tests (proxy-rejects-bad-URL, geography, retry config/disable/overall-timeout, ColumnType parity, 50k-row decimal parity, CloudFetch chunk-knob drain) run against the staging warehouse. Each commit was reviewed with Isaac Review and its findings addressed before commit.

This pull request and its description were written by Isaac.

mani-mathur-arch and others added 9 commits July 18, 2026 13:49
Fill the username / password / bypass_hosts args into the kernel's
set_proxy setter (the kernel path passed nil,nil,nil, carrying only the
URL). These are the "advanced" fields the HTTP(S)_PROXY / NO_PROXY
environment path can't express: a structured bypass list (NO_PROXY is
consumed during environment resolution, not forwarded) and out-of-band
basic-auth credentials (rather than embedded in the URL userinfo).

- New KernelExperimentalConfig proxy fields + WithKernelProxy(url, user,
  pass, bypassHosts) connector option (kernel-only; the Thrift path
  rejects it like the other WithKernel* options).
- newKernelBackend prefers an explicit WithKernelProxy over the env-var
  resolution — an explicit proxy is a deliberate override, and consulting
  both would be ambiguous. resolveKernelProxy is untagged so the
  explicit-over-env precedence is covered under CGO_ENABLED=0.
- Kernel backend Config gains ProxyUsername / ProxyPassword /
  ProxyBypassHosts; applyProxy passes each as NULL when empty.

Tests: experimental-field classification guard + option-wiring +
Thrift-reject + DeepCopy extended for the proxy fields (untagged);
resolveKernelProxy precedence (untagged); TestSetProxy drives the real
cgo setter across all field combinations (tagged); live e2e
TestKernelE2EProxyRejectsBadURL (routing through an unreachable proxy
must fail — proof the setter is applied). Both build paths + full suite
green; go vet clean. Isaac Review clean (0 valid findings).

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
#393 shipped Geometry (WKT string); Geography is the sibling geospatial
type left out (split as separate subtasks). No renderer is needed: the
kernel maps GEOMETRY and GEOGRAPHY to the same Arrow Utf8 shape (WKT
text), distinguished only by a databricks.type_name field-metadata hint
that does not change the scanned value — both hit the same string arm on
the kernel and Thrift paths. So this is verify-and-close: prove the parity
and pin it, no source change.

- arrowscan parity test gains a geography_wkt case (kernel == Thrift ==
  "POINT(1 2)"), documenting the shared rendering.
- Live e2e TestKernelE2EDataTypes gains a geography case that SKIPs (not
  fails) when the warehouse rejects the type — GEOGRAPHY is gated on some
  warehouses, and the case documents the parity without breaking runs
  where it is unavailable.
- doc.go lists GEOMETRY / GEOGRAPHY (WKT) in the result-type parity set.

Isaac Review clean (0 actionable findings).

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
…d error drop

Emit connection-configuration telemetry on the kernel path (PECOBLR-3627)
and stop silently dropping connection-scoped errors (PECOBLR-3628).

Neither backend populated DriverConnectionParameters before: the struct
existed but was never filled, and recordConnection was dead code. This is
a net-new emission on top of the #399 per-statement telemetry (which
already emits EXECUTE_STATEMENT / CLOSE_STATEMENT + chunk details and
per-statement errors — not duplicated here).

- telemetry: telemetryMetric gains connParams; createTelemetryRequest
  serializes it (and mirrors AuthMech onto the top-level AuthType) only
  for a "connection" metric — a statement/operation/error metric leaves
  it nil and serializes byte-identically to before (pinned by a test).
  Interceptor.RecordConnectionConfig replaces the dead recordConnection.
- aggregator: a non-terminal error with no statement to attach to (a
  connection-scoped error, empty statementID) was silently dropped. It
  now flushes immediately instead — the connection-scoped error-log path
  (3628). Both backends benefit.
- driver: the connector emits RecordConnectionConfig at connect, KERNEL
  PATH ONLY (gated on the backend type, not just WithUseKernel), so the
  default (Thrift) path's telemetry is byte-identical. The payload is
  built by untagged kernelConnectionTelemetry(cfg): mode=SEA (the closed
  DatabricksClientType enum has no "kernel" member — emitting it NULLs the
  field on ingestion), auth_mech ∈ {PAT, OAUTH} + auth_flow ∈
  {CLIENT_CREDENTIALS, BROWSER_BASED_AUTHENTICATION} (the closed enums, not
  the driver's own auth names), proxy usage, arrow, query tags, metric-view
  — mirroring Python's TelemetryHelper enum mapping so all drivers land the
  same values.

Tests: untagged builder test; serializer + "statement metric unchanged" +
full-loop (RecordConnectionConfig lands; connection-scoped error not
dropped) tests. Both build paths + full suite green; go vet clean. Isaac
Review clean (0 actionable findings).

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
…e kernel

PECOBLR-3606 (token caching) and PECOBLR-3626 (client tokens / connection
reuse) are verify-and-close: both are handled entirely inside the kernel,
below the C ABI, so there is no driver work and no driver-side knob.

Verified against kernel source: OAuth U2M tokens persist to disk
(~/.config/databricks-sql-kernel/oauth/, with refresh-token lifecycle),
M2M tokens cache in-memory with background refresh, and a single pooled
reqwest client is reused per session across the control-plane, CloudFetch,
and auth-refresh calls (pool_max_idle_per_host). doc.go now states this so
the inherited behavior is documented rather than silently assumed.

Isaac Review clean (0 findings).

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
Honor the driver's WithRetries policy (RetryWaitMin / RetryWaitMax /
RetryMax) on the kernel path by forwarding it to the kernel's new
kernel_session_config_set_retry_config C-ABI setter (PECOBLR-3598).
Before, WithRetries was silently ignored on the kernel path and the
disable form (RetryMax < 0) was rejected at connect — the kernel had
exponential backoff with configurable HttpConfig::retry_* fields but no
C-ABI setter, so the caller's policy could not reach it.

- kernel backend Config gains Retry *RetryConfig; applyRetry forwards it
  via the setter (a no-op when nil, so the kernel's default policy — 5
  retries, 1s..60s, 900s budget — is preserved).
- Untagged kernelRetryConfig resolves WithRetries into the descriptor:
  the connector's WithDefaults guarantees positive waits + RetryMax 4; a
  negative RetryMax (the disable form) maps to MaxRetries=0 and is honored
  EVEN with zero waits (WithRetries(-1,0,0) is idiomatic) by substituting
  a valid placeholder range the setter accepts (backoff unused with no
  retries). A non-disabling degenerate range returns nil (keep kernel
  default) so a stray zero can't fail the connect.
- validateKernelConfig no longer rejects WithRetries(-1).
- WithKernelRetryOverallTimeout adds the 4th knob (cumulative retry
  budget) — kernel-only, since the Thrift WithRetries surface has no
  overall-budget equivalent; mirrors the pyo3/napi retry_overall_timeout.
- KERNEL_REV bumped to the kernel PR head that adds the setter
  (b5f6dda); re-pin to the squash-merge SHA once that kernel PR lands.

cgo note: cgo silently drops the direct declaration of the retry setter
(a parser quirk — valid C, compiles + links, but omitted from the Go
bindings). A static inline shim in backend.go's preamble forwards to it;
the shim must be in the same file as its caller (a shim in another cgo
preamble in this package is dropped the same way). The kernel header is
unchanged (valid C, used verbatim by the C-only ODBC consumer).

Tests: untagged TestKernelRetryConfig (defaults / disable incl. zero
waits / overall timeout / degenerate range); field-classification guards
updated (RetryMax/Wait* now forwarded; RetryOverallTimeout classified);
tagged TestSetRetry drives the real cgo setter incl. the InvalidArgument
rejections; live e2e retry config / disable / overall-timeout. Both build
paths + full suite green; go vet + gofmt clean. Isaac Review clean.

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
golangci-lint's gosec G101 ("potential hardcoded credentials") flagged
three non-credential string literals: the ProxyPassword test literals in
TestResolveKernelProxy / TestSetProxy, and the CLIENT_CREDENTIALS
telemetry auth_flow enum value. None is a real secret. Suppress each with
//nolint:gosec + a reason (the repo's established pattern), clearing the
Lint CI gate. gosec anchors the struct-literal G101 to the composite-lit
line, so the nolint sits there, not on the field.

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
kernelRows implemented only driver.Rows, so database/sql fell back to ""
DatabaseTypeName and an interface{} ScanType for every column on the
kernel backend — whereas the Thrift path returns BIGINT/DECIMAL/DATE
names and int64/float64/time.Time/sql.RawBytes scan types (PECOBLR-3692).
ORMs and typed-scan tooling (GORM, sqlx, schema reflection, BI drivers)
rely on that metadata to pick Go destination types, so the omission was a
silent behavioral regression vs Thrift that value-level tests can't see.

- New shared, pure-Go arrowscan.ColumnTypeInfoFor(arrow.DataType) maps an
  Arrow column type to {DatabaseTypeName, ScanType, Length} matching the
  Thrift backend exactly (getScanType / GetDBTypeName / ColumnTypeLength).
  It lives next to ScanCellCached and covers precisely the Arrow types the
  scanner produces, so the reported type and the scanned value stay in
  lockstep. Ground truth for the mapping was captured live from the Thrift
  backend across all 21 supported types.
- kernelRows now implements RowsColumnTypeScanType /
  DatabaseTypeName / Nullable / Length, computing per-column info once at
  construction from the schema it already imports for Columns(). Nullable
  returns ok=false like Thrift (no reliable per-column flag); Length
  reports MaxInt64 for variable-length types and (0,false) otherwise.
- DECIMAL reports sql.RawBytes (Thrift's DECIMAL scan type) though the
  value renders as an exact string; VARCHAR/CHAR/VARIANT/GEOMETRY and both
  INTERVAL types collapse to STRING, matching what the prod-default Thrift
  server declares (documented inline, incl. the native-interval caveat).

Why this wasn't caught: the kernel-vs-Thrift parity suites compare
scanned VALUES via sql.RawBytes, which is structurally blind to the
Rows.ColumnType* metadata (it was a missing-interface gap, not a wrong
value). This adds the guards that would have caught it: pure-Go
TestColumnTypeInfoFor / ...CoversScanner (run in the default CGO_ENABLED=0
CI build, no warehouse) and the live TestKernelThriftColumnTypeParity,
which compares full sql.ColumnType metadata across both backends for every
type. Verified: neutering the mapper makes the live test fail (empty
name / nil scan type), confirming it's a real regression guard.

Both build paths + full suite green; go vet + gofmt + golangci-lint clean.
Live kernel parity/datatype suites pass. Isaac Review clean.

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
…nel)

decimalfmt.ExactString rendered every DECIMAL cell via big.Int.String()
plus ~4 heap allocations, and it is on the shared render path both
backends use (the Thrift arrow path's ValueString and the kernel scan
path). On decimal-heavy result sets that per-cell allocation churn was a
measurable throughput/RSS cost on the kernel backend vs Thrift, whose
server-pre-formatted decimals arrive as zero-copy Arrow STRING
(PECOBLR-3691).

Rewrite the renderer to allocate only the returned string:
- render the unscaled magnitude right-to-left into a stack scratch and
  place the decimal point by slice copy, with math/big only as the
  fallback for a true 128-bit magnitude (hi != 0) — which every
  DECIMAL(<=18), and every DECIMAL value under 2^64, never reaches.
- factor an exported Append(dst, n, scale) so a caller can render into a
  reused buffer with zero heap allocation (byte-identical to ExactString).

Output is unchanged: this is a cost-only rewrite of a value on the prod
Thrift path, so it must be byte-for-byte identical for every input. The
guard is TestExactStringOracleParity, which keeps the pre-rewrite
implementation verbatim as an oracle and fuzzes the two against each other
across both signs, the full scale range, the uint64/128-bit boundary, and
the DECIMAL(38) / 2^127-1 extremes. Micro-bench: 38.9ns/18B/1alloc ->
~12ns/0B/0alloc; Append into a reused buffer is ~9ns/0alloc.

The kernel scan path continues to render top-level decimals through this
shared renderer (one string per cell, now alloc-cheaper); the further
zero-alloc batch-arena optimization is deliberately deferred to a
follow-up so this first kernel release carries no unsafe.

Also adds the live TestKernelThriftDecimalScaleParity (50k rows spanning
multiple kernel batches, incl. a DECIMAL(38,4) past float64 range) to pin
the integrated kernel scan path byte-identical to Thrift at scale.

Both build paths + full suite green; go vet + gofmt + golangci-lint clean.
Live kernel parity/datatype suites pass. Isaac Review clean.

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
…sInMemory

Give callers a way to bound the kernel's peak RSS on large result sets
(PECOBLR-3691, the RSS half of the decimal-heavy launch risk). The kernel
holds cloudfetch_max_chunks_in_memory (default 16) decompressed CloudFetch
chunks at once; on wide, row-heavy results that drives ~1.2 GB peak, vs
Thrift's flat ~+200 MB. Lowering the bound trades a little throughput for
a large RSS reduction (measured: chunks=4 -> ~265 MB vs chunks=32 -> ~856
MB peak on a 3M-row query, a 3.2x swing driven purely by the knob).

- New EXPERIMENTAL kernel-only option WithKernelMaxChunksInMemory(n),
  carried on KernelExperimentalConfig.MaxChunksInMemory. A value <= 0 (the
  default) leaves the kernel's built-in default (16) untouched.
- buildKernelConfig injects it into the KERNEL backend's own SessionConf
  as the client-only "cloudfetch_max_chunks_in_memory" key
  (config.KernelMaxChunksInMemoryConfKey) — NOT via EffectiveSessionParams,
  which both backends share, so it can never leak onto the Thrift path or
  the server. The kernel (PR that pairs with this KERNEL_REV bump) reads
  the key in Session::open, folds it into its result config, and strips it
  before the SEA wire; the key is absent from the kernel's server
  allowlist so it never becomes a server SET param.
- No new C-ABI symbol: it rides the existing
  kernel_session_config_set_session_conf setter.
- KERNEL_REV bumped to the kernel head that adds the override reader;
  re-pin to the squash-merge SHA once that kernel PR lands.

Tests: the experimental-field classification guard gains the new field
(so it can't be silently dropped); option->config wiring + Thrift-reject +
DeepCopy cases; buildKernelConfig subtests assert the key is injected when
set, absent when unset/zero, and NOT present in EffectiveSessionParams
(the kernel-only invariant); live TestKernelE2EMaxChunksInMemory drains a
1M-row CloudFetch result with the bound lowered (proves the key is
accepted by the kernel and stripped before the wire — a bad key would
error server-side). Both build paths + full suite green; go vet + gofmt +
golangci-lint clean. Isaac Review clean.

Co-authored-by: Isaac <isaac@databricks.com>
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
Comment thread kernel_config.go

// Non-disabling: a degenerate range means WithDefaults didn't run — leave the
// kernel's default policy in place rather than fail the connect on a bad range.
if cfg.RetryWaitMin <= 0 || cfg.RetryWaitMax < cfg.RetryWaitMin {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Medium] WithRetries(N, 0, 0) silently reverts to the kernel's default retry policy

The non-disabling branch returns nil (→ the kernel keeps its built-in 5-retry default) whenever RetryWaitMin <= 0 || RetryWaitMax < RetryWaitMin, dropping the caller's RetryMax. Because WithDefaults() runs before options and WithRetries(10, 0, 0) overwrites the waits to 0, the idiomatic WithRetries(10, 0, 0) (per its own godoc, which promises sane wait defaults) leaves RetryWaitMin == 0, hits this guard, and runs the kernel's default 5 retries instead of the requested 10 — silently, with no log. The in-code comment ("unusual outside tests / a Config without WithDefaults") is inaccurate: the normal option path reaches this. This also contradicts doc.go's claim that WithRetries is forwarded to the kernel's HTTP retry config.

Flagged independently by 3 reviewers (language, ops, devil's-advocate); the Thrift path (go-retryablehttp) honors the same input, so it's a silent cross-backend divergence.

Suggested fix

For RetryMax >= 0 with a degenerate range, substitute the placeholder wait bounds (as the disable branch already does) while keeping the caller's MaxRetries, rather than returning nil. Alternatively emit a logger.Warn naming the dropped values.

--- Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

Comment thread telemetry/aggregator.go
// connection-scoped error (empty statementID), or one whose statement
// was already flushed. Emit it standalone (flushed immediately) rather
// than dropping it silently, so a connection-level error still lands.
agg.batch = append(agg.batch, metric)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Medium] The "connection-scoped error-drop fix" targets a path no production code produces

This new else branch flushes a non-terminal "error" metric standalone instead of dropping it — but no production code emits metricType: "error". The only recordMetric callers are AfterExecute ("statement"), RecordOperation ("operation"), RecordConnectionConfig ("connection"), and completeStatement ("statement"); connection failures surface as operation metrics with errorType set, never this branch. TestConnectionScopedError_NotDropped reaches it only by calling recordMetric directly, a path unreachable from any exported API — so the advertised fix changes no observable behavior today.

Two concerns: (1) reviewers/operators may believe connection-level errors now land, when nothing routes here; (2) latent — if a producer is ever added, every non-terminal error triggers an immediate un-batched flushUnlocked (one HTTP request per error). Note this also modifies the shared telemetry path (both backends) inside a kernel-focused PR.

Suggested fix

Either wire a real producer for the "error" metric type, or reframe the fix/test to describe the branch as defensive (no current producer) so it isn't read as an active behavior change.

--- Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

arrow.StructOf(arrow.Field{Name: "x", Type: arrow.PrimitiveTypes.Int64}),
&arrow.DurationType{Unit: arrow.Microsecond},
arrow.FixedWidthTypes.MonthInterval,
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Low] Coverage guard omits the unsigned Arrow types the scanner handles, so its completeness claim is false

TestColumnTypeInfoScanTypeCoversScanner asserts "every Arrow type the value scanner (ScanCellCached) handles must also have a non-fallback entry in ColumnTypeInfoFor." But ScanCellCached handles Uint8/16/32/64 (returning int64), while ColumnTypeInfoFor has no arrow.UINT* case — they fall to the default arm (DatabaseTypeName "", ScanType *interface{}). This scannerTypes list silently omits every Uint type, so the stated invariant is already violated yet the test passes.

Practical impact is low (Databricks emits no unsigned types; the scanner arms are documented as defensive/unreachable), but the "guard" overclaims and would not catch a future scalar added to the scanner without a matching metadata entry.

Suggested fix

Either add a Uint* case to ColumnTypeInfoFor (mapping to BIGINT/int64, matching the scanner's output) or drive this list from a shared enumeration; add the Uint rows and assert the guard actually fails on an uncovered type.

--- Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

// The mapping mirrors the Thrift backend (internal/rows/rows.go getScanType /
// ColumnTypeDatabaseTypeName / ColumnTypeLength) so a query reports byte-identical
// column metadata on either backend — the same "identical results across backends"
// contract the value renderers hold. TestColumnTypeInfoMatchesThrift and the live

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Low] Doc comment names a guard test that does not exist

This comment claims "TestColumnTypeInfoMatchesThrift and the live TestKernelThriftColumnTypeParity are the guards," but no TestColumnTypeInfoMatchesThrift exists anywhere in the repo (grep across the tree returns only this comment). The actual pure-Go guards are TestColumnTypeInfoFor and TestColumnTypeInfoScanTypeCoversScanner. A maintainer chasing the named guard to understand or extend the parity contract finds nothing.

Suggested fix

Replace TestColumnTypeInfoMatchesThrift with the real names TestColumnTypeInfoFor / TestColumnTypeInfoScanTypeCoversScanner.

--- Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

Comment thread doc.go
carried by the backend-neutral WithRetries (also honored on the kernel path). It
is kernel-only because the Thrift WithRetries surface has no overall-budget
equivalent; it mirrors the pyo3/napi retry_overall_timeout knob. Zero keeps the
kernel's default budget (900s).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Low] WithKernelMaxChunksInMemory is absent from the doc.go experimental-options catalog

This "Experimental kernel-only options" list enumerates WithKernelTrustedCerts, WithKernelSkipHostnameVerify, WithKernelProxy, and WithKernelRetryOverallTimeout, but omits WithKernelMaxChunksInMemory — a public ConnOption added in this PR (connector.go:672) with complete godoc of its own. Nothing in doc.go mentions the CloudFetch in-memory-chunk / memory-tuning knob, so a consumer (or agent) using the package overview as the authoritative option catalog won't discover it.

Suggested fix

Add a WithKernelMaxChunksInMemory(n) bullet to the list, mirroring the other four.

--- Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

// because they compare scanned VALUES, not Rows.ColumnType* metadata. The
// expected DatabaseTypeName / ScanType / Length values are the ground truth
// captured from the Thrift backend on a live warehouse.
func TestColumnTypeInfoFor(t *testing.T) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Low] Coltype↔Thrift parity has no pure-Go drift guard (nightly-only)

ColumnTypeInfoFor (plus the duplicated scanType* vars) restates the Thrift path's getScanType / GetDBTypeName / ColumnTypeLength decisions from internal/rows/rows.go, but TestColumnTypeInfoFor pins its own hardcoded expectations rather than deriving them from the Thrift mapping. A change to the Thrift mapping (e.g. DECIMAL's scan type) leaves coltype.go silently divergent while CI stays green — the "byte-identical across backends" contract is then enforced only by the warehouse-gated TestKernelThriftColumnTypeParity (nightly, not PR CI), so parity regressions ship until a live run catches them. (The two switch on different type systems — Arrow IDs vs Thrift TTypeIds — so a shared map isn't trivial, but a cross-check test is.)

Suggested fix

Have a pure-Go test assert ColumnTypeInfoFor against the Thrift mapping functions directly for the shared Databricks types, so drift fails in CGO_ENABLED=0 PR CI.

--- Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if err := trySetProxy(c.cfg); err != nil {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Low] Proxy credential/bypass forwarding to the kernel is never verified

TestSetProxy asserts only err == nil. kernel_session_config_set_proxy stores the strings and returns OK regardless, so a swap or drop of the ProxyUsername / ProxyPassword / ProxyBypassHosts args is undetectable. The e2e TestKernelE2EProxyRejectsBadURL passes empty credentials and only proves the URL slot reaches the kernel; TestResolveKernelProxy / the round-trip test stop at config plumbing. A bug mapping ProxyUsername → the wrong slot (or dropping ProxyBypassHosts) would pass every test and silently break proxy basic-auth in production.

Suggested fix

Add an e2e case routing through a proxy that requires basic-auth (assert success with correct creds, failure with wrong), or expose a kernel-config readback seam to assert the credential/bypass args.

--- Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

Comment thread kernel_config.go
// path: newKernelBackend forwards it via kernelRetryConfig →
// kernel_session_config_set_retry_config, and a negative RetryMax (the disable
// form) maps to zero kernel retries. So it is neither rejected nor silently
// ignored here (it was rejected before the kernel exposed a retry-config setter).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

[Low] History-reference comment belongs in the commit message

This comment ends "(it was rejected before the kernel exposed a retry-config setter)," and the companion test opens "Previously rejected —". Both describe prior behavior; the code should describe the present contract, and the historical rationale is already captured by the diff/commit. These lines rot as the "before" recedes.

Suggested fix

Drop the parenthetical (and the test's "Previously rejected —" clause), keeping only the present-tense statement that WithRetries (including the disable form) is forwarded on the kernel path.

--- Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

@mani-mathur-arch

Copy link
Copy Markdown
Collaborator Author

Code Review Squad — Review

Score: 85/100 — MODERATE RISK

Large additive PR closing out the SEA-via-kernel new-items backlog (~8 features). The high-risk internals are solid: the alloc-free decimal renderer is correct at the uint64↔128-bit boundary (benchmarked 12.4ns/0-alloc), carries no injection surface, and proxy credentials/tokens never reach logs or telemetry — no Critical and no security findings. Remaining findings cluster around one real correctness gap (WithRetries silently ignored on a user-reachable input) plus advertised-but-thin items (a stale rejection message, a telemetry fix targeting a currently-dead path) and documentation/test-coverage polish. A separately-tracked KERNEL_REV re-pin (acknowledged by the author, to be fixed before finalizing) was dismissed from this review. All findings verified against head SHA 1cff39c.


Medium Findings

[Medium] Thrift-path rejection message names a stale 2-option subsetconnector.go:54-55

(Posted here rather than inline: the cited lines are pre-existing code not present in this PR's diff, so GitHub can't anchor an inline comment there.)

The rejection error hardcodes "(WithKernelTrustedCerts / WithKernelSkipHostnameVerify)", but the three options added in this PR — WithKernelProxy, WithKernelRetryOverallTimeout, WithKernelMaxChunksInMemory — all allocate KernelExperimental and hit the same KernelExperimental != nil gate. A caller who sets WithKernelProxy and forgets WithUseKernel is told about two TLS options they never touched, misdirecting a human or agent debugging the connect failure. TestWithKernelOptionsRejectedOnThriftPath only asserts errors.Is(ErrRequiresKernelBackend), so the staleness is untested. Flagged by 3 reviewers (agent-compat, architecture, ops).

Suggested fix

Generalize the message to "a WithKernel* option" (drop the specific list) or enumerate all five current options; update the guarding comment (connector.go:48-52) to drop "TLS."


Posted by code-review-squad · /full-review · feedback: #code-review-squad-feedback

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