ci: dispatch the SEA-via-kernel integration leg behind kernel labels + kernel CLOSE_STATEMENT telemetry & auth-rejection sentinel#403
Merged
mani-mathur-arch merged 3 commits intoJul 15, 2026
Conversation
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 14, 2026 17:01
5f940a0 to
90122c9
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-nightly-e2e
branch
from
July 14, 2026 18:43
2a43d24 to
ebedfc7
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 14, 2026 18:43
90122c9 to
2a9715b
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-nightly-e2e
branch
from
July 14, 2026 18:49
ebedfc7 to
23de162
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 14, 2026 18:49
2a9715b to
21a18d7
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-nightly-e2e
branch
from
July 14, 2026 18:53
23de162 to
fb098a1
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 14, 2026 18:53
21a18d7 to
c9ff45d
Compare
mani-mathur-arch
marked this pull request as ready for review
July 15, 2026 05:18
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 15, 2026 05:37
d49b653 to
1d357ba
Compare
|
Go integration tests triggered ( |
|
Go integration tests triggered ( |
mani-mathur-arch
force-pushed
the
mani/sea-kernel-nightly-e2e
branch
from
July 15, 2026 08:46
6376422 to
4512646
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 15, 2026 08:51
1d357ba to
2b09947
Compare
|
Integration test approval reset. New commits were pushed to this PR. Label(s) A maintainer must re-review and re-add a label to preview tests again. (The real gate runs in the merge queue.) Latest commit: 2b09947 |
mani-mathur-arch
force-pushed
the
mani/sea-kernel-nightly-e2e
branch
from
July 15, 2026 09:20
4512646 to
091accc
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 15, 2026 09:22
2b09947 to
a3d9c92
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-nightly-e2e
branch
from
July 15, 2026 09:49
091accc to
ac112d4
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 15, 2026 09:49
a3d9c92 to
cf06659
Compare
mani-mathur-arch
added a commit
that referenced
this pull request
Jul 15, 2026
…rnel Follow-up to the review round: the unsupported-authenticator default case in resolveKernelAuth still returned a plain errors.New, while every other unsupported kernel option wraps ErrNotSupportedByKernel and doc.go advertises that errors.Is(err, ErrNotSupportedByKernel) detects any unsupported kernel feature. So this PR shipped a documented contract its own code broke for token-provider / external / federated auth. Wrap it with %w to honor the contract (same fix #403 makes one commit up the stack — matching its wording so the two converge cleanly on rebase). The empty-PAT case stays unwrapped: a missing token is misconfiguration to fix, not a feature the kernel can't honor. Tighten the "non-PAT/non-OAuth authenticator rejected" test to assert errors.Is(err, ErrNotSupportedByKernel) instead of only err != nil, so the contract is pinned rather than documented as an exception. Verified: default-build suite passes, go vet + gofmt clean. Co-authored-by: Isaac Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
Extend the driver-test dispatch so the Go integration suite can run against the SEA-via-kernel backend, selected by label — the analogue of the existing Thrift labels, not a copy. Adds one kernel-namespaced label: - integration-test-kernel → sea backend, passthrough (real warehouse) The label resolves both proxy_mode and a new go_mode (thrift vs sea), and go_mode rides in the repository_dispatch client_payload. databricks-driver-test reads it to decide whether to build the kernel static lib and run the tagged (databricks_kernel) leg; the Thrift labels send go_mode=thrift and are unchanged. The new label is added to the on-new-commit label-drop list and the skip-stub guidance. The kernel label is passthrough (not replay): the sea leg has no committed recordings to replay yet, so there is no sea replay label until those are captured. The required merge-queue gate stays Thrift-only (go_mode pinned to thrift): the kernel leg is previewable on demand but not a required gate until the SEA backend ships in a released driver. Co-authored-by: Isaac Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
…h rejection Two review-driven fixes on the kernel backend, both Go-only. CLOSE_STATEMENT telemetry: kernelRows.Close() now fires the OnClose callback, so kernel queries record close latency / statement success-or-failure the same way the Thrift path does (conn gates that recording on OnClose firing). Previously it never fired, so kernel traffic emitted no close telemetry — including failures — a production observability blind spot. Next() is split into a thin wrapper that records the first non-EOF error as iterationErr (io.EOF is normal drain), which Close() passes to the callback; closeErr is nil since the kernel teardown has no fallible close RPC. The callback is armed only after newKernelRows finishes constructing (mirroring the Thrift NewRows), so a schema-fetch/import failure's cleanup Close() does not record a falsely-successful CLOSE_STATEMENT. Auth rejection sentinel: the unsupported-authenticator branch of resolveKernelAuth wrapped a bare errors.New, so fallback logic could only substring-match. It now wraps ErrNotSupportedByKernel via %w so callers can errors.Is it, matching the other kernel config rejections. The missing-personal-access-token error stays a plain error (missing-required-config, not an unsupported feature — it must not signal "fall back to Thrift"). Tests: TestKernelRowsCloseFiresOnClose (success, iterationErr propagation, idempotent double-close, nil-callbacks, construction-failure-no-success-close); strengthened the non-PAT authenticator rejection to assert errors.Is(ErrNotSupportedByKernel). Co-authored-by: Isaac Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
…x Thrift comment Addresses two review comments on the CLOSE_STATEMENT telemetry change: - The "construction-failure Close must not fire a success OnClose" subtest was a no-op: `fired` was never assignable to true, so it duplicated the nil-callbacks case and asserted nothing. Replaced with a test that drives the real newKernelRows cleanup path — a nil result stream makes kernel_result_stream_get_schema return a defined InvalidArgument error (the kernel null-checks the handle, never UB), so newKernelRows takes its r.Close() cleanup branch and returns an error, and the supplied OnClose must not fire. Verified by mutation: arming the callback before the schema import makes the test fail as intended. - Reworded the newKernelRows comment that claimed the deferred callback assignment matches Thrift's NewRows "just before returning" — Thrift actually assigns closeCallback during construction. Dropped the inaccurate comparison and state the invariant directly. Co-authored-by: Isaac
mani-mathur-arch
force-pushed
the
mani/sea-kernel-nightly-e2e
branch
from
July 15, 2026 12:40
ac112d4 to
0c68dfb
Compare
mani-mathur-arch
force-pushed
the
mani/sea-kernel-c2-dispatch
branch
from
July 15, 2026 12:41
cf06659 to
94ced6a
Compare
Base automatically changed from
mani/sea-kernel-nightly-e2e
to
mani/sea-kernel-consolidated
July 15, 2026 13:48
mani-mathur-arch
merged commit Jul 15, 2026
94ced6a
into
mani/sea-kernel-consolidated
5 checks passed
mani-mathur-arch
added a commit
that referenced
this pull request
Jul 15, 2026
…rnel Follow-up to the review round: the unsupported-authenticator default case in resolveKernelAuth still returned a plain errors.New, while every other unsupported kernel option wraps ErrNotSupportedByKernel and doc.go advertises that errors.Is(err, ErrNotSupportedByKernel) detects any unsupported kernel feature. So this PR shipped a documented contract its own code broke for token-provider / external / federated auth. Wrap it with %w to honor the contract (same fix #403 makes one commit up the stack — matching its wording so the two converge cleanly on rebase). The empty-PAT case stays unwrapped: a missing token is misconfiguration to fix, not a feature the kernel can't honor. Tighten the "non-PAT/non-OAuth authenticator rejected" test to assert errors.Is(err, ErrNotSupportedByKernel) instead of only err != nil, so the contract is pinned rather than documented as an exception. Verified: default-build suite passes, go vet + gofmt clean. Co-authored-by: Isaac Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
mani-mathur-arch
added a commit
that referenced
this pull request
Jul 17, 2026
…tly workflows for e2e tests (#399) ## What Extends the SEA-via-kernel backend for the Go driver with the full DAIS gap-closure + PuPr feature set: authentication, session setup, type rendering, query execution, telemetry, richer TLS, kernel-log routing, and CI. This PR consolidates what was a 5-PR stack (#400 richer-TLS, #401 log-unify, #402 nightly-e2e, #403 c2-dispatch) into a single reviewable PR. The stack was linear, so the branches were fast-forwarded into this one — every change is preserved as a **distinct, logically-scoped commit** (23 commits), so it reads commit-by-commit rather than as one blob. #400–#403 now show as merged (their commits live here). ## Features **Authentication** - **OAuth M2M / U2M** — the kernel drives its own auth flow from `cfg.Authenticator` (mirroring pyo3/napi). Adds a `kernel.Auth` descriptor + `resolveKernelAuth`, wired through the `set_auth_pat` / `_m2m` / `_u2m` C-ABI setters. `cfg.Authenticator` is the single source of truth (last-writer-wins, matching Thrift). - **Unsupported auth is sentinel-wrapped** — token-provider / external / federated authenticators reject with `%w`-wrapped `ErrNotSupportedByKernel`, the same programmatic-fallback contract every other unsupported kernel option follows. **Session setup** - **Initial namespace** — post-connect `USE CATALOG` / `USE SCHEMA` with identifier quoting (the kernel C ABI has no namespace setter). - **Metric-view metadata** — `config.EffectiveSessionParams()` folds the server conf in backend-neutrally, so the kernel path sends the identical conf Thrift does. **Type rendering** - **INTERVAL** day-time & year-month rendering in `internal/arrowscan` (kernel returns native arrow values; formatted Go-side to the Thrift path's string form). Handles the `math.MinInt64` / `math.MinInt32` negation bound without overflow. - Parity coverage for **TIMESTAMP vs TIMESTAMP_NTZ** and **VARIANT / GEOMETRY** (live-probed on both backends). **Query execution & telemetry** - **Bound query parameters** via the kernel raw-param C ABI (`kernel_statement_bind_parameter`). The positional/named + SQL-NULL/empty-string decision is a pure `paramBindArg` seam, unit-tested under `CGO_ENABLED=0`. - **Kernel errors surfaced as `DBExecutionError`** carrying sqlstate + server query id, so `errors.As` → `SqlState()` / `QueryId()` works on the kernel path. The execute path deliberately reports **non-retryable** (a sent statement may have committed — no double-write), matching Thrift. - **Server query id** via a real `StatementID()` accessor (`kernel_executed_statement_query_id`), threaded into EXECUTE_STATEMENT telemetry, plus CLOSE_STATEMENT telemetry on the result-read path. - **Cancelled execute** evicts a session-fatal conn and preserves the kernel error metadata (multi-`%w`: `errors.Is(DeadlineExceeded)` AND `errors.As(*KernelError)` both hold). **Richer TLS (Go options)** - CA-bundle + independent hostname-skip setters mapped to the kernel's own TLS knobs (defensive PEM copy; the wholesale custom `WithTransport` stays rejected). **Kernel logging** - Kernel log output routed through the driver log level with connId/corrId/queryId correlation; allocation-free above Debug (guards the Arrow-batch hot path). - **scope note (please read before flagging):** - This unifies the *control knob*, not the *sink*, and that boundary is intentional. `DATABRICKS_LOG_LEVEL`/`SetLogLevel` now drives both the Go binding lines and the kernel's Rust lines from one level. But they stay two physical streams: Go lines go through `logger.Logger` (and honor `logger.SetLogOutput`), while the kernel's Rust lines go straight to stderr — the kernel C ABI exposes **no sink/callback hook**, so there is currently no way to route them through the Go logger. Consequences a reviewer will notice, all expected: - A custom `SetLogOutput`/file captures only the Go lines; Rust lines stay on stderr. - With the default sink both land on stderr but only *race* there — not a single ordered, merged stream. - The Rust subscriber's level is sampled once, at the first kernel connect. Fully merging both into one ordered sink requires a kernel log callback and is tracked separately (<TICKET>); it's out of scope here because it's a kernel-side ABI change, not a driver one. **CI** - A scheduled + dispatchable **nightly E2E** workflow that runs the credential-gated e2e + Thrift-vs-kernel parity suites against a real warehouse (the ordinary CI injects no warehouse secrets, so those tests otherwise skip). SEA-via-kernel integration leg gated behind a kernel label. ## Notable behavior - Bound query parameters are now supported (previously rejected at connect). - **Staging operations remain rejected** — the kernel path can't perform the local file transfer and the C ABI surfaces no staging signal. ## Testing - **Default pure-Go** (`CGO_ENABLED=0`): `go build` / `go vet` / `go test ./...` — 24 packages ok. - **Tagged kernel path** (`CGO_ENABLED=1 -tags databricks_kernel`, linked against a locally-built kernel `.a` at `KERNEL_REV`): 24 packages ok. - **Live e2e + parity** against a real warehouse: all pass — data types (incl. variant/geometry/decimal), NTZ, params-vs-Thrift (10/10), CloudFetch, cancellation, connection pool (40/40), StatementID, initial namespace, and **M2M** (OAuth client-credentials). - `gofmt` clean; Isaac Review clean (0 final comments). ## Merge gate - **Re-pin `KERNEL_REV` at merge time.** It currently points at the kernel dependency's PR-head SHA (GC-able once that kernel change merges); bump it to the resulting kernel `main` SHA, re-sync the cgo drift assertions in `cgo.go` if any signatures changed, and run `make test-kernel` against the new rev. This pull request and its description were written by Isaac. --------- Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context for reviewers
Two changes for the SEA-via-kernel backend (the alternative backend that talks to Databricks SQL through the Rust
databricks-sql-kernelstatic lib over a C ABI, behind thedatabricks_kernelbuild tag):databricks-driver-testdispatch so the Go integration suite can run against the SEA-via-kernel backend, selected by label.CLOSE_STATEMENTtelemetry fromkernelRows.Close(), and make the unsupported-authenticator rejection programmatically detectable via theErrNotSupportedByKernelsentinel.The two are unrelated in subject but small and both review-driven; they share this PR because the telemetry/sentinel commit was folded onto this branch. Reviewable independently — the CI change touches only
.github/workflows/, the kernel change onlyinternal/backend/kernel/+kernel_config*.go.Stack position (top of the stack):
1. CI: kernel integration-test dispatch
Extend the
databricks-driver-testdispatch so the Go integration suite can run against the SEA-via-kernel backend, selected by label — the analogue of the existing Thrift labels, not a copy.integration-testintegration-test-fullintegration-test-kernelproxy_modeand a newgo_mode(thrift vs sea).go_moderides in therepository_dispatchclient_payload. The receiver in driver-test reads it to decide whether to build the kernel static lib and run thedatabricks_kernel-tagged leg. Thrift labels sendgo_mode: thriftand are unchanged.go_modepinned tothrift): the kernel leg is previewable on demand but not a required gate until the SEA backend ships in a released driver.Two-repo change
This is the driver-side half. The receiver-side half (read
go_mode, sea-gated kernel build prerequisites, threadDATABRICKS_GO_MODE, guard sea+replay) is a separate PR indatabricks-driver-test. The runner + harness already handleDATABRICKS_GO_MODE=seaend-to-end. On the receiver side the review gate caught (and fixed before merge) two real defects worth knowing about: a backend-awareRECORDING_NAME(databricks-go-${go_mode}) so a sea run can't clobber/serve the committed thrift recordings, and a narrowed git-tokeninsteadOfscope (exactdatabricks-sql-kernelrepo, not the wholedatabricks/org) so the kernel App-token isn't applied to unrelated org fetches.2. Kernel backend: CLOSE_STATEMENT telemetry + auth-rejection sentinel
Two review-driven, Go-only fixes on the kernel backend.
CLOSE_STATEMENT telemetry
connrecordsCLOSE_STATEMENT/ close latency / statement success-or-failure only when the rows'OnClosecallback fires (the Thrift path fires it).kernelRows.Close()never called it, so kernel queries emitted no close telemetry — including failures — a production observability blind spot.Close()now times the teardown and firesOnClose(latencyMs, chunkCount, iterationErr, nil).closeErris nil because the kernel teardown (C stream/statement close) has no fallible close RPC to report, unlike Thrift'sCloseOperation.Next()is split into a thin wrapper overnext()that records the first non-EOF error asiterationErr(io.EOFis normal drain, not a failure), whichClose()passes to the callback — mirroring the Thrift path'siterationErr.newKernelRowsfinishes constructing successfully, so the cleanupClose()on a schema-fetch/import failure does not record a falsely-successfulCLOSE_STATEMENT(matching the ThriftNewRows, which sets the close callback just before returning).closedguard means a double-ClosefiresOnCloseexactly once.Auth-rejection sentinel
resolveKernelAuth's unsupported-authenticator branch (token-provider / external / federated) returned a bareerrors.New, so fallback logic ("kernel can't honor this auth → use Thrift") could only fragile substring-match. It now wrapsErrNotSupportedByKernelvia%wso callers canerrors.Isit, matching the other kernel-config rejections.Deliberately not wrapped: the "requires a personal access token" (empty-token) error — that is missing-required-config, not an unsupported feature; wrapping it would wrongly signal "fall back to Thrift" for a forgotten token.
Testing
integration-test→thrift/replay,integration-test-full→thrift/passthrough,integration-test-kernel→sea/passthrough.TestKernelRowsCloseFiresOnClose(tagged): success path (nil errs), iterationErr propagation, idempotent double-close, nil-callbacks-safe, construction-failure-no-success-close.TestValidateKernelConfig: strengthened the non-PAT authenticator rejection to asserterrors.Is(err, ErrNotSupportedByKernel).CGO_ENABLED=0+ taggeddatabricks_kernel: build + vet + test — 24 packages ok, 0 fail each.Stacking
Stacked on #402 (
mani/sea-kernel-nightly-e2e).This pull request and its description were written by Isaac.