0.1.6
Added
-
Paging no longer reports a stall on a query whose rows are identical. The
guard compared each page's first and last row, soselect {n: 1}produced the
same signature on every page whether the offset advanced or not, and raised
"paging is not advancing" atrepeat_limit * page_sizerows on a query that
was paging correctly. A page whose first and last rows match is now skipped as
carrying no evidence, and the message names the other possibility.Reported as a Forward-side cap at 250,000 rows. It is not one: 250,000 is the
defaultrepeat_limitof 25 times a 10,000-row page. Verified against a
545,464-row result, which now pages to completion in 55 pages, and where
Forward returns 3 rows at offset 545,461 and 0 at 545,464, so the offset is
honoured to the last row.A genuinely stalled server returning uniform rows is no longer diagnosed by
this guard. It still terminates, bounded bymax_rows,max_pagesand the
reported total. -
A failed NQE query now says what was wrong with it. Forward's message is the
fixed string "Error encountered while executing the NQE query" for every
failure, whatever went wrong; the detail lives in a separateerrorslist
that the SDK carried on the exception but left out of its message, so every
query failure read identically in a log. Up to three diagnostics, with line
and column, now reach the message, and the full list stays onquery_errors. -
CounterSnapshotreads as a mapping, sodict(snapshot)and**snapshot
work. It always hadas_dict(), but nothing signalled that, and a consumer
who tried the obvious thing concluded it could not be serialized. -
error.denialon an API error, which says what kind of refusal it is. Read
from Forward's server source rather than inferred: its access enforcer sets
reasontonullon every refusal, so no code distinguishes a missing
permission from an unlicensed feature from a setting switched off, but its
wording does. Six kinds are recognised, each from the enforcer's own format
string. This is prose rather than a contract, so it is documented as something
to show an operator rather than something to branch on.This narrows a question the SDK previously called unanswerable. Denials remain
indistinguishable by status code; they are not indistinguishable in practice. -
use_latest_data_filesonnqe.execute(). A published field on the execution
request that the SDK never sent, so a caller could not evaluate a query
against the most recently uploaded data files instead of the versions the
snapshot captured. -
snapshot_cache_ttl="lifetime", which resolves a snapshot once and keeps that
answer for the life of the client. A number of seconds was the wrong shape for
the case the setting was added for: a run that has pinned one point in time
does not want the answer to change underneath it, and a TTL expiring mid-run
lets the next resolution return a different snapshot, so the run straddles two
moments with nothing raising and the data real on both sides.Seconds remain right for repeated independent reads, and the documentation now
says which shape suits which caller rather than leaving it to be discovered.
"lifetime"still yields to an upload through the same client, because that is
an event that makes the answer wrong rather than merely old. Suggested by the
Nautobot integration, whose own cache is lifetime-scoped for this reason.