Skip to content

Introduce ASOF and ASOF LEFT joins with single-inequality anchor#27703

Closed
Pluies wants to merge 1 commit into
trinodb:masterfrom
Pluies:asof-joins
Closed

Introduce ASOF and ASOF LEFT joins with single-inequality anchor#27703
Pluies wants to merge 1 commit into
trinodb:masterfrom
Pluies:asof-joins

Conversation

@Pluies
Copy link
Copy Markdown
Contributor

@Pluies Pluies commented Dec 19, 2025

Description

  • Adds ASOF/ASOF LEFT joins for nearest‑neighbor matching.
  • ON clause requires exactly one inequality comparing a right‑side expression to a left‑side expression; additional equi and same‑side predicates are allowed.
  • Implements analyzer/planner support and predicate pushdown semantics.
  • Updates documentation and adds focused analyzer, planner, and query tests.

Additional context and related issues

Hey folks 👋 Seeing #27641 being pushed in order to implement #21759, I'm rushing our plans of upstreaming ASOF joins as implemented recently in Dune 🎁

We have developed and built this feature on top of Trino 467, and this is a quick rebase on top of master to get the ball rolling. Expect potential bugs and test failures; I'll come back and clean this up asap.

I'm not expecting either this PR or #27641 to be adopted wholesale, but hopefully this can help in the conversation wrt which syntax and implementation of ASOF joins ends up in Trino!

cc @martint

Related, our user-facing Dune docs: https://docs.dune.com/query-engine/Functions-and-operators/asof-join

Release notes

( ) This is not user-visible or is docs only, and no release notes are required.
(x) Release notes are required. Please propose a release note for me.
( ) Release notes are required, with the following suggested text:

## Section
* Fix some things. ({issue}`issuenumber`)

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Dec 19, 2025

Thank you for your pull request and welcome to the Trino community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. Continue to work with us on the review and improvements in this PR, and submit the signed CLA to cla@trino.io. Photos, scans, or digitally-signed PDF files are all suitable. Processing may take a few days. The CLA needs to be on file before we merge your changes. For more information, see https://github.com/trinodb/cla

- Adds ASOF/ASOF LEFT joins for nearest‑neighbor matching.
- ON clause requires exactly one inequality comparing a right‑side expression to a left‑side expression; additional equi and same‑side predicates are allowed.
- Implements analyzer/planner support and predicate pushdown semantics.
- Updates documentation and adds focused analyzer, planner, and query tests.
@findepi
Copy link
Copy Markdown
Member

findepi commented Dec 31, 2025

That's a cool feature!

Seeing #27641 being pushed in order to implement #21759, I'm rushing our plans of upstreaming ASOF joins as implemented recently in Dune 🎁

Would be nice if we could have one PR to collaborate on.
Given you created this PR knowing about #27641, does this mean this implementation is more complete than the other one?

Can you please chime in on #27641 too?

@Pluies
Copy link
Copy Markdown
Contributor Author

Pluies commented Dec 31, 2025

Would be nice if we could have one PR to collaborate on. Given you created this PR knowing about #27641, does this mean this implementation is more complete than the other one?

I believe this PR is slightly more production-ready.

My understanding is:

  • This PR supports ASOF LEFT as well as ASOF
  • Broader support for the inequality condition: if I read Implement ASOF join #27641 correctly, the inequality condition has to be the last column (here), whereas in this PR there is no such limitation
  • This PR includes stronger syntax checks; see checks in StatementAnalyzer.java and inequality checks in LocalExecutionPlanner.java
  • Less of a technical point and more... social proof?, but this PR includes documentation and has been in use in prod at Dune for a few months already!

But these could all be ported between PR if needed. I believe the main difference is in the way these PRs approach the issue in the first place: this PR supports ASOF joins as a native construct, whereas #27641 supports ASOF joins by means of rewriting them into a LEFT JOIN via RewriteAsofJoinToLeftJoinWithTop1.java ; an SQL syntax that Trino already understands.

cc @jirislav , let me know if I misunderstood changes 🙏

Can you please chime in on #27641 too?

Linking this comment there!

@Pluies Pluies mentioned this pull request Dec 31, 2025
@jirislav
Copy link
Copy Markdown

jirislav commented Jan 2, 2026

I agree with @Pluies about this PR being more production-ready. My PR (#27641) was intended to only establish the syntax with a simple translation to a LEFT JOIN, so we could ship the improvements of ASOF join implementation incrementally (for example by shipping a sort-merge operator using binary search).

Broader support for the inequality condition: if I read #27641 correctly, the inequality condition has to be the last column (here), whereas in this PR there is no such limitation

It is only a requirement when the user chooses the USING expression (e.g. ASOF JOIN b USING (a, b, ts). When the USING keyword is not used, then it is perfectly possible to use a ASOF JOIN b ON a.ts <= b.ts AND a.key = b.key).

Note that having the time-dimension as the last one after the USING keyword is the most common behavior in major platforms, see:

@github-actions
Copy link
Copy Markdown

This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack.

@github-actions github-actions Bot added the stale label Jan 23, 2026
@Pluies Pluies closed this Feb 11, 2026
@Pluies Pluies deleted the asof-joins branch February 11, 2026 14:14
@Pluies Pluies restored the asof-joins branch February 11, 2026 14:14
@jirislav
Copy link
Copy Markdown

@Pluies what is the reason to close this? Do we have some alternative PR somewhere I'm not aware of?

@Pluies Pluies reopened this Feb 11, 2026
@Pluies
Copy link
Copy Markdown
Contributor Author

Pluies commented Feb 11, 2026

@jirislav sorry, my bad - I was cleaning up branches in my fork and deleted this one by mistake 🤦

@github-actions github-actions Bot removed the stale label Feb 11, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 5, 2026

This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack.

@github-actions github-actions Bot added the stale label Mar 5, 2026
@github-actions
Copy link
Copy Markdown

Closing this pull request, as it has been stale for six weeks. Feel free to re-open at any time.

@github-actions github-actions Bot closed this Mar 27, 2026
@jirislav jirislav reopened this Mar 27, 2026
Copy link
Copy Markdown
Member

@kasiafi kasiafi left a comment

Choose a reason for hiding this comment

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

Hi @Pluies, I have some high level comments/questions:

  1. The syntax. I understand that the proposed syntax is something invented and adopted by other DBs. One thing I don't like about this syntax is that the "ASOF-inequality" does not stand out in any way from other join conditions, while it's semantics is very different. Are there alternative syntax approaches that consider this?

  2. The "ASOF-inequality" also doesn't get any special treatment in the planner -- it becomes a regular part of the Join filter. And then it has to be extracted again after the query is optimized. This approach seems brittle. What if the inequality gets transformed or optimized-out altogether? What if some optimization adds another inequality to the Join filter? I think that the "ASOF-inequality" must be carried separately from the Join filter if we want to be sure that we still have it on the other end of the Planner.

  3. Where is the logic responsible for returning one match for each row?

  4. What happens if there are other join conditions than equalities/inequalities?

  5. If there are ties on the build side, how are they solved?

  6. If there are ties on the probe side matching ties on the build side, is the result consistent for each tied probe row?

@github-actions github-actions Bot removed the stale label Mar 30, 2026
@github-actions
Copy link
Copy Markdown

This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack.

@github-actions github-actions Bot added the stale label Apr 20, 2026
@jirislav
Copy link
Copy Markdown

The feature request #21759 was resolved by the NEAREST join support (#28937), so I'm closing this. Anyway, thanks for the effort @Pluies !

@jirislav jirislav closed this Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

5 participants