After NH3.2.0GA perhaps I'll gift you the FUTURIZER ;) ... perhaps... On Mon, Jun 27, 2011 at 12:26 PM, Patrick Earl <[email protected]> wrote:
> With any luck, we'll be hearing about some new thoughts and patches of > yours sometime soon. ;) > > Patrick Earl > > On Mon, Jun 27, 2011 at 12:29 AM, Harald Mueller > <[email protected]> wrote: > > Patrick - > > > > Thanks for the thanks - but you did the main work to make it > "production-ready" ... and I would have liked to contribute more, but this > and that and whatever always came up with higher priority. > > > > The next problem in this area is, as I see it, the failing outer joins in > sub-selects (http://216.121.112.228/browse/NH-2648), which is IMHO > necessary to get correct Any behavior ( > http://216.121.112.228/browse/NH-2649); but as the joins already fail in > (Java) Hibernate, it is probably not too easy ... > > > > Regards > > Harald > > > > -------- Original-Nachricht -------- > >> Datum: Sun, 26 Jun 2011 19:18:16 -0600 > >> Von: Patrick Earl <[email protected]> > >> An: [email protected] > >> Betreff: Re: RE: [nhibernate-development] NH-2583 - Query with || > operator and navigations (many-to-one) creates wrong joins > > > >> Just to bring this old and long thread back to life for a brief > >> moment, I committed my new version of the algorithm and resolved the > >> issue. I'm very thankful for the work that Harald did to make this > >> happen... especially in framing the important question of whether a > >> member expression will produce true if emptily outer joined. I've > >> been looking at this problem on and off since the start of this > >> thread, and after a few mornings of insight (after several evenings of > >> head bashing), I was able to make the connection to an easy to > >> understand solution to the problem, which has the potential for even > >> inner join optimization in even complex scenarios. > >> > >> So in summary... thanks Harald... and I think we're done with this one > >> for now. :) > >> > >> Patrick Earl > >> > >> On Sun, Apr 24, 2011 at 3:45 PM, Fabio Maulo <[email protected]> > wrote: > >> > Just a very minus-little.. > >> > Patrick, > >> > That work is may be "managed" by query-substitution (true -> 1), we > >> should > >> > never use 0 for false and 1 for true during the conversion of a Linq > to > >> HQL. > >> > The Linq-provider should work with true/false and the final Hql2Sql > >> > translator will do the replacement. > >> > On Sun, Apr 24, 2011 at 6:19 PM, Patrick Earl <[email protected]> > wrote: > >> >> > >> >> On Sun, Apr 24, 2011 at 5:02 AM, Harald Mueller > >> <[email protected]> > >> >> wrote: > >> >> > Maybe I need to stress the following once more: What we try here, > is > >> to > >> >> > "put 3-valued logic ('SQL logic') over navigational expressions > >> ('Linq > >> >> > expressions')". So it is a *new semantics* for Linq expressions. As > I > >> have > >> >> > pointed out repeatedly, I personally would have liked to "force" > >> >> > Linq2Objects logic into NHib.Linq expressions. However, we agreed > >> that we > >> >> > want "simple implementations" by way of using SQL logic as much as > >> possible. > >> >> > But when we do this, let's do it in earnest! That means, above all, > >> clearly > >> >> > separating *expressions* and *conditions* in our analysis. Of > course, > >> Linq > >> >> > expressions do not have this separation - so we need special rules > to > >> >> > distinguish them. Right now, in the code, we loosely rule that > >> expressions > >> >> > with result type bool are conditions, unless they are leaf > >> expressions, in > >> >> > which case they are interpreted as conditions of the form expr == > 1. > >> Let's > >> >> > stick to this at least for some more time. > >> >> > > >> >> > (This ruling does most certainly not work in cases like (a == b) != > >> (c < > >> >> > d), where a direct transformation is simply not allowed in SQL - > and > >> >> > probably also in HQL. But such "cross-overs" between expressions > and > >> >> > conditions are a different topic - right now, I just propose that > we > >> do not > >> >> > support them). > >> >> > >> >> > >> >> Just a couple minor notes. It's more like expr == <true> since some > >> >> databases actually have a boolean type. Additionally, it should > >> >> ultimately be a dialect-specific transformation to decide how the SQL > >> >> for these booleans is ultimately generated. That work is avoided for > >> >> the time being. Additionally, (a==b) != (c<d) is actually a valid > >> >> expression in databases like PostgreSQL and SQLite. It is actually > >> >> rather unfortunate that MSSQL opted not to have a boolean type. Now > >> >> we need to perform crazy hacks like "case when x = y then 1 else 0" > :( > >> >> I don't think it's unreasonable that Linq will actually transform > >> >> expressions like (a==b) != (c<d) into valid case statements at some > >> >> point. > >> >> > >> >> > >> >> > (e) expr <op> <constant(s)> (where <constant(s)> are not > value-nulls) > >> >> > > >> >> > Old result: { mE -> n } for all joined mE's in expr. > >> >> > > >> >> > New result: > >> >> > - If an outer-joined mE makes the expression expr null (we have u > in > >> the > >> >> > expression mapping), it makes the condition n. > >> >> > - If outer-joining that mE makes the expression not-null (we have v > >> in > >> >> > the expression), the condition can become t or f, but also n. The > >> latter > >> >> > happens if *another* member expression, when outer joined, makes > the > >> >> > expression null. > >> >> > > >> >> > Concisely: > >> >> > { mE -> n } if { mE -> u } in expr > >> >> > { mE -> tnf } if { mE -> v } in expr > >> >> > >> >> > >> >> Wouldn't it be tf? > >> >> > >> >> > >> >> > Case (k): > >> >> > Constants: Constants do not contain any member expressions, so the > >> >> > mapping comes out empty. > >> >> > >> >> Much of this section you already discuss below, but I wrote this part > >> >> without reading your remaining comments. > >> >> > >> >> When determining the result of an operator, it's handy to have the > >> >> result of the constant around. I was considering three possible > >> >> values for expressions based on your original design: > >> >> > >> >> oj-null > >> >> value-null > >> >> value-not-null > >> >> > >> >> It would technically even be possible to propagate constants as far > as > >> >> possible to optimize out known expression results. For example, 1+1 > = > >> >> 2 could be T instead of TF. While we're ultimately only interested > in > >> >> how to join the member expressions, there's significant intermediate > >> >> information available in the expressions. Providing a framework for > >> >> taking advantage of that information may be helpful. > >> >> > >> >> I've also been thinking about how to avoid accidental inner joins for > >> >> partially supported cases. I've an idea about wrapping > >> >> VisitExpression and ensuring that the visitor marks the result as > >> >> handled. Sadly there's no technique that can avoid errors in > >> >> development. :) > >> >> > >> >> > >> >> > Case (l) ["ell"]: > >> >> > Dot operator on complete expressions: (expr).P - this could be > >> something > >> >> > like (a.B ?? a.D).E or worse. I think we should not support such > >> expressions > >> >> > (i.e., we allow wrong results); or at least should not support > inner > >> join > >> >> > optimization for them! In the latter case, we have to invest some > >> thought - > >> >> > we'd have to remove all those mappings. Here is a suggestion to > solve > >> this > >> >> > easily: > >> >> > > >> >> > We replace all mapped values with the pessimistic assumption uv. > >> >> > >> >> > >> >> This is an interesting case. I wonder if the code produces joins for > >> >> this right now. > >> >> > >> >> > >> >> > Of course, we *could* implement that "possible expression value" > >> >> > concept. In the following, I use pairs <M,Z> as expression results, > >> where M > >> >> > is the mapping as above and Z is the set of all possible expression > >> values. > >> >> > The Z set can then be intersected with all mapping results to > >> possibly > >> >> > reduce the mappings. I do not give the complete formalism (which > >> requires > >> >> > all the case tables above to be rewritten to add those "possible > >> values"), > >> >> > but just an outline: > >> >> > >> >> > >> >> Ya, this is how it would need to be designed for maximum flexibility. > >> >> I've also got another stack design up my sleeves to eliminate the > need > >> >> for the separate left/right traversals currently utilized. Basically > >> >> each expression node would push a single result onto the stack. In a > >> >> binary expression, it would pop two off and push one back on. > >> >> > >> >> > >> >> I'll be working on this this afternoon. I hope it comes out in a > >> >> concise manner. > >> >> > >> >> Thanks for all your great thoughts Harald! I especially liked the > >> >> (expr).P example. > >> >> > >> >> Patrick Earl > >> > > >> > > >> > > >> > -- > >> > Fabio Maulo > >> > > >> > > > > > -- > > Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir > > belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de > > > -- Fabio Maulo
