fix: preserve all function revisions through SQL history (#4786)

`list_functions()` promises every published immutable revision. Request
`SHOW FUNCTIONS HISTORY` so the SQL server's latest-only default does
not hide older revisions, and preserve the server's numeric revision
ordering when constructing page cursors (`1`, `2`, `10`).

```python
[(fn.name, fn.version) for fn in db.list_functions(page_limit=2)]
# [("embed", "1"), ("embed", "2"), ("embed", "10")]
```

```sql
SHOW FUNCTIONS; -- latest visible revision per name
SHOW FUNCTIONS HISTORY WITH (limit = 3, include_definition = true);
SHOW FUNCTIONS HISTORY WITH (after_name = 'embed', after_version = '2', limit = 3);
```

Each listing page uses the existing SQL query and polling transport; the
continuation token stores the last returned name/revision and remains
bound to its database and namespace. Function mutations keep their
query-backed job handles: `Job.id` is the query's ID and `job_type` is
`query`, so waiting observes that same SQL execution. No registry job or
second query ID is added.

Update the SQL and Python documentation for exact-revision drops:
sibling revisions and grants survive, and only the last visible
revision's removal releases the name and schedules object cleanup.
Extend the existing Flight SQL regression to paginate revisions `1`,
`2`, and `10` and verify the explicit history statement. Formatting and
static Python checks pass; local builds and tests were intentionally not
run.
This commit is contained in:
Jack Ye
2026-11-02 01:15:39 +08:00
committed by GitHub
parent cbc24fa84f
commit eeb244fa57
6 changed files with 92 additions and 52 deletions
+13 -7
View File
@@ -107,12 +107,15 @@ from it.
```sql
SHOW FUNCTIONS
SHOW FUNCTIONS IN "analytics" WITH (name = 'embed', limit = 100)
SHOW FUNCTIONS WITH (after_name = 'embed', after_version = '1', limit = 100)
SHOW FUNCTIONS HISTORY IN "analytics" WITH (name = 'embed', limit = 100)
SHOW FUNCTIONS HISTORY WITH (after_name = 'embed', after_version = '1', limit = 100)
```
Rows are ordered lexicographically by name and version. `after_name` and
`after_version` must be supplied together for keyset pagination. `limit` bounds
`SHOW FUNCTIONS` returns the highest published numeric revision for each name.
Add `HISTORY` to list every published revision, as Python's `list_functions()`
does. Rows are ordered by name and numeric revision, so `2` comes before `10`.
`after_name` and `after_version` must be supplied together for keyset pagination.
`limit` bounds
the response; `include_definition = false` omits the optional definition JSON.
## DROP FUNCTION {#drop}
@@ -122,9 +125,12 @@ DROP FUNCTION embed WITH (version = '1')
DROP FUNCTION IF EXISTS embed WITH (version = '1')
```
`version` must identify an existing revision. DROP releases the function name
and its object binding; physical cleanup continues separately. The result
reports `dropped` or `not_found`. `IF EXISTS` allows a missing name.
DROP removes only the requested revision from lookup and listing. Other
published revisions and their grants remain available. Dropping the last visible
revision releases the name and object binding; physical cleanup continues
separately. The result reports `dropped` or `not_found`. `IF EXISTS` allows a
missing name or a repeated drop of a previously published revision. A revision
that was never published under an existing name is an error.
All function object commands retain shared results even when general query-result
copying is disabled, so asynchronous polling can resume on another query node.