Skip to content

Commit fb364f8

Browse files
Merge branch 'main' of github.com:BaseXdb/basex
2 parents 26ce16e + 0ca71e0 commit fb364f8

2 files changed

Lines changed: 40 additions & 13 deletions

File tree

basex-core/src/main/java/org/basex/query/func/PartFunc.java

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.basex.query.ann.*;
1010
import org.basex.query.expr.*;
1111
import org.basex.query.util.list.*;
12+
import org.basex.query.value.*;
1213
import org.basex.query.value.item.*;
1314
import org.basex.query.value.seq.*;
1415
import org.basex.query.value.type.*;
@@ -37,7 +38,7 @@ public final class PartFunc extends Arr {
3738
*/
3839
public PartFunc(final InputInfo info, final Expr[] exprs, final int placeholders,
3940
final int[] placeholderPerm) {
40-
super(info, Types.FUNCTION_O, exprs);
41+
super(info, Types.FUNCTION_ZM, exprs);
4142
this.placeholders = placeholders;
4243
this.placeholderPerm = placeholderPerm;
4344
}
@@ -55,25 +56,39 @@ public Expr optimize(final CompileContext cc) throws QueryException {
5556
if(values(false, cc)) return cc.preEval(this);
5657

5758
final Expr func = body();
58-
final FuncType ft = func.funcType();
59-
if(ft != null && ft != Types.FUNCTION) {
60-
final int nargs = exprs.length - 1, arity = ft.argTypes.length;
61-
if(nargs != arity) throw arityError(func, nargs, arity, false, info);
62-
63-
final SeqType[] args = new SeqType[placeholders];
64-
for(int a = 0, e = 0; e < nargs; e++) if(placeholder(exprs[e])) {
65-
args[placeholderPerm == null ? a : placeholderPerm[a]] = ft.argTypes[e];
66-
++a;
59+
if(func.size() == 1) {
60+
final FuncType ft = func.funcType();
61+
if(ft != null && ft != Types.FUNCTION) {
62+
final int nargs = exprs.length - 1, arity = ft.argTypes.length;
63+
if(nargs != arity) throw arityError(func, nargs, arity, false, info);
64+
65+
final SeqType[] args = new SeqType[placeholders];
66+
for(int a = 0, e = 0; e < nargs; e++) if(placeholder(exprs[e])) {
67+
args[placeholderPerm == null ? a : placeholderPerm[a]] = ft.argTypes[e];
68+
++a;
69+
}
70+
exprType.assign(FuncType.get(ft.declType, args).seqType());
6771
}
68-
exprType.assign(FuncType.get(ft.declType, args).seqType());
6972
}
7073
return this;
7174
}
7275

7376
@Override
74-
public FuncItem item(final QueryContext qc, final InputInfo ii) throws QueryException {
75-
final FItem func = toFunction(body(), qc);
77+
public Value value(final QueryContext qc) throws QueryException {
78+
final ValueBuilder vb = new ValueBuilder(qc);
79+
for(final Item item : body().value(qc)) vb.add(funcItem(toFunction(item, qc), qc));
80+
return vb.value(this);
81+
}
7682

83+
/**
84+
* Creates a function item over a dynamic function call to the given function item, with the
85+
* arguments constructed from the parameters and expressions of this partially applied function.
86+
* @param func function item to be called
87+
* @param qc query context
88+
* @return new function item
89+
* @throws QueryException query exception
90+
*/
91+
private FuncItem funcItem(final FItem func, final QueryContext qc) throws QueryException {
7792
final int el = exprs.length - 1;
7893
final int nargs = el, arity = func.arity();
7994
if(nargs != arity) throw arityError(func, nargs, arity, false, info);

basex-core/src/test/java/org/basex/query/ast/FuncItemTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ public final class FuncItemTest extends SandboxTest {
6868
error("declare function g($x := .) { $x }; let $f := fn() { g() } return 1!$f()", NOCTX_X);
6969
}
7070

71+
/** Checks that partial application supports function sequences. */
72+
@Test public void partAppSequence() {
73+
query("let $f := ()(12, ?) return $f(5)", "");
74+
query("let $f := (op('+'), 42, op('-'))[. instance of fn(*)](12, ?) return $f(5)", "17\n7");
75+
query("declare function a($x, $y as xs:integer) {$y};\n"
76+
+ "declare function b($y, $z as xs:decimal) {$z};\n"
77+
+ "(((a#2, b#2)((), ?)(text{'3'}))) =!> type-of()\n",
78+
"xs:integer\nxs:decimal");
79+
80+
error("let $f := (op('+'), 42, op('-'))(12, ?) return $f(5)", INVTYPE_X);
81+
}
82+
7183
/** Checks that the Y combinator is pre-compiled. */
7284
@Test public void yCombinatorTest() {
7385
check("function($f) {" +

0 commit comments

Comments
 (0)