Skip to content

Commit e7dc1f7

Browse files
committed
[bugfix] Fix detection of recusive functions in XQuery
Closes eXist-db/exist#5685
1 parent 8fe42df commit e7dc1f7

File tree

4 files changed

+137
-10
lines changed

4 files changed

+137
-10
lines changed

exist-core/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,9 @@
686686
<include>src/main/java/org/exist/dom/memtree/reference/TextReferenceImpl.java</include>
687687
<include>src/main/java/org/exist/util/ByteOrderMark.java</include>
688688
<include>src/test/java/org/exist/xquery/ImportFromPkgTest.java</include>
689+
<include>src/main/java/org/exist/xquery/UserDefinedFunction.java</include>
689690
<include>src/test/java/org/exist/xquery/WatchdogTest.java</include>
691+
<include>src/main/java/org/exist/xquery/XQueryContext.java</include>
690692
<include>src/test/java/org/exist/xquery/value/DateTimeTypesTest.java</include>
691693
<include>src/test/java/org/exist/xquery/functions/fn/FunXmlToJsonTest.java</include>
692694
<include>src/test/java/org/exist/xquery/functions/fn/ParsingFunctionsTest.java</include>
@@ -855,6 +857,7 @@
855857
<include>src/main/java/org/exist/xslt/XsltURIResolverHelper.java</include>
856858
<include>src/test/resources/org/exist/validation/catalog.xml</include>
857859
<include>src/test/resources/standalone-webapp/WEB-INF/web.xml</include>
860+
<include>src/test/xquery/maps/maps.xqm</include>
858861
<include>src/test/xquery/util/util.xml</include>
859862
<include>src/test/xquery/xquery3/serialize.xql</include>
860863
</includes>
@@ -997,7 +1000,9 @@
9971000
<exclude>src/main/java/org/exist/xqj/Marshaller.java</exclude>
9981001
<exclude>src/test/java/org/exist/xquery/ImportFromPkgTest.java</exclude>
9991002
<exclude>src/main/java/org/exist/xquery/NameTest.java</exclude>
1003+
<exclude>src/main/java/org/exist/xquery/UserDefinedFunction.java</exclude>
10001004
<exclude>src/test/java/org/exist/xquery/WatchdogTest.java</exclude>
1005+
<exclude>src/main/java/org/exist/xquery/XQueryContext.java</exclude>
10011006
<exclude>src/main/java/org/exist/xquery/functions/fn/FunUriCollection.java</exclude>
10021007
<exclude>src/main/java/org/exist/xquery/functions/fn/FunXmlToJson.java</exclude>
10031008
<exclude>src/test/java/org/exist/xquery/functions/fn/FunXmlToJsonTest.java</exclude>
@@ -1043,6 +1048,7 @@
10431048
<exclude>src/main/java/org/exist/xslt/XsltURIResolverHelper.java</exclude>
10441049
<exclude>src/test/resources/org/exist/validation/catalog.xml</exclude>
10451050
<exclude>src/test/resources/standalone-webapp/WEB-INF/web.xml</exclude>
1051+
<exclude>src/test/xquery/maps/maps.xqm</exclude>
10461052
<exclude>src/test/xquery/util/util.xml</exclude>
10471053
<exclude>src/main/java/org/exist/resolver/ResolverFactory.java</exclude>
10481054
<exclude>src/main/java/org/exist/resolver/XercesXmlResolverAdapter.java</exclude>

exist-core/src/main/java/org/exist/xquery/UserDefinedFunction.java

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -185,21 +209,25 @@ public void dump(ExpressionDumper dumper) {
185209
dumper.display(signature.getReturnType().toString());
186210
}
187211

