Will there be a way in SQM to specify the argument types of a function? If so, then you could introduce the concept of var-args and then a parameter will only be a multi-valued parameter if the function argument it is used for is a var-arg parameter. If not, then you probably need a custom syntax. Maybe something like ":param...", ":...param", ":*param" or ":param*"?
Am 10.09.2016 um 15:30 schrieb Steve Ebersole: > Semantic means the "meaning" of something, but also the "intent". > Here, specifically, the intent is "is this param placeholder > representing a single- or multi-valued parameter? So I'll ask you... > Given a query: > > "from Something order by field( id, :param )" > > Does ":param" represent a single- or multi-valued parameter? Because > that is part of the semantic of the query... the ability to answer > such questions... > > > On Sat, Sep 10, 2016 at 7:34 AM Christian Beikov > <christian.bei...@gmail.com <mailto:christian.bei...@gmail.com>> wrote: > > May I ask how the semantics of a query could change in case of > parameter > expansion in different places than IN predicate? > Since such collection valued parameters only make sense on some > sort of > varg-args accepting thingy like IN or a SQLFunction, I don't > really see > how this is an issue. > > You could have 2 caches e.g. > > * SQMCache<HQL, SQMQuery> > * SQLCache<SQMQuery, Cache<ParameterMetadata, SQLString>> > > Can you please elaborate what you think is problematic about something > like that? > > Am 09.09.2016 um 23:39 schrieb Steve Ebersole: > > Although, thinking about it some more, SQM itself already > exposes some > > of the things QueryPlan does today. So maybe this is not such a big > > issue. > > > > I personally am just not a fan of not understanding the semantic > of a > > query up front. Good translation in part comes down to good > design of > > the language so that as much semantic as possible is available > > statically (from the Query itself, and from Session/SessionFactory). > > > > > > On Fri, Sep 9, 2016 at 4:35 PM Steve Ebersole > <st...@hibernate.org <mailto:st...@hibernate.org> > > <mailto:st...@hibernate.org <mailto:st...@hibernate.org>>> wrote: > > > > Not any particular reason, HHH-10502 or otherwise. Its more a > > general question as I am integrating SQM and the new query > > translators upstream. > > > > Again, I think y'all are missing the point. The concern is not > > whether a query is cacheable or not. The concern is *when* > I know > > whether it is cacheable. > > > > Consider some psuedo-code. First, the ideal case: > > > > SessionImpl#createQuery(...) { > > ... > > > > // interpret the query into SQM > > SqmStatementSelect sqm = > SemanticQueryInterpreter.interpret(...); > > > > QueryPlan queryPlan; > > if ( isCacheable( sqm ) ) { > > queryPlan = queryPlanCache.get( ... ); > > if ( queryPlan == null ) { > > queryPlan = new QueryPlan( ... ); > > queryPlanCache.put( ..., queryPlan ); > > } > > } > > else { > > queryPlan = new QueryPlan( ... ); > > } > > > > return new QueryImpl( sqm, queryPlan, this ); > > } > > > > versus: > > > > SessionImpl#createQuery(...) { > > ... > > > > // interpret the query into SQM > > SqmStatementSelect sqm = > SemanticQueryInterpreter.interpret(...); > > > > // now we have to delay creation of the QueryPlan until > later > > // because we do not know if the query is cacheable, because > > // we do not know yet whether it contains any multi-valued > > // parameters. > > > > return new QueryImpl( sqm, this ); > > } > > > > > > > > On Fri, Sep 9, 2016 at 4:17 PM Christian Beikov > > <christian.bei...@gmail.com > <mailto:christian.bei...@gmail.com> > <mailto:christian.bei...@gmail.com > <mailto:christian.bei...@gmail.com>>> > > wrote: > > > > Ah ok, I thought you wanted to drop parameter lists in > general ^^ > > I suppose you are discussing this because of > > https://hibernate.atlassian.net/browse/HHH-10502? > > > > I personally don't have a use case for a general > parameter list > > expansion like the reporter of that issue and I also don't > > think that > > people are directly writing that kind of stuff into a > query, but a > > wrapper does. All in all, I think people will be able to > > workaround if > > you remove the parameter list expansion for other places. Is > > this such a > > problem to keep around that feature? > > > > Would be interesting to see how other people make use of > that > > feature. > > If everyone uses such collection valued parameters at least > > for an IN > > predicate and maybe additionally for something else like > that > > FIELD > > function, you would have to wait for the parameter list > anyway. > > > > Query caching can generally be handled if you introduce a > > configuration > > parameter for a fixed expansion size, but that would > probably > > be even > > more work because then you would have to exectue the query > > multiple times. > > > > I just don't think that removing this feature will bring any > > benefits. > > > > Regards, > > Christian > > > > Am 09.09.2016 um 22:30 schrieb Steve Ebersole: > > > BTW, JPA really requires that we support accepting > > multi-valued bindings > > > for parameters through #setParameter. Yet another > reason to > > do away with > > > #setParameterList. > > > > > > > > > On Fri, Sep 9, 2016 at 3:26 PM Steve Ebersole > > <st...@hibernate.org <mailto:st...@hibernate.org> > <mailto:st...@hibernate.org <mailto:st...@hibernate.org>>> wrote: > > > > > >> WRT the "collection_valued_input_parameter" bit, that is > > limited in the > > >> spec to IN clauses. And more specifically in fact > the spec > > specifically > > >> limits this in *exactly* the way I suggested :) > > >> > > >> <quote> > > >> in_expression ::= > > >> {state_valued_path_expression | > > type_discriminator} [ NOT ] IN > > >> { ( in_item { , in_item}* ) | ( subquery ) | > > >> collection_valued_input_parameter } > > >> > > >> in_item ::= literal | single_valued_input_parameter > > >> </quote> > > >> > > >> (see "4.6.9 In Expressions" or "4.14 BNF") > > >> > > >> In other words, the "values" of an IN expression may be > > *one of* the > > >> following: > > >> > > >> 1. an explicit list of "in-items", which in turn are > > specifically > > >> single values > > >> 2. a subquery > > >> 3. a *single* multivalued param (one placeholder to > > rule them all) > > >> > > >> > > >> As I said in my original email: > > >> > > >> <quote> > > >> we could simply assume that a IN predicate with a > single > > parameter > > >> placeholder is going to be a multivalued parameter > > >> </quote> > > >> > > >> That's what JPA supports for multi-valued parameters. > > Hibernate has long > > >> supported a broader definition of > > "collection_valued_input_parameter". I > > >> am simply suggesting that we align with the > limitation JPA > > already has in > > >> place. > > >> > > >> Really, the only thing I am really asking about is the > > overloaded forms of > > >> Query#setParameterList. We have to support multi-valued > > parameters *in > > >> this very limited* case. Sure. The problem with our > existing > > >> broader/open-ended multi-valued param support is that > we do > > not know that a > > >> parameter is multi-valued *from the query* itself. > > Specifically we have > > >> to wait and see if #setParameter or #setParameterList is > > called, on any of > > >> the parameters. > > >> > > >> Again, the "win" is that we could then know *up > front* that > > a query is not > > >> cacheable (precompile-able), whereas today we have to > wait > > until just > > >> before the execution (so that #setParameter and > > #setParameterList have all > > >> been called). > > >> > > >> > > >> @Vlad It depends what "query cannot be precompiled" > *means* > > which is of > > >> course open to interpretation. Heck what compilation > of a > > query means at > > >> all is outside the scope of the spec. Any > "compilation" of > > the query that > > >> resolves to SQL of course has to wait. But "compilation" > > to a semantic > > >> form (aka, SQM) does not need to wait. In fact the SQM is > > the exact place > > >> you'd look to know whether the query (plan) is cacheable. > > >> > > >> > > >> > > >> On Fri, Sep 9, 2016 at 8:20 AM Vlad Mihalcea > > <mihalcea.v...@gmail.com > <mailto:mihalcea.v...@gmail.com> <mailto:mihalcea.v...@gmail.com > <mailto:mihalcea.v...@gmail.com>>> > > >> wrote: > > >> > > >>> Hi, > > >>> > > >>> I don't think we should deprecate such a feature. > > >>> > > >>> First, the JPA specs says the follows: > > >>> > > >>> "All input parameters must be single-valued, except > in IN > > expressions > > >>> (see section 4.6.9), which support > > >>> the use of collection-valued input parameters." > > >>> > > >>> So, we kinda need to support it one way or another. > > >>> > > >>> Also, the JPA specs says that: > > >>> > > >>> "Note that use of a collection-valued input > parameter will > > mean that a > > >>> static query cannot be precompiled." > > >>> > > >>> So, it's expected to have such a behavior. > > >>> > > >>> I don't think that multi-load support can replace > > paremeterList since the > > >>> former cannot use any property from a given entity. > > >>> Also, the IN predicate with parameter list applies > to DTO > > projections or > > >>> native queries, so it's useful to have it. > > >>> > > >>> Vlad > > >>> > > >>> On Fri, Sep 9, 2016 at 4:03 PM, andrea boriero > > <and...@hibernate.org <mailto:and...@hibernate.org> > <mailto:and...@hibernate.org <mailto:and...@hibernate.org>>> > > >>> wrote: > > >>> > > >>>> I am also not able to figure out another use case than > > the IN predicate > > >>>> so > > >>>> I am for always considering IN predicates as > multi-valued. > > >>>> > > >>>> On 9 September 2016 at 14:20, Steve Ebersole > > <st...@hibernate.org <mailto:st...@hibernate.org> > <mailto:st...@hibernate.org <mailto:st...@hibernate.org>>> > > >>>> wrote: > > >>>> > > >>>>> To be clear, this is the feature that lets you > define a > > query like: > > >>>>> > > >>>>> select ... from Person p where p.name > <http://p.name> <http://p.name> in > > (:names) > > >>>>> > > >>>>> And then bind varied multiple values into that single > > parameter holder: > > >>>>> > > >>>>> query.setParameterList( "names", new String[] { > "Larry", > > "Curly", > > >>>> "Moe" } > > >>>>> ); > > >>>>> query.setParameterList( "names", new String[] { > "John", > > "Jane" } ); > > >>>>> > > >>>>> Which magically transforms to the following > (rough) SQL: > > >>>>> > > >>>>> select ... from PERSON p where p.name > <http://p.name> <http://p.name> in > > (?, ?, ?) > > >>>>> select ... from PERSON p where p.name > <http://p.name> <http://p.name> in > > (?, ?) > > >>>>> > > >>>>> Effectively parameter lists allow expansion of the HQL > > statement - they > > >>>>> literally are handled by altering the HQL on the > fly as > > we prepare to > > >>>>> execute the query. What that means is that we can > > really not cache > > >>>> these > > >>>>> queries, at least not until the parameters are bound > > (which kind of > > >>>> defeats > > >>>>> the purpose). > > >>>>> > > >>>>> I'd like to discuss dropping support for parameter > > lists. There are > > >>>> quite > > >>>>> a few reasons I would like to drop this support: > > >>>>> > > >>>>> 1. This is the main culprit that leads to the > > ever-resurrecting > > >>>>> discussion about DB limits on IN clauses. The one > > valid use case I > > >>>> saw > > >>>>> for > > >>>>> that lead me to add multi-load support in 5.1. > > >>>>> 2. In terms of a QueryPlan cache, this support > means > > we can never > > >>>>> effectively cache the plans for these queries > > because the SQL is > > >>>>> different > > >>>>> every time we execute the query. The problem > though > > is that we do > > >>>> not > > >>>>> know > > >>>>> this until well after the point that we'd resolve > > the QueryPlan. > > >>>>> chicken-egg. > > >>>>> 3. This is more an internal detail, but > handling the > > parameter > > >>>> bindings > > >>>>> for these differently gets quite complicated. > > >>>>> 4. An additional internal detail is that > re-writing > > the HQL on the > > >>>> fly > > >>>>> is problematic. And some of that leaks to the > user > > in terms of > > >>>> result > > >>>>> caching and stats (which HQL do we use?). > > >>>>> > > >>>>> I get that this can be a useful feature for apps that > > dynamically build > > >>>>> HQL, although really for dynamic query building I > think > > a criteria > > >>>> approach > > >>>>> is more appropriate. It is not so much supporting > this > > feature that > > >>>> bugs > > >>>>> me, it's how we expose it. So an alternative to > > dropping this support > > >>>>> would be to support it in a different way. The main > > issue is that I > > >>>> would > > >>>>> like to *syntactically* understanding that a parameter > > placeholder > > >>>> will be > > >>>>> used for multi-valued parameter from the query itself. > > This is a > > >>>>> beyond-JPA feature, so we definitely have some leeway > > here to define > > >>>> this > > >>>>> however we want. > > >>>>> > > >>>>> I am open to suggestions as to the best syntax to > > declare that. > > >>>>> > > >>>>> An alternative would be to make some assumptions. > > Specifically, the > > >>>> only > > >>>>> time I can think this is used is inside an IN > > predicate. Am I missing > > >>>>> others? If that is the case, we could simply assume > > that a IN > > >>>> predicate > > >>>>> with a single parameter placeholder is going to be a > > multivalued > > >>>>> parameter. That assumption holds valid even if just a > > single value is > > >>>>> bound. The main win there is that we can get rid > of the > > >>>>> Query#setParameterList > > >>>>> variants. setParameterList was only ever needed > so that > > we could > > >>>>> understand that the parameter is multivalued - > here we'd > > assume that > > >>>> from > > >>>>> its context as the IN predicate value. > > >>>>> > > >>>>> Continuing to support parameters-lists in any form > does > > not really > > >>>>> address point > > >>>>> (1) above; but that's ok - the user really could , But > > each of the > > >>>>> alternatives does help with the other problems > currently > > stemming from > > >>>>> parameter-list support. > > >>>>> _______________________________________________ > > >>>>> hibernate-dev mailing list > > >>>>> hibernate-dev@lists.jboss.org > <mailto:hibernate-dev@lists.jboss.org> > > <mailto:hibernate-dev@lists.jboss.org > <mailto:hibernate-dev@lists.jboss.org>> > > >>>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev > > >>>>> > > >>>> _______________________________________________ > > >>>> hibernate-dev mailing list > > >>>> hibernate-dev@lists.jboss.org > <mailto:hibernate-dev@lists.jboss.org> > > <mailto:hibernate-dev@lists.jboss.org > <mailto:hibernate-dev@lists.jboss.org>> > > >>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev > > >>>> > > >>> > > > _______________________________________________ > > > hibernate-dev mailing list > > > hibernate-dev@lists.jboss.org > <mailto:hibernate-dev@lists.jboss.org> > > <mailto:hibernate-dev@lists.jboss.org > <mailto:hibernate-dev@lists.jboss.org>> > > > https://lists.jboss.org/mailman/listinfo/hibernate-dev > > > > _______________________________________________ > > hibernate-dev mailing list > > hibernate-dev@lists.jboss.org <mailto:hibernate-dev@lists.jboss.org> > > <mailto:hibernate-dev@lists.jboss.org > <mailto:hibernate-dev@lists.jboss.org>> > > https://lists.jboss.org/mailman/listinfo/hibernate-dev > > > > _______________________________________________ > hibernate-dev mailing list > hibernate-dev@lists.jboss.org <mailto:hibernate-dev@lists.jboss.org> > https://lists.jboss.org/mailman/listinfo/hibernate-dev > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev