[hibernate-dev] Continue "parameter list" support?

Steve Ebersole steve at hibernate.org
Sun Sep 11 09:48:47 EDT 2016


The direction I went for now was to push collection of the parameters to
SQM itself and expose that from SqmStatement#getQueryParameters.
Additionally I have SQM validate the positional parameters per JPA spec
(1-based, contiguous).

I added org.hibernate.sqm.query.Parameter#allowsMultiValuedBinding which
gets set based on the parameters context.  We can leverage that in ORM.
The one caveat to that is the function stuff because atm SQM has no "object
view" of a function (SQLFunction or otherwise) so it has no idea if a
function allows "varargs"... we will have to either:

   1. validate that on the ORM side
   2. provide some "object view" of a function to SQM (via ConsumerContext)
   to check that.

(2) is nice because it would also allow us to understand the result-type of
a function also.


On Sat, Sep 10, 2016 at 10:02 AM Steve Ebersole <steve at hibernate.org> wrote:

> BTW... the question is not necessarily whether that parameter *is*
> multi-valued.  The question is whether it *can be* multi-valued.
>
> So from the initial SQM build we'd understand that a particular parameter
> is used in a way that indicated that its binding might be multi-valued.
> When we resolve that to a SQLFunction, e.g., we'd be able to ask the
> SQLFunction if it accepts varargs and:
>
> if ( sqmFunctionArgumentParameter.allowsMultiValues() ) {
>     if ( !sqlFunction.acceptsVarargs() ) {
>         log.debug( "SQLFunction [%s] does not accept varargs, adjusting
> SqmParameterExpression [%s] used as argument to not allow multi-values, ..
> );
>         sqmFunctionArgumentParameter.allowMultiValues( false );
>     }
> }
>
> On Sat, Sep 10, 2016 at 9:53 AM Steve Ebersole <steve at hibernate.org>
> wrote:
>
>> We are actually getting close to being able to wholly determine FUNCTION
>> syntactically.  So adding support for "collection valued input
>> parameters" as function arg should be pretty straight forward.
>>
>> And validation-wise I think it still works out nicely.  Basically that
>> leaves us 3 conditions:
>>
>>    1. "collection valued input parameters" as IN expression value -
>>    supported by HQL and JPQL
>>    2. "collection valued input parameters" as (final) function argument
>>    - supported by HQL but not JPQL strictly
>>    3. "collection valued input parameters" anywhere else - not supported
>>    in HQL or JPQL
>>
>>
>>
>>
>> On Sat, Sep 10, 2016 at 9:43 AM Christian Beikov <
>> christian.beikov at gmail.com> wrote:
>>
>>> My idea was to allow a parameter to be a collection valued parameter
>>> only in two cases
>>>
>>>  1. When used with the IN predicate
>>>  2. When used as last argument for a function and the parameter is a
>>>     var-arg parameter
>>>
>>> That way the query can be validated upfront when knowing the registered
>>> functions and their argument types, but it's obviously not clear from
>>> just looking at the query string if a parameter is multi-valued or not.
>>> If you want to make the semantics independent of the functions, then you
>>> must introduce a syntax of course. I was just trying to suggest
>>> something that is mostly compatible to the way it is right now.
>>>
>>> Am 10.09.2016 um 16:10 schrieb Steve Ebersole:
>>> > WRT the "double caches"... yes there will be a few caches.
>>> >
>>> > I'm not understanding what that has to do with defining a clear
>>> > semantic for a particular language element.
>>> >
>>> > ----
>>> >
>>> > Look, to me this whole thing boils down to the fact that JPA defines
>>> > specific/limited support for this "collection valued input parameter"
>>> > language element.  It does that btw because the ideal in language
>>> > design is to be able to wholly understand the semantic of a part of a
>>> > query based only on the syntax[1]. Further, JPA requires that we
>>> > handle a user binding a "collection valued input parameter" directly
>>> > through #setParameter.
>>> >
>>> > So all told we have a set of overloaded methods (#setParameterList)
>>> > that are not really providing any value[2], but that are needed
>>> > because that provides the only indication we ever get that a
>>> > particular parameter placeholder identifies a "collection valued input
>>> > parameter" rather than a"single valued input parameter". For all the
>>> > reasons discussed[1], thats not the ideal language design because it
>>> > is not deterministic from the grammar.
>>> >
>>> > Think of it this way...  It would be nice++ to be able to say "this
>>> > parameter is allowing multi-valued input" or "this parameter is
>>> > expecting single-valued input (multi-value input disallowed)", right?
>>> > Its the whole reason JPA defines its grammar (BNF) the way it does, so
>>> > that we can properly validate the incoming parameter input.  Today I
>>> > can do something like this:
>>> >
>>> > s.createQuery("from Zoo z where z.name <http://z.name> = :name" )
>>> >        .setParameterList("name",new String[] {"San Antonio Zoo","Waco
>>> Zoo" } )
>>> >        .list();
>>> > That is a completely "valid" query.  Its not going to return anything
>>> > useful, but syntactically it is valid because we cannot understand the
>>> > proper semantic.   And we do not understand the proper semantic
>>> > because it is not deterministic wrt the grammar/syntax. Ideally you'd
>>> > want to throw an exception back to the user here as soon as they try
>>> > to call #setParameterList for a parameter we conceptually *know*
>>> > should not accept "collection valued input parameters"
>>> >
>>> > ----
>>> >
>>> > [1] This gets into language and grammar design, but there are a few
>>> > reasons you want to encode as much semantic understanding into the
>>> > syntax as possible.  There are a few reasons for this; the 2 main ones
>>> > for us:
>>> >
>>> >  1. validation - again, here if I understand that a parameter
>>> >     placeholder should or should-not allow "collection valued input
>>> >     parameter" I can apply better validation up front (the sooner this
>>> >     type of feedback can happen the better)
>>> >  2. performance - anytime the query itself is not clear as to its
>>> >     semantic there is going to be a performance aspect to resolving
>>> >     that unclarity.
>>> >
>>> > [2] I can see the argument of #setParameterList providing a better API
>>> > for passing the multi-value bind value in terms of type signature.
>>> > But ultimately IMO both "collection valued input parameter" and
>>> > "single valued input parameter" ought to be stored in one structure.
>>> > Today they are not, can't because we need to know that
>>> > #setParameterList was called instead of #setParameter because that is
>>> > our only understanding of the semantic - that this is a "collection
>>> > valued input parameter", not a"single valued input parameter".
>>> >
>>> >
>>>
>>> _______________________________________________
>>> hibernate-dev mailing list
>>> hibernate-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>
>>


More information about the hibernate-dev mailing list