Skip to content

SEA backend (use_sea=True): metadata methods return raw SHOW column names instead of JDBC/DB-API column names (Thrift & kernel differ) #844

Description

@eric-wang-1990

Summary

When the connection uses the native SEA backend (databricks.sql.connect(..., use_sea=True)), the metadata methods Cursor.catalogs(), .schemas(), .tables(), and .columns() return result sets whose column names are the raw SHOW … output columns (e.g. catalog, databaseName, namespace/tableName, col_name) instead of the JDBC / DB-API metadata column names (TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, …).

The Thrift backend (default) and the Rust kernel backend (use_kernel=True) both return the JDBC-standard column names for these same calls. So the native SEA path is inconsistent with the other two backends, and any code that reads metadata results by the documented JDBC column names breaks under use_sea=True.

Affected API

Cursor.catalogs(), Cursor.schemas(), Cursor.tables(), Cursor.columns() — via the SEA backend only.

Expected vs. actual cursor.description column names

Call Expected (Thrift & kernel, JDBC/DB-API) Actual (native SEA)
catalogs() TABLE_CAT catalog
schemas() TABLE_SCHEM (+ TABLE_CATALOG) databaseName
tables() TABLE_CAT, TABLE_SCHEM, TABLE_NAME, TABLE_TYPE, REMARKS namespace, tableName, isTemporary, information, catalogName, tableType, remarks
columns() TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE, … col_name, catalogName, namespace, tableName, columnType, columnSize, decimalDigits, radix, isNullable, remarks, ordinalPosition, isAutoIncrement, isGenerated

Root cause

In src/databricks/sql/backend/sea/backend.py, the metadata methods execute raw SQL and return the SHOW command's result set as-is, with no projection/rename to the JDBC metadata schema:

  • get_catalogs()SHOW CATALOGS
  • get_schemas()SHOW SCHEMAS IN <catalog> [LIKE …]
  • get_tables()SHOW TABLES IN … [LIKE …]
  • get_columns()SHOW COLUMNS …

The columns of those SHOW … result sets differ from the GetCatalogs/GetSchemas/GetTables/GetColumns Thrift RPC schemas (which follow the JDBC DatabaseMetaData contract). The SEA backend needs to map/rename these to the same column names the Thrift and kernel backends expose so metadata results are backend-agnostic.

Impact

Any consumer that reads metadata results positionally-by-name against the documented JDBC contract (e.g. row["TABLE_NAME"], or indexing cursor.description by TABLE_CAT/TABLE_SCHEM/COLUMN_NAME) silently breaks when use_sea=True, while working on Thrift and the Rust kernel. This makes the backend non-substitutable for metadata use cases.

Reproduction

from databricks import sql

conn = sql.connect(
    server_hostname="<host>",
    http_path="<warehouse-http-path>",
    access_token="<token>",
    use_sea=True,   # native SEA backend
)
with conn.cursor() as cur:
    cur.catalogs()
    print([c[0] for c in cur.description])   # SEA: ['catalog']   — expected: ['TABLE_CAT', ...]
    cur.tables()
    print([c[0] for c in cur.description])   # SEA: ['namespace','tableName',...] — expected: [...,'TABLE_NAME',...]

Run the same with the default (Thrift) connection or use_kernel=True and the column names follow the JDBC contract.

Environment

  • databricks-sql-connector installed from main (git+https://github.com/databricks/databricks-sql-python@main), connector main HEAD d303706497c3 (2026-07-03).
  • Python 3.11, against a SQL warehouse.
  • Observed via a cross-backend conformance suite that runs the identical tests over Thrift, native SEA, and the Rust kernel: Thrift and kernel pass all metadata assertions (23 passed / 0 failed on kernel); native SEA fails ~18 of them purely on the column-name mismatch.

Other native-SEA divergences surfaced by the same run (may warrant separate issues)

  1. Statement cancel returns HTTP 501 (Not Implemented). Cursor.cancel() on the SEA backend fails with RequestError: SEA HTTP request failed with status 501 (seen for cancel of a running statement and for concurrent-cancel). Thrift supports CancelOperation.
  2. schemas(catalog_name=<nonexistent>) raises instead of returning an empty result. Native SEA raises ServerOperationError: [NO_SUCH_CATALOG_EXCEPTION] Catalog '<x>' was not found where the JDBC/DB-API convention (and Thrift) is an empty result set for a non-matching filter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions