Skip to content

[FLINK-40131][docs] Document LATERAL SNAPSHOT join#28737

Open
fhueske wants to merge 1 commit into
apache:masterfrom
confluentinc:fhueske-FLINK-40131-Add-LATERAL-SNAPSHOT-docs
Open

[FLINK-40131][docs] Document LATERAL SNAPSHOT join#28737
fhueske wants to merge 1 commit into
apache:masterfrom
confluentinc:fhueske-FLINK-40131-Add-LATERAL-SNAPSHOT-docs

Conversation

@fhueske

@fhueske fhueske commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of the change

Add documentation for FLIP-579: LATERAL SNAPSHOT join

Brief change log

Add docs for FLIP-579: LATERAL SNAPSHOT join

Verifying this change

docs only change

Does this pull request potentially affect one of the following parts:

  • Dependencies (does it add or upgrade a dependency): no
  • The public API, i.e., is any changed class annotated with @Public(Evolving): no
  • The serializers: no
  • The runtime per-record code paths (performance sensitive): no
  • Anything that affects deployment or recovery: JobManager (and its components), Checkpointing, Kubernetes/Yarn, ZooKeeper: no
  • The S3 file system connector: no

Documentation

  • Does this pull request introduce a new feature? no
  • If yes, how is the feature documented? n/a

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude Code 2.1.200 (Opus 4.8)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@flinkbot

flinkbot commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

CI report:

Bot commands The @flinkbot bot supports the following commands:
  • @flinkbot run azure re-run the last Azure build


{{< label Streaming >}}

A `LATERAL SNAPSHOT` join is a *stream enrichment* join that augments an append-only table (the *probe* side) with the current state of an updating table (the *build* side).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have we defined what the probe side is - if so we should include a link to the definition). If not we should define the names for each side before referencing this.


A `LATERAL SNAPSHOT` join is a *stream enrichment* join that augments an append-only table (the *probe* side) with the current state of an updating table (the *build* side).
Unlike an [event-time temporal join](#event-time-temporal-join), it does not correlate each probe-side row with a specific historical version of the build side.
Instead, every probe-side row is joined with the build-side state that is current at the time the row is processed, similar to a [processing-time temporal join](#processing-time-temporal-join), but with well-defined behavior at query start-up.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am curious what the other joins not having well-defined behavior means. It would be worth mentioning this here to help show the value of this join.

[ load_completed_time => <timestamp_ltz>, ]
[ load_completed_idle_timeout => <interval>, ]
[ state_ttl => <interval> ])) AS s
ON probe_table.key = s.key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be worth expanding the example so we can see where the .keys are defined for each side.


The `LATERAL SNAPSHOT` join is designed for scenarios where the other temporal joins are a poor fit:

- The build side updates **infrequently**. An event-time temporal join relies on continuous build-side watermarks to emit results, so a build side that rarely advances its watermark stalls the join and lets probe-side state accumulate. A `LATERAL SNAPSHOT` join does not stall when the build side goes idle.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when you say infrequently. It would be worth defining how the frequency is defined


- The build side updates **infrequently**. An event-time temporal join relies on continuous build-side watermarks to emit results, so a build side that rarely advances its watermark stalls the join and lets probe-side state accumulate. A `LATERAL SNAPSHOT` join does not stall when the build side goes idle.
- The application has **low-latency** requirements that are incompatible with the watermark-induced delay of an event-time temporal join.
- The build side has **no primary key**. Event-time and processing-time temporal joins require the build-side primary key to appear in the equi-join condition; a `LATERAL SNAPSHOT` join does not.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mean the probe side has a primary key?

ON orders.currency = rates.currency;
```

The probe side must be an append-only table, and its time attributes are preserved in the output. The build side may be an updating table and must declare a watermark. The result is append-only. A build-side rowtime attribute that is projected into the output is materialized as a regular `TIMESTAMP` and is no longer a time attribute. Probe-side watermarks are forwarded downstream in join phase; build-side watermarks are consumed internally and are not propagated.

@davidradl davidradl Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest a picture (sequence diagram or the like) showing the time line including

  • the build side and probe side
  • watermarks (the internal build one and the probe one)
  • how the select is triggered including the load phase
  • maybe an example input and output

ON probe_table.key = s.key
```

The `SNAPSHOT` function accepts the following arguments:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the SNAPSHOT function be documented in the SQL functions section

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| `input` | TABLE | yes | The build-side table. It may use any [changelog mode]({{< ref "docs/sql/reference/queries/changelog" >}}) (inserts, updates, and deletes) and must declare a [watermark]({{< ref "docs/concepts/sql-table-concepts/time_attributes" >}}#event-time). |
| `load_completed_condition` | STRING | no | Determines when the initial load phase completes. One of `'compile_time'` (default) or `'user_time'`. With `'compile_time'`, the load phase completes once the build-side watermark reaches the wall-clock time at which the query was compiled. With `'user_time'`, it completes once the build-side watermark reaches the explicit `load_completed_time`. |

@davidradl davidradl Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a table here would be good describing each option and why you would use them . I think more description as to what exactly compile time and user time means would help.

does the load phase happen more than once?What other phases are there?

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.

3 participants