GoogleCloudPlatform / spring-cloud-gcp

New home for Spring Cloud GCP development starting with version 2.0.
Apache License 2.0
426 stars 317 forks source link

spring-cloud-gcp-data-spanner does not support BEFORE #811

Open MusikPolice opened 2 years ago

MusikPolice commented 2 years ago

Describe the bug Using the Before operator in a repository method causes an exception to be thrown.

Sample If I create a repository method like this:

fun deleteByUserIdAndCreatedTimestampBefore(userId: String, createdTimestamp: Timestamp)

I expect that it would delete all records belonging to the user with the specified userId and having a createdTimestamp greater than the specified timestamp.

If I try to execute this function, an exception is thrown:

java.lang.UnsupportedOperationException: The statement type: BEFORE (1): [IsBefore, Before] is not supported.
    at com.google.cloud.spring.data.spanner.repository.query.SpannerStatementQueryExecutor.lambda$buildWhere$4(SpannerStatementQueryExecutor.java:585)
    at java.base/java.lang.Iterable.forEach(Iterable.java:75)
    at com.google.cloud.spring.data.spanner.repository.query.SpannerStatementQueryExecutor.lambda$buildWhere$5(SpannerStatementQueryExecutor.java:507)
    at java.base/java.util.ArrayList$Itr.forEachRemaining(ArrayList.java:1033)
    at com.google.cloud.spring.data.spanner.repository.query.SpannerStatementQueryExecutor.buildWhere(SpannerStatementQueryExecutor.java:502)
    at com.google.cloud.spring.data.spanner.repository.query.SpannerStatementQueryExecutor.buildPartTreeSqlString(SpannerStatementQueryExecutor.java:447)
    at com.google.cloud.spring.data.spanner.repository.query.SpannerStatementQueryExecutor.executeQuery(SpannerStatementQueryExecutor.java:96)
    at com.google.cloud.spring.data.spanner.repository.query.PartTreeSpannerQuery.lambda$getDeleteFunction$1(PartTreeSpannerQuery.java:81)
    at com.google.cloud.spring.data.spanner.core.SpannerTemplate$1.run(SpannerTemplate.java:417)
    at com.google.cloud.spanner.TransactionRunnerImpl.lambda$runInternal$0(TransactionRunnerImpl.java:942)

Potential Solution So far as I can tell, this is because the SpannerStatementQueryExecutor.buildWhere(...) function does not have a case that supports the Part.Type.BEFORE part.

I think that the correct fix here is to add a case for BEFORE that adds <= $timestamp to the WHERE clause of the generated SQL statement.

zhumin8 commented 2 years ago

Thanks for looking into this. You are right that before is not supported, only the listed filters here in our documentation is supported query by convention for now.