Avoid re-using query plan embedding different constant values. #1542
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
As said in #1363, I find the
insideSelectClause
trick a bit hackish, and I was willing to investigate patches from #1363 and #866 corresponding JIRAs.The one from #1363 was quite interesting, but is missing cases where the constant is not parameterized while not being in select clause (handled by a post transformer), as in #866. (Cases which are also missed by the
insideSelectClause
trick.)Patch from #866 just addresses custom LINQ extensions needing to signal a constant as non-parameterized. So it was fixing just a very small subset of the trouble, while requiring many changes, both in NHibernate and on user side.
Here I propose yet another way: detect than some constants have not been used as parameters, and refine adequately the plan caching. This must be a two steps process since such constants are only known once the plan has been generated.
So at that point, if such constants are detected, the query is flagged as refined, it has a new refined key, and it is cached for that additional key, along with being cached with its "original" key.
On cache hit with a non-refined key, the key is refined thanks to plan's query informations, and checked against plan's query again. If not matching, it is looked-up again, but this time with the key already refined.
It allows to remove the
insideSelectClause
trick, and solves most of the cases. Only the "cached object instance" issue remains, but with a workaround.If this PR is merged before #1540, #1540 would then be obsoleted and no more needed.