GoogleCloudPlatform / GoogleCloudPlatform/spring-cloud-gcp
spring-cloud-gcp-data-spanner does not support BEFORE
- Dominant language
- Java
- Stars
- 551
- Forks
- 349
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 14
Description
**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](https://github.com/GoogleCloudPlatform/spring-cloud-gcp/blob/main/spring-cloud-gcp-data-spanner/src/main/java/com/google/cloud/spring/data/spanner/repository/query/SpannerStatementQueryExecutor.java#L535) that supports [the `Part.Type.BEFORE` part](https://github.com/spring-projects/spring-data-commons/blob/main/src/main/java/org/springframework/data/repository/query/parser/Part.java#L189).
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.
Contributor guide
Research direction
Start in spring-cloud-gcp-data-spanner/src/main/java/com/google/cloud/spring/data/spanner/repository/query/SpannerStatementQueryExecutor.java, especially buildWhere(...), where the stack trace and issue identify the missing Part.Type.BEFORE case. Reproduce the repository method using deleteByUserIdAndCreatedTimestampBefore, then verify that the generated WHERE clause uses the expected timestamp comparison and no longer throws UnsupportedOperationException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100