Skip to content

fix: Avoid ON TRUE and multiple USING joins in the ClickHouse point-in-time join - #7152

Open
ShivamSharma43 wants to merge 1 commit into
feast-dev:masterfrom
ShivamSharma43:fix/clickhouse-join-on-using
Open

ShivamSharma43 wants to merge 1 commit into
feast-dev:masterfrom
ShivamSharma43:fix/clickhouse-join-on-using

Conversation

@ShivamSharma43

Copy link
Copy Markdown

What this PR does / why we need it:

The ClickHouse offline store's point-in-time join template has two joins that ClickHouse's old query analyzer rejects, so get_historical_features fails on ClickHouse servers that use it: versions before 24.3, and newer versions with enable_analyzer = 0 (allow_experimental_analyzer = 0).

  1. The feature rows are joined to the entity rows with ON TRUE AND subquery."driver_id" = entity_dataframe."driver_id". The old analyzer fails on the constant TRUE: Code: 403. Illegal expression 'true' in JOIN ON section (INVALID_JOIN_ON_EXPRESSION). This happens for every query.
  2. The final SELECT joins each feature view back with USING ("<feature_view>__entity_row_unique_id"). With two or more feature views there are several USING joins in that SELECT, and the old analyzer fails with Code: 48. Multiple USING statements are not supported.

Changes:

  • The entity join is now ON subquery."k1" = entity_dataframe."k1" AND subquery."k2" = ..., without the TRUE. A feature view with no entities had only ON TRUE (a cross join), so it now uses CROSS JOIN.
  • The final SELECT joins each feature view with ON "<fv>"."<fv>__entity_row_unique_id" = entity_dataframe."<fv>__entity_row_unique_id" instead of USING. Only the entity columns and feature columns are selected, so the extra id column on the right side changes nothing in the output.

I rendered the template on master and on this branch for two feature views (one with a created_timestamp_column and a TTL) and, separately, with an extra feature view that has no entities, with the tables inlined as values() subqueries. I ran the queries on ClickHouse through fiddle.clickhouse.com and play.clickhouse.com:

ClickHouse master this PR
23.8 (old analyzer is the default) INVALID_JOIN_ON_EXPRESSION; with only the ON TRUE fixed: Multiple USING statements are not supported correct rows
24.3, 25.8 with allow_experimental_analyzer = 0 INVALID_JOIN_ON_EXPRESSION correct rows
24.3, 26.10 (new analyzer) correct rows same rows

The new analyzer runs both versions, and the results are the same.

Which issue(s) this PR fixes:

Fixes #6141

Checks

  • I've made sure the tests are passing.
  • My commits are signed off (git commit -s)
  • My PR title follows conventional commits format

Testing Strategy

  • Unit tests
  • Integration tests
  • Manual tests
  • Testing is not required for this change

Added TestPointInTimeJoinTemplate to sdk/python/tests/unit/infra/offline_stores/test_clickhouse.py. It renders the template and checks that there is no ON TRUE, that the entity keys are joined with ON ... AND ..., that the final SELECT joins every feature view with ON and has no USING, and that a feature view without entities gets a CROSS JOIN. All three tests fail on master. The existing tests in that file still pass.

I did not run the ClickHouse integration suite (make test-python-universal-clickhouse-offline): it needs a ClickHouse container, and Docker isn't available on my machine. The manual runs above are what I have instead.

Misc

This change was written with help from an AI assistant (Claude Code). The ClickHouse runs above were done against real servers, not inferred.

🤖 Generated with Claude Code

https://claude.ai/code/session_012XPuJeHi7A5CeHSKHjHmwx

@ShivamSharma43
ShivamSharma43 requested a review from a team as a code owner November 13, 2026 07:50
Copilot AI balanced review requested due to automatic review settings November 13, 2026 07:50

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@codecov-commenter

codecov-commenter commented Nov 13, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.40%. Comparing base (5eefef9) to head (54a5d33).
⚠️ Report is 5 commits behind head on master.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #7152   +/-   ##
=======================================
  Coverage   52.39%   52.40%           
=======================================
  Files         459      459           
  Lines       58156    58160    +4     
  Branches     8572     8574    +2     
=======================================
+ Hits        30470    30476    +6     
+ Misses      25606    25604    -2     
  Partials     2080     2080           
Flag Coverage Δ
go-feature-server 30.96% <ø> (ø)
python-unit 53.90% <ø> (+<0.01%) ⬆️
Files with missing lines Coverage Δ
...res/contrib/clickhouse_offline_store/clickhouse.py 32.55% <ø> (ø)

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 171d601...54a5d33. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…n-time join

ClickHouse's old analyzer (the default before 24.3, and still used with
enable_analyzer = 0) rejects two joins in the point-in-time join template:

- `ON TRUE AND subquery.k = entity_dataframe.k` fails with
  INVALID_JOIN_ON_EXPRESSION ("Illegal expression 'true' in JOIN ON
  section"), for every query.
- The final SELECT joins each feature view back with USING, and with two
  or more feature views it fails with "Code: 48. Multiple USING
  statements are not supported".

Join the entity keys with `ON k1 = k1 AND k2 = k2`, use CROSS JOIN for a
feature view without entities (it only had `ON TRUE`), and join the
feature views back with `ON "<fv>"."<fv>__entity_row_unique_id" =
entity_dataframe."<fv>__entity_row_unique_id"`.

Fixes feast-dev#6141

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012XPuJeHi7A5CeHSKHjHmwx
Signed-off-by: Shivam Sharma <[email protected]>
@ntkathole
ntkathole force-pushed the fix/clickhouse-join-on-using branch from 7c03889 to 54a5d33 Compare November 13, 2026 13:46

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ClickHouse offline store: ON TRUE and Multiple USING in JOIN not supported

4 participants