Skip to content

docs: fix the quickstart flip_activities view - #38865

Open
bosconi wants to merge 2 commits into
mainfrom
jc/quickstart-flip-window
Open

bosconi wants to merge 2 commits into
mainfrom
jc/quickstart-flip-window

Conversation

@bosconi

@bosconi bosconi commented Sep 15, 2026

Copy link
Copy Markdown
Member

The quickstart defines a flip as buying an item and reselling it at a higher price "within an 8-day period", but the query never enforced that bound.

datediff(unit, start, end) returns end - start, so datediff('days', w2.bid_time, w1.bid_time) evaluates to purchase_time - sale_time. w1 is the purchase leg and w2 the sale leg, so for any genuine flip this is negative and therefore always < 8.

Two consequences:

  • The 8-day window is inert — a resale years after the purchase still qualifies.
  • timeframe_days reports a negative number on every genuine flip.

This swaps the arguments so the value is sale - purchase, and adds an explicit ordering predicate, since < 8 alone still admits pairs whose sale precedes the purchase.

Found while investigating memory growth in a demo derived from this quickstart. Worth noting the view is quadratic either way — the fixed window bounds it only once the data spans well beyond 8 days — so this is a correctness fix, not a performance one.

A second commit adds a short note after the index step: the view's output grows with winning_bids, the 8-day bound is what keeps that growth linear rather than quadratic, and an index or materialized view over flip_activities retains that state continuously, so keep the bound or add a temporal filter on winning_bids.

Manual testing

Run in the Materialize Cloud Console SQL shell. Constant queries, no tables involved.

1. Sign convention of datediff:

SELECT
  datediff('days', '2026-01-01'::timestamptz, '2026-01-09'::timestamptz) AS start_then_end,
  datediff('days', '2026-01-09'::timestamptz, '2026-01-01'::timestamptz) AS end_then_start;
start_then_end  end_then_start
8               -8

2. The quickstart's expression applied to a genuine flip (bought Jan 1, sold Jan 5):

WITH flip AS (
  SELECT '2026-01-01 10:00'::timestamptz AS w1_bid_time,   -- purchase leg
         '2026-01-05 10:00'::timestamptz AS w2_bid_time    -- sale leg
)
SELECT
  datediff('days', w2_bid_time, w1_bid_time)      AS timeframe_days_as_written,
  datediff('days', w2_bid_time, w1_bid_time) < 8  AS passes_filter_as_written,
  datediff('days', w1_bid_time, w2_bid_time)      AS timeframe_days_corrected
FROM flip;
timeframe_days_as_written  passes_filter_as_written  timeframe_days_corrected
-4                         true                      4

3. The 8-day bound does nothing (same flip, sold five years later):

SELECT
  datediff('days', '2031-01-01'::timestamptz, '2026-01-01'::timestamptz)      AS timeframe_days_as_written,
  datediff('days', '2031-01-01'::timestamptz, '2026-01-01'::timestamptz) < 8  AS passes_filter_as_written;
timeframe_days_as_written  passes_filter_as_written
-1826                      true

A resale 1,826 days after the purchase passes a filter the prose describes as "within an 8-day period". With the arguments swapped, query 2 reports 4 and query 3 reports 1826, which the < 8 bound then correctly rejects.

🤖 Generated with Claude Code

https://claude.ai/code/session_01W1yEF7rh559n9vxcrSpwWs

bosconi and others added 2 commits September 15, 2026 09:28
The quickstart defines a flip as buying an item and reselling it at a
higher price "within an 8-day period", but the query never enforced that
bound.

datediff(unit, start, end) returns end - start, so
datediff('days', w2.bid_time, w1.bid_time) evaluates to
purchase_time - sale_time. For any genuine flip the purchase precedes
the sale, making the value negative and therefore always < 8. The window
was inert: a resale years after the purchase still qualified, and the
timeframe_days column reported a negative number on every real flip.

Swap the arguments so the value is sale - purchase, and add an explicit
ordering predicate, since "< 8" alone still admits pairs whose sale
precedes the purchase.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1yEF7rh559n9vxcrSpwWs
The quickstart already explains that the self-join grows quadratically
in winning_bids and adds indexes to make each query cheaper. It did not
say that an index or materialized view over flip_activities retains
that state continuously, or that the 8-day bound is what keeps the
growth linear. Add a short paragraph after the index step saying so and
pointing at temporal filters.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1yEF7rh559n9vxcrSpwWs
@bosconi bosconi changed the title docs: fix quickstart flip_activities 8-day window docs: fix the quickstart flip_activities view Sep 15, 2026
@bosconi
bosconi marked this pull request as ready for review September 16, 2026 00:56
@bosconi
bosconi requested a review from a team as a code owner September 16, 2026 00:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant