Issue Details (XML | Word | Printable)

Key: NUCRDBMS-487
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: Tom Zurkan
Votes: 1
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
DataNucleus Store RDBMS

Collection.contains when the contained object is a primitive creates incorrect query

Created: 06/Jan/11 11:25 PM   Updated: 23/Jan/11 11:53 AM   Resolved: 09/Jan/11 03:48 PM
Component/s: Queries
Affects Version/s: 2.2.0.release
Fix Version/s: 2.2.2, 3.0.0.m1

Datastore: MySQL
Severity: Production


 Description  « Hide
putting together a unit test now but wanted to open the bug.

the following JDOQL fails:
SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId );
The filter becomes compiled to:
[filter:InvokeExpression{[ParameterExpression{p0}].contains(PrimaryExpression{this.fbId})}]

The contains expression is never evaluated nor turned into an expression and the where clause becomes where (1=0). This is just passing in a list of longs and comparing it to a big int (this.fbId).

Any parameter based collection using contains will fail.

Fernando Padilla added a comment - 07/Jan/11 12:15 AM
Here is a snippet from a log file of this breaking. You can see the desire query with the contains expression. Then you can see the generated SQL at the bottom where that is converted into "(1=0)".




2011-01-05 19:08:43,925 [main] DEBUG DataNucleus.Query - JDOQL Single-String with "select this from com.protrade.ffplayoffs.data.entities.User where :p0.contains( this.fbId )"
2011-01-05 19:08:43,925 [main] DEBUG DataNucleus.Query - JDOQL Query : Compiling "SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId )"
2011-01-05 19:08:43,926 [main] DEBUG DataNucleus.Query - JDOQL Query : Compile Time = 1 ms
2011-01-05 19:08:43,926 [main] DEBUG DataNucleus.Query - QueryCompilation:
  [result:PrimaryExpression{this}]
  [filter:InvokeExpression{[ParameterExpression{p0}].contains(PrimaryExpression{this.fbId})}]
  [symbols: p0 type=unknown, this type=com.protrade.ffplayoffs.data.entities.User]
