Skip to content

Commit 4705ad0

Browse files
committed
MLE-25585 implement optic transitive closure in java client.
Add generated code with minor changes. Add tests for op.transitiveClosure. Add triple data for tests. Some copyright header fixes.
1 parent 4964dc7 commit 4705ad0

File tree

9 files changed

+625
-4
lines changed

9 files changed

+625
-4
lines changed

marklogic-client-api/src/main/java/com/marklogic/client/expression/PlanBuilder.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
2+
* Copyright (c) 2010-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
33
*/
44

55
package com.marklogic.client.expression;
@@ -2043,6 +2043,36 @@ public interface ModifyPlan extends PreparePlan, PlanBuilderBase.ModifyPlanBase
20432043
* @since 7.2.0; requires MarkLogic 12
20442044
*/
20452045
public abstract ModifyPlan shortestPath(PlanExprCol start, PlanExprCol end, PlanExprCol path, PlanExprCol length, PlanExprCol weight);
2046+
/**
2047+
* This method performs a transitive closure operation over a graph-like structure, identifying all reachable node pairs from a given start node to an end node through one or more intermediate steps. A set of (start, end) node pairs where a path exists between them with a length between minLength and maxLength, inclusive. This models the SPARQL one-or-more (+) operator, enabling recursive or chained relationships to be queried efficiently.
2048+
* @param start The column is the starting node of the traversal. The column can be named with a string or a column function such as op:col, op:view-col, or op:schema-col, or constructed from an expression with the op:as function. See {@link PlanBuilder#col(XsStringVal)}
2049+
* @param end The column is the end node of the traversal. The column can be named with a string or a column function such as op:col, op:view-col, or op:schema-col, or constructed from an expression with the op:as function. See {@link PlanBuilder#col(XsStringVal)}
2050+
* @return a ModifyPlan object
2051+
*/
2052+
public abstract ModifyPlan transitiveClosure(String start, String end);
2053+
/**
2054+
* This method performs a transitive closure operation over a graph-like structure, identifying all reachable node pairs from a given start node to an end node through one or more intermediate steps. A set of (start, end) node pairs where a path exists between them with a length between minLength and maxLength, inclusive. This models the SPARQL one-or-more (+) operator, enabling recursive or chained relationships to be queried efficiently.
2055+
* @param start The column is the starting node of the traversal. The column can be named with a string or a column function such as op:col, op:view-col, or op:schema-col, or constructed from an expression with the op:as function. See {@link PlanBuilder#col(XsStringVal)}
2056+
* @param end The column is the end node of the traversal. The column can be named with a string or a column function such as op:col, op:view-col, or op:schema-col, or constructed from an expression with the op:as function. See {@link PlanBuilder#col(XsStringVal)}
2057+
* @return a ModifyPlan object
2058+
*/
2059+
public abstract ModifyPlan transitiveClosure(PlanExprCol start, PlanExprCol end);
2060+
/**
2061+
* This method performs a transitive closure operation over a graph-like structure, identifying all reachable node pairs from a given start node to an end node through one or more intermediate steps. A set of (start, end) node pairs where a path exists between them with a length between minLength and maxLength, inclusive. This models the SPARQL one-or-more (+) operator, enabling recursive or chained relationships to be queried efficiently.
2062+
* @param start The column is the starting node of the traversal. The column can be named with a string or a column function such as op:col, op:view-col, or op:schema-col, or constructed from an expression with the op:as function. See {@link PlanBuilder#col(XsStringVal)}
2063+
* @param end The column is the end node of the traversal. The column can be named with a string or a column function such as op:col, op:view-col, or op:schema-col, or constructed from an expression with the op:as function. See {@link PlanBuilder#col(XsStringVal)}
2064+
* @param options This is either an array of strings or an object containing keys and values for the options to this operator. Options include: min-length This option is the minimum number of steps (edges) required in the path. It should be a non-negative integer, and the default is 1.max-length This option Maximum number of steps (edges) allowed in the path. It should be a non-negative integer, and the default is unlimited.
2065+
* @return a ModifyPlan object
2066+
*/
2067+
public abstract ModifyPlan transitiveClosure(String start, String end, PlanTransitiveClosureOptions options);
2068+
/**
2069+
* This method performs a transitive closure operation over a graph-like structure, identifying all reachable node pairs from a given start node to an end node through one or more intermediate steps. A set of (start, end) node pairs where a path exists between them with a length between minLength and maxLength, inclusive. This models the SPARQL one-or-more (+) operator, enabling recursive or chained relationships to be queried efficiently.
2070+
* @param start The column is the starting node of the traversal. The column can be named with a string or a column function such as op:col, op:view-col, or op:schema-col, or constructed from an expression with the op:as function. See {@link PlanBuilder#col(XsStringVal)}
2071+
* @param end The column is the end node of the traversal. The column can be named with a string or a column function such as op:col, op:view-col, or op:schema-col, or constructed from an expression with the op:as function. See {@link PlanBuilder#col(XsStringVal)}
2072+
* @param options This is either an array of strings or an object containing keys and values for the options to this operator. Options include: min-length This option is the minimum number of steps (edges) required in the path. It should be a non-negative integer, and the default is 1.max-length This option Maximum number of steps (edges) allowed in the path. It should be a non-negative integer, and the default is unlimited.
2073+
* @return a ModifyPlan object
2074+
*/
2075+
public abstract ModifyPlan transitiveClosure(PlanExprCol start, PlanExprCol end, PlanTransitiveClosureOptions options);
20462076
}
20472077

