From cb4f002f01ac8aac90ee8dfe339451429e8f213d Mon Sep 17 00:00:00 2001 From: wxggzz Date: Wed, 29 Jul 2026 09:20:09 +0800 Subject: [PATCH] Parse `long` literals in `FilterExpressionTextParser` Numeric literals without an `L` suffix were always parsed as `Integer`, so filter expressions with values outside the int range (for example a `long` metadata id) failed with a `NumberFormatException`. Fall back to `Long` when the literal exceeds the int range, keeping the existing `Integer` result for smaller values. Fixes #4705 Signed-off-by: wxggzz --- .../filter/FilterExpressionTextParser.java | 9 ++++++++- .../filter/FilterExpressionTextParserTests.java | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParser.java b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParser.java index 45d1bb6d70..b2aeb1549f 100644 --- a/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParser.java +++ b/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParser.java @@ -231,7 +231,14 @@ private String unescapeStringValue(String in) { @Override public Filter.Operand visitIntegerConstant(FiltersParser.IntegerConstantContext ctx) { - return new Filter.Value(Integer.valueOf(ctx.getText())); + String text = ctx.getText(); + try { + return new Filter.Value(Integer.valueOf(text)); + } + catch (NumberFormatException ex) { + // Fall back to Long for literals that exceed the int range (gh-4705). + return new Filter.Value(Long.valueOf(text)); + } } @Override diff --git a/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParserTests.java b/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParserTests.java index bf227923a7..b78dadfc0e 100644 --- a/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParserTests.java +++ b/spring-ai-vector-store/src/test/java/org/springframework/ai/vectorstore/filter/FilterExpressionTextParserTests.java @@ -66,6 +66,21 @@ public void testEQ() { assertThat(this.parser.getCache().get("WHERE " + "country == 'BG'")).isEqualTo(exp); } + @Test + public void testLongValueLiteral() { + // id == 9223372036854775807 (Long.MAX_VALUE, exceeds the int range) + Expression exp = this.parser.parse("id == " + Long.MAX_VALUE); + assertThat(exp).isEqualTo(new Expression(EQ, new Key("id"), new Value(Long.MAX_VALUE))); + + // id == -9223372036854775808 (Long.MIN_VALUE) + exp = this.parser.parse("id == " + Long.MIN_VALUE); + assertThat(exp).isEqualTo(new Expression(EQ, new Key("id"), new Value(Long.MIN_VALUE))); + + // Values within the int range are still parsed as Integer + exp = this.parser.parse("year == 2020"); + assertThat(((Value) exp.right()).value()).isInstanceOf(Integer.class).isEqualTo(2020); + } + @Test public void tesEqAndGte() { // genre == "drama" AND year >= 2020