188-
/* (non-Javadoc)
189-
* @see java.lang.Object#toString()
190-
*/
212+
@Override
191213
public String toString() {
192214
final FunctionSignature signature = getSignature();
193215
final StringBuilder buf = new StringBuilder();
194-
if (signature.getName() != null)
195-
{buf.append(signature.getName());}
216+
if (signature.getName() != null) {
217+
buf.append(signature.getName());
218+
}
196219
buf.append('(');
197-
for(int i = 0; i < signature.getArgumentTypes().length; i++) {
198-
if(i > 0)
199-
{buf.append(", ");}
220+
for (int i = 0; i < signature.getArgumentTypes().length; i++) {
221+
if (i > 0) {
222+
buf.append(", ");
223+
}
224+
buf.append('$');
225+
buf.append(getParameters().get(i));
226+
buf.append(" as ");
200227
buf.append(signature.getArgumentTypes()[i]);
201228
}
202-
buf.append(')');
229+
buf.append(") as ");
230+
buf.append(signature.getReturnType());
203231
return buf.toString();
204232
}
205233

exist-core/src/main/java/org/exist/xquery/XQueryContext.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -2513,7 +2537,13 @@ public void functionEnd() {
25132537

25142538
@Override
25152539
public boolean tailRecursiveCall(final FunctionSignature signature) {
2516-
return callStack.contains(signature);
2540+
// NOTE(AR) this should be improved further... eXist-db lacked any sort of proper escape analysis!
2541+
for (final FunctionSignature existingFunctionSignature : callStack) {
2542+
if (existingFunctionSignature == signature) {
2543+
return true;
2544+
}
2545+
}
2546+
return false;
25172547
}
25182548

25192549
@Override

exist-core/src/test/xquery/maps/maps.xqm

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
(:
2+
: Elemental
3+
: Copyright (C) 2024, Evolved Binary Ltd
4+
:
5+
6+
: https://www.evolvedbinary.com | https://www.elemental.xyz
7+
:
8+
: This library is free software; you can redistribute it and/or
9+
: modify it under the terms of the GNU Lesser General Public
10+
: License as published by the Free Software Foundation; version 2.1.
11+
:
12+
: This library is distributed in the hope that it will be useful,
13+
: but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
: Lesser General Public License for more details.
16+
:
17+
: You should have received a copy of the GNU Lesser General Public
18+
: License along with this library; if not, write to the Free Software
19+
: Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
:
21+
: NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
: The original license header is included below.
23+
:
24+
: =====================================================================
25+
:
226
: eXist-db Open Source Native XML Database
327
: Copyright (C) 2001 The eXist-db Authors
428
:
@@ -51,6 +75,14 @@ declare variable $mt:integerKeys := map {
5175

5276
declare variable $mt:mapOfSequences := map {0: (), 1 : ("One", "Two") };
5377

78+
declare variable $mt:nested-places := map {
79+
"Italia": map {
80+
"Piemonte": map {
81+
"Bardonecchia": 1
82+
}
83+
}
84+
};
85+
5486
declare
5587
%test:assertEquals("Wednesday")
5688
function mt:createLiteral1() {
@@ -188,6 +220,37 @@ function mt:for-each2() {
188220
$nm?b
189221
};
190222

223+
declare
224+
%test:assertEquals("<country>Italia<region>Piemonte</region></country>")
225+
function mt:for-each3() {
226+
map:for-each($mt:nested-places, function($country-key, $region-map) {
227+
<country>{
228+
$country-key,
229+
map:for-each($region-map, function($region-key, $town-map) {
230+
<region>{$region-key}</region>
231+
})
232+
}</country>
233+
})
234+
};
235+
236+
declare
237+
%test:assertEquals("<country>Italia<region>Piemonte<town>Bardonecchia</town></region></country>")
238+
function mt:for-each4() {
239+
map:for-each($mt:nested-places, function($country-key, $region-map) {
240+
<country>{
241+
$country-key,
242+
map:for-each($region-map, function($region-key, $town-map) {
243+
<region>{
244+
$region-key,
245+
map:for-each($town-map, function($town-key, $town-value) {
246+
<town>{$town-key}</town>
247+
})
248+
}</region>
249+
})
250+
}</country>
251+
})
252+
};
253+
191254
declare
192255
%test:assertEquals("Sunday")
193256
function mt:createWithSingleKey() {

0 commit comments

Comments
 (0)