2011-01-05 19:08:43,927 [main] DEBUG DataNucleus.Query - JDOQL Query : Compiling "SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId )" for datastore
2011-01-05 19:08:43,927 [main] DEBUG DataNucleus.Query - Parameter ParameterExpression{p0} is being resolved as a literal, so the query is no longer precompilable
2011-01-05 19:08:43,941 [main] DEBUG DataNucleus.Query - JDOQL Query : Compile Time for datastore = 14 ms
2011-01-05 19:08:43,942 [main] DEBUG DataNucleus.Query - SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId ) Query compiled to datastore query "SELECT `A0`.`CREATETIME`,`A0`.`ALLOWAPPEMA
IL`,`A0`.`APPADDED`,`A0`.`BIRTHDATE`,`A0`.`EMAIL`,`A0`.`EMAILREPLACED`,`A0`.`EMAILUPDATE`,`A0`.`FBID`,`A0`.`LEAGUENAME`,`A0`.`SEENMODAL`,`A0`.`SUBSCRIBED`,`A0`.`JDOID`,`A0`.`JDOVERSION` FROM `USER0` `A0` WHERE (1=0)"
2011-01-05 19:08:43,942 [main] DEBUG DataNucleus.Query - Not caching the datastore compilation since some parameters are evaluated during the compilation and aren't present in the final datastore-specific query
2011-01-05 19:08:43,942 [main] DEBUG DataNucleus.Query - JDOQL Query : Executing "SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId )" ...
2011-01-05 19:08:43,944 [main] DEBUG DataNucleus.Datastore.Retrieve - Retrieving PreparedStatement for connection "jdbc:mysql://devdb.protrade.com:3306/hudson_playoffs, UserName=hudson@10.0.16.22, MySQL-AB JDBC Driver"
2011-01-05 19:08:43,945 [main] DEBUG DataNucleus.Datastore.Native - SELECT `A0`.`CREATETIME`,`A0`.`ALLOWAPPEMAIL`,`A0`.`APPADDED`,`A0`.`BIRTHDATE`,`A0`.`EMAIL`,`A0`.`EMAILREPLACED`,`A0`.`EMAILUPDATE`,`A0`.`FBID`,`A0`.`LEAGUENA
ME`,`A0`.`SEENMODAL`,`A0`.`SUBSCRIBED`,`A0`.`JDOID`,`A0`.`JDOVERSION` FROM `USER0` `A0` WHERE (1=0)
2011-01-05 19:08:43,948 [main] DEBUG DataNucleus.Datastore.Retrieve - Execution Time = 3 ms
2011-01-05 19:08:43,948 [main] DEBUG DataNucleus.Query - JDOQL Query : Execution Time = 6 ms
2011-01-05 19:08:43,954 [main] DEBUG DataNucleus.Query - JDOQL Single-String with "select this from com.protrade.ffplayoffs.data.entities.User where :p0.contains( this.fbId )"
2011-01-05 19:08:43,954 [main] DEBUG DataNucleus.Query - Query "SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId )" of language "JDOQL" has been run before so reusing existing generic c
ompilation
2011-01-05 19:08:43,954 [main] DEBUG DataNucleus.Query - JDOQL Query : Compiling "SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId )" for datastore
2011-01-05 19:08:43,955 [main] DEBUG DataNucleus.Query - Parameter ParameterExpression{p0} is being resolved as a literal, so the query is no longer precompilable
2011-01-05 19:08:43,956 [main] DEBUG DataNucleus.Query - JDOQL Query : Compile Time for datastore = 2 ms
2011-01-05 19:08:43,959 [main] DEBUG DataNucleus.Query - SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId ) Query compiled to datastore query "SELECT `A0`.`CREATETIME`,`A0`.`ALLOWAPPEMA
IL`,`A0`.`APPADDED`,`A0`.`BIRTHDATE`,`A0`.`EMAIL`,`A0`.`EMAILREPLACED`,`A0`.`EMAILUPDATE`,`A0`.`FBID`,`A0`.`LEAGUENAME`,`A0`.`SEENMODAL`,`A0`.`SUBSCRIBED`,`A0`.`JDOID`,`A0`.`JDOVERSION` FROM `USER0` `A0` WHERE (1=0)"
2011-01-05 19:08:43,959 [main] DEBUG DataNucleus.Query - Not caching the datastore compilation since some parameters are evaluated during the compilation and aren't present in the final datastore-specific query
2011-01-05 19:08:43,959 [main] DEBUG DataNucleus.Query - JDOQL Query : Executing "SELECT this FROM com.protrade.ffplayoffs.data.entities.User WHERE :p0.contains( this.fbId )" ...
2011-01-05 19:08:43,971 [main] DEBUG DataNucleus.Datastore.Retrieve - Retrieving PreparedStatement for connection "jdbc:mysql://devdb.protrade.com:3306/hudson_playoffs, UserName=hudson@10.0.16.22, MySQL-AB JDBC Driver"
2011-01-05 19:08:43,971 [main] DEBUG DataNucleus.Datastore.Native - SELECT `A0`.`CREATETIME`,`A0`.`ALLOWAPPEMAIL`,`A0`.`APPADDED`,`A0`.`BIRTHDATE`,`A0`.`EMAIL`,`A0`.`EMAILREPLACED`,`A0`.`EMAILUPDATE`,`A0`.`FBID`,`A0`.`LEAGUENA
ME`,`A0`.`SEENMODAL`,`A0`.`SUBSCRIBED`,`A0`.`JDOID`,`A0`.`JDOVERSION` FROM `USER0` `A0` WHERE (1=0)
2011-01-05 19:08:43,975 [main] DEBUG DataNucleus.Datastore.Retrieve - Execution Time = 4 ms
2011-01-05 19:08:43,975 [main] DEBUG DataNucleus.Query - JDOQL Query : Execution Time = 16 ms

Fernando Padilla added a comment - 07/Jan/11 12:17 AM
by the way, I could not find any unit tests that would cover the "contains" expression.. am I just looking at the wrong places?

Tom Zurkan added a comment - 07/Jan/11 12:35 AM
so, the error is related to a recent check that was put into CollectionContainsMethod
line 112 in 2.2.0-release:
                    if (collElemType.isAssignableFrom(elemtype) || elemtype.isAssignableFrom(collElemType))

this fails if the elemType is a primitive (i.e. no autoboxing).

Fernando Padilla added a comment - 07/Jan/11 12:37 AM
We're still looking at it, but it seems that it might be a false positive "type mismatch" issue..

the field (this.fbId) is a type "long"

the collection contains type "java.lang.Long"

Somewhere in the code, you're doing a check if those two class objects are Class.isAssignableFrom, which they are not, since they do not match (without conversion/autoboxing). So that code simply gives up even though it should be able to continue...

Andy Jefferson added a comment - 07/Jan/11 09:36 AM
Whether you're looking in the wrong place for tests I've no idea, since I don't know where your looking. Obviously a simple inspection of test.jdo.datastore (or application) would reveal JDOQLContainerTest which has many many tests for such things.
I'll await *your* testcase

Fernando Padilla added a comment - 07/Jan/11 05:07 PM
shoot, sorry to have been a pain then.. It was confusing because within core and store.dbms projects you have test directories; forgot that you have a slew of test projects outside of of the main codebase.. I svn'd up the test/accessplatform/trunk directory now.

Andy Jefferson made changes - 09/Jan/11 03:47 PM
Field Original Value New Value
Summary JDO: using a parameter expression that is a collection... Collection.contains when the contained object is a primitive creates incorrect query
Andy Jefferson made changes - 09/Jan/11 03:48 PM
Project DataNucleus Access Platform [ 10140 ] DataNucleus Store RDBMS [ 10144 ]
Key NUCACCESS-82 NUCRDBMS-487
Affects Version/s 2.2.0.release [ 10932 ]
Affects Version/s 2.2.0.release [ 10994 ]
Component/s Queries [ 10142 ]
Component/s Software [ 10242 ]
Andy Jefferson added a comment - 09/Jan/11 03:48 PM
SVN for 2.2 and 3.0 work now for me

Andy Jefferson made changes - 09/Jan/11 03:48 PM
Status Open [ 1 ] Resolved [ 5 ]
Fix Version/s 2.2.2 [ 11127 ]
Fix Version/s 3.0.0.m1 [ 11062 ]
Resolution Fixed [ 1 ]
Fernando Padilla added a comment - 09/Jan/11 07:03 PM
you're awesome Andy. thank you!

you would think that java would have that coercible check available.. anyhow :)

thank you

Andy Jefferson made changes - 23/Jan/11 11:53 AM
Status Resolved [ 5 ] Closed [ 6 ]