Skip to content

Make RelationalExpression#equalsWithoutChildren() compare the result values where necessary#4185

Open
RobertBrunel wants to merge 1 commit into
FoundationDB:mainfrom
RobertBrunel:EliminateNullOnEmptyRule-1
Open

Make RelationalExpression#equalsWithoutChildren() compare the result values where necessary#4185
RobertBrunel wants to merge 1 commit into
FoundationDB:mainfrom
RobertBrunel:EliminateNullOnEmptyRule-1

Conversation

@RobertBrunel
Copy link
Copy Markdown
Contributor

@RobertBrunel RobertBrunel commented May 20, 2026

This change adds semanticEqualsForResults(…) comparisons to any RelationalExpression#equalsWithoutChildren() implementations that were missing it. Without this comparison, the Cascades memoizer will unify plans that differ (only) in their result value or type, which is incorrect. See Issue #4184 for details.

This change does not adjust the hashCodeWithoutChildren() methods likewise, as this is not strictly necessary. Leaving these methods untouched avoids needless plan changes (since the hashes are used as a tie-breaker in the cost model).

The potentially incorrect memoization prior to this change can trigger a sanity-check in Reference.insertUnchecked(), if enabled. Note though that in production the sanity-checks are disabled, so a violation would have gone undetected there.

Testing:

  • Existing test coverage.
  • Add missing equals…() coverage for RecordQueryDeletePlan.

Fixes #4184.

@RobertBrunel RobertBrunel self-assigned this May 20, 2026
@RobertBrunel RobertBrunel added bug fix Change that fixes a bug planner Related to the query planner labels May 20, 2026
@RobertBrunel
Copy link
Copy Markdown
Contributor Author

To Do: Can we make the sanity-check unconditional?

@RobertBrunel RobertBrunel force-pushed the EliminateNullOnEmptyRule-1 branch 4 times, most recently from 40c8825 to 333bc75 Compare May 21, 2026 12:37
@RobertBrunel RobertBrunel changed the title Extend equalsWithoutChildren() in plan nodes to also compare the result types where necessary Make RelationalExpression#equalsWithoutChildren() compare the result types where necessary May 21, 2026
@RobertBrunel RobertBrunel requested a review from normen662 May 21, 2026 12:47
@RobertBrunel RobertBrunel force-pushed the EliminateNullOnEmptyRule-1 branch from 333bc75 to be94860 Compare May 21, 2026 14:15
@RobertBrunel RobertBrunel changed the title Make RelationalExpression#equalsWithoutChildren() compare the result types where necessary Make RelationalExpression#equalsWithoutChildren() compare the result values where necessary May 21, 2026
…t values where necessary

This change adds  `semanticEqualsForResults(…)` comparisons to any `RelationalExpression#equalsWithoutChildren()` implementations that were missing it. Without this comparison, the Cascades memoizer will unify plans that differ (_only_) in their result value or type, which is incorrect. See Issue FoundationDB#4184 for details.

This change does not adjust the `hashCodeWithoutChildren()` methods likewise, as this is not strictly necessary. Leaving these methods untouched avoids needless plan changes (since the hashes are used as a tie-breaker in the cost model).

The potentially incorrect memoization prior to this change can trigger a sanity-check in `Reference.insertUnchecked()`, if enabled. Note though that in production the sanity-checks are disabled, so a violation would have gone undetected there.

Testing:
* Existing test coverage.
* Add missing `equals…()` coverage for `RecordQueryDeletePlan`.

Fixes FoundationDB#4184.
@RobertBrunel RobertBrunel force-pushed the EliminateNullOnEmptyRule-1 branch from be94860 to 7435863 Compare May 21, 2026 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug fix Change that fixes a bug planner Related to the query planner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

equalsWithoutChildren() does not take the result types into account in some plan nodes

1 participant