feat: Enhanced projection handling - new types#117
Open
luanpotter wants to merge 2 commits intomainfrom
Open
Conversation
Member
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
d3ab85f to
1d29904
Compare
1d29904 to
a44ad7e
Compare
QuinnB73
approved these changes
Mar 16, 2026
Collaborator
QuinnB73
left a comment
There was a problem hiding this comment.
This is amazing! I'm so excited to see us decouple further from Hibernate
I just have a few questions mostly for my understanding
a44ad7e to
2e033fc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.

I am redesigning our projection infra! This will be a relatively big change, so I am attempting to split this the best as possible to facilitate review (and migration). I will go over the translation plan below.
Design Goals
My design goals:
Current Problem
Let me go into some detail for the later - what actually current breaks and the limitations of how we do things (other than the coupling).
Let's see how hibernate works first for context when using nested projections. As a simple example, consider this nested double projection list:
You might think that this will result in a
[name, [pages, language]]array, but it doesn't. Since this translates to a list of sql clauses, hibernate returns[name, pages, language].That breaks yawn's current implementation which would expect the former. The current projections are unaware of this flattening. the following test will break when trying to cast the string pages into an array of [pages, language].
This is not only impactful for contrived examples, but blocks us from having transformations as well. A very simple example is
YawnProjections.mappingthat I wanted to add; you can see how the test is incorrect due to me copy and pasting the output.The whole reason is that yawn doesn't know the indices of where projection columns will go. We also ran into this when I added the "constant" projection. as you can see in the impl, it has to add a sentinel to the hibernate projection list that is actually added to the sql query for no reason other than appeasing the indexing management. that constant could be entirely populated in memory by yawn on the resulting object instead.
In a way, we will be taking over and re-implementing part of hibernate. we will never do nested projectionLists(), and always send the simplest possible set of flattened projections to hibernate. all nesting, mapping, and transforming is resolved by yawn.
A Bright New Future
With all that in mind, I am proposing a bold new structure; the
YawnQueryProjectionis broken into two parts:YawnProjectoris what column defs, data class projections and custom projections onYawnProjectionsimplement. they are not project-ions, they are project-ors, that can be projected to aProjectionNode. they do not do the actual projecting, they define how to do it. this is what you compose to make your projection node treeproject()now it actually does something -> it will convert the projection node tree into a resolved projection. this actually does a lot of heavy lifting: it will flatten groups, collect value nodes, de-dupe, re-index and store a final list of projections to send to hibernate (or the ORM), and is able to then re-collect the result in order to generate the final object after the code is run.That is the basic structure plus some niceties. Hopefully this first PR will make it more clear. The following will add a compatibility adapter so that we can try out the new structure within the framework of the old one on our internal repos.
Migration Path
My proposed migration path is as follows: merge PRs (1) and (2) which are entirely net-new and release a version. Test it out at small scale on our internal repos by using the "adapt" method. That goes through the whole tree parsing and the most complicated parts but still uses the v1 query factory. that will be the first test. note that the ergonomics for the adapt method are clunky (you can see on PR (2)), but that is because you have to explicitly create the projectors. the actual end user facing api will be identical in the end. and the actual definitions of specific typed projections, column def and data-class-projections will be simpler. once we have sufficiently tested v2, we can update
YawnProjectiontsto hook up v2 by default, and then remove the adapt method.