From 9143ac0841b1b8d2165fe8a2ab4e46be576ab13c Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Mon, 5 Oct 2026 15:57:12 +0200 Subject: [PATCH 1/4] Return undefined from $match when str is undefined jsonata-js returns undefined from $match when its str argument is undefined and the pattern is a regex. JSONata4Java threw "Argument 1 of function $match does not match function signature" instead. Co-Authored-By: Claude Code Signed-off-by: Jan Nedbal --- .../expressions/functions/MatchFunction.java | 4 ++++ .../api/jsonata4java/expressions/MatchFunctionTests.java | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java index a1406c37..6da40bb6 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java @@ -98,6 +98,10 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex final JsonNode argPattern = FunctionUtils.getValuesListExpression(expressionVisitor, ctx, useContext ? 0 : 1); int limit = -1; + // As in jsonata-js, an undefined str with a regex pattern returns undefined + if (argString == null && argPattern instanceof POJONode) { + return null; + } // Make sure that we have the right number of arguments if (argString == null || !argString.isTextual() || argString.asText().isEmpty()) { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); diff --git a/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java b/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java index ce830061..d62df8e9 100644 --- a/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java @@ -176,6 +176,15 @@ public static Collection data() { { "$match(' ', a.b.c)", null, ERR_MSG_ARG2_BAD_TYPE }, // + { + "$match(a.b.c, /b/)", null, null + }, // + { + "$match(a.b.c, /b/, 1)", null, null + }, // + { + "$match($substringAfter(a.b.c, 'x'), /(b)/).groups[0]", null, null + }, // { "$match('foo bar', 'a')", "{\"match\":\"a\",\"index\":5,\"groups\":[]}", null From f1bdc44e21f66ec39156b00d3a9c6fc2aa144508 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Mon, 5 Oct 2026 16:13:03 +0200 Subject: [PATCH 2/4] Validate the $match limit type when str is undefined jsonata-js rejects a non-number limit (T0410, argument 3) also when str is undefined. A negative limit still returns undefined, because jsonata-js returns before it checks the limit value. Co-Authored-By: Claude Code Signed-off-by: Jan Nedbal --- .../expressions/functions/MatchFunction.java | 6 ++++++ .../api/jsonata4java/expressions/MatchFunctionTests.java | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java index 6da40bb6..eb3f453c 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java @@ -100,6 +100,12 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex int limit = -1; // As in jsonata-js, an undefined str with a regex pattern returns undefined if (argString == null && argPattern instanceof POJONode) { + if (argCount == 3) { + final JsonNode argLimit = FunctionUtils.getValuesListExpression(expressionVisitor, ctx, useContext ? 1 : 2); + if (argLimit != null && !argLimit.isNumber()) { + throw new EvaluateRuntimeException(ERR_ARG3BADTYPE); + } + } return null; } // Make sure that we have the right number of arguments diff --git a/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java b/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java index d62df8e9..f0861cdb 100644 --- a/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java @@ -182,6 +182,15 @@ public static Collection data() { { "$match(a.b.c, /b/, 1)", null, null }, // + { + "$match(a.b.c, /b/, -1)", null, null + }, // + { + "$match(a.b.c, /b/, 'x')", null, ERR_MSG_ARG3_BAD_TYPE + }, // + { + "$match(a.b.c, /b/, null)", null, ERR_MSG_ARG3_BAD_TYPE + }, // { "$match($substringAfter(a.b.c, 'x'), /(b)/).groups[0]", null, null }, // From d057d7d05cc26553522cfb6db44b592bf925f432 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Mon, 5 Oct 2026 16:13:24 +0200 Subject: [PATCH 3/4] Accept an empty str in $match jsonata-js applies the pattern to an empty string like to any other string. For example, $match("", /^$/) returns one match at index 0. JSONata4Java threw an argument 1 error instead. Co-Authored-By: Claude Code Signed-off-by: Jan Nedbal --- .../jsonata4java/expressions/functions/MatchFunction.java | 2 +- .../api/jsonata4java/expressions/MatchFunctionTests.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java index eb3f453c..987e025e 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java @@ -109,7 +109,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex return null; } // Make sure that we have the right number of arguments - if (argString == null || !argString.isTextual() || argString.asText().isEmpty()) { + if (argString == null || !argString.isTextual()) { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } // Make sure that the pattern is a non-empty string. diff --git a/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java b/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java index f0861cdb..55a24ea6 100644 --- a/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java @@ -195,6 +195,12 @@ public static Collection data() { "$match($substringAfter(a.b.c, 'x'), /(b)/).groups[0]", null, null }, // + { + "$match('', /^$/)", "{\"match\":\"\",\"index\":0,\"groups\":[]}", null + }, // + { + "$match('', /(x*)/)", "{\"match\":\"\",\"index\":0,\"groups\":[\"\"]}", null + }, // { "$match('foo bar', 'a')", "{\"match\":\"a\",\"index\":5,\"groups\":[]}", null }, // From b1851e8c79e3040c1ac89f6083ae77fc26e2e451 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Mon, 5 Oct 2026 16:13:59 +0200 Subject: [PATCH 4/4] Return undefined from $match when nothing matches jsonata-js returns an empty sequence (undefined) when the pattern does not match. JSONata4Java returned []. A limit of 0 already returned undefined. The existing test for $match('ababbabbcc','a(b+)') expected []. It checks that a string pattern matches literally, so it now expects undefined. Co-Authored-By: Claude Code Signed-off-by: Jan Nedbal --- .../expressions/functions/MatchFunction.java | 4 ++++ .../jsonata4java/expressions/MatchFunctionTests.java | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java index 987e025e..1895c4f4 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java @@ -176,6 +176,10 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } else { return null; } + // As in jsonata-js, no match returns undefined + if (result.size() == 0) { + return null; + } } else { // check for a function call context as 2nd parameter ExprContext exprCtx = ctx.exprValues().exprList().expr(useContext ? 0 : 1); diff --git a/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java b/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java index 55a24ea6..29e04a70 100644 --- a/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/MatchFunctionTests.java @@ -201,6 +201,15 @@ public static Collection data() { { "$match('', /(x*)/)", "{\"match\":\"\",\"index\":0,\"groups\":[\"\"]}", null }, // + { + "$match('abc', /z/)", null, null + }, // + { + "$match('abc', /z/, 1)", null, null + }, // + { + "$match('', /b/)", null, null + }, // { "$match('foo bar', 'a')", "{\"match\":\"a\",\"index\":5,\"groups\":[]}", null }, // @@ -245,7 +254,7 @@ public static Collection data() { null }, { - "$match('ababbabbcc','a(b+)')", "[]", null + "$match('ababbabbcc','a(b+)')", null, null }, { "$match('aba(b+)babbcc','a(b+)')", "{\"match\":\"a(b+)\",\"index\":2,\"groups\":[]}", null