diff --git a/core/src/main/java/org/opensearch/sql/ast/tree/GraphLookup.java b/core/src/main/java/org/opensearch/sql/ast/tree/GraphLookup.java
index 6771c35c43..2b0243656e 100644
--- a/core/src/main/java/org/opensearch/sql/ast/tree/GraphLookup.java
+++ b/core/src/main/java/org/opensearch/sql/ast/tree/GraphLookup.java
@@ -23,8 +23,8 @@
/**
* AST node for graphLookup command. Performs BFS graph traversal on a lookup table.
*
- *
Example: source=employees | graphLookup employees fromField=manager toField=name maxDepth=3
- * depthField=level direction=uni as hierarchy
+ *
Example: source=employees | graphLookup employees startWith=manager connectFromField=manager
+ * connectToField=name maxDepth=3 depthField=level direction=uni as hierarchy
*/
@Getter
@Setter
@@ -46,13 +46,13 @@ public enum Direction {
private final UnresolvedPlan fromTable;
/** Field in sourceTable to start with. */
- private final Field startField;
+ private final Field startWith;
/** Field in fromTable that represents the outgoing edge. */
- private final Field fromField;
+ private final Field connectFromField;
/** Field in input/fromTable to match against for traversal. */
- private final Field toField;
+ private final Field connectToField;
/** Output field name for collected traversal results. */
private final Field as;
diff --git a/core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java b/core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java
index 9a16f2bf80..fc84b43a5c 100644
--- a/core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java
+++ b/core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java
@@ -2589,9 +2589,9 @@ public RelNode visitGraphLookup(GraphLookup node, CalcitePlanContext context) {
RelNode sourceTable = builder.build();
// 2. Extract parameters
- String startFieldName = node.getStartField().getField().toString();
- String fromFieldName = node.getFromField().getField().toString();
- String toFieldName = node.getToField().getField().toString();
+ String startWithName = node.getStartWith().getField().toString();
+ String connectFromFieldName = node.getConnectFromField().getField().toString();
+ String connectToFieldName = node.getConnectToField().getField().toString();
String outputFieldName = node.getAs().getField().toString();
String depthFieldName = node.getDepthFieldName();
boolean bidirectional = node.getDirection() == Direction.BI;
@@ -2621,9 +2621,9 @@ public RelNode visitGraphLookup(GraphLookup node, CalcitePlanContext context) {
LogicalGraphLookup.create(
sourceTable,
lookupTable,
- startFieldName,
- fromFieldName,
- toFieldName,
+ startWithName,
+ connectFromFieldName,
+ connectToFieldName,
outputFieldName,
depthFieldName,
maxDepthValue,
diff --git a/core/src/main/java/org/opensearch/sql/calcite/plan/rel/GraphLookup.java b/core/src/main/java/org/opensearch/sql/calcite/plan/rel/GraphLookup.java
index 02ed97faf0..a942d96178 100644
--- a/core/src/main/java/org/opensearch/sql/calcite/plan/rel/GraphLookup.java
+++ b/core/src/main/java/org/opensearch/sql/calcite/plan/rel/GraphLookup.java
@@ -40,9 +40,9 @@
public abstract class GraphLookup extends BiRel {
// TODO: use RexInputRef instead of String for there fields
- protected final String startField; // Field in source table (start entities)
- protected final String fromField; // Field in lookup table (edge source)
- protected final String toField; // Field in lookup table (edge target)
+ protected final String startWith; // Field in source table (start entities)
+ protected final String connectFromField; // Field in lookup table (edge source)
+ protected final String connectToField; // Field in lookup table (edge target)
protected final String outputField; // Name of output array field
@Nullable protected final String depthField; // Name of output array field
@@ -63,9 +63,9 @@ public abstract class GraphLookup extends BiRel {
* @param traitSet Trait set
* @param source Source table RelNode
* @param lookup Lookup table RelNode
- * @param startField Field name for start entities
- * @param fromField Field name for outgoing edges
- * @param toField Field name for incoming edges
+ * @param startWith Field name for start entities
+ * @param connectFromField Field name for outgoing edges
+ * @param connectToField Field name for incoming edges
* @param outputField Name of the output array field
* @param depthField Name of the depth field
* @param maxDepth Maximum traversal depth (-1 for unlimited)
@@ -81,9 +81,9 @@ protected GraphLookup(
RelTraitSet traitSet,
RelNode source,
RelNode lookup,
- String startField,
- String fromField,
- String toField,
+ String startWith,
+ String connectFromField,
+ String connectToField,
String outputField,
@Nullable String depthField,
int maxDepth,
@@ -93,9 +93,9 @@ protected GraphLookup(
boolean usePIT,
@Nullable RexNode filter) {
super(cluster, traitSet, source, lookup);
- this.startField = startField;
- this.fromField = fromField;
- this.toField = toField;
+ this.startWith = startWith;
+ this.connectFromField = connectFromField;
+ this.connectToField = connectToField;
this.outputField = outputField;
this.depthField = depthField;
this.maxDepth = maxDepth;
@@ -130,7 +130,7 @@ protected RelDataType deriveRowType() {
RelDataType sourceRowType = getSource().getRowType();
RelDataType sourceArrayType =
getCluster().getTypeFactory().createArrayType(sourceRowType, -1);
- builder.add(startField, sourceArrayType);
+ builder.add(startWith, sourceArrayType);
// Second field: aggregated lookup rows as array
RelDataType lookupRowType = getLookup().getRowType();
@@ -178,8 +178,8 @@ public double estimateRowCount(RelMetadataQuery mq) {
@Override
public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw)
- .item("fromField", fromField)
- .item("toField", toField)
+ .item("connectFromField", connectFromField)
+ .item("connectToField", connectToField)
.item("outputField", outputField)
.item("depthField", depthField)
.item("maxDepth", maxDepth)
diff --git a/core/src/main/java/org/opensearch/sql/calcite/plan/rel/LogicalGraphLookup.java b/core/src/main/java/org/opensearch/sql/calcite/plan/rel/LogicalGraphLookup.java
index 94db3689f8..c2198e7385 100644
--- a/core/src/main/java/org/opensearch/sql/calcite/plan/rel/LogicalGraphLookup.java
+++ b/core/src/main/java/org/opensearch/sql/calcite/plan/rel/LogicalGraphLookup.java
@@ -28,9 +28,9 @@ public class LogicalGraphLookup extends GraphLookup {
* @param traitSet Trait set
* @param source Source table RelNode
* @param lookup Lookup table RelNode
- * @param startField Field name for start entities
- * @param fromField Field name for outgoing edges
- * @param toField Field name for incoming edges
+ * @param startWith Field name for start entities
+ * @param connectFromField Field name for outgoing edges
+ * @param connectToField Field name for incoming edges
* @param outputField Name of the output array field
* @param depthField Name of the depth field
* @param maxDepth Maximum traversal depth (-1 for unlimited)
@@ -45,9 +45,9 @@ protected LogicalGraphLookup(
RelTraitSet traitSet,
RelNode source,
RelNode lookup,
- String startField,
- String fromField,
- String toField,
+ String startWith,
+ String connectFromField,
+ String connectToField,
String outputField,
@Nullable String depthField,
int maxDepth,
@@ -61,9 +61,9 @@ protected LogicalGraphLookup(
traitSet,
source,
lookup,
- startField,
- fromField,
- toField,
+ startWith,
+ connectFromField,
+ connectToField,
outputField,
depthField,
maxDepth,
@@ -79,9 +79,9 @@ protected LogicalGraphLookup(
*
* @param source Source table RelNode
* @param lookup Lookup table RelNode
- * @param startField Field name for start entities
- * @param fromField Field name for outgoing edges
- * @param toField Field name for incoming edges
+ * @param startWith Field name for start entities
+ * @param connectFromField Field name for outgoing edges
+ * @param connectToField Field name for incoming edges
* @param outputField Name of the output array field
* @param depthField Named of the output depth field
* @param maxDepth Maximum traversal depth (-1 for unlimited)
@@ -95,9 +95,9 @@ protected LogicalGraphLookup(
public static LogicalGraphLookup create(
RelNode source,
RelNode lookup,
- String startField,
- String fromField,
- String toField,
+ String startWith,
+ String connectFromField,
+ String connectToField,
String outputField,
@Nullable String depthField,
int maxDepth,
@@ -113,9 +113,9 @@ public static LogicalGraphLookup create(
traitSet,
source,
lookup,
- startField,
- fromField,
- toField,
+ startWith,
+ connectFromField,
+ connectToField,
outputField,
depthField,
maxDepth,
@@ -133,9 +133,9 @@ public RelNode copy(RelTraitSet traitSet, List inputs) {
traitSet,
inputs.get(0),
inputs.get(1),
- startField,
- fromField,
- toField,
+ startWith,
+ connectFromField,
+ connectToField,
outputField,
depthField,
maxDepth,
diff --git a/docs/user/ppl/cmd/graphlookup.md b/docs/user/ppl/cmd/graphlookup.md
index 2d6220edae..258fc4ae87 100644
--- a/docs/user/ppl/cmd/graphlookup.md
+++ b/docs/user/ppl/cmd/graphlookup.md
@@ -8,19 +8,19 @@ The `graphLookup` command performs recursive graph traversal on a collection usi
The `graphLookup` command has the following syntax:
```syntax
-graphLookup startField= fromField= toField= [maxDepth=] [depthField=] [direction=(uni | bi)] [supportArray=(true | false)] [batchMode=(true | false)] [usePIT=(true | false)] [filter=()] as
+graphLookup startWith= connectFromField= connectToField= [maxDepth=] [depthField=] [direction=(uni | bi)] [supportArray=(true | false)] [batchMode=(true | false)] [usePIT=(true | false)] [filter=()] as
```
The following are examples of the `graphLookup` command syntax:
```syntax
-source = employees | graphLookup employees startField=reportsTo fromField=reportsTo toField=name as reportingHierarchy
-source = employees | graphLookup employees startField=reportsTo fromField=reportsTo toField=name maxDepth=2 as reportingHierarchy
-source = employees | graphLookup employees startField=reportsTo fromField=reportsTo toField=name depthField=level as reportingHierarchy
-source = employees | graphLookup employees startField=reportsTo fromField=reportsTo toField=name direction=bi as connections
-source = travelers | graphLookup airports startField=nearestAirport fromField=connects toField=airport supportArray=true as reachableAirports
-source = airports | graphLookup airports startField=airport fromField=connects toField=airport supportArray=true as reachableAirports
-source = employees | graphLookup employees startField=reportsTo fromField=reportsTo toField=name filter=(status = 'active' AND age > 18) as reportingHierarchy
+source = employees | graphLookup employees startWith=reportsTo connectFromField=reportsTo connectToField=name as reportingHierarchy
+source = employees | graphLookup employees startWith=reportsTo connectFromField=reportsTo connectToField=name maxDepth=2 as reportingHierarchy
+source = employees | graphLookup employees startWith=reportsTo connectFromField=reportsTo connectToField=name depthField=level as reportingHierarchy
+source = employees | graphLookup employees startWith=reportsTo connectFromField=reportsTo connectToField=name direction=bi as connections
+source = travelers | graphLookup airports startWith=nearestAirport connectFromField=connects connectToField=airport supportArray=true as reachableAirports
+source = airports | graphLookup airports startWith=airport connectFromField=connects connectToField=airport supportArray=true as reachableAirports
+source = employees | graphLookup employees startWith=reportsTo connectFromField=reportsTo connectToField=name filter=(status = 'active' AND age > 18) as reportingHierarchy
```
## Parameters
@@ -30,13 +30,13 @@ The `graphLookup` command supports the following parameters.
| Parameter | Required/Optional | Description |
| --- | --- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `` | Required | The name of the index to perform the graph traversal on. Can be the same as the source index for self-referential graphs. |
-| `startField=` | Required | The field in the source documents whose value is used to start the recursive search. The value of this field is matched against `toField` in the lookup index. We support both single value and array values as starting points. |
-| `fromField=` | Required | The field in the lookup index documents that contains the value to recurse on. After matching a document, the value of this field is used to find the next set of documents. It supports both single value and array values. |
-| `toField=` | Required | The field in the lookup index documents to match against. Documents where `toField` equals the current traversal value are included in the results. |
-| `maxDepth=` | Optional | The maximum recursion depth of hops. Default is `0`. A value of `0` means only the direct connections to the statr values are returned. A value of `1` means 1 hop connections (initial match plus one recursive step), and so on. |
+| `startWith=` | Required | The field in the source documents whose value is used to start the recursive search. The value of this field is matched against `connectToField` in the lookup index. We support both single value and array values as starting points. |
+| `connectFromField=` | Required | The field in the lookup index documents that contains the value to recurse on. After matching a document, the value of this field is used to find the next set of documents. It supports both single value and array values. |
+| `connectToField=` | Required | The field in the lookup index documents to match against. Documents where `connectToField` equals the current traversal value are included in the results. |
+| `maxDepth=` | Optional | The maximum recursion depth of hops. Default is `0`. A value of `0` means only the direct connections to the start values are returned. A value of `1` means 1 hop connections (initial match plus one recursive step), and so on. |
| `depthField=` | Optional | The name of the field to add to each traversed document indicating its recursion depth. If not specified, no depth field is added. Depth starts at `0` for the first level of matches. |
| `direction=(uni \| bi)` | Optional | The traversal direction. `uni` (default) performs unidirectional traversal following edges in the forward direction only. `bi` performs bidirectional traversal, following edges in both directions. |
-| `supportArray=(true \| false)` | Optional | When `true`, disables early visited-node filter pushdown to OpenSearch. Default is `false`. Set to `true` when `fromField` or `toField` contains array values to ensure correct traversal behavior. See [Array Field Handling](#array-field-handling) for details. |
+| `supportArray=(true \| false)` | Optional | When `true`, disables early visited-node filter pushdown to OpenSearch. Default is `false`. Set to `true` when `connectFromField` or `connectToField` contains array values to ensure correct traversal behavior. See [Array Field Handling](#array-field-handling) for details. |
| `batchMode=(true \| false)` | Optional | When `true`, collects all start values from all source rows and performs a single unified BFS traversal. Default is `false`. The output changes to two arrays: `[Array, Array]`. See [Batch Mode](#batch-mode) for details. |
| `usePIT=(true \| false)` | Optional | When `true`, enables PIT (Point In Time) search for the lookup table, allowing paginated retrieval of complete results without the `max_result_window` size limit. Default is `false`. See [PIT Search](#pit-search) for details. |
| `filter=()` | Optional | A filter condition to restrict which lookup table documents participate in the graph traversal. Only documents matching the condition are considered as candidates during BFS. Parentheses around the condition are required. Example: `filter=(status = 'active' AND age > 18)`. |
@@ -46,13 +46,13 @@ The `graphLookup` command supports the following parameters.
The `graphLookup` command performs a breadth-first search (BFS) traversal:
-1. For each source document, extract the value of `startField`
-2. Query the lookup index to find documents where `toField` matches the start value
+1. For each source document, extract the value of `startWith`
+2. Query the lookup index to find documents where `connectToField` matches the start value
3. Add matched documents to the result array
-4. Extract `fromField` values from matched documents to continue traversal
+4. Extract `connectFromField` values from matched documents to continue traversal
5. Repeat steps 2-4 until no new documents are found or `maxDepth` is reached
-For bidirectional traversal (`direction=bi`), the algorithm also follows edges in the reverse direction by additionally matching `fromField` values.
+For bidirectional traversal (`direction=bi`), the algorithm also follows edges in the reverse direction by additionally matching `connectFromField` values.
## Example 1: Employee Hierarchy Traversal
@@ -72,9 +72,9 @@ The following query finds the reporting chain for each employee:
```ppl ignore
source = employees
| graphLookup employees
- startField=reportsTo
- fromField=reportsTo
- toField=name
+ startWith=reportsTo
+ connectFromField=reportsTo
+ connectToField=name
as reportingHierarchy
```
@@ -102,9 +102,9 @@ The following query adds a depth field to track how many levels each manager is
```ppl ignore
source = employees
| graphLookup employees
- startField=reportsTo
- fromField=reportsTo
- toField=name
+ startWith=reportsTo
+ connectFromField=reportsTo
+ connectToField=name
depthField=level
as reportingHierarchy
```
@@ -133,9 +133,9 @@ The following query limits traversal to 2 levels using `maxDepth=1`:
```ppl ignore
source = employees
| graphLookup employees
- startField=reportsTo
- fromField=reportsTo
- toField=name
+ startWith=reportsTo
+ connectFromField=reportsTo
+ connectToField=name
maxDepth=1
as reportingHierarchy
```
@@ -174,9 +174,9 @@ The following query finds reachable airports from each airport:
```ppl ignore
source = airports
| graphLookup airports
- startField=airport
- fromField=connects
- toField=airport
+ startWith=airport
+ connectFromField=connects
+ connectToField=airport
as reachableAirports
```
@@ -209,9 +209,9 @@ The following query finds reachable airports for each traveler:
```ppl ignore
source = travelers
| graphLookup airports
- startField=nearestAirport
- fromField=connects
- toField=airport
+ startWith=nearestAirport
+ connectFromField=connects
+ connectToField=airport
as reachableAirports
```
@@ -235,9 +235,9 @@ The following query performs bidirectional traversal to find both managers and c
source = employees
| where name = 'Ron'
| graphLookup employees
- startField=reportsTo
- fromField=reportsTo
- toField=name
+ startWith=reportsTo
+ connectFromField=reportsTo
+ connectToField=name
direction=bi
as connections
```
@@ -279,9 +279,9 @@ Use `batchMode=true` when:
```ppl ignore
source = travelers
| graphLookup airports
- startField=nearestAirport
- fromField=connects
- toField=airport
+ startWith=nearestAirport
+ connectFromField=connects
+ connectToField=airport
batchMode=true
maxDepth=2
as reachableAirports
@@ -324,9 +324,9 @@ Use `usePIT=true` when:
```ppl ignore
source = employees
| graphLookup employees
- startField=reportsTo
- fromField=reportsTo
- toField=name
+ startWith=reportsTo
+ connectFromField=reportsTo
+ connectToField=name
usePIT=true
as reportingHierarchy
```
@@ -342,9 +342,9 @@ The following query traverses only active employees in the reporting hierarchy:
```ppl ignore
source = employees
| graphLookup employees
- startField=reportsTo
- fromField=reportsTo
- toField=name
+ startWith=reportsTo
+ connectFromField=reportsTo
+ connectToField=name
filter=(status = 'active')
as reportingHierarchy
```
diff --git a/integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePPLGraphLookupIT.java b/integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePPLGraphLookupIT.java
index fbaefdb8c3..f42a79eb7e 100644
--- a/integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePPLGraphLookupIT.java
+++ b/integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePPLGraphLookupIT.java
@@ -59,9 +59,9 @@ public void testEmployeeHierarchyBasicTraversal() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " as reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -89,9 +89,9 @@ public void testEmployeeHierarchyWithDepthField() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " depthField=level"
+ " as reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -120,9 +120,9 @@ public void testEmployeeHierarchyWithMaxDepth() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " maxDepth=1"
+ " as reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -160,9 +160,9 @@ public void testEmployeeHierarchyForSpecificEmployee() throws IOException {
"source=%s"
+ " | where name = 'Dev'"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " as reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -185,9 +185,9 @@ public void testAirportConnections() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=airport"
- + " fromField=connects"
- + " toField=airport"
+ + " startWith=airport"
+ + " connectFromField=connects"
+ + " connectToField=airport"
+ " supportArray=true"
+ " as reachableAirports",
TEST_INDEX_GRAPH_AIRPORTS, TEST_INDEX_GRAPH_AIRPORTS));
@@ -215,9 +215,9 @@ public void testAirportConnectionsWithMaxDepth() throws IOException {
"source=%s"
+ " | where airport = 'JFK'"
+ " | graphLookup %s"
- + " startField=airport"
- + " fromField=connects"
- + " toField=airport"
+ + " startWith=airport"
+ + " connectFromField=connects"
+ + " connectToField=airport"
+ " maxDepth=1"
+ " supportArray=true"
+ " as reachableAirports",
@@ -245,9 +245,9 @@ public void testAirportConnectionsWithDepthField() throws IOException {
"source=%s"
+ " | where airport = 'JFK'"
+ " | graphLookup %s"
- + " startField=connects"
- + " fromField=connects"
- + " toField=airport"
+ + " startWith=connects"
+ + " connectFromField=connects"
+ + " connectToField=airport"
+ " depthField=numConnections"
+ " as reachableAirports",
TEST_INDEX_GRAPH_AIRPORTS, TEST_INDEX_GRAPH_AIRPORTS));
@@ -272,9 +272,9 @@ public void testTravelersReachableAirports() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=nearestAirport"
- + " fromField=connects"
- + " toField=airport"
+ + " startWith=nearestAirport"
+ + " connectFromField=connects"
+ + " connectToField=airport"
+ " as reachableAirports",
TEST_INDEX_GRAPH_TRAVELERS, TEST_INDEX_GRAPH_AIRPORTS));
@@ -302,9 +302,9 @@ public void testTravelerReachableAirportsWithDepthField() throws IOException {
"source=%s"
+ " | where name = 'Dev'"
+ " | graphLookup %s"
- + " startField=nearestAirport"
- + " fromField=connects"
- + " toField=airport"
+ + " startWith=nearestAirport"
+ + " connectFromField=connects"
+ + " connectToField=airport"
+ " depthField=hops"
+ " as reachableAirports",
TEST_INDEX_GRAPH_TRAVELERS, TEST_INDEX_GRAPH_AIRPORTS));
@@ -329,9 +329,9 @@ public void testTravelerReachableAirportsWithMaxDepth() throws IOException {
"source=%s"
+ " | where name = 'Jeff'"
+ " | graphLookup %s"
- + " startField=nearestAirport"
- + " fromField=connects"
- + " toField=airport"
+ + " startWith=nearestAirport"
+ + " connectFromField=connects"
+ + " connectToField=airport"
+ " maxDepth=1"
+ " supportArray=true"
+ " as reachableAirports",
@@ -364,9 +364,9 @@ public void testBidirectionalEmployeeHierarchy() throws IOException {
"source=%s"
+ " | where name = 'Ron'"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " direction=bi"
+ " as connections",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -401,9 +401,9 @@ public void testBidirectionalAirportConnections() throws IOException {
"source=%s"
+ " | where airport = 'ORD'"
+ " | graphLookup %s"
- + " startField=connects"
- + " fromField=connects"
- + " toField=airport"
+ + " startWith=connects"
+ + " connectFromField=connects"
+ + " connectToField=airport"
+ " direction=bi"
+ " as allConnections",
TEST_INDEX_GRAPH_AIRPORTS, TEST_INDEX_GRAPH_AIRPORTS));
@@ -435,9 +435,9 @@ public void testEmployeeHierarchyWithFilter() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " filter=(id > 3)"
+ " as reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -477,9 +477,9 @@ public void testEmployeeHierarchyWithKeywordFilter() throws IOException {
"source=%s"
+ " | where name = 'Ron'"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " filter=(name != 'Andrew')"
+ " as reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -506,9 +506,9 @@ public void testEmployeeHierarchyWithFilterAndMaxDepth() throws IOException {
"source=%s"
+ " | where name = 'Dev'"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " maxDepth=3"
+ " filter=(id <= 3)"
+ " as reportingHierarchy",
@@ -538,9 +538,9 @@ public void testEmptySourceResult() throws IOException {
"source=%s"
+ " | where name = 'NonExistent'"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " as reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -562,9 +562,9 @@ public void testEmployeeWithNoManager() throws IOException {
"source=%s"
+ " | where name = 'Andrew'"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " as reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -585,9 +585,9 @@ public void testGraphLookupWithStats() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " as reportingHierarchy"
+ " | stats count() by name",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -611,9 +611,9 @@ public void testGraphLookupWithFieldsProjection() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " as reportingHierarchy"
+ " | fields name, reportingHierarchy",
TEST_INDEX_GRAPH_EMPLOYEES, TEST_INDEX_GRAPH_EMPLOYEES));
@@ -646,9 +646,9 @@ public void testBatchModeEmployeeHierarchy() throws IOException {
"source=%s"
+ " | where name in ('Dev', 'Asya')"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " depthField=depth"
+ " maxDepth=3"
+ " batchMode=true"
@@ -675,9 +675,9 @@ public void testBatchModeTravelersAirports() throws IOException {
String.format(
"source=%s"
+ " | graphLookup %s"
- + " startField=nearestAirport"
- + " fromField=connects"
- + " toField=airport"
+ + " startWith=nearestAirport"
+ + " connectFromField=connects"
+ + " connectToField=airport"
+ " batchMode=true"
+ " depthField=depth"
+ " maxDepth=3"
@@ -711,9 +711,9 @@ public void testBatchModeBidirectional() throws IOException {
"source=%s"
+ " | where name in ('Dev', 'Dan')"
+ " | graphLookup %s"
- + " startField=reportsTo"
- + " fromField=reportsTo"
- + " toField=name"
+ + " startWith=reportsTo"
+ + " connectFromField=reportsTo"
+ + " connectToField=name"
+ " depthField=depth"
+ " maxDepth=3"
+ " direction=bi"
diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/planner/rules/EnumerableGraphLookupRule.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/planner/rules/EnumerableGraphLookupRule.java
index e210095b48..940c280b51 100644
--- a/opensearch/src/main/java/org/opensearch/sql/opensearch/planner/rules/EnumerableGraphLookupRule.java
+++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/planner/rules/EnumerableGraphLookupRule.java
@@ -92,9 +92,9 @@ public RelNode convert(RelNode rel) {
traitSet,
convertedSource,
convertedLookup,
- graphLookup.getStartField(),
- graphLookup.getFromField(),
- graphLookup.getToField(),
+ graphLookup.getStartWith(),
+ graphLookup.getConnectFromField(),
+ graphLookup.getConnectToField(),
graphLookup.getOutputField(),
graphLookup.getDepthField(),
graphLookup.getMaxDepth(),
diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/storage/scan/CalciteEnumerableGraphLookup.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/storage/scan/CalciteEnumerableGraphLookup.java
index 6307a74146..cc497b3a1c 100644
--- a/opensearch/src/main/java/org/opensearch/sql/opensearch/storage/scan/CalciteEnumerableGraphLookup.java
+++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/storage/scan/CalciteEnumerableGraphLookup.java
@@ -68,9 +68,9 @@ public class CalciteEnumerableGraphLookup extends GraphLookup implements Enumera
* @param source Source table RelNode
* @param lookup Lookup table RelNode // * @param lookupIndex OpenSearchIndex for the lookup table
* (extracted from lookup RelNode)
- * @param startField Field name for start entities
- * @param fromField Field name for outgoing edges
- * @param toField Field name for incoming edges
+ * @param startWith Field name for start entities
+ * @param connectFromField Field name for outgoing edges
+ * @param connectToField Field name for incoming edges
* @param outputField Name of the output array field
* @param depthField Name of the depth field
* @param maxDepth Maximum traversal depth (-1 for unlimited)
@@ -85,9 +85,9 @@ public CalciteEnumerableGraphLookup(
RelTraitSet traitSet,
RelNode source,
RelNode lookup,
- String startField,
- String fromField,
- String toField,
+ String startWith,
+ String connectFromField,
+ String connectToField,
String outputField,
String depthField,
int maxDepth,
@@ -101,9 +101,9 @@ public CalciteEnumerableGraphLookup(
traitSet,
source,
lookup,
- startField,
- fromField,
- toField,
+ startWith,
+ connectFromField,
+ connectToField,
outputField,
depthField,
maxDepth,
@@ -121,9 +121,9 @@ public RelNode copy(RelTraitSet traitSet, List inputs) {
traitSet,
inputs.get(0),
inputs.get(1),
- startField,
- fromField,
- toField,
+ startWith,
+ connectFromField,
+ connectToField,
outputField,
depthField,
maxDepth,
@@ -214,9 +214,9 @@ private static class GraphLookupEnumerator implements Enumerator<@Nullable Objec
List sourceFields = graphLookup.getSource().getRowType().getFieldNames();
this.lookupFields = graphLookup.getLookup().getRowType().getFieldNames();
- this.startFieldIndex = sourceFields.indexOf(graphLookup.getStartField());
- this.fromFieldIdx = lookupFields.indexOf(graphLookup.fromField);
- this.toFieldIdx = lookupFields.indexOf(graphLookup.toField);
+ this.startFieldIndex = sourceFields.indexOf(graphLookup.getStartWith());
+ this.fromFieldIdx = lookupFields.indexOf(graphLookup.connectFromField);
+ this.toFieldIdx = lookupFields.indexOf(graphLookup.connectToField);
// Push down user-specified filter to the lookup scan
if (graphLookup.filter != null) {
diff --git a/ppl/src/main/antlr/OpenSearchPPLLexer.g4 b/ppl/src/main/antlr/OpenSearchPPLLexer.g4
index 09ec84c453..0dec7c4eb6 100644
--- a/ppl/src/main/antlr/OpenSearchPPLLexer.g4
+++ b/ppl/src/main/antlr/OpenSearchPPLLexer.g4
@@ -53,9 +53,9 @@ APPENDCOL: 'APPENDCOL';
ADDTOTALS: 'ADDTOTALS';
ADDCOLTOTALS: 'ADDCOLTOTALS';
GRAPHLOOKUP: 'GRAPHLOOKUP';
-START_FIELD: 'STARTFIELD';
-FROM_FIELD: 'FROMFIELD';
-TO_FIELD: 'TOFIELD';
+START_WITH: 'STARTWITH';
+CONNECT_FROM_FIELD: 'CONNECTFROMFIELD';
+CONNECT_TO_FIELD: 'CONNECTTOFIELD';
MAX_DEPTH: 'MAXDEPTH';
DEPTH_FIELD: 'DEPTHFIELD';
DIRECTION: 'DIRECTION';
diff --git a/ppl/src/main/antlr/OpenSearchPPLParser.g4 b/ppl/src/main/antlr/OpenSearchPPLParser.g4
index 7b9e1a0b5f..e34c9ae162 100644
--- a/ppl/src/main/antlr/OpenSearchPPLParser.g4
+++ b/ppl/src/main/antlr/OpenSearchPPLParser.g4
@@ -632,9 +632,9 @@ graphLookupCommand
;
graphLookupOption
- : (START_FIELD EQUAL fieldExpression)
- | (FROM_FIELD EQUAL fieldExpression)
- | (TO_FIELD EQUAL fieldExpression)
+ : (START_WITH EQUAL fieldExpression)
+ | (CONNECT_FROM_FIELD EQUAL fieldExpression)
+ | (CONNECT_TO_FIELD EQUAL fieldExpression)
| (MAX_DEPTH EQUAL integerLiteral)
| (DEPTH_FIELD EQUAL fieldExpression)
| (DIRECTION EQUAL (UNI | BI))
@@ -1695,8 +1695,9 @@ searchableKeyWord
| ROW
| COL
| COLUMN_NAME
- | FROM_FIELD
- | TO_FIELD
+ | START_WITH
+ | CONNECT_FROM_FIELD
+ | CONNECT_TO_FIELD
| MAX_DEPTH
| DEPTH_FIELD
| DIRECTION
diff --git a/ppl/src/main/java/org/opensearch/sql/ppl/parser/AstBuilder.java b/ppl/src/main/java/org/opensearch/sql/ppl/parser/AstBuilder.java
index 9c367d7398..187a3196df 100644
--- a/ppl/src/main/java/org/opensearch/sql/ppl/parser/AstBuilder.java
+++ b/ppl/src/main/java/org/opensearch/sql/ppl/parser/AstBuilder.java
@@ -1490,10 +1490,10 @@ public UnresolvedPlan visitGraphLookupCommand(OpenSearchPPLParser.GraphLookupCom
UnresolvedPlan fromTable = visitTableSourceClause(ctx.lookupTable);
// Parse options with defaults
- Field fromField = null;
- Field toField = null;
+ Field connectFromField = null;
+ Field connectToField = null;
Literal maxDepth = Literal.ZERO;
- Field startField = null;
+ Field startWith = null;
Field depthField = null;
Direction direction = Direction.UNI;
boolean supportArray = false;
@@ -1502,17 +1502,17 @@ public UnresolvedPlan visitGraphLookupCommand(OpenSearchPPLParser.GraphLookupCom
UnresolvedExpression filter = null;
for (OpenSearchPPLParser.GraphLookupOptionContext option : ctx.graphLookupOption()) {
- if (option.FROM_FIELD() != null) {
- fromField = (Field) internalVisitExpression(option.fieldExpression());
+ if (option.CONNECT_FROM_FIELD() != null) {
+ connectFromField = (Field) internalVisitExpression(option.fieldExpression());
}
- if (option.TO_FIELD() != null) {
- toField = (Field) internalVisitExpression(option.fieldExpression());
+ if (option.CONNECT_TO_FIELD() != null) {
+ connectToField = (Field) internalVisitExpression(option.fieldExpression());
}
if (option.MAX_DEPTH() != null) {
maxDepth = (Literal) internalVisitExpression(option.integerLiteral());
}
- if (option.START_FIELD() != null) {
- startField = (Field) internalVisitExpression(option.fieldExpression());
+ if (option.START_WITH() != null) {
+ startWith = (Field) internalVisitExpression(option.fieldExpression());
}
if (option.DEPTH_FIELD() != null) {
depthField = (Field) internalVisitExpression(option.fieldExpression());
@@ -1539,17 +1539,18 @@ public UnresolvedPlan visitGraphLookupCommand(OpenSearchPPLParser.GraphLookupCom
Field as = (Field) internalVisitExpression(ctx.outputField);
- if (fromField == null || toField == null) {
- throw new SemanticCheckException("fromField and toField must be specified for graphLookup");
+ if (connectFromField == null || connectToField == null) {
+ throw new SemanticCheckException(
+ "connectFromField and connectToField must be specified for graphLookup");
}
return GraphLookup.builder()
.fromTable(fromTable)
- .fromField(fromField)
- .toField(toField)
+ .connectFromField(connectFromField)
+ .connectToField(connectToField)
.as(as)
.maxDepth(maxDepth)
- .startField(startField)
+ .startWith(startWith)
.depthField(depthField)
.direction(direction)
.supportArray(supportArray)
diff --git a/ppl/src/main/java/org/opensearch/sql/ppl/utils/PPLQueryDataAnonymizer.java b/ppl/src/main/java/org/opensearch/sql/ppl/utils/PPLQueryDataAnonymizer.java
index 90f4ce9272..f0d1a71dc3 100644
--- a/ppl/src/main/java/org/opensearch/sql/ppl/utils/PPLQueryDataAnonymizer.java
+++ b/ppl/src/main/java/org/opensearch/sql/ppl/utils/PPLQueryDataAnonymizer.java
@@ -230,11 +230,11 @@ public String visitGraphLookup(GraphLookup node, String context) {
String child = node.getChild().get(0).accept(this, context);
StringBuilder command = new StringBuilder();
command.append(child).append(" | graphlookup ").append(MASK_TABLE);
- if (node.getStartField() != null) {
- command.append(" startField=").append(MASK_COLUMN);
+ if (node.getStartWith() != null) {
+ command.append(" startWith=").append(MASK_COLUMN);
}
- command.append(" fromField=").append(MASK_COLUMN);
- command.append(" toField=").append(MASK_COLUMN);
+ command.append(" connectFromField=").append(MASK_COLUMN);
+ command.append(" connectToField=").append(MASK_COLUMN);
if (node.getMaxDepth() != null && !Integer.valueOf(0).equals(node.getMaxDepth().getValue())) {
command.append(" maxDepth=").append(MASK_LITERAL);
}
diff --git a/ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLGraphLookupTest.java b/ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLGraphLookupTest.java
index 2790f3aadd..c07b98ca7d 100644
--- a/ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLGraphLookupTest.java
+++ b/ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLGraphLookupTest.java
@@ -43,12 +43,12 @@ public CalcitePPLGraphLookupTest() {
public void testGraphLookupBasic() {
// Test basic graphLookup with same source and lookup table
String ppl =
- "source=employee | graphLookup employee startField=reportsTo fromField=reportsTo"
- + " toField=name as reportingHierarchy";
+ "source=employee | graphLookup employee startWith=reportsTo connectFromField=reportsTo"
+ + " connectToField=name as reportingHierarchy";
RelNode root = getRelNode(ppl);
String expectedLogical =
- "LogicalGraphLookup(fromField=[reportsTo], toField=[name],"
+ "LogicalGraphLookup(connectFromField=[reportsTo], connectToField=[name],"
+ " outputField=[reportingHierarchy], depthField=[null], maxDepth=[0],"
+ " bidirectional=[false])\n"
+ " LogicalSort(fetch=[100])\n"
@@ -61,12 +61,12 @@ public void testGraphLookupBasic() {
public void testGraphLookupWithDepthField() {
// Test graphLookup with depthField parameter
String ppl =
- "source=employee | graphLookup employee startField=reportsTo fromField=reportsTo"
- + " toField=name depthField=level as reportingHierarchy";
+ "source=employee | graphLookup employee startWith=reportsTo connectFromField=reportsTo"
+ + " connectToField=name depthField=level as reportingHierarchy";
RelNode root = getRelNode(ppl);
String expectedLogical =
- "LogicalGraphLookup(fromField=[reportsTo], toField=[name],"
+ "LogicalGraphLookup(connectFromField=[reportsTo], connectToField=[name],"
+ " outputField=[reportingHierarchy], depthField=[level],"
+ " maxDepth=[0], bidirectional=[false])\n"
+ " LogicalSort(fetch=[100])\n"
@@ -79,12 +79,12 @@ public void testGraphLookupWithDepthField() {
public void testGraphLookupWithMaxDepth() {
// Test graphLookup with maxDepth parameter
String ppl =
- "source=employee | graphLookup employee startField=reportsTo fromField=reportsTo"
- + " toField=name maxDepth=3 as reportingHierarchy";
+ "source=employee | graphLookup employee startWith=reportsTo connectFromField=reportsTo"
+ + " connectToField=name maxDepth=3 as reportingHierarchy";
RelNode root = getRelNode(ppl);
String expectedLogical =
- "LogicalGraphLookup(fromField=[reportsTo], toField=[name],"
+ "LogicalGraphLookup(connectFromField=[reportsTo], connectToField=[name],"
+ " outputField=[reportingHierarchy], depthField=[null], maxDepth=[3],"
+ " bidirectional=[false])\n"
+ " LogicalSort(fetch=[100])\n"
@@ -97,12 +97,12 @@ public void testGraphLookupWithMaxDepth() {
public void testGraphLookupWithFilter() {
// Test graphLookup with filter parameter
String ppl =
- "source=employee | graphLookup employee startField=reportsTo fromField=reportsTo"
- + " toField=name filter=(id > 2) as reportingHierarchy";
+ "source=employee | graphLookup employee startWith=reportsTo connectFromField=reportsTo"
+ + " connectToField=name filter=(id > 2) as reportingHierarchy";
RelNode root = getRelNode(ppl);
String expectedLogical =
- "LogicalGraphLookup(fromField=[reportsTo], toField=[name],"
+ "LogicalGraphLookup(connectFromField=[reportsTo], connectToField=[name],"
+ " outputField=[reportingHierarchy], depthField=[null], maxDepth=[0],"
+ " bidirectional=[false], filter=[>($0, 2)])\n"
+ " LogicalSort(fetch=[100])\n"
@@ -115,12 +115,12 @@ public void testGraphLookupWithFilter() {
public void testGraphLookupWithCompoundFilter() {
// Test graphLookup with compound filter condition
String ppl =
- "source=employee | graphLookup employee startField=reportsTo fromField=reportsTo"
- + " toField=name filter=(id > 1 AND name != 'Andrew') as reportingHierarchy";
+ "source=employee | graphLookup employee startWith=reportsTo connectFromField=reportsTo"
+ + " connectToField=name filter=(id > 1 AND name != 'Andrew') as reportingHierarchy";
RelNode root = getRelNode(ppl);
String expectedLogical =
- "LogicalGraphLookup(fromField=[reportsTo], toField=[name],"
+ "LogicalGraphLookup(connectFromField=[reportsTo], connectToField=[name],"
+ " outputField=[reportingHierarchy], depthField=[null], maxDepth=[0],"
+ " bidirectional=[false], filter=[AND(>($0, 1), <>($1, 'Andrew'))])\n"
+ " LogicalSort(fetch=[100])\n"
@@ -133,12 +133,12 @@ public void testGraphLookupWithCompoundFilter() {
public void testGraphLookupBidirectional() {
// Test graphLookup with bidirectional traversal
String ppl =
- "source=employee | graphLookup employee startField=reportsTo fromField=reportsTo"
- + " toField=name direction=bi as reportingHierarchy";
+ "source=employee | graphLookup employee startWith=reportsTo connectFromField=reportsTo"
+ + " connectToField=name direction=bi as reportingHierarchy";
RelNode root = getRelNode(ppl);
String expectedLogical =
- "LogicalGraphLookup(fromField=[reportsTo], toField=[name],"
+ "LogicalGraphLookup(connectFromField=[reportsTo], connectToField=[name],"
+ " outputField=[reportingHierarchy], depthField=[null], maxDepth=[0],"
+ " bidirectional=[true])\n"
+ " LogicalSort(fetch=[100])\n"
diff --git a/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstBuilderTest.java b/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstBuilderTest.java
index f7cadaaf57..6764420d13 100644
--- a/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstBuilderTest.java
+++ b/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstBuilderTest.java
@@ -1649,58 +1649,58 @@ public void testMvmapWithNonFieldFirstArgThrowsException() {
public void testGraphLookupCommand() {
// Basic graphLookup with required parameters
assertEqual(
- "source=t | graphLookup employees fromField=manager toField=name maxDepth=3"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name maxDepth=3"
+ " as reportingHierarchy",
GraphLookup.builder()
.child(relation("t"))
.fromTable(relation("employees"))
- .fromField(field("manager"))
- .toField(field("name"))
+ .connectFromField(field("manager"))
+ .connectToField(field("name"))
.as(field("reportingHierarchy"))
.maxDepth(intLiteral(3))
- .startField(null)
+ .startWith(null)
.depthField(null)
.direction(GraphLookup.Direction.UNI)
.build());
- // graphLookup with startField filter
+ // graphLookup with startWith filter
assertEqual(
- "source=t | graphLookup employees fromField=manager toField=name"
- + " startField=id as reportingHierarchy",
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ + " startWith=id as reportingHierarchy",
GraphLookup.builder()
.child(relation("t"))
.fromTable(relation("employees"))
- .fromField(field("manager"))
- .toField(field("name"))
+ .connectFromField(field("manager"))
+ .connectToField(field("name"))
.as(field("reportingHierarchy"))
.maxDepth(intLiteral(0))
- .startField(field("id"))
+ .startWith(field("id"))
.depthField(null)
.direction(GraphLookup.Direction.UNI)
.build());
// graphLookup with depthField and bidirectional
assertEqual(
- "source=t | graphLookup employees fromField=manager toField=name"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ " depthField=level direction=bi as reportingHierarchy",
GraphLookup.builder()
.child(relation("t"))
.fromTable(relation("employees"))
- .fromField(field("manager"))
- .toField(field("name"))
+ .connectFromField(field("manager"))
+ .connectToField(field("name"))
.as(field("reportingHierarchy"))
.maxDepth(intLiteral(0))
- .startField(null)
+ .startWith(null)
.depthField(field("level"))
.direction(GraphLookup.Direction.BI)
.build());
- // Error: missing fromField - SemanticCheckException thrown by AstBuilder
+ // Error: missing connectFromField - SemanticCheckException thrown by AstBuilder
assertThrows(
SemanticCheckException.class,
() ->
plan(
- "source=t | graphLookup employees toField=name startField=id as"
+ "source=t | graphLookup employees connectToField=name startWith=id as"
+ " reportingHierarchy"));
// Error: missing lookup table - SyntaxCheckException from grammar
@@ -1708,12 +1708,14 @@ public void testGraphLookupCommand() {
SyntaxCheckException.class,
() ->
plan(
- "source=t | graphLookup fromField=manager toField=name as"
+ "source=t | graphLookup connectFromField=manager connectToField=name as"
+ " reportingHierarchy"));
- // Error: missing toField - SemanticCheckException thrown by AstBuilder
+ // Error: missing connectToField - SemanticCheckException thrown by AstBuilder
assertThrows(
SemanticCheckException.class,
- () -> plan("source=t | graphLookup employees fromField=manager as reportingHierarchy"));
+ () ->
+ plan(
+ "source=t | graphLookup employees connectFromField=manager as reportingHierarchy"));
}
}
diff --git a/ppl/src/test/java/org/opensearch/sql/ppl/utils/PPLQueryDataAnonymizerTest.java b/ppl/src/test/java/org/opensearch/sql/ppl/utils/PPLQueryDataAnonymizerTest.java
index 0398d30bf1..c14b341029 100644
--- a/ppl/src/test/java/org/opensearch/sql/ppl/utils/PPLQueryDataAnonymizerTest.java
+++ b/ppl/src/test/java/org/opensearch/sql/ppl/utils/PPLQueryDataAnonymizerTest.java
@@ -647,67 +647,67 @@ public void testLookup() {
public void testGraphLookup() {
// Basic graphLookup with required parameters
assertEquals(
- "source=table | graphlookup table fromField=identifier toField=identifier"
+ "source=table | graphlookup table connectFromField=identifier connectToField=identifier"
+ " direction=uni as identifier",
anonymize(
- "source=t | graphLookup employees fromField=manager toField=name"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ " as reportingHierarchy"));
// graphLookup with maxDepth
assertEquals(
- "source=table | graphlookup table fromField=identifier toField=identifier"
+ "source=table | graphlookup table connectFromField=identifier connectToField=identifier"
+ " maxDepth=*** direction=uni as identifier",
anonymize(
- "source=t | graphLookup employees fromField=manager toField=name"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ " maxDepth=3 as reportingHierarchy"));
// graphLookup with depthField
assertEquals(
- "source=table | graphlookup table fromField=identifier toField=identifier"
+ "source=table | graphlookup table connectFromField=identifier connectToField=identifier"
+ " depthField=identifier direction=uni as identifier",
anonymize(
- "source=t | graphLookup employees fromField=manager toField=name"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ " depthField=level as reportingHierarchy"));
// graphLookup with bidirectional mode
assertEquals(
- "source=table | graphlookup table fromField=identifier toField=identifier"
+ "source=table | graphlookup table connectFromField=identifier connectToField=identifier"
+ " direction=bi as identifier",
anonymize(
- "source=t | graphLookup employees fromField=manager toField=name"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ " direction=bi as reportingHierarchy"));
// graphLookup with all optional parameters
assertEquals(
- "source=table | graphlookup table startField=identifier fromField=identifier"
- + " toField=identifier maxDepth=*** depthField=identifier direction=bi"
+ "source=table | graphlookup table startWith=identifier connectFromField=identifier"
+ + " connectToField=identifier maxDepth=*** depthField=identifier direction=bi"
+ " as identifier",
anonymize(
- "source=t | graphLookup employees fromField=manager toField=name"
- + " startField=id maxDepth=5 depthField=level direction=bi as reportingHierarchy"));
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ + " startWith=id maxDepth=5 depthField=level direction=bi as reportingHierarchy"));
// graphLookup with supportArray
assertEquals(
- "source=table | graphlookup table fromField=identifier toField=identifier"
+ "source=table | graphlookup table connectFromField=identifier connectToField=identifier"
+ " direction=uni supportArray=true as identifier",
anonymize(
- "source=t | graphLookup airports fromField=connects toField=airport"
+ "source=t | graphLookup airports connectFromField=connects connectToField=airport"
+ " supportArray=true as reachableAirports"));
// graphLookup with batchMode
assertEquals(
- "source=table | graphlookup table fromField=identifier toField=identifier"
+ "source=table | graphlookup table connectFromField=identifier connectToField=identifier"
+ " direction=uni batchMode=true as identifier",
anonymize(
- "source=t | graphLookup employees fromField=manager toField=name"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ " batchMode=true as reportingHierarchy"));
// graphLookup with filter
assertEquals(
- "source=table | graphlookup table fromField=identifier toField=identifier"
+ "source=table | graphlookup table connectFromField=identifier connectToField=identifier"
+ " direction=uni filter=(identifier = ***) as identifier",
anonymize(
- "source=t | graphLookup employees fromField=manager toField=name"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ " filter=(status = 'active') as reportingHierarchy"));
// graphLookup with compound filter
assertEquals(
- "source=table | graphlookup table fromField=identifier toField=identifier"
+ "source=table | graphlookup table connectFromField=identifier connectToField=identifier"
+ " direction=uni filter=(identifier = *** and identifier > ***) as identifier",
anonymize(
- "source=t | graphLookup employees fromField=manager toField=name"
+ "source=t | graphLookup employees connectFromField=manager connectToField=name"
+ " filter=(status = 'active' AND id > 2) as reportingHierarchy"));
}