Kirill Shirokov created IGNITE-7068:
---------------------------------------

             Summary: Incorrect error reporting for incompatible type in SQL 
WHERE clause
                 Key: IGNITE-7068
                 URL: https://issues.apache.org/jira/browse/IGNITE-7068
             Project: Ignite
          Issue Type: Bug
          Components: sql
    Affects Versions: 2.3
            Reporter: Kirill Shirokov


When we create a cache with some POJO key type, say AffinityKey => String and 
try to search in it using a statement tries to compare the key with an integer 
argument (e.g., "select name from Person where _key = 25"), we get a misleading 
exception:

{noformat}
javax.cache.CacheException: class org.apache.ignite.IgniteCheckedException: 
Deserialization failed, cause: "class org.apache.ignite.IgniteCheckedException: 
Not enough data to read the value [position=1, requiredBytes=4, 
remainingBytes=0]" [90027-195]
        at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:1927)
        at 
org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:585)
        at 
org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:560)
        at 
org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.query(GatewayProtectedCacheProxy.java:382)
        at 
org.apache.ignite.internal.processors.cache.IgniteCacheAbstractFieldsQuerySelfTest.testIncompatibleTypesInWhereClause(IgniteCacheAbstractFieldsQuerySelfTest.java:688)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at junit.framework.TestCase.runTest(TestCase.java:176)
        at 
org.apache.ignite.testframework.junits.GridAbstractTest.runTestInternal(GridAbstractTest.java:2000)
        at 
org.apache.ignite.testframework.junits.GridAbstractTest.access$000(GridAbstractTest.java:132)
        at 
org.apache.ignite.testframework.junits.GridAbstractTest$5.run(GridAbstractTest.java:1915)
        at java.lang.Thread.run(Thread.java:745)
Caused by: class org.apache.ignite.IgniteCheckedException: Deserialization 
failed, cause: "class org.apache.ignite.IgniteCheckedException: Not enough data 
to read the value [position=1, requiredBytes=4, remainingBytes=0]" [90027-195]
        at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:2489)
        at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:1924)
        ... 13 more
Caused by: org.h2.message.DbException: Deserialization failed, cause: "class 
org.apache.ignite.IgniteCheckedException: Not enough data to read the value 
[position=1, requiredBytes=4, remainingBytes=0]" [90027-195]
        at org.h2.message.DbException.get(DbException.java:168)
        at org.h2.util.JdbcUtils.deserialize(JdbcUtils.java:422)
        at 
org.h2.value.ValueJavaObject$NotSerialized.getObject(ValueJavaObject.java:166)
        at 
org.h2.value.ValueJavaObject$NotSerialized.getString(ValueJavaObject.java:143)
        at 
org.h2.value.ValueJavaObject$NotSerialized.getDisplaySize(ValueJavaObject.java:174)
        at 
org.h2.expression.ValueExpression.getDisplaySize(ValueExpression.java:134)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromExpression(GridSqlType.java:106)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser.parseExpression(GridSqlQueryParser.java:1581)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser.parseExpression0(GridSqlQueryParser.java:1683)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser.parseExpression(GridSqlQueryParser.java:1578)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser.parseSelect(GridSqlQueryParser.java:635)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser.parseQuery(GridSqlQueryParser.java:1531)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser.parse(GridSqlQueryParser.java:1489)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuerySplitter.parse(GridSqlQuerySplitter.java:1635)
        at 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuerySplitter.split(GridSqlQuerySplitter.java:199)
        at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.queryDistributedSqlFields(IgniteH2Indexing.java:1525)
        at 
org.apache.ignite.internal.processors.query.GridQueryProcessor$5.applyx(GridQueryProcessor.java:1919)
        at 
org.apache.ignite.internal.processors.query.GridQueryProcessor$5.applyx(GridQueryProcessor.java:1917)
        at 
org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36)
        at 
org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:2466)
        ... 14 more
Caused by: org.h2.jdbc.JdbcSQLException: Deserialization failed, cause: "class 
org.apache.ignite.IgniteCheckedException: Not enough data to read the value 
[position=1, requiredBytes=4, remainingBytes=0]" [90027-195]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
        ... 34 more
Caused by: class org.apache.ignite.IgniteCheckedException: Not enough data to 
read the value [position=1, requiredBytes=4, remainingBytes=0]
        at 
org.apache.ignite.internal.util.IgniteUtils.unmarshal(IgniteUtils.java:9867)
        at 
org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing$13.deserialize(IgniteH2Indexing.java:2263)
        at org.h2.util.JdbcUtils.deserialize(JdbcUtils.java:400)
        ... 32 more
Caused by: class org.apache.ignite.binary.BinaryObjectException: Not enough 
data to read the value [position=1, requiredBytes=4, remainingBytes=0]
        at 
org.apache.ignite.internal.binary.streams.BinaryAbstractInputStream.ensureEnoughData(BinaryAbstractInputStream.java:304)
        at 
org.apache.ignite.internal.binary.streams.BinaryAbstractInputStream.readInt(BinaryAbstractInputStream.java:127)
        at 
org.apache.ignite.internal.binary.BinaryUtils.doReadTimeArray(BinaryUtils.java:1491)
        at 
org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1904)
        at 
org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1714)
        at 
org.apache.ignite.internal.binary.GridBinaryMarshaller.deserialize(GridBinaryMarshaller.java:310)
        at 
org.apache.ignite.internal.binary.BinaryMarshaller.unmarshal0(BinaryMarshaller.java:99)
        at 
org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller.unmarshal(AbstractNodeNameAwareMarshaller.java:82)
        at 
org.apache.ignite.internal.util.IgniteUtils.unmarshal(IgniteUtils.java:9861)
        ... 34 more
{noformat}

The actual reason is the impossibility of converting integer to POJO when 
comparing keys. The integer is stored as ValueInt. H2 tries to convert it to 
ValueJavaObject by attempting to deserialize integer binary representation.

To reproduce:

1. Add the following code to 
modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractFieldsQuerySelfTest.java:

{noformat}
    public void testIncompatibleTypesInWhereClause() throws Exception {
        QueryCursor<List<?>> qry =
            personCache.query(sqlFieldsQuery("select name from Person where 
_key = 25"));

        List<List<?>> res = qry.getAll();
    }
{noformat}

2. Run IgniteCacheAtomicFieldsQuerySelfTest.testIncompatibleTypesInWhereClause



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to