morningman opened a new issue, #67578:
URL: https://github.com/apache/doris/issues/67578
This issue tracks two halves of one goal: bringing Doris's **Arrow Flight
SQL server up to the
spec's feature set**, and maintaining an **official `doris` driver in the
ADBC Driver Foundry**, so
that a user runs `dbc install doris` and connects with a single URI.
Part of #65615. Part A depends on #67577 (one protocol-agnostic session and
execution layer) for its
session and prepared-statement items; Part B can start before that and ship
a pre-release built on
the subset that works today.
## Why
ADBC is becoming for columnar analytics what JDBC is for row-oriented
access. The ADBC Driver
Foundry already hosts drivers for ClickHouse, Databricks, Snowflake, Trino,
Spark, SingleStore,
Presto, Redshift, MSSQL and BigQuery, all implementing ADBC 1.1 and callable
from Go, Python, R and
Rust. Doris is not on that list, so when someone picks a data source in
pandas, polars, Ibis or R,
Doris is not among the options.
Doris users are not blocked today - they use the generic
`adbc_driver_flightsql` and then deal with
the gaps themselves. Doris's own FAQ lists twelve of them: BE unreachable
from the client unless
`public_host` or an Nginx reverse proxy is configured, tokens evicted when a
client never calls
`close()`, DATETIME arriving as an integer on the Java side, nested ARRAY
failing in JDBC clients,
gRPC message-size limits, `parameter ordinal 1 out of range` on
prepared-statement binding. A driver
is supposed to absorb that.
At the same time the server implements only a small part of the spec.
Session actions, parallel
endpoints, native metadata commands, bulk ingestion, cancellation and
renewal are all missing, so
users emulate them with SQL strings - `SET exec_mem_limit=2000` in place of
a session option.
**Design principles.** One ADBC connection is one Doris session is one
Flight SQL connection: no
second channel and no MySQL-protocol fallback, because a fallback path hides
missing capabilities
instead of reporting them - a gap should surface as
`ADBC_STATUS_NOT_IMPLEMENTED` and appear in the
capability matrix. Only the spec, no private RPCs: Doris-specific semantics
ride on session-option
names and Arrow extension type names, which are the extension points the
spec already provides. The
control plane stays in the FE and the data plane in the BE, but both belong
to one session - session
state only affects planning, and after planning the FE issues tickets and
the BE streams, so a
distributed data plane does not break the session's singularity.
## Status convention
Same as #65615: `[x]` means merged or confirmed complete; `[ ]` means open
or needs follow-up.
## Part A - server-side completeness
- [ ] **A1. Session lifecycle through the standard actions.**
`SetSessionOptions` /
`GetSessionOptions` / `CloseSession` mapped onto Doris session variables
(`SET`, `SHOW VARIABLES`),
with `adbc.connection.current_catalog` and `current_db_schema` as session
options (`SWITCH`,
`USE`). `CloseSession` also invalidates the session's authentication
context, as the spec requires.
The session object is the one from #67577, held by the Flight adapter,
which removes the separate
token cache and the `invalid bearer token` failure mode with it. Covers
#59742 and the client-close
half of #36331.
- [ ] **A2. Parallel result return.** `GetFlightInfo` returns N
`FlightEndpoint`s, one per BE result
sink, each with its own ticket, fetched concurrently. Three shapes:
scan-only queries grouped by
tablet (row bandwidth equals cluster bandwidth); aggregation or join at
the top, one sink per
fragment instance (what `enable_parallel_result_sink` already does - this
proposes making it the
default rather than an opt-in); a global sort at the top, still multiple
endpoints but with
`FlightInfo.ordered = true` and endpoint order equal to result order, so
clients fetch in parallel
and concatenate. Tickets must be self-contained and verifiable (query id,
fragment instance id,
expiry, signature) so the BE never has to call back to the FE, which would
make the FE the new
bottleneck. BE addressing uses the spec's
`arrow-flight-reuse-connection://?` location, which is a
cleaner and standard answer to the reachability problem behind #62538,
#62217, #59490 and #44599.
Related: #67368, where the short-circuit point-query path registers no
Flight endpoint at all.
- [ ] **A3. Native metadata commands.** `CommandGetCatalogs`,
`GetDbSchemas`, `GetTables`,
`GetTableTypes`, `GetXdbcTypeInfo`, `GetPrimaryKeys`, `GetImportedKeys`,
`GetExportedKeys`,
`GetSqlInfo` served from catalog metadata directly as Arrow, instead of
being rewritten into
`information_schema` SQL. Doris's multi-catalog model (internal plus Hive,
Iceberg, JDBC, Paimon)
maps exactly onto ADBC's catalog / db_schema / table hierarchy, so one
ADBC connection gives a
Python client a federated view of the whole lakehouse - something the
Snowflake and ClickHouse
drivers cannot offer.
- [ ] **A4. Bulk ingestion through `CommandStatementIngest`.** ADBC's
`adbc.ingest.target_table` plus
`BindStream` plus `ExecuteUpdate` is `DoPut` carrying
`CommandStatementIngest`, with
`DoPutUpdateResult` returned in `PutResult.app_metadata`. Two pieces on
the Doris side: an Arrow IPC
input format for Stream Load, and routing `CommandStatementIngest` to it,
so `conn.adbc_ingest()`
lands Arrow memory without a CSV or JSON round trip. The FE should
redirect the ingest `DoPut` to
the BEs the way Stream Load already redirects, and allow parallel writes,
otherwise ingestion
becomes the new bottleneck. Ingest modes map to `CREATE TABLE` + load,
Stream Load,
`INSERT OVERWRITE`, and create-then-append. Covers the ingestion request
in #25514.
- [ ] **A5. Prepared statements and parameter binding.**
`ActionCreatePreparedStatementRequest`
returns an opaque handle plus, optionally, result and parameter schemas;
per the spec the result
schema may depend on the bound parameters, so it is better to return
nothing than something wrong.
Doris reuses the prepared-statement object extracted in #67577 and
receives Arrow parameter batches
over `DoPut`. `ExecuteSchema` needs plan-without-execute, which the FE
planner can already do.
Covers
[apache/arrow-java#1009](https://github.com/apache/arrow-java/issues/1009); the
`parameter ordinal 1 out of range` error itself is the upstream bug
[apache/arrow#40118](https://github.com/apache/arrow/issues/40118) and
needs tracking there.
- [ ] **A6. Cancellation, renewal and polling.** `AdbcStatementCancel` onto
`CancelFlightInfo` with
the query id taken from `FlightInfo.app_metadata`, cancelling the
associated poll descriptors and
any issued-but-unconsumed tickets; `RenewFlightEndpoint` to extend the
life of a large result;
`PollFlightInfo` for asynchronous submission and progress of long queries.
- [ ] **A7. Authentication and compression.** Bearer token from `Handshake`
as the session credential,
mTLS, and the existing LDAP and Kerberos plugins; Arrow IPC body
compression (LZ4, ZSTD) negotiated
as a connection option, which matters most across data centers.
## Part B - the official driver
- [ ] **B1. Repository and stack.** An `adbc-drivers/doris` repository under
the Foundry (open an
issue in `adbc-drivers/onboarding` from the template; Foundry admins
create the repo with CI,
workflows and validation templates, then the Doris community members are
invited). Written in Go on
`driverbase-go`, built as a shared library exporting `AdbcDriverDorisInit`.
- [ ] **B2. Layering.** `driver/` (ADBC surface), `flight/` (handshake,
token renewal, endpoint
routing and parallel scheduling, retries), `types/` (type mapping and
Arrow extension registration),
`catalog/` (metadata commands to `GetObjects`), `ingest/`. The type
mapping in `types/` shares one
source of truth with the server via code generation, so the two cannot
drift.
- [ ] **B3. ADBC 1.1 surface** mapped onto Flight SQL calls, including
`ExecutePartitions` returning
serialized `FlightEndpoint`s as partitions and `ReadPartition` opening one
`DoGet` each, with
default parallelism `min(len(endpoints), GOMAXPROCS)`.
- [ ] **B4. Driver options and URI.** `doris.read.parallelism`,
`doris.read.compression`,
`doris.grpc.max_message_size`, `doris.ingest.format`,
`doris.catalog.include_external`, and a single
URI form `doris://user:pass@fe_host:port/catalog.db?param=value` - no more
`grpc://` in Python
versus `jdbc:arrow-flight-sql://` in Java. The initial catalog/schema in
the URI covers
[apache/arrow-java#829](https://github.com/apache/arrow-java/issues/829).
## Testing
- [ ] **Baseline first, before any code.** Install the Foundry `mysql`
driver, point it at Doris's
MySQL port, run the Foundry validation suite and record what fails. That
list is both the
requirements document and good community-issue material. (The Foundry
`mysql` driver already
documents a non-MySQL backend, Databend, through its `mysql.vendor`
option, so this is a supported
way to measure.)
- [ ] A `DriverQuirks` implementation declaring Doris's capabilities, a
`docs/doris.md` skeleton
filled in from validation results, and a `compose.yaml` so validation runs
against a real cluster in
CI on every PR and release.
- [ ] Parallel-read correctness in the Doris repo: merged multi-endpoint
results equal the
single-endpoint result, `ordered = true` really is ordered, and partial
endpoint failure propagates
the error as expected. The cross-protocol consistency suite from #67577 is
reused as is.
- [ ] Throughput and memory baselines on a ClickBench or TPC-H result-fetch,
comparing `jdbc:mysql`,
the generic flightsql driver and the official driver.
## Release and promotion
The Foundry's bar for a first release is Linux, macOS and Windows, the three
minimum capabilities
(query, bulk ingest, `GetObjects`), and a passing standard validation run;
anything short of that
ships as a pre-release such as `v0.1.0-alpha.1`.
Suggested sequence: Part B ships an alpha on the subset that works today,
the validation report then
drives Part A's priorities, and each finished Part A item removes one
`NOT_IMPLEMENTED` from the
driver. When the minimum set is complete, tag v0.1.0 and ask the Foundry
admins for CDN
distribution.
Arrow Flight SQL is still marked experimental in Doris, which is the right
window for the breaking
changes in A1 (session and token lifetime) and A2 (parallel return changes
result arrival order for
unordered queries). Both go in the release notes. Proposed condition for
promoting Flight SQL out of
experimental: **A1 through A6 complete and the Foundry validation minimum
set green.**
The generic `adbc_driver_flightsql` keeps working and is not deprecated; the
official driver is the
recommended path, not the only one.
## Rejected alternatives
- **Rename the generic flightsql driver and publish it under the Foundry.**
Fastest way onto the
driver list, but it solves none of the user-visible problems - the
connection string, BE
reachability and type conversion all stay with the user - and replacing it
later costs more than
doing it properly once.
- **Wrap `go-sql-driver/mysql` in sqlwrapper and speak the MySQL protocol.**
Zero kernel changes and
compatible with every version, but the Arrow conversion happens on the
client, so it unifies the
API without gaining any transport speedup - which was the reason for doing
this at all. Valuable as
the measurement baseline above, not as the destination.
- **Two channels on the client: control plane over MySQL, data plane over
Flight SQL.** The session is
then not shared; see the same entry in #67577.
- **Private Flight extension RPCs for Doris-specific semantics.** Session
options and Arrow extension
types already cover it, and private RPCs would make the driver unusable by
generic clients, which
defeats the point of shipping a standard driver.
## References
- Arrow Flight SQL spec: https://arrow.apache.org/docs/format/FlightSql.html
- Building a driver in the ADBC Driver Foundry:
https://adbc-drivers.org/building-drivers/
- Existing Foundry drivers: https://adbc-drivers.org/drivers/
- `driverbase-go`: https://github.com/adbc-drivers/driverbase-go
- Foundry validation suite: https://github.com/adbc-drivers/validation
- Doris Arrow Flight SQL docs:
https://doris.apache.org/docs/dev/connection-integration/arrow-flight-sql
- The original Arrow Flight SQL issue: #25514
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]