Skip to content

Reimplement EF.Constant without introducing constant nodes in the funcletizer #33674

@roji

Description

@roji

#31552 (8.0) introduced EF.Constant as a way of telling EF to integrate a captured variable ("parameter") as a constant in the SQL; the implementation was done in the funcletizer, where EF.Constant is stripped away and a constant node is inserted instead. Since the constant node is introduced very early - before our query caching mechanism - different values inside EF.Constant cause cache misses, causing a recompilation of the entire query. This is very heavy for a mechanism that is generally meant to ensure constants in SQL only.

An alternative implementation would ignore EF.Constant in the funcletizer, and have a preprocessing step that records in the QueryCompilationContext that the parameter in question is to actually be constantized. Then, in the 2nd part of the query pipeline - where we have access to parameter values - we'd recognize the parameter based on the QCC record, and replace it with a constant of the actual value. This still means we wouldn't be able to cache the SQL (very much by design), but that's still far better than a full recompilation of the query for different values.

One problematic aspect is that this would need to be implemented for non-relational providers as well (e.g. Cosmos), whereas the funcletizer-based implementation is universal. But that doesn't seem to me to be a blocker (it's very unlikely anyone is using EF.Constant with non-relational providers at this point).

Thanks to @stevendarby for exploring this direction in #25630.

Metadata

Metadata

Assignees

No fields configured for Feature.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions