docs(driver.sql): topByTimestamp is only defined when the ordering column is unique (Driver.Sql-008)
This commit is contained in:
@@ -80,6 +80,14 @@ the nested form.
|
||||
}
|
||||
```
|
||||
|
||||
⚠️ **`topByTimestamp` needs an ordering column that is unique per row.** It is executed as an
|
||||
`ORDER BY <column> DESC` with the dialect's single-row limit, so when the column ties the server
|
||||
returns an arbitrary row among the tied ones — and the driver cannot warn about it, because the other
|
||||
rows were discarded before the result set reached it (the `whereColumn`/`whereValue` form *does*
|
||||
warn, on `Rows.Count > 1`). A `date`-typed column ties for every row written on the same day, and
|
||||
browse-commit will nominate one. Prefer a `datetime2`/sequence column that is unique per row, or
|
||||
point the tag at a latest-row view.
|
||||
|
||||
`whereValue` may be authored as a JSON string, number or boolean (it is bound as a parameter either
|
||||
way). `keyValue` on the `KeyValue` model must be a **string**.
|
||||
|
||||
|
||||
@@ -566,9 +566,19 @@ public sealed class SqlPollReader
|
||||
/// one. Worse, it would destroy the only evidence this method has that the selector is ambiguous
|
||||
/// (<c>Rows.Count > 1</c>), converting a loud misconfiguration into a permanently silent one —
|
||||
/// precisely the failure mode this class's summary calls its top risk. The <c>topByTimestamp</c>
|
||||
/// form keeps its row limit because there the <c>ORDER BY</c> makes "the first row" a defined
|
||||
/// answer. The accepted cost is that an ambiguous selector materialises every matching row for one
|
||||
/// form keeps its row limit because there the <c>ORDER BY</c> at least fixes <em>which</em> rows can
|
||||
/// be first. The accepted cost is that an ambiguous selector materialises every matching row for one
|
||||
/// poll; the warning is what gets it fixed.</para>
|
||||
/// <para><b>⚠ The <c>topByTimestamp</c> answer is only defined when the ordering column is unique</b>
|
||||
/// (Driver.Sql-008). <c>ORDER BY ts DESC</c> plus a one-row limit over a column with ties returns an
|
||||
/// arbitrary row among the tied ones, and — unlike the where-pair form — this method can never
|
||||
/// detect it, because the server discarded the other rows before the result set was built: there is
|
||||
/// no <c>Rows.Count > 1</c> left to warn about. The tie shape is reachable rather than
|
||||
/// theoretical, since <c>SqlBrowseSession.PreferredTimestampColumn</c> will nominate a
|
||||
/// <c>date</c>-typed column, which ties for every row written on the same day. The model's premise is
|
||||
/// unchanged — the selector must identify one row — but for this form the operator, not the driver,
|
||||
/// is the only thing that can check it. Point the tag at a column that is unique per row (or at a
|
||||
/// latest-row view).</para>
|
||||
/// </summary>
|
||||
private object?[]? SelectWideRow(SqlQueryPlan plan, GroupResult outcome)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user