From c56f910cc935e2c06ce7b953bdff4f47826683f3 Mon Sep 17 00:00:00 2001 From: stumpylog <797416+stumpylog@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:19:26 -0700 Subject: [PATCH] docs(search): scope the relative-offset warning to a value standing alone The warning said relative offsets such as "-1 week" "in practice mean no documents at all", unqualified, one bullet after the range-bound rule offered added:['-1 week' to now] as the example of quoting a bound. Both sentences were true in their own scope, but read together they talk a user out of a query that works: the bare value is a zero-width instant, the same offset as a bound is a real seven-day window (verified: lo=2026-06-08T12:00, hi=2026-06-15T12:00 from a frozen 2026-06-15T12:00). Also widens the last sentence to say now-3days and "3 days ago" are rejected wherever they appear, having checked they are rejected as range bounds too, single- or double-quoted, not only as bare values. Restores the 'added:"-1 week"' case to the standalone-forms list, which the docs name by that exact spelling, and pins the bound reading beside it so neither half of the warning is an unpinned claim. Co-Authored-By: Claude Opus 5 --- docs/usage.md | 2 +- .../tests/search/test_documented_syntax.py | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index da5633256..b38e12fac 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -999,7 +999,7 @@ added:[2005-06-15T09:00:00Z to 2005-06-15T17:00:00Z] !!! warning - `now`, `noon`, `midnight` and relative offsets such as `"-3 days"` or `"-1 week"` are accepted by the parser but resolve to a single instant rather than to a span of time, so they match only a document whose timestamp is exactly that instant, which in practice means no documents at all. Quoting does not change this. Spellings like `now-3days` and `"3 days ago"` are rejected outright. + As a value on its own, `now`, `noon`, `midnight` and relative offsets such as `"-3 days"` or `"-1 week"` are accepted by the parser but resolve to a single instant rather than to a span of time, so they match only a document whose timestamp is exactly that instant, which in practice means no documents at all. Quoting does not change this. As a *range bound* they are the opposite of a trap and are what you want: `added:['-1 week' to now]` covers the whole of the last seven days. Spellings like `now-3days` and `"3 days ago"` are rejected outright wherever they appear. #### Searching custom fields diff --git a/src/documents/tests/search/test_documented_syntax.py b/src/documents/tests/search/test_documented_syntax.py index 5baa5ae58..34b93e3dc 100644 --- a/src/documents/tests/search/test_documented_syntax.py +++ b/src/documents/tests/search/test_documented_syntax.py @@ -269,6 +269,11 @@ class TestDocumentedDateForms: # of the resulting range, not the way the value is delimited. 'added:"now"', 'added:"midnight"', + # A relative offset, which the warning in the docs names by this + # exact spelling. Standing alone it is an instant like the rest of + # this list; the same offset used as a range bound is a real + # window, pinned by the test below. + 'added:"-1 week"', ], ) def test_forms_the_docs_warn_about_match_nothing( @@ -298,6 +303,24 @@ class TestDocumentedDateForms: assert exc_info.value.field == "added" assert exc_info.value.value == "2005-03-" + def test_relative_offset_as_a_range_bound_is_a_real_window( + self, + backend: TantivyBackend, + dated: dict[str, int], + ) -> None: + """The same offset that matches nothing on its own spans the last + seven days as a lower bound. The docs say so, next to the warning + about the standalone form, so both readings are pinned together. + + "last_monday" is indexed at 2026-06-08T10:00, two hours before the + window opens, so its exclusion is what shows the bound is the offset + and not a whole-day rounding of it. + """ + assert _matched_ids(backend, "added:['-1 week' to now]") == { + dated["today"], + dated["yesterday"], + } + def test_double_quoted_range_bound_is_rejected( self, backend: TantivyBackend,