micronaut-projects / micronaut-data

Ahead of Time Data Repositories
Apache License 2.0
467 stars 198 forks source link

Incorrect number of parameters expected when using IN Query with property injection #2959

Open timyates opened 5 months ago

timyates commented 5 months ago

Expected Behavior

Writing an IN @Query with properties injected (such as "SELECT name, '${property.value}' as property_value FROM data WHERE id IN (:id)") should work as with other non-IN queries

Actual Behaviour

We get an exception

java.lang.IllegalStateException: Expandable query parts size should be the same as parameters size + 1. 3 != 1 + 1 SELECT name, 'woo' as property_value FROM data WHERE id IN (?) [SELECT name,  'woo' as property_value FROM data WHERE id IN (, )]
    at io.micronaut.data.runtime.operations.internal.sql.DefaultSqlStoredQuery.<init>(DefaultSqlStoredQuery.java:68)
    at io.micronaut.data.runtime.operations.internal.sql.AbstractSqlRepositoryOperations.decorate(AbstractSqlRepositoryOperations.java:184)
    at io.micronaut.data.runtime.intercept.AbstractQueryInterceptor.findStoreQuery(AbstractQueryInterceptor.java:282)
    at io.micronaut.data.runtime.intercept.AbstractQueryInterceptor.prepareQuery(AbstractQueryInterceptor.java:260)
    at io.micronaut.data.runtime.intercept.AbstractQueryInterceptor.prepareQuery(AbstractQueryInterceptor.java:241)
    at io.micronaut.data.runtime.intercept.AbstractQueryInterceptor.prepareQuery(AbstractQueryInterceptor.java:225)
    at io.micronaut.data.runtime.intercept.DefaultFindAllInterceptor.intercept(DefaultFindAllInterceptor.java:50)
    at io.micronaut.data.runtime.intercept.DefaultFindAllInterceptor.intercept(DefaultFindAllInterceptor.java:35)
    at io.micronaut.data.runtime.intercept.DataIntroductionAdvice.intercept(DataIntroductionAdvice.java:83)
    at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:138)
    at data.query.parameter.issue.DataRepository$Intercepted.findDataById(Unknown Source)

Steps To Reproduce

Pull the reproducer and run ./gradlew test. The first test fails, but the workaround (using @ParameterExpression) works

Environment Information

OSX, Java 17

Example Application

https://github.com/bloidonia/data-query-parameter-issue/blob/main/src/test/java/data/query/parameter/issue/DataQueryParameterIssueTest.java

Version

4.4.2

dstepanov commented 5 months ago

We don’t support expressions in the queries

mkimberlin commented 5 months ago

@dstepanov Any particular reason? It seems to be at least partially supported, as we are using these property injections in our queries across our application and they only fail to work in this case. Perhaps this lack of support should be documented somewhere? It doesn't seem to be stated in either the javadoc or the guides that I can find.

timyates commented 5 months ago

This non-IN query works with the parameter injected... is that by luck more than design?

https://github.com/bloidonia/data-query-parameter-issue/blob/bcc529dd5e099cbb1af5672d3e1105f0e6d74fc5/src/main/java/data/query/parameter/issue/DataRepository.java#L16-L20

dstepanov commented 5 months ago

Because for this case, we have to generate the query at the runtime, and to make it easy, we split it into parts at the compilation time, and that breaks the expressions