Ah yes - that's what we all are planning, aren't we? Somehow, it's slow going, however ...
Harald M. -------- Original-Nachricht -------- > Datum: Mon, 27 Jun 2011 11:25:49 -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 > Is this the signature for the method? > > session.MakeFutureHappen<NHibernate>(DateTime.Now)? > > Patrick Earl > > On Mon, Jun 27, 2011 at 10:11 AM, Fabio Maulo <[email protected]> > wrote: > > 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 > > > > -- NEU: FreePhone - kostenlos mobil telefonieren! Jetzt informieren: http://www.gmx.net/de/go/freephone
