feat(databases): load a query result via --result#203
Conversation
There was a problem hiding this comment.
LGTM. Clean addition: --result is symmetrically wired into all four conflicts_with_all sets, both flow variants and both main.rs call sites are updated, the source-selection match is exhaustive, and the new tests follow the existing pattern (body builder + no-upload-step assertion).
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
| // connection-scoped endpoint, where the server scopes a result-sourced load | ||
| // by the X-Database-Id header; that must name the --catalog/--database | ||
| // target, not the ambient active database (which may be unset or different). | ||
| let api = api.scoped_to_database(&db.id); |
There was a problem hiding this comment.
This scopes api to db.id, but the auto-declare recovery path below (the "not declared" branch, ~line 1500-1554) deletes and recreates the database under a new id (new_db.id) and then retries the load with this same api — which still carries X-Database-Id: db.id (now deleted).
Per the rationale here, the server scopes a result-sourced load by the X-Database-Id header. So a --result load into a not-yet-declared table will hit recovery, recreate the DB, and then POST the retry with a header naming the deleted database instead of new_db.id — the load fails or misroutes. File/URL/upload loads survive because the server resolves the target from the connection-scoped URL path; only --result depends on the header, and that combination isn't tested.
Re-scope to the recreated database before the retry POST, e.g.:
let api = api.scoped_to_database(&new_db.id);
let new_path = managed_table_load_path(&new_db.default_connection_id, schema, table);There was a problem hiding this comment.
Review
Blocking Issues
src/commands/databases.rs:1411— The connection-scopedtables_loadscopesapito the resolveddb.id, but the auto-declare recovery branch deletes and recreates the database under a new id (new_db.id) and retries the load with the sameapi, which still carriesX-Database-Id: db.id. Since a--resultload is scoped by that header (the stated reason for addingscoped_to_database), a--resultload into a not-yet-declared table will retry against the deleted database. File/URL/upload sources are unaffected because they resolve via the URL path.
Action Required
Re-scope the handle to new_db.id before the recovery retry POST (see inline comment). Consider adding a test covering --result + auto-declare recovery, since that path is currently untested.
Add `--result-id` as a fourth source (mutually exclusive with --file /
--url / --upload-id) to `databases load` and `databases tables load`: it
posts `{ "mode": "replace", "result_id": "<id>" }` to the load endpoint and
skips the upload step, publishing a persisted query result into a table.
The result must belong to the target database. The server scopes a
result-sourced load by the X-Database-Id header, so the standard flow scopes
the request to the resolved target database (via scoped_to_database_opt)
rather than the ambient active one; uploads keep the ambient scope. The
database-API-token flow uses the path-scoped endpoint and needs no header.
Skip the delete-and-recreate auto-declare recovery for result loads: it
mints a new database id, which would orphan the result (the server scopes
it to the original database), and a result load into an undeclared table is
auto-declared server-side anyway.
5c85f83 to
cfa6be2
Compare
There was a problem hiding this comment.
Prior blocking issue (stale X-Database-Id on the auto-declare retry for result loads) is resolved: result loads now bypass the delete+recreate recovery path entirely (&& result_id.is_none()) and scope the API to the resolved target database. Correct approach. LGTM.
What
databases loadgains a--result <id>flag — a fourth source alongside--file,--url, and--upload-id(mutually exclusive with all three):When set, the CLI skips the upload step and posts
{ "mode": "replace", "result_id": "<id>" }to the load endpoint. The result id is the one printed in a query's[result-id: …]footer or listed byhotdata results.How
--resultto bothdatabases loadanddatabases tables load, wired into the existingconflicts_with_allsets.load_table_request_from_resultbody builder;tables_load/tables_load_database_scopedselect the request body by source. Everything downstream (spinner, auto-declare recovery, success output) is unchanged.Testing
result_idbody hits the load endpoint with no upload step.--resultsends the correct body).Depends on
Server support for
result_id: hotdata-dev/runtimedb#897. Until that is deployed,--resultagainst prod returnsmissing field 'upload_id'.