Skip to content

Commit

Permalink
refactor(interactive): Support elementId Operator to Get Node Ident…
Browse files Browse the repository at this point in the history
…ifier in Cypher (#3758)

<!--
Thanks for your contribution! please review
https://github.com/alibaba/GraphScope/blob/main/CONTRIBUTING.md before
opening an issue.
-->

## What do these changes do?
1. Support `elementId` operator in cypher, used to obtain the inner id
specific to graph storage;
2. Support obtaining inner id through `elementId` in Gremlin expression
syntax sugar;

<!-- Please give a short brief about these changes. -->

## Related issue number

<!-- Are there any issues opened that will be resolved by merging this
change? -->

Fixes

Co-authored-by: Longbin Lai <[email protected]>
  • Loading branch information
shirly121 and longbinlai authored Apr 29, 2024
1 parent 8ef28e7 commit 908cb46
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/interactive_engine/neo4j/supported_cypher.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Note that some Aggregator operators, such as `max()`, we listed here are impleme
| ListLiteral | Fold expressions into a single list | [] | [] | <input type="checkbox" disabled checked /> | |
| MapLiteral | Fold expressions with keys into a single map | {} | {} | <input type="checkbox" disabled checked /> | |
| Labels | Get label name of a vertex type | labels() | labels() | <input type="checkbox" disabled checked /> | |
| elementId | Get a vertex or an edge identifier, unique by an object type and a database | elementId() | elementId() | <input type="checkbox" disabled checked /> | |
| Type | Get label name of an edge type | type() | type() | <input type="checkbox" disabled checked /> | |
| Extract | Get interval value from a temporal type | \<temporal\>.\<interval\> | \<temporal\>.\<interval\> | <input type="checkbox" disabled checked /> | |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,7 @@ aggregate | AVG | calculate the average value of the elements | unsupported | AV
aggregate | COLLECT | fold the elements into a list | unsupported | COLLECT(_.age)
aggregate | HEAD(COLLECT()) | find the first value of the elements | unsupported | HEAD(COLLECT(_.age))
other | LABELS | get the labels of the specified tag which is a vertex | @a.~label | LABELS(a)
other | elementId | get a vertex or an edge identifier, unique by an object type and a database | @a.~id | elementId(a)
other | TYPE | get the type of the specified tag which is an edge | @a.~label |TYPE(a)
other | LENGTH | get the length of the specified tag which is a path | @a.~len | LENGTH(a)
Expand Down
5 changes: 4 additions & 1 deletion interactive_engine/compiler/src/main/antlr4/ExprGS.g4
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,16 @@ FOLD : ( 'F' | 'f' ) ( 'O' | 'o' ) ( 'L' | 'l' ) ( 'D' | 'd' );
MEAN : ( 'M' | 'm' ) ( 'E' | 'e' ) ( 'A' | 'a' ) ( 'N' | 'n' );

oC_ScalarFunctionInvocation
: ( LENGTH | POWER | LABELS | TYPE | HEAD | DURATION ) SP? '(' SP? ( oC_Expression SP? ( ',' SP? oC_Expression SP? )* )? ')' ;
: ( LENGTH | POWER | LABELS | ELEMENTID | TYPE | HEAD | DURATION ) SP? '(' SP? ( oC_Expression SP? ( ',' SP? oC_Expression SP? )* )? ')' ;

LENGTH : ( 'L' | 'l' ) ( 'E' | 'e' ) ( 'N' | 'n' ) ( 'G' | 'g' ) ( 'T' | 't' ) ( 'H' | 'h' );

POWER : ( 'P' | 'p' ) ( 'O' | 'o' ) ( 'W' | 'w' ) ( 'E' | 'e' ) ( 'R' | 'r' );

LABELS : ( 'L' | 'l' ) ( 'A' | 'a' ) ( 'B' | 'b' ) ( 'E' | 'e' ) ( 'L' | 'l' ) ( 'S' | 's' );

ELEMENTID: ( 'E' | 'e' ) ( 'L' | 'l' ) ( 'E' | 'e' ) ( 'M' | 'm' ) ( 'E' | 'e' ) ( 'N' | 'n' ) ( 'T' | 't' ) ( 'I' | 'i' ) ( 'D' | 'd' );

TYPE : ( 'T' | 't' ) ( 'Y' | 'y' ) ( 'P' | 'p' ) ( 'E' | 'e' );

HEAD : ( 'H' | 'h' ) ( 'E' | 'e' ) ( 'A' | 'a' ) ( 'D' | 'd' );
Expand Down Expand Up @@ -361,6 +363,7 @@ oC_SymbolicName

oC_ReservedWord
: LABELS
| ELEMENTID
| TYPE
| LENGTH
| POWER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,13 @@ public ExprVisitorResult visitOC_ScalarFunctionInvocation(
"'type' can only be applied on edge type");
return new ExprVisitorResult(
builder.variable(exprCtx.get(0).getText(), GraphProperty.LABEL_KEY));
case "ELEMENTID":
RexNode idVar = builder.variable(exprCtx.get(0).getText());
Preconditions.checkArgument(
idVar.getType() instanceof GraphSchemaType,
"'elementId' can only be applied on vertex or edge type");
return new ExprVisitorResult(
builder.variable(exprCtx.get(0).getText(), GraphProperty.ID_KEY));
case "LENGTH":
Preconditions.checkArgument(
!exprCtx.isEmpty(), "LENGTH function should have one argument");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,13 @@ public ExprVisitorResult visitOC_ScalarFunctionInvocation(
"'type' can only be applied on edge type");
return new ExprVisitorResult(
builder.variable(exprCtx.get(0).getText(), GraphProperty.LABEL_KEY));
case "ELEMENTID":
RexNode idVar = builder.variable(exprCtx.get(0).getText());
Preconditions.checkArgument(
idVar.getType() instanceof GraphSchemaType,
"'elementId' can only be applied on vertex or edge type");
return new ExprVisitorResult(
builder.variable(exprCtx.get(0).getText(), GraphProperty.ID_KEY));
case "LENGTH":
Preconditions.checkArgument(
!exprCtx.isEmpty(), "LENGTH function should have one argument");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,15 @@ public void where_10_test() {
}
Assert.fail("should have thrown exceptions for property 'name' is not a date type");
}

@Test
public void where_11_test() {
// the condition is fused into source and identified as primary key filtering
RelNode where = Utils.eval("Match (a:person) Where elementId(a) = 2 Return a").build();
Assert.assertEquals(
"GraphLogicalProject(a=[a], isAppend=[false])\n"
+ " GraphLogicalSource(tableConfig=[{isAll=false, tables=[person]}],"
+ " alias=[a], opt=[VERTEX], uniqueKeyFilters=[=(_.~id, 2)])",
where.explain().trim());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1511,4 +1511,15 @@ public void g_V_select_expr_interval_minus_interval_test() {
+ " person]}], alias=[_], opt=[VERTEX])",
after.explain().trim());
}

@Test
public void g_V_as_a_select_expr_id_a_test() {
// the condition is fused into source and identified as primary key filtering
RelNode node = eval("g.V().as('a').where(expr(elementId(a) = 2))");
Assert.assertEquals(
"GraphLogicalProject(a=[a], isAppend=[false])\n"
+ " GraphLogicalSource(tableConfig=[{isAll=true, tables=[software, person]}],"
+ " alias=[a], opt=[VERTEX], uniqueKeyFilters=[=(_.~id, 2)])",
node.explain().trim());
}
}

0 comments on commit 908cb46

Please sign in to comment.