There are various (perhaps lot of) things failing in Hb and not failing in NH ;)
On Mon, Jun 27, 2011 at 3: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
