Skip to content

databricks: support Lakehouse//RT, auto-detecting the SEA backend - #9879

Open
dey-abhishek wants to merge 4 commits into
rilldata:mainfrom
dey-abhishek:databricks-rt-sea-main
Open

databricks: support Lakehouse//RT, auto-detecting the SEA backend#9879
dey-abhishek wants to merge 4 commits into
rilldata:mainfrom
dey-abhishek:databricks-rt-sea-main

Conversation

@dey-abhishek

@dey-abhishek dey-abhishek commented Sep 11, 2026

Copy link
Copy Markdown

databricks: support Lakehouse//RT, auto-detecting the SEA backend (backward compatible with DBSQL)

Problem

Lakehouse//RT (real-time) Databricks warehouses only speak the Statement Execution
API (SEA)
protocol and reject the Thrift/HiveServer2 protocol that databricks-sql-go
uses by default:

BAD_REQUEST: Lakehouse/RT is not supported for Thrift protocol.
Please update your Databricks SQL Driver version to the latest version,
which supports the Statement Execution API protocol  (HTTP 400)

Rill currently pins databricks-sql-go v1.10.0, which predates the driver's SEA/kernel
backend, so Rill cannot connect to Lakehouse//RT warehouses at all — the connector fails
at open, before any query runs.

