diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/PgSql.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/PgSql.java index d17051f10..c16e83566 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/PgSql.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/PgSql.java @@ -237,6 +237,13 @@ public final class PgSql { return and(QueryExpression.column(column)); } + public PgCriteria.PostgresCriteriaStep and(String column, Function wrappingFunction) { + + Assert.hasText(column, "Column name must not be null or empty"); + + return and(wrappingFunction.apply(new PgSqlImpl.DefaultOperators(QueryExpression.column(column)))); + } + @Override public PgCriteria.PostgresCriteriaStep and(QueryExpression expression) { @@ -253,6 +260,13 @@ public final class PgSql { return or(QueryExpression.column(column)); } + public PgCriteria.PostgresCriteriaStep or(String column, Function wrappingFunction) { + + Assert.hasText(column, "Column name must not be null or empty"); + + return or(wrappingFunction.apply(new PgSqlImpl.DefaultOperators(QueryExpression.column(column)))); + } + @Override public PgCriteria.PostgresCriteriaStep or(QueryExpression expression) { @@ -302,6 +316,60 @@ public final class PgSql { * @return */ PgCriteria asBoolean(); + + @Override + PgCriteria is(Object value); + + @Override + PgCriteria not(Object value); + + @Override + PgCriteria in(Object... values); + + @Override + PgCriteria in(Collection values); + + @Override + PgCriteria notIn(Object... values); + + @Override + PgCriteria notIn(Collection values); + + @Override + PgCriteria between(Object begin, Object end); + + @Override + PgCriteria notBetween(Object begin, Object end); + + @Override + PgCriteria lessThan(Object value); + + @Override + PgCriteria lessThanOrEquals(Object value); + + @Override + PgCriteria greaterThan(Object value); + + @Override + PgCriteria greaterThanOrEquals(Object value); + + @Override + PgCriteria like(Object value); + + @Override + PgCriteria notLike(Object value); + + @Override + PgCriteria isNull(); + + @Override + PgCriteria isNotNull(); + + @Override + PgCriteria isTrue(); + + @Override + PgCriteria isFalse(); } /** diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/PgSqlImpl.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/PgSqlImpl.java index 3d7b198c2..fb6c34720 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/PgSqlImpl.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/PgSqlImpl.java @@ -103,6 +103,96 @@ class PgSqlImpl { public PgSql.PgCriteria asBoolean() { return createCriteria(DefaultPostgresQueryExpression.queryExpression(getLhs()).asBoolean()); } + + @Override + public PgSql.PgCriteria is(Object value) { + return (PgSql.PgCriteria) super.is(value); + } + + @Override + public PgSql.PgCriteria not(Object value) { + return (PgSql.PgCriteria) super.not(value); + } + + @Override + public PgSql.PgCriteria in(Object... values) { + return (PgSql.PgCriteria) super.in(values); + } + + @Override + public PgSql.PgCriteria in(Collection values) { + return (PgSql.PgCriteria) super.in(values); + } + + @Override + public PgSql.PgCriteria notIn(Object... values) { + return (PgSql.PgCriteria) super.notIn(values); + } + + @Override + public PgSql.PgCriteria notIn(Collection values) { + return (PgSql.PgCriteria) super.notIn(values); + } + + @Override + public PgSql.PgCriteria between(Object begin, Object end) { + return (PgSql.PgCriteria) super.between(begin, end); + } + + @Override + public PgSql.PgCriteria notBetween(Object begin, Object end) { + return (PgSql.PgCriteria) super.notBetween(begin, end); + } + + @Override + public PgSql.PgCriteria lessThan(Object value) { + return (PgSql.PgCriteria) super.lessThan(value); + } + + @Override + public PgSql.PgCriteria lessThanOrEquals(Object value) { + return (PgSql.PgCriteria) super.lessThanOrEquals(value); + } + + @Override + public PgSql.PgCriteria greaterThan(Object value) { + return (PgSql.PgCriteria) super.greaterThan(value); + } + + @Override + public PgSql.PgCriteria greaterThanOrEquals(Object value) { + return (PgSql.PgCriteria) super.greaterThanOrEquals(value); + } + + @Override + public PgSql.PgCriteria like(Object value) { + return (PgSql.PgCriteria) super.like(value); + } + + @Override + public PgSql.PgCriteria notLike(Object value) { + return (PgSql.PgCriteria) super.notLike(value); + } + + @Override + public PgSql.PgCriteria isNull() { + return (PgSql.PgCriteria) super.isNull(); + } + + @Override + public PgSql.PgCriteria isNotNull() { + return (PgSql.PgCriteria) super.isNotNull(); + } + + @Override + public PgSql.PgCriteria isTrue() { + return (PgSql.PgCriteria) super.isTrue(); + } + + @Override + public PgSql.PgCriteria isFalse() { + return (PgSql.PgCriteria) super.isFalse(); + } } private record DefaultPostgresQueryExpression(QueryExpression source) implements PgSql.PostgresQueryExpression { diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/QueryExpression.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/QueryExpression.java index bf9006c63..906e96409 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/QueryExpression.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/query/QueryExpression.java @@ -78,6 +78,12 @@ public interface QueryExpression { return ExpressionTypeContext.object(); } + /** + * Name hint for this expression. The hint can be a function or column name. Hints are used to provide more detail + * context for e.g. bind markers. + * + * @return the name hint if applicable, or {@literal null} if no name hint is available. + */ default @Nullable String getNameHint() { return null; } diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/PgSqlUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/PgSqlUnitTests.java index 49e7a53ae..0f62f15e9 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/PgSqlUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/query/PgSqlUnitTests.java @@ -50,14 +50,18 @@ class PgSqlUnitTests { @Test // GH-1953 void distanceLessThanTransformFunction() { + // TODO // where(distanceOf("embedding", vector).l2()).lessThan(…) - Criteria embedding = PgSql + PgSql.PgCriteria embedding = PgSql .where("embedding", it -> it.distanceTo(Vector.of(1, 2, 3), PgSql.VectorSearchOperators.Distances::cosine)) - .lessThan("0.8"); // converter converts to Number + .lessThan("0.8"); + // .and("some_json", it -> it.json().field("country")).is("Some Country"); String sql = toSql(embedding); + // assertThat(embedding).hasToString("embedding <=> '[1.0, 2.0, 3.0]' < 0.8 AND some_json -> 'country' = 'Some + // Country'"); assertThat(embedding).hasToString("embedding <=> '[1.0, 2.0, 3.0]' < 0.8"); assertThat(sql).contains("with_embedding.the_embedding <=> :p0 < :p1"); assertThat(bindings.getValues()).containsValue(new BigDecimal("0.8"));