Fixing lift-ids duplication issue in dynamic query lists #520
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.
Fixes all known cases of #318
More holistic approach than #398
This issue really bothered me throughout the latter half of 2023 and I feared that it was a fundemental flaw of the approach in ProtoQuill that I had decided use for runtime lifts (i.e. generating UIDs at runtime in the call-site of the lift macro). I reasoned through multiple approaches such as adding secondary runtime-specific UUIDs as well as embedding lifts directly into the Ast, a step which I was very hesitant to take because it would mean that the tree can no-longer be serialized (and would be harder to cache). Recently however, I realized that the solution was far simpler than I had thought because there are two fundemental constraints to the problem:
(e.g.
(quotationVaseQuotationA || quotationVaseQuotationB).filter(...)
) it is fully available in the parent quotation runtimeLifts list as a separate item.The consequence of these two constraints is that we can trivially know where duplicate lifts are and can physically inspect and dudupe them. Furthermore, it is not even necessary to find out what the duplicate lifts are. We can merely regenerate the UUIDs for all the lifts in each QuotationVase individually. That means that when they are merged back into the final query, they will have unique UUIDs. (We can also do this to the UUIDs of the QuotationVase/QuotationTag themselves to ensure that they are unique as well - since the whole quotation might have been inserted from a dynamic list).
Therefore in dynamic situations that collect and then combine multiple queries e.g:
since the lift(a) UID is determined at compile-time the trees of both "a", and "b" variants will have the same value for it resulting in a tree that looks like this (before being flattened into a single filter which happens during query compilation):