mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-14 07:42:28 +00:00
feat(sql): bind query parameters over Flight DoExchange (#4345)
`execute_query` / `execute_query_async` can now bind values to `$1` /
`$name` placeholders instead of splicing them into the SQL text. The
values travel as Arrow, so a float32 keeps its exact bits and type and a
vector stays a compact `FixedSizeList` (3 KB for 768 dims rather than ~9
KB of decimal literals parsed back as Float64).
```rust
db.execute_query_async("SELECT id FROM docs ORDER BY distance(vector, $vector) LIMIT $k")
.parameters(batch) // one-row RecordBatch
.execute()
.await?;
```
```python
db.execute_query(sql, parameters={"vector": np.float32_vector, "k": 10})
```
- A statement with parameters is sent on one `DoExchange`: the first
message carries the `CommandStatementQuery` descriptor and the parameter
schema, the second the one-row batch, and the result rows stream back on
the same call. Statements without parameters keep `PollFlightInfo` +
`DoGet` unchanged.
- Column `i` binds `$<i+1>`; a column whose name is not a number also
binds `$<name>`. Python accepts a list (positional), a dict (named), or
a one-row `RecordBatch` / `Table`; 1-D numpy / pyarrow arrays become a
`FixedSizeList` of their element type.
- A parameterized query runs on its call: `cancel()`, dropping the
handle before reading, or dropping the reader ends the call and stops
the server-side statement. It is still registered for `describe_query`.
- `Database::execute_query_async` now takes an `ExecuteQueryRequest`
options struct.
Server side: lancedb/sophon#8256.
This commit is contained in:
@@ -86,6 +86,15 @@ print(query.describe().status)
|
||||
for batch in query.reader():
|
||||
print(batch.num_rows)
|
||||
|
||||
# Values bind to $1 / $name placeholders and travel as Arrow, so a float32
|
||||
# stays a float32 and a vector stays a compact fixed-size list:
|
||||
import numpy as np
|
||||
|
||||
reader = db.execute_query(
|
||||
"SELECT id FROM docs ORDER BY distance(vector, $vector) LIMIT $k",
|
||||
parameters={"vector": np.random.rand(768).astype(np.float32), "k": 10},
|
||||
)
|
||||
|
||||
# The async connection exposes the same lifecycle without blocking:
|
||||
# async_db = await lancedb.connect_async(
|
||||
# "db://analytics",
|
||||
@@ -201,6 +210,8 @@ listing a storage directory.
|
||||
|
||||
::: lancedb.sql.QueryDescription
|
||||
|
||||
::: lancedb.sql.QueryParameters
|
||||
|
||||
## Materialized Views (Synchronous)
|
||||
|
||||
::: lancedb.materialized_view.MaterializedView
|
||||
|
||||
Reference in New Issue
Block a user