You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Andrus Adamchik <an...@objectstyle.org> on 2008/06/10 14:28:51 UTC

Converting non-string and non-numeric expression parameters to EJBQL

Hi Lachlan, sorry for confusion on my part...

As it turned out, there are actually 3 separate issues

* Serialization when running EJBQL with ROP (CAY-1072 - fixed)
* Converting lists of values to EJBQL Strings (CAY-1073 - fixed)
* Converting non-string and non-numeric expression parameters to EJBQL  
(no Jira yet, I will pen one soon...).

In regards to the last one, per my second comment on CAY-1072, I  
totally agree with you that we need to handle this case. However we  
can't convert those to Strings. This is just not possible because (a)  
EJBQL syntax only supports literals for Strings, numerics, enums and  
booleans; (b) Cayenne fundamentally would not deal with things like  
Date[Time] to String and back conversion, as this is the functionality  
of the JDBC layer.

So the solution has to be elsewhere. What I was proposing (maybe there  
is a better one?) is this:

   Expression.toEJBQL(String rootId, Map parametersCallback);

Expression object would stick any parameters generated internally into  
'parametersCallback' map. So that later you could pass it to  
EJBQLQuery. Note that this does not affect how you create your  
original Expression objects.

Does that sound reasonable?

Andrus


On Jun 10, 2008, at 3:08 PM, Lachlan Deck (JIRA) wrote:

