Skip to content

Commit 08b700e

Browse files
committed
[hotfix] Fix use of Function References within Predicates
Closes #4412
1 parent a2b8ac3 commit 08b700e

File tree

5 files changed

+60
-1
lines changed

5 files changed

+60
-1
lines changed

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ public DynamicFunctionCall(final XQueryContext context, final Expression fun, fi
4545
this.isPartial = partial;
4646
}
4747

48+
@Override
49+
public int getDependencies() {
50+
int dependencies = functionExpr.getDependencies();
51+
if (arguments != null) {
52+
for (final Expression argument : arguments) {
53+
dependencies |= argument.getDependencies();
54+
}
55+
}
56+
return dependencies;
57+
}
58+
4859
@Override
4960
public void analyze(AnalyzeContextInfo contextInfo) throws XPathException {
5061
cachedContextInfo = new AnalyzeContextInfo(contextInfo);
@@ -94,7 +105,7 @@ public Sequence eval(Sequence contextSequence, Item contextItem)
94105
ref.analyze(new AnalyzeContextInfo(cachedContextInfo));
95106
// Evaluate the function
96107
try {
97-
return ref.eval(contextSequence);
108+
return ref.eval(contextSequence, contextItem);
98109
} catch (XPathException e) {
99110
if (e.getLine() <= 0) {
100111
e.setLocation(getLine(), getColumn(), getSource());

exist-core/src/main/java/org/exist/xquery/functions/array/ArrayType.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ public Sequence eval(Sequence contextSequence) throws XPathException {
214214
return accessorFunc.eval(contextSequence);
215215
}
216216

217+
@Override
218+
public Sequence eval(final Sequence contextSequence, final Item contextItem) throws XPathException {
219+
return accessorFunc.eval(contextSequence, contextItem);
220+
}
221+
217222
@Override
218223
public Sequence evalFunction(final Sequence contextSequence, final Item contextItem, final Sequence[] seq) throws XPathException {
219224
final AccessorFunc af = (AccessorFunc) accessorFunc.getFunction();

exist-core/src/main/java/org/exist/xquery/functions/map/AbstractMapType.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ public Sequence eval(Sequence contextSequence) throws XPathException {
111111
return getAccessorFunc().eval(contextSequence);
112112
}
113113

114+
@Override
115+
public Sequence eval(final Sequence contextSequence, final Item contextItem) throws XPathException {
116+
return getAccessorFunc().eval(contextSequence, contextItem);
117+
}
118+
114119
@Override
115120
public Sequence evalFunction(final Sequence contextSequence, final Item contextItem, final Sequence[] seq) throws XPathException {
116121
final AccessorFunc accessorFunc = (AccessorFunc) getAccessorFunc().getFunction();

exist-core/src/main/java/org/exist/xquery/value/FunctionReference.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ public Sequence eval(Sequence contextSequence) throws XPathException {
8686
return functionCall.eval(contextSequence);
8787
}
8888

89+
/**
90+
* Calls {@link FunctionCall#eval(Sequence, Item)}.
91+
*
92+
* @param contextSequence the input sequence
93+
* @param contextItem optional: the current context item
94+
* @return evaluation result of the function call
95+
* @throws XPathException in case of dynamic error
96+
*/
97+
public Sequence eval(final Sequence contextSequence, final Item contextItem) throws XPathException {
98+
return functionCall.eval(contextSequence, contextItem);
99+
}
100+
89101
/**
90102
* Calls {@link FunctionCall#evalFunction(Sequence, Item, Sequence[])}.
91103
*

exist-core/src/test/xquery/xquery3/fnRefs.xql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,29 @@ function fnRefs:concat-arity2() {
5252
fn:concat#2
5353
)
5454
};
55+
56+
declare
57+
%test:assertEquals("b")
58+
function fnRefs:call-from-predicate() {
59+
let $predicate := function($x as xs:string, $y as xs:string) as xs:boolean { $x eq $y }
60+
return
61+
("a", "b", "c")[$predicate("b", .)]
62+
};
63+
64+
declare function fnRefs:pred($x as xs:string, $y as xs:string) as xs:boolean {
65+
$x eq $y
66+
};
67+
68+
declare
69+
%test:assertEquals("b")
70+
function fnRefs:call-from-predicate-via-variable() {
71+
let $predicate := fnRefs:pred#2
72+
return
73+
("a", "b", "c")[$predicate("b", .)]
74+
};
75+
76+
declare
77+
%test:assertEquals("b")
78+
function fnRefs:call-from-predicate-inline() {
79+
("a", "b", "c")[function($x as xs:string, $y as xs:string) as xs:boolean { $x eq $y }("b", .)]
80+
};

0 commit comments

Comments
 (0)