You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ignite.apache.org by "Kirill Shirokov (JIRA)" <ji...@apache.org> on 2017/11/29 11:40:00 UTC

[jira] [Created] (IGNITE-7068) Incorrect error reporting for incompatible type in SQL WHERE clause

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)