>
>    [ https://issues.apache.org/cayenne/browse/CAY-1073?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12950 
> #action_12950 ]
>
> Lachlan Deck commented on CAY-1073:
> -----------------------------------
>
> Comments from CAY-1072: Andrus wrote:
> ----
> Yes, converting dates to Strings are a no-go. I don't see us being  
> able to fix that on the short run. Could you try a parameterized  
> expression instead (using $param instead of date literals).
> On the other hand, we need some way to handle dates or other  
> parameters that can't be converted into literals... I guess one way  
> is to generate "synthetic" parameters and collect values in a map  
> passed as an argument.
> ----
>
> The problem is that I can't use parameter based expressions as they  
> are constructed elsewhere (as instances of Expression) and re-used  
> in various places (including in-memory).
>
> Is it not possible to re-use whatever code in Cayenne already  
> converts such values (depending on the associated DbAttribute, for  
> example)?

Re: Converting non-string and non-numeric expression parameters to EJBQL

Posted by Lachlan Deck <la...@gmail.com>.
Hi Andrus,

On 11/06/2008, at 5:37 PM, Andrus Adamchik wrote:

> On Jun 11, 2008, at 3:26 AM, Lachlan Deck wrote:
>
>> Would that then be like this:
>> EJBQLQuery query; // assume exists
>> for (Map.Entry<String,Object> param : parametersCallback) {
>> 	query.setParameter(param.getKey(), param.getValue());
>> }
>>
>> Or would there still need to be special treatment given to dates  
>> and the like?
>
> Yes - as simple as your example above. Nothing special to do about  
> dates, etc.

Is there a JIRA for this already?

I've spent some time (as seen in the thread  
ObjEntity.translateToDbPath) attempting to come up with various  
methods to achieve agregate queries such as avg, max, min etc.  
Building the sql is reasonably trivial (and I've mucked around with  
trying to subclass the SelectTranslator, SelectAction, SelectQuery  
etc... and I keep getting snookered by default level access and  
such... besides which it's all overkill :)

So I think I'm stuck without the above enhancement.

>>> Note that this does not affect how you create your original  
>>> Expression objects.
>>>
>>> Does that sound reasonable?
>>
>> Sounds good, sure (so far as mapping between cayenne expressions  
>> and EJBQL). I wonder, however, if the parameters callback would be  
>> more generally useful. i.e., if it would make sense to place all  
>> values in there and not just the ones that can't be stringified.
>
> Possibly, especially for non-integer numerics, to avoid any possible  
> fuzziness.
>
>> Would it also make sense to have a Cayenne based CountQuery?
>> e.g.,
>> CountQuery count = new CountQuery(SelectQuery);
>
> We've had extensive discussions abut "utility" queries in the past.  
> I think we do need query-related utility classes/methods in some  
> form. I am not sure there should be a standalone query for each one  
> of them. Consider that there are also AVG, MAX, MIN, and other  
> things that a user might want to select. But more generally making  
> those types of queries easier to assemble and run is on the TODO list.

Here's what I'm aiming for. I've got the below class. Perhaps a  
variation of this is what could go into Cayenne (with the right  
visitor/sqlaction stuff)?
Or is it more about the column descriptors/meta data for a select query?

int avg = new StatsQuery.Avg(SomeClass.class, "age"[,  
anExpression]).intResult(oc);
int count = new StatsQuery.Count(SomeClass.class[,  
anExpression]).intResult(oc);
int max = new StatsQuery.Max(SomeClass.class, "age"[,  
anExpression]).intResult(oc);
int min = new StatsQuery.Min(SomeClass.class, "age"[,  
anExpression]).intResult(oc);
int sum = new StatsQuery.Sum(SomeClass.class, "age"[,  
anExpression]).intResult(oc);

with regards,
--

Lachlan Deck


Re: Converting non-string and non-numeric expression parameters to EJBQL

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 11, 2008, at 3:26 AM, Lachlan Deck wrote:

> Would that then be like this:
> EJBQLQuery query; // assume exists
> for (Map.Entry<String,Object> param : parametersCallback) {
> 	query.setParameter(param.getKey(), param.getValue());
> }
>
> Or would there still need to be special treatment given to dates and  
> the like?

Yes - as simple as your example above. Nothing special to do about  
dates, etc.


>> Note that this does not affect how you create your original  
>> Expression objects.
>>
>> Does that sound reasonable?
>
> Sounds good, sure (so far as mapping between cayenne expressions and  
> EJBQL). I wonder, however, if the parameters callback would be more  
> generally useful. i.e., if it would make sense to place all values  
> in there and not just the ones that can't be stringified.

Possibly, especially for non-integer numerics, to avoid any possible  
fuzziness.

> Would it also make sense to have a Cayenne based CountQuery?
> e.g.,
> CountQuery count = new CountQuery(SelectQuery);

We've had extensive discussions abut "utility" queries in the past. I  
think we do need query-related utility classes/methods in some form. I  
am not sure there should be a standalone query for each one of them.  
Consider that there are also AVG, MAX, MIN, and other things that a  
user might want to select. But more generally making those types of  
queries easier to assemble and run is on the TODO list.

Andrus

Re: Converting non-string and non-numeric expression parameters to EJBQL

Posted by Lachlan Deck <la...@gmail.com>.
Hi Andrus,

On 10/06/2008, at 10:28 PM, Andrus Adamchik wrote:

> Hi Lachlan, sorry for confusion on my part...

No problems...

> As it turned out, there are actually 3 separate issues
>
> * Serialization when running EJBQL with ROP (CAY-1072 - fixed)
> * Converting lists of values to EJBQL Strings (CAY-1073 - fixed)

Excellent. Thanks.

> * Converting non-string and non-numeric expression parameters to  
> EJBQL (no Jira yet, I will pen one soon...).
>
> In regards to the last one, per my second comment on CAY-1072, I  
> totally agree with you that we need to handle this case. However we  
> can't convert those to Strings. This is just not possible because  
> (a) EJBQL syntax only supports literals for Strings, numerics, enums  
> and booleans; (b) Cayenne fundamentally would not deal with things  
> like Date[Time] to String and back conversion, as this is the  
> functionality of the JDBC layer.
>
> So the solution has to be elsewhere. What I was proposing (maybe  
> there is a better one?) is this:
>
>  Expression.toEJBQL(String rootId, Map parametersCallback);
>
> Expression object would stick any parameters generated internally  
> into 'parametersCallback' map. So that later you could pass it to  
> EJBQLQuery.

Would that then be like this:
EJBQLQuery query; // assume exists
for (Map.Entry<String,Object> param : parametersCallback) {
	query.setParameter(param.getKey(), param.getValue());
}

Or would there still need to be special treatment given to dates and  
the like?

> Note that this does not affect how you create your original  
> Expression objects.
>
> Does that sound reasonable?

Sounds good, sure (so far as mapping between cayenne expressions and  
EJBQL). I wonder, however, if the parameters callback would be more  
generally useful. i.e., if it would make sense to place all values in  
there and not just the ones that can't be stringified.

Would it also make sense to have a Cayenne based CountQuery?
e.g.,
CountQuery count = new CountQuery(SelectQuery);

with regards,
--

Lachlan Deck
lachlan@ish.com.au


with regards,
--

Lachlan Deck