Hello, Courtney.

I did some investigation.

It seems, current behavior is correct, in general.

Looks like passing list of values as a parameter is common issue for JDBC SQL 
queries [1] [2] [3].
Tried to find formal requirements in JDBC spec but didn’t find clear 
description :)

Anyway, If you are interested in details:

H2 engine optimize IN clause of your query to Equals query, because it contains 
only one item [4]. 
So in time Ignite receive filter it looks like «find string equals to array» - 
this leads to the exception after [5]. 

Calcite engine behave a little bit different and returns empty results for the 
same query.
Didn’t look deeper to explain this.


I will close ticket [6] as «Won’t fix».
Feel free to reopen it.

[1] https://www.baeldung.com/spring-jdbctemplate-in-list
[2] 
https://stackoverflow.com/questions/45696465/how-to-pass-list-of-values-as-a-parameter-to-in-clause-using-jdbc-template
 
<https://stackoverflow.com/questions/45696465/how-to-pass-list-of-values-as-a-parameter-to-in-clause-using-jdbc-template>
[3] 
https://stackoverflow.com/questions/1327074/how-to-execute-in-sql-queries-with-springs-jdbctemplate-effectively
 
<https://stackoverflow.com/questions/1327074/how-to-execute-in-sql-queries-with-springs-jdbctemplate-effectively>
[4] 
https://github.com/h2database/h2database/blob/master/h2/src/main/org/h2/expression/condition/ConditionIn.java#L129
[5] https://issues.apache.org/jira/browse/IGNITE-13056 
<https://issues.apache.org/jira/browse/IGNITE-13056>
[6] https://issues.apache.org/jira/browse/IGNITE-16991

