Skip to content

fix CTE deterministic functions#86967

Merged
yakov-olkhovskiy merged 6 commits intomasterfrom
fix-cte-deterministic-functions
Sep 23, 2025
Merged

fix CTE deterministic functions#86967
yakov-olkhovskiy merged 6 commits intomasterfrom
fix-cte-deterministic-functions

Conversation

@yakov-olkhovskiy
Copy link
Copy Markdown
Member

@yakov-olkhovskiy yakov-olkhovskiy commented Sep 10, 2025

Changelog category (leave one):

  • Bug Fix (user-visible misbehavior in an official stable release)

Changelog entry (a [user-readable short description]

Fix result of function calculated in CTE being non-deterministic in the query.

closes #86591

@clickhouse-gh
Copy link
Copy Markdown
Contributor

clickhouse-gh bot commented Sep 10, 2025

Workflow [PR], commit [49756e8]

Summary:

@clickhouse-gh clickhouse-gh bot added the pr-bugfix Pull request with bugfix, not backported by default label Sep 10, 2025
@devcrafter devcrafter self-assigned this Sep 11, 2025
Copy link
Copy Markdown
Member

@devcrafter devcrafter left a comment

Choose a reason for hiding this comment

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

LGTM from my side, but let's confirm with @novikd

@@ -0,0 +1,2 @@
with (select randConstant()) as a select a = a;
with (select now() + sleep(1)) as a select a = a;
Copy link
Copy Markdown
Member

@devcrafter devcrafter Sep 11, 2025

Choose a reason for hiding this comment

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

Please add test where select has more than 1 parent select, and check that such function is executed once and the calculated value used everywhere in the query

{
/// This is a hack to allow a query like `select randConstant(), randConstant(), randConstant()`.
/// Function randConstant() would return the same value for the same arguments (in scope).
/// Also we want to use most outer scope for function deterministic in scope of query.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So, we store a function value in most outer scope, i.e., globally for the query on a local node. Logically looks as expected behavior, but I'd double-check with somebody who can know better - @novikd @KochetovNicolai

IdentifierResolveScope * function_scope = &scope;
if (resolver && resolver->isDeterministicInScopeOfQuery())
while (function_scope->parent_scope)
function_scope = function_scope->parent_scope;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we always use the most outer scope then maybe it'd be better to put the cache into the query context or into QueryAnalyzer.

It doesn't make sense to keep it in each scope if we only fill the most outer one.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

we only do it for isDeterministicInScopeOfQuery() functions, for non-deterministic-in-scope functions we use local scope - I don't think it makes sense to create special cache for this - it's logically consistent that upper scope is also a global scope for the whole query


String getName() const override { return name; }
bool isDeterministic() const override { return false; }
bool isDeterministicInScopeOfQuery() const override { return false; }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It disables constant folding for this function, doesn't it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

not sure about this - is it required for such functions to forfeit constant folding? not obvious to me...

@novikd novikd self-assigned this Sep 11, 2025
@yakov-olkhovskiy yakov-olkhovskiy added this pull request to the merge queue Sep 23, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks Sep 23, 2025
@yakov-olkhovskiy yakov-olkhovskiy added this pull request to the merge queue Sep 23, 2025
Merged via the queue into master with commit 4ba5e89 Sep 23, 2025
241 of 242 checks passed
@yakov-olkhovskiy yakov-olkhovskiy deleted the fix-cte-deterministic-functions branch September 23, 2025 20:42
@robot-clickhouse-ci-1 robot-clickhouse-ci-1 added the pr-synced-to-cloud The PR is synced to the cloud repo label Sep 23, 2025
@yakov-olkhovskiy yakov-olkhovskiy added the pr-must-backport Pull request should be backported intentionally. Use this label with great care! label Sep 24, 2025
@robot-ch-test-poll3 robot-ch-test-poll3 added pr-backports-created-cloud deprecated label, NOOP pr-must-backport-synced The `*-must-backport` labels are synced into the cloud Sync PR labels Sep 24, 2025
robot-clickhouse-ci-2 added a commit that referenced this pull request Sep 24, 2025
Cherry pick #86967 to 25.9: fix CTE deterministic functions
yakov-olkhovskiy added a commit that referenced this pull request Sep 25, 2025
Backport #86967 to 25.9: fix CTE deterministic functions
@robot-clickhouse-ci-2 robot-clickhouse-ci-2 added the pr-backports-created Backport PRs are successfully created, it won't be processed by CI script anymore label Sep 25, 2025
clickhouse-gh bot added a commit that referenced this pull request Sep 25, 2025
Backport #86967 to 25.7: fix CTE deterministic functions
yakov-olkhovskiy added a commit that referenced this pull request Sep 25, 2025
Backport #86967 to 25.8: fix CTE deterministic functions
clickhouse-gh bot added a commit that referenced this pull request Sep 25, 2025
Backport #86967 to 25.6: fix CTE deterministic functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-backports-created Backport PRs are successfully created, it won't be processed by CI script anymore pr-backports-created-cloud deprecated label, NOOP pr-bugfix Pull request with bugfix, not backported by default pr-must-backport Pull request should be backported intentionally. Use this label with great care! pr-must-backport-synced The `*-must-backport` labels are synced into the cloud Sync PR pr-synced-to-cloud The PR is synced to the cloud repo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Function now is not deterministic with CTEs

7 participants