What this changes

  1. Bump databricks-sql-go v1.10.0 → v1.15.1. v1.15.0 introduced the opt-in
    SEA/kernel backend (useKernel=true / WithUseKernel(true)). The default remains
    Thrift, so this bump alone changes no behavior.
  2. Auto-detect Lakehouse//RT (no configuration needed). On first connect the
    connector probes once; if the warehouse rejects Thrift (the RT signal), it
    transparently switches to the SEA backend. The probe result is cached and shared by
    both the OLAP path and the warehouse ingest path (effectiveDSN). DBSQL warehouses
    accept Thrift and are left unchanged. This means a user can add an RT warehouse in
    the UI with no special knowledge — no use_kernel, no UseThriftClient — and it
    just works.
  3. use_kernel connector property (default false) as an explicit override. Forces
    SEA and skips the probe. Rarely needed given auto-detection, but useful to force SEA.
  4. warehouse.go ingest fallback. The bulk-ingest path prefers
    GetArrowIPCStreams (unchanged Thrift path). The SEA backend doesn't implement IPC
    streams — it exports Arrow C Data — and returns an error wrapping
    dbsqlerr.ErrNotSupportedByKernel. On that sentinel we fall back to
    GetArrowBatches and re-serialize each record to a self-contained Arrow IPC stream
    (via the driver's Arrow v12 ipc.Writer), which the existing v18 ipc.Reader
    parquet path consumes untouched. This bridges the driver's Arrow v12 ↔ Rill's Arrow
    v18 without changing the DBSQL path. Rill's OLAP path (olap.go, sqlx rows) was
    already SEA-compatible and is unchanged.
  5. information_schema.Lookup de-JOINed. The per-table schema lookup JOINed
    information_schema.tables and columns; that join forces a shuffle that RT's Photon
    rejects (PHOTON_INTERNAL_ERROR, retry unsupported), breaking the schema browser.
    Split into two filtered point-lookups (no shuffle) — verified against a real RT
    warehouse (the JOIN fails, both point-lookups succeed); equivalent on DBSQL.

Backward compatibility

  • Default builds (no databricks_kernel tag) compile unchanged; use_kernel defaults to
    false, so DBSQL warehouses are byte-for-byte on the same Thrift path.
  • If use_kernel: true is set in a build without the kernel backend linked, the driver
    fails at connect with a clear error wrapping ErrKernelNotCompiled (no silent Thrift
    fallback, no crash).

Build / distribution note (needs a maintainer decision)

The SEA backend links a native library and is gated behind -tags databricks_kernel
with CGO. Rill already builds with CGO enabled (DuckDB, confluent-kafka), so the only
additional cost is adding the tag and linking the per-platform kernel archive
(databricks-sql-kernel-bindings, ~60–95 MB/platform). This PR makes RT support
available and correct when built with the tag, and a graceful error otherwise. How
(and whether) to enable the tag in shipped release binaries is left as a follow-up for
maintainers.

Testing

  • New unit tests runtime/drivers/databricks/dsn_internal_test.go: TestResolveDSN
    (backend selection — no useKernel by default, set when opted in, DSN pass-through,
    ?/& joining, no duplicate), TestRTRequiresSEA (only the Thrift-not-supported
    message triggers the switch — 403/refused/nil don't), and TestWithUseKernel.
  • Auto-detection verified live against a real Lakehouse//RT warehouse with no
    use_kernel set: the connector logged the Thrift→SEA switch and both the connector
    and a model reconciled; a regular DBSQL warehouse stayed on Thrift and reconciled.
  • Manual, both paths, end to end (kernel-tag build, macOS arm64):
    • Lakehouse//RT (use_kernel: true): connector + a SELECT current_catalog(), now()
      model reconcile successfully and materialize into DuckDB.
    • Regular DBSQL serverless warehouse (use_kernel unset, Thrift): a
      SELECT current_catalog(), current_version(), now() model reconciles successfully —
      current_version() works here but is UNRESOLVED_ROUTINE on RT, confirming the
      Thrift path is unaffected.

Checklist:

  • Covered by tests (unit test for DSN resolution; manual e2e for both backends)
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases (missing kernel build → clear error; no duplicate param)
  • Linked the issues it closes
  • Checked if the docs need to be updated (updated the Databricks connector doc)
  • Intend to cherry-pick into the release branch
  • I'm proud of this work!

Lakehouse//RT warehouses only speak the Statement Execution API (SEA) and
reject the Thrift protocol, so Rill (pinned to databricks-sql-go v1.10.0)
could not connect to them at all.

Bump databricks-sql-go v1.10.0 -> v1.15.1 (adds the SEA/kernel backend) and
auto-detect RT: on first connect the connector probes once and, if the
warehouse rejects Thrift, transparently switches to the SEA backend. The
decision is cached and shared by both the OLAP path and the warehouse ingest
path (effectiveDSN), so an RT warehouse works with no configuration. DBSQL
warehouses accept Thrift and are unchanged. A `use_kernel` connector property
(default false) is available as an explicit override.

The SEA backend exports Arrow C Data rather than IPC streams, so the bulk
ingest path in warehouse.go falls back from GetArrowIPCStreams to
GetArrowBatches (re-serialized to a self-contained Arrow IPC stream via the
driver's Arrow v12 writer, which the existing v18 ipc.Reader consumes) when
the driver returns ErrNotSupportedByKernel. The OLAP path already worked over
SEA.

information_schema.Lookup previously JOINed information_schema.tables and
columns; that join forces a shuffle that RT's Photon rejects
(PHOTON_INTERNAL_ERROR, retry unsupported), breaking the schema browser. Split
it into two filtered point-lookups (no shuffle); equivalent on DBSQL.

Adds unit tests for DSN resolution, the RT-detection predicate, and the
useKernel DSN helper, and documents the behavior.

Co-authored-by: Isaac <no-reply@databricks.com>
@k-anshul k-anshul self-assigned this Sep 11, 2026
dey-abhishek and others added 3 commits September 13, 2026 10:35
Adds TestOLAP_LakehouseRT, a live integration test that drives the full Rill
Databricks OLAP path against a Lakehouse//RT (Reyden) SQL warehouse over the
auto-detected SEA backend. The connector config passes only the DSN (no
use_kernel), so a passing query proves the Thrift->SEA autodetection end to end.

Because Lakehouse//RT speaks only SEA, the test requires the SEA-via-kernel
backend and carries //go:build databricks_kernel (CGO), excluding it from the
default Thrift-only build and the standard `go test -short ./...` CI job. It is
otherwise gated like the existing Databricks/Snowflake live tests: a leading
t.Skip disables it by default, testmode.Expensive keeps it out of normal runs,
and it needs RILL_RUNTIME_DATABRICKS_RT_TEST_DSN to point at an RT warehouse.

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
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