> 17 мая 2022 г., в 12:16, Courtney Robinson <court...@crlog.info> написал(а):
> 
> Hey,
> I just checked and it doesn't seem as if any of the test cases use arrays 
> with more than 1 element in them.
> It also gives the wrong results if I use an array with multiple values.
>  
> 
> On Tue, 17 May 2022 at 09:56, Николай Ижиков <nizhi...@apache.org 
> <mailto:nizhi...@apache.org>> wrote:
> Hello, Courtney.
> 
> I’m able to reproduce your issue [1]
> 
> Can you, please, confirm - Do you have use-case when memberIds contains more 
> then one element?
> Is it return correct results?
> 
> Before 2.11 SQL query with IN clause and array argument executed and return 
> some results.
> But, in my reproducer results are wrong when I pass more then one element 
> array.
> 
> Anyway, I will continue investigation of the issue [1]
> 
>         // This work as expected.
>         assertEquals(1, sql(
>             "SELECT IID FROM T1 WHERE ID IN (?) AND IID = ?",
>             new Object[] {Arrays.asList("1").toArray(), "1"}
>         ).size());
> 
>         // And this works OK.
>         assertEquals(2, sql(
>             "SELECT IID FROM T1 WHERE ID IN ('1', '4') AND IID = ?",
>             new Object[] {"1"}
>         ).size());
> 
>         // Executed without exception but return no results.
>       assertEquals(2, sql(
>             "SELECT IID FROM T1 WHERE ID IN (?) AND IID = ?",
>             new Object[] {Arrays.asList("1", "4").toArray(), "1"}).size()
>       );
> 
> [1] https://issues.apache.org/jira/browse/IGNITE-16991 
> <https://issues.apache.org/jira/browse/IGNITE-16991>
> 
> 
> 
>> 17 мая 2022 г., в 08:36, Courtney Robinson <court...@crlog.info 
>> <mailto:court...@crlog.info>> написал(а):
>> 
>> Hey Николай,
>> 
>> Java code:
>> 
>> private FieldsQueryCursor<List<?>> doQuery(boolean isMutation, String sql, 
>> Object... args) {
>>   var timer = isMutation ? rawMutTimer : rawQryTimer;
>>   return timer.record(() -> {
>>     try {
>>       var query = new SqlFieldsQuery(sql)
>>         .setTimeout(5, SECONDS)
>>         //.setDistributedJoins(true)
>>         .setSchema(PUBLIC_SCHEMA_NAME);
>>       if (args != null && args.length > 0) {
>>         query.setArgs(args);
>>       }
>>       var res = cache.query(query);
>>       if (isMutation) {
>>         ctx.backup(sql, args);
>>       }
>>       return res;
>>     } catch (Exception e) {
>>       this.rawDBErrCntr.count();
>>       if (e.getCause() instanceof CacheStoppedException) {
>>         log.error("Ignite cache stopped unexpectedly. No further queries are 
>> possible so must exit. Shutting down node");
>>         System.exit(-1);
>>       }
>>       if (e instanceof DBException) {
>>         throw e;
>>       } else {
>>         throw new DBException("Unexpected error whilst executing database 
>> query", e);
>>       }
>>     }
>>   });
>> }
>> The call that used to work is:
>> var results = repo.query(false, "SELECT HYPI_INSTANCEID, COUNT(HYPI_ID) FROM 
>> " +
>>   TABLE_ACC + " WHERE HYPI_ID IN (?) AND HYPI_INSTANCEID=? GROUP BY 
>> HYPI_INSTANCEID", memberIds.toArray(), instanceId);
>> 
>> We had to change this to:
>> List<Object> args = new ArrayList<>();
>> String qs = memberIds.stream()
>>   .peek(args::add)
>>   .map(v -> "?")
>>   .collect(Collectors.joining(","));
>> args.add(instanceId);
>> var results = repo.query(
>>   false,
>>   "SELECT HYPI_INSTANCEID, COUNT(HYPI_ID) FROM " +
>>     TABLE_ACC + " WHERE HYPI_ID IN (" + qs + ") AND HYPI_INSTANCEID=? GROUP 
>> BY HYPI_INSTANCEID",
>>   args.toArray()
>> );
>> 
>> memberIds is a List<String>. 
>> repo.query is the public method that will eventually call doQuery after some 
>> internal stuff.
>> 
>> The table here referred to as TABLE_ACC is
>> CREATE TABLE PUBLIC.ACCOUNT (
>>      VERIFIED BOOLEAN,
>>      ENABLED BOOLEAN,
>>      HYPI_INSTANCEID VARCHAR,
>>      HYPI_ID VARCHAR,
>>      USERNAME VARCHAR,
>>      CONSTRAINT PK_PUBLIC_HYPI_01E8NPNFADNKECH7BR0K5FDE2C_ACCOUNT PRIMARY 
>> KEY (HYPI_INSTANCEID,HYPI_ID)
>> );
>> 
>> I removed most fields as they're not necessary to reproduce
>> 
>> 
>> On Fri, 13 May 2022 at 15:24, Николай Ижиков <nizhi...@apache.org 
>> <mailto:nizhi...@apache.org>> wrote:
>> Hello, Courtney.
>> 
>> Can, you, please, send SQL table definition and example of query (java code 
>> and SQL) that worked on 2.8 and start failing on 2.13.
>> 
>> > This seems like a regression, was this intentional?
>> 
>> Looks like a bug to me.
>> Details of your schema and query can help in further investigation.
>> 
>> 
>>> 10 мая 2022 г., в 10:14, Courtney Robinson <court...@crlog.info 
>>> <mailto:court...@crlog.info>> написал(а):
>>> 
>>> Hi all,
>>> 
>>> We're looking to do a major upgrade from 2.8.0 to 2.13.0
>>> After the initial upgrade our test suite started failing (about 15% of 
>>> tests now fail).
>>> No other change has been made other than the Ignite version number.
>>> 
>>> org.apache.ignite.internal.processors.query.IgniteSQLException: General 
>>> error: "class org.apache.ignite.IgniteException: Failed to wrap 
>>> value[type=17, value=[Ljava.lang.Object;@667eb78]"; SQL statement:
>>> SELECT HYPI_INSTANCEID, COUNT(HYPI_ID) FROM 
>>> hypi_01E8NPNFADNKECH7BR0K5FDE2C_Account WHERE HYPI_ID IN (?) AND 
>>> HYPI_INSTANCEID=? GROUP BY HYPI_INSTANCEID [50000-197]
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeSqlQuery(IgniteH2Indexing.java:898)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeSqlQueryWithTimer(IgniteH2Indexing.java:985)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.twostep.GridMapQueryExecutor.onQueryRequest0(GridMapQueryExecutor.java:471)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.twostep.GridMapQueryExecutor.onQueryRequest(GridMapQueryExecutor.java:284)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.onMessage(IgniteH2Indexing.java:2219)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor$1.applyx(GridReduceQueryExecutor.java:157)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor$1.applyx(GridReduceQueryExecutor.java:152)
>>> at 
>>> org.apache.ignite.internal.util.lang.IgniteInClosure2X.apply(IgniteInClosure2X.java:38)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.send(IgniteH2Indexing.java:2344)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor.send(GridReduceQueryExecutor.java:1201)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.twostep.GridReduceQueryExecutor.query(GridReduceQueryExecutor.java:463)
>>> at 
>>> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing$7.iterator(IgniteH2Indexing.java:1846)
>>> at 
>>> org.apache.ignite.internal.processors.cache.QueryCursorImpl.iter(QueryCursorImpl.java:102)
>>> at 
>>> org.apache.ignite.internal.processors.cache.query.RegisteredQueryCursor.iter(RegisteredQueryCursor.java:91)
>>> at 
>>> org.apache.ignite.internal.processors.cache.QueryCursorImpl.getAll(QueryCursorImpl.java:124)
>>> 
>>> Investigating this I found that IndexKeyFactory has since been added in a 
>>> release after 2.8.0.
>>> It is the source of the exception
>>> throw new IgniteException("Failed to wrap value[type=" + keyType + ", 
>>> value=" + o + "]");
>>> 
>>> The key type 17 is ARRAY, defined in `org.h2.value.Value` (ARRAY enum value 
>>> line 137)
>>> Looking further I can see that IndexKeyFactory registers:
>>> IndexKeyFactory.register(IndexKeyTypes.DATE, DateIndexKey::new);
>>> IndexKeyFactory.register(IndexKeyTypes.TIME, TimeIndexKey::new);
>>> IndexKeyFactory.register(IndexKeyTypes.TIMESTAMP, TimestampIndexKey::new);--
>>> 
>>> And these are the only additional key types registered anywhere in the 
>>> 2.13.0 code base.
>>> 
>>> Looking further, I found that the problem is wherever we use the `IN` clause
>>> In 2.8.0 we had a query like this:
>>> DELETE FROM permission_cause WHERE instanceId = ? AND policyId = ? AND 
>>> rowId IN (?) AND accountId = ?
>>> And we would pass in a Java array as the 3rd argument
>>> instanceId, policyId, toDelete.toArray(), accountId
>>> 
>>> This would work fine with the toDelete.toArray()
>>> Now, we have to change it and expand from IN(?) to IN(?,?,?) putting in as 
>>> many ? as there are entries in the array and pass in the values 
>>> individually.
>>> 
>>> This seems like a regression, was this intentional?
>>> 
>>> Best,
>>> Courtney
>> 
>> 
>> 
>> -- 
>> Courtney Robinson
>> court...@crlog.info <mailto:court...@crlog.info>
>> http://zcourts.com <http://zcourts.com/>
>> 020 3287 0961
> 
> 
> 
> -- 
> Courtney Robinson
> court...@crlog.info <mailto:court...@crlog.info>
> http://zcourts.com <http://zcourts.com/>
> 020 3287 0961

Reply via email to