20482078

marklogic-client-api/src/main/java/com/marklogic/client/expression/PlanBuilderBase.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
2+
* Copyright (c) 2010-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
33
*/
44
package com.marklogic.client.expression;
55

@@ -356,6 +356,15 @@ public interface PlanBuilderBase {
356356
*/
357357
PlanSparqlOptions sparqlOptions();
358358

359+
/**
360+
* Provides a transitive closure option object to configure the execution of the
361+
* {@link PlanBuilder.ModifyPlan#transitiveClosure(PlanExprCol, PlanExprCol, PlanTransitiveClosureOptions)}
362+
* operator. Use the fluent methods of the transitive closure option object
363+
* to set the configuration.
364+
* @return the configuration object
365+
*/
366+
PlanTransitiveClosureOptions transitiveClosureOptions();
367+
359368
/**
360369
* Specifies a JavaScript or XQuery function installed on the server for use
361370
* in post-processing in a map() or reduce() operation.

marklogic-client-api/src/main/java/com/marklogic/client/impl/PlanBuilderImpl.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
2+
* Copyright (c) 2010-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
33
*/
44

55
package com.marklogic.client.impl;
@@ -2268,6 +2268,42 @@ public ModifyPlan shortestPath(PlanExprCol start, PlanExprCol end, PlanExprCol p
22682268
}
22692269

22702270

2271+
@Override
2272+
public ModifyPlan transitiveClosure(String start, String end) {
2273+
return transitiveClosure((start == null) ? (PlanExprCol) null : exprCol(start), (end == null) ? null : exprCol(end));
2274+
}
2275+
2276+
2277+
@Override
2278+
public ModifyPlan transitiveClosure(PlanExprCol start, PlanExprCol end) {
2279+
if (start == null) {
2280+
throw new IllegalArgumentException("start parameter for transitiveClosure() cannot be null");
2281+
}
2282+
if (end == null) {
2283+
throw new IllegalArgumentException("end parameter for transitiveClosure() cannot be null");
2284+
}
2285+
return new PlanBuilderSubImpl.ModifyPlanSubImpl(this, "op", "transitive-closure", new Object[]{ start, end });
2286+
}
2287+
2288+
2289+
@Override
2290+
public ModifyPlan transitiveClosure(String start, String end, PlanTransitiveClosureOptions options) {
2291+
return transitiveClosure((start == null) ? null : exprCol(start), (end == null) ? null : exprCol(end), options);
2292+
}
2293+
2294+
2295+
@Override
2296+
public ModifyPlan transitiveClosure(PlanExprCol start, PlanExprCol end, PlanTransitiveClosureOptions options) {
2297+
if (start == null) {
2298+
throw new IllegalArgumentException("start parameter for transitiveClosure() cannot be null");
2299+
}
2300+
if (end == null) {
2301+
throw new IllegalArgumentException("end parameter for transitiveClosure() cannot be null");
2302+
}
2303+
return new PlanBuilderSubImpl.ModifyPlanSubImpl(this, "op", "transitive-closure", new Object[]{ start, end, PlanBuilderSubImpl.asArg(PlanBuilderSubImpl.makeMap(options)) });
2304+
}
2305+
2306+
22712307
@Override
22722308
public ModifyPlan union(ModifyPlan right) {
22732309
if (right == null) {

marklogic-client-api/src/main/java/com/marklogic/client/impl/PlanBuilderSubImpl.java

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
2+
* Copyright (c) 2010-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
33
*/
44
package com.marklogic.client.impl;
55

@@ -487,6 +487,10 @@ public PlanSampleByOptions withLimit(XsIntVal limit) {
487487
public PlanSparqlOptions sparqlOptions() {
488488
return new PlanSparqlOptionsImpl(this);
489489
}
490+
@Override
491+
public PlanTransitiveClosureOptions transitiveClosureOptions() {
492+
return new PlanTransitiveClosureOptionsImpl(this);
493+
}
490494
static class PlanSparqlOptionsImpl implements PlanSparqlOptions {
491495
private PlanBuilderBaseImpl pb;
492496
private XsBooleanVal deduplicate;
@@ -526,6 +530,45 @@ public PlanSparqlOptions withDeduplicated(XsBooleanVal deduplicate) {
526530
}
527531
}
528532

533+
static class PlanTransitiveClosureOptionsImpl implements PlanTransitiveClosureOptions {
534+
private PlanBuilderBaseImpl pb;
535+
private XsLongVal minLength;
536+
private XsLongVal maxLength;
537+
PlanTransitiveClosureOptionsImpl(PlanBuilderBaseImpl pb) {
538+
this.pb = pb;
539+
}
540+
PlanTransitiveClosureOptionsImpl(PlanBuilderBaseImpl pb, XsLongVal minLength, XsLongVal maxLength) {
541+
this(pb);
542+
this.minLength = minLength;
543+
this.maxLength = maxLength;
544+
}
545+
546+
@Override
547+
public XsLongVal getMinLength() {
548+
return minLength;
549+
}
550+
@Override
551+
public PlanTransitiveClosureOptions withMinLength(long minLength) {
552+
return withMinLength(pb.xs.longVal(minLength));
553+
}
554+
@Override
555+
public PlanTransitiveClosureOptions withMinLength(XsLongVal minLength) {
556+
return new PlanTransitiveClosureOptionsImpl(this.pb, minLength, this.maxLength);
557+
}
558+
@Override
559+
public XsLongVal getMaxLength() {
560+
return maxLength;
561+
}
562+
@Override
563+
public PlanTransitiveClosureOptions withMaxLength(long maxLength) {
564+
return withMaxLength(pb.xs.longVal(maxLength));
565+
}
566+
@Override
567+
public PlanTransitiveClosureOptions withMaxLength(XsLongVal maxLength) {
568+
return new PlanTransitiveClosureOptionsImpl(this.pb, this.minLength, maxLength);
569+
}
570+
}
571+
529572
@Override
530573
public ServerExpression caseExpr(PlanCase... cases) {
531574
int lastPos = cases.length - 1;
@@ -744,6 +787,29 @@ static Map<String,String> makeMap(PlanSparqlOptions options) {
744787

745788
return mapdef;
746789
}
790+
static Map<String,Object> makeMap(PlanTransitiveClosureOptions options) {
791+
if (options == null) {
792+
return null;
793+
}
794+
795+
Map<String,Object> mapdef = null;
796+
797+
XsLongVal minLength = options.getMinLength();
798+
if (minLength != null) {
799+
mapdef = new HashMap<>();
800+
mapdef.put("minLength", minLength.getLong());
801+
}
802+
803+
XsLongVal maxLength = options.getMaxLength();
804+
if (maxLength != null) {
805+
if (mapdef == null) {
806+
mapdef = new HashMap<>();
807+
}
808+
mapdef.put("maxLength", maxLength.getLong());
809+
}
810+
811+
return mapdef;
812+
}
747813
static Map<String,String> makeMap(String key, String value) {
748814
Map<String, String> map = new HashMap<String, String>();
749815
if (key != null) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) 2010-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3+
*/
4+
package com.marklogic.client.type;
5+
6+
// IMPORTANT: Do not edit. This file is generated.
7+
8+
/**
9+
* Options for controlling transitive closure operations, including minimum and maximum
10+
* path lengths.
11+
*/
12+
public interface PlanTransitiveClosureOptions {
13+
XsLongVal getMinLength();
14+
PlanTransitiveClosureOptions withMinLength(long minLength);
15+
PlanTransitiveClosureOptions withMinLength(XsLongVal minLength);
16+
XsLongVal getMaxLength();
17+
PlanTransitiveClosureOptions withMaxLength(long maxLength);
18+
PlanTransitiveClosureOptions withMaxLength(XsLongVal maxLength);
19+
}

0 commit comments

Comments
 (0)