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
|
`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**.
|
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
|
/// 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 —
|
/// (<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>
|
/// 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
|
/// form keeps its row limit because there the <c>ORDER BY</c> at least fixes <em>which</em> rows can
|
||||||
/// answer. The accepted cost is that an ambiguous selector materialises every matching row for one
|
/// 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>
|
/// 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>
|
/// </summary>
|
||||||
private object?[]? SelectWideRow(SqlQueryPlan plan, GroupResult outcome)
|
private object?[]? SelectWideRow(SqlQueryPlan plan, GroupResult outcome)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user