Skip to content

Commit 28d6cff

Browse files
authored
fix(interactive): Fix Expand Direction in Graph Type Inference (#4580)
<!-- Thanks for your contribution! please review https://github.com/alibaba/GraphScope/blob/main/CONTRIBUTING.md before opening an issue. --> ## What do these changes do? as titled. <!-- 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
1 parent 43e4252 commit 28d6cff

File tree

6 files changed

+156
-12
lines changed

6 files changed

+156
-12
lines changed

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/config/PlannerConfig.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ public class PlannerConfig {
3939
public static final Config<Integer> GRAPH_PLANNER_GROUP_CLEAR_INTERVAL_MINUTES =
4040
Config.intConfig("graph.planner.group.clear.interval.minutes", 30);
4141
public static final Config<String> TRIM_CLASS_NAMES =
42-
Config.stringConfig("graph.planner.trim.class.names", "GraphLogicalExpand");
42+
Config.stringConfig(
43+
"graph.planner.trim.class.names",
44+
"GraphLogicalExpand, GraphLogicalSource, GraphLogicalGetV");
4345

4446
private final Configs configs;
4547
private final List<String> rules;

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/config/YamlConfigs.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public class YamlConfigs extends Configs {
4040
.put(
4141
"graph.planner.cbo.glogue.size",
4242
(Configs configs) -> configs.get("compiler.planner.cbo.glogue.size"))
43+
.put(
44+
"graph.planner.trim.class.names",
45+
(Configs configs) -> configs.get("compiler.planner.trim_class_names"))
4346
.put(
4447
"graph.planner.rules",
4548
(Configs configs) -> {
@@ -216,7 +219,10 @@ public class YamlConfigs extends Configs {
216219
(Configs configs) -> configs.get("compiler.calcite_default_charset"))
217220
.put(
218221
"gremlin.script.language.name",
219-
(Configs configs) -> configs.get("compiler.gremlin_script_language_name"));
222+
(Configs configs) -> configs.get("compiler.gremlin_script_language_name"))
223+
.put(
224+
"graph.type.inference.enabled",
225+
(Configs configs) -> configs.get("compiler.type_inference_enabled"));
220226
valueGetterMap = mapBuilder.build();
221227
}
222228

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/GraphIOProcessor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.alibaba.graphscope.common.ir.planner;
1818

19+
import com.alibaba.graphscope.common.config.Configs;
20+
import com.alibaba.graphscope.common.config.FrontendConfig;
1921
import com.alibaba.graphscope.common.ir.meta.IrMeta;
2022
import com.alibaba.graphscope.common.ir.meta.glogue.CountHandler;
2123
import com.alibaba.graphscope.common.ir.meta.glogue.DetailedExpandCost;
@@ -456,6 +458,10 @@ private PatternEdge visitEdge(
456458
}
457459

458460
private void checkPattern(Pattern pattern) {
461+
Configs configs = (Configs) builder.getContext();
462+
if (configs != null && !FrontendConfig.GRAPH_TYPE_INFERENCE_ENABLED.get(configs)) {
463+
return;
464+
}
459465
for (PatternEdge edge : pattern.getEdgeSet()) {
460466
PatternVertex src = edge.getSrcVertex();
461467
PatternVertex dst = edge.getDstVertex();

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/type/GraphTypeInference.java

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,61 @@ private RelNode dfs(
135135
}
136136
}
137137
RelDataType oldType = getType(top);
138+
RelNode newTop = top;
138139
if (!typeEquals(oldType, newType)) {
139140
updated.add(top);
140-
RelNode newTop = newRel(top, newType);
141+
newTop = newRel(top, newType);
142+
}
143+
newTop = newExpandOpt(newTop, newNeighbors);
144+
if (top != newTop) {
141145
RelNode parent = relGraph.getParent(top);
142146
if (parent != null) {
143147
parent.replaceInput(0, newTop);
144148
}
145-
return newTop;
146149
}
147-
return top;
150+
return newTop;
151+
}
152+
153+
private GraphOpt.Expand getExpandOpt(
154+
GraphLogicalExpand expand, GraphSchemaType expandType, List<RelNode> children) {
155+
if (expand.getOpt() != GraphOpt.Expand.BOTH) {
156+
return expand.getOpt();
157+
}
158+
List<String> childrenLabels = Lists.newArrayList();
159+
children.forEach(
160+
c -> {
161+
RelDataType type = getType(c);
162+
if (type instanceof GraphSchemaType) {
163+
childrenLabels.addAll(
164+
((GraphSchemaType) type)
165+
.getLabelType().getLabelsEntry().stream()
166+
.map(k -> k.getLabel())
167+
.collect(Collectors.toList()));
168+
}
169+
});
170+
List<String> srcLabels = Lists.newArrayList();
171+
List<String> dstLabels = Lists.newArrayList();
172+
expandType
173+
.getLabelType()
174+
.getLabelsEntry()
175+
.forEach(
176+
k -> {
177+
srcLabels.add(k.getSrcLabel());
178+
dstLabels.add(k.getDstLabel());
179+
});
180+
if (srcLabels.stream().noneMatch(dstLabels::contains)) {
181+
if (childrenLabels.stream()
182+
.collect(Collectors.toSet())
183+
.equals(srcLabels.stream().collect(Collectors.toSet()))) {
184+
return GraphOpt.Expand.OUT;
185+
}
186+
if (childrenLabels.stream()
187+
.collect(Collectors.toSet())
188+
.equals(dstLabels.stream().collect(Collectors.toSet()))) {
189+
return GraphOpt.Expand.IN;
190+
}
191+
}
192+
return expand.getOpt();
148193
}
149194

150195
private boolean typeEquals(RelDataType type1, RelDataType type2) {
@@ -702,6 +747,49 @@ private RelNode newRel(RelNode rel, RelDataType newType) {
702747
return rel;
703748
}
704749

750+
private RelNode newExpandOpt(RelNode rel, List<RelNode> children) {
751+
if (rel instanceof GraphLogicalExpand) {
752+
GraphLogicalExpand expand = (GraphLogicalExpand) rel;
753+
GraphSchemaType expandType =
754+
(GraphSchemaType) expand.getRowType().getFieldList().get(0).getType();
755+
GraphOpt.Expand newOpt = getExpandOpt(expand, expandType, children);
756+
if (expand.getOpt() != newOpt) {
757+
GraphLogicalExpand newExpand =
758+
GraphLogicalExpand.create(
759+
(GraphOptCluster) builder.getCluster(),
760+
ImmutableList.of(),
761+
expand.getInputs().isEmpty() ? null : expand.getInput(0),
762+
newOpt,
763+
expand.getTableConfig(),
764+
expand.getAliasName(),
765+
expand.getStartAlias(),
766+
expand.isOptional(),
767+
expand.getFilters(),
768+
expandType);
769+
return newExpand;
770+
}
771+
} else if (rel instanceof GraphLogicalPathExpand) {
772+
GraphLogicalPathExpand pxd = (GraphLogicalPathExpand) rel;
773+
RelNode newExpand = newExpandOpt(pxd.getExpand(), children);
774+
if (newExpand != pxd.getExpand()) {
775+
return GraphLogicalPathExpand.create(
776+
(GraphOptCluster) builder.getCluster(),
777+
ImmutableList.of(),
778+
pxd.getInput(),
779+
newExpand,
780+
pxd.getGetV(),
781+
pxd.getOffset(),
782+
pxd.getFetch(),
783+
pxd.getResultOpt(),
784+
pxd.getPathOpt(),
785+
pxd.getUntilCondition(),
786+
pxd.getAliasName(),
787+
pxd.getStartAlias());
788+
}
789+
}
790+
return rel;
791+
}
792+
705793
private TableConfig newTableConfig(AbstractBindableTableScan rel, RelDataType newType) {
706794
List<RelOptTable> oldTables = rel.getTableConfig().getTables();
707795
List<RelOptTable> newTables = Lists.newArrayList();

interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/GraphTypeInferenceTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,48 @@ public void schema_type_test_10() {
251251
}
252252
Assert.fail();
253253
}
254+
255+
@Test
256+
public void person_likes_post_type_test() {
257+
RelNode match =
258+
com.alibaba.graphscope.cypher.antlr4.Utils.eval(
259+
"Match (a:PERSON)-[:KNOWS]-(:PERSON)-[:LIKES]-(c:POST) Return c",
260+
Utils.mockGraphBuilder("schema/ldbc.json"))
261+
.build();
262+
Assert.assertEquals(
263+
"GraphLogicalProject(c=[c], isAppend=[false])\n"
264+
+ " GraphLogicalSingleMatch(input=[null],"
265+
+ " sentence=[GraphLogicalGetV(tableConfig=[{isAll=false, tables=[POST]}],"
266+
+ " alias=[c], opt=[OTHER])\n"
267+
+ " GraphLogicalExpand(tableConfig=[[EdgeLabel(LIKES, PERSON, POST)]],"
268+
+ " alias=[_], opt=[OUT])\n"
269+
+ " GraphLogicalGetV(tableConfig=[{isAll=false, tables=[PERSON]}],"
270+
+ " alias=[_], opt=[OTHER])\n"
271+
+ " GraphLogicalExpand(tableConfig=[{isAll=false, tables=[KNOWS]}],"
272+
+ " alias=[_], opt=[BOTH])\n"
273+
+ " GraphLogicalSource(tableConfig=[{isAll=false, tables=[PERSON]}],"
274+
+ " alias=[a], opt=[VERTEX])\n"
275+
+ "], matchOpt=[INNER])",
276+
match.explain().trim());
277+
}
278+
279+
@Test
280+
public void person_likes_post_type_test_2() {
281+
RelNode match =
282+
com.alibaba.graphscope.cypher.antlr4.Utils.eval(
283+
"Match (a)-[:LIKES]-(c) Return c",
284+
Utils.mockGraphBuilder("schema/ldbc.json"))
285+
.build();
286+
Assert.assertEquals(
287+
"GraphLogicalProject(c=[c], isAppend=[false])\n"
288+
+ " GraphLogicalSingleMatch(input=[null],"
289+
+ " sentence=[GraphLogicalGetV(tableConfig=[{isAll=false, tables=[PERSON, POST,"
290+
+ " COMMENT]}], alias=[c], opt=[OTHER])\n"
291+
+ " GraphLogicalExpand(tableConfig=[{isAll=false, tables=[LIKES]}], alias=[_],"
292+
+ " opt=[BOTH])\n"
293+
+ " GraphLogicalSource(tableConfig=[{isAll=false, tables=[PERSON, POST,"
294+
+ " COMMENT]}], alias=[a], opt=[VERTEX])\n"
295+
+ "], matchOpt=[INNER])",
296+
match.explain().trim());
297+
}
254298
}

interactive_engine/compiler/src/test/java/com/alibaba/graphscope/gremlin/antlr4x/GraphBuilderTest.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,13 +1830,11 @@ public void g_V_match_as_a_person_both_as_b_test() {
18301830
RelNode after2 = optimizer.optimize(node2, new GraphIOProcessor(builder, irMeta));
18311831
Assert.assertEquals(
18321832
"GraphLogicalAggregate(keys=[{variables=[], aliases=[]}], values=[[{operands=[a,"
1833-
+ " b], aggFunction=COUNT, alias='$f0', distinct=false}]])\n"
1834-
+ " GraphPhysicalGetV(tableConfig=[{isAll=false, tables=[person]}], alias=[b],"
1835-
+ " opt=[OTHER], physicalOpt=[ITSELF])\n"
1836-
+ " GraphPhysicalExpand(tableConfig=[{isAll=false, tables=[created]}],"
1837-
+ " alias=[_], startAlias=[a], opt=[BOTH], physicalOpt=[VERTEX])\n"
1838-
+ " GraphLogicalSource(tableConfig=[{isAll=false, tables=[software]}],"
1839-
+ " alias=[a], opt=[VERTEX])",
1833+
+ " b], aggFunction=COUNT, alias='$f0', distinct=false}]])\n"
1834+
+ " GraphPhysicalExpand(tableConfig=[{isAll=false, tables=[created]}],"
1835+
+ " alias=[b], startAlias=[a], opt=[IN], physicalOpt=[VERTEX])\n"
1836+
+ " GraphLogicalSource(tableConfig=[{isAll=false, tables=[software]}],"
1837+
+ " alias=[a], opt=[VERTEX])",
18401838
after2.explain().trim());
18411839
RelNode node3 = eval("g.V().match(as('a').both().as('b')).count()", builder);
18421840
RelNode after3 = optimizer.optimize(node3, new GraphIOProcessor(builder, irMeta));

0 commit comments

Comments
 (0)