Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(interactive): Fix Bugs of Property Loss of Edge Type After Type Inference #4032

Merged
merged 9 commits into from
Aug 13, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.commons.lang3.ObjectUtils;
Expand Down Expand Up @@ -160,116 +161,116 @@
return true;
}

private RelDataType restrictChild(
RelGraph relGraph, RelNode child, RelNode parent, RelDataType parentType) {
if (child instanceof GraphLogicalSource
&& ((GraphLogicalSource) child).getOpt() == GraphOpt.Source.VERTEX
|| child instanceof GraphLogicalGetV) {
GraphSchemaType childType = (GraphSchemaType) getType(child);
GraphLabelType childLabelType = childType.getLabelType();
if (parent instanceof GraphLogicalPathExpand) {
GraphLogicalPathExpand pxd = (GraphLogicalPathExpand) parent;
int minHop =
(pxd.getOffset() == null)
? 0
: ((Number) ((RexLiteral) pxd.getOffset()).getValue()).intValue();
int maxHop =
pxd.getFetch() == null
? Integer.MAX_VALUE
: ((Number) ((RexLiteral) pxd.getFetch()).getValue()).intValue()
+ minHop
- 1;
GraphPathTypeInference pathTypeInfer =
new GraphPathTypeInference(
childLabelType,
null,
(GraphPathType) parentType,
((GraphLogicalExpand) pxd.getExpand()).getOpt(),
minHop,
maxHop);
return createSchemaType(
GraphOpt.Source.VERTEX,
pathTypeInfer.inferStartVType().getLabelsEntry(),
childType);
}
if (parent instanceof GraphLogicalExpand) {
GraphLogicalExpand expand = (GraphLogicalExpand) parent;
GraphLabelType parentLabelType = ((GraphSchemaType) parentType).getLabelType();
List<GraphLabelType.Entry> commonLabels =
commonLabels(childLabelType, parentLabelType, expand.getOpt(), true, false);
return createSchemaType(GraphOpt.Source.VERTEX, commonLabels, childType);
}
throw new IllegalArgumentException(
"graph generic type error: unable to establish an extension relationship"
+ " between node "
+ child
+ " with node "
+ parent);
}
if (child instanceof GraphLogicalSource
&& ((GraphLogicalSource) child).getOpt() == GraphOpt.Source.EDGE
|| child instanceof GraphLogicalExpand) {
Preconditions.checkArgument(
parent instanceof GraphLogicalGetV,
"graph generic type error: unable to establish an extension relationship"
+ " between node %s with node %s",
child,
parent);
GraphLogicalGetV getV = (GraphLogicalGetV) parent;
GraphSchemaType childType = (GraphSchemaType) getType(child);
GraphLabelType childLabelType = childType.getLabelType();
GraphLabelType parentLabelType = ((GraphSchemaType) parentType).getLabelType();
GraphLabelType otherVLabelType = null;
if (getV.getOpt() == GraphOpt.GetV.OTHER) {
RelDataType otherVType = relGraph.getNeighborsType(child);
Preconditions.checkArgument(
otherVType != null && otherVType instanceof GraphSchemaType,
"graph generic type error: invalid opt %s in node %s",
getV.getOpt(),
getV);
otherVLabelType = ((GraphSchemaType) otherVType).getLabelType();
}
List<GraphLabelType.Entry> commonLabels =
commonLabels(
otherVLabelType, childLabelType, parentLabelType, getV.getOpt(), true);
return createSchemaType(GraphOpt.Source.EDGE, commonLabels, childType);
}
if (child instanceof GraphLogicalPathExpand) {
Preconditions.checkArgument(
parent instanceof GraphLogicalGetV,
"graph generic type error: unable to establish an extension relationship"
+ " between node %s with node %s",
child,
parent);
GraphLogicalPathExpand pxd = (GraphLogicalPathExpand) child;
int minHop =
(pxd.getOffset() == null)
? 0
: ((Number) ((RexLiteral) pxd.getOffset()).getValue()).intValue();
int maxHop =
pxd.getFetch() == null
? Integer.MAX_VALUE
: ((Number) ((RexLiteral) pxd.getFetch()).getValue()).intValue()
+ minHop
- 1;
GraphPathTypeInference pathTypeInfer =
new GraphPathTypeInference(
((GraphSchemaType) getType(child.getInput(0))).getLabelType(),
((GraphSchemaType) parentType).getLabelType(),
(GraphPathType) getType(child),
((GraphLogicalExpand) pxd.getExpand()).getOpt(),
minHop,
maxHop);
return pathTypeInfer.inferPathType();
}
throw new IllegalArgumentException(
"graph generic type error: unable to establish an extension relationship between"
+ " node "
+ child
+ " with node "
+ parent);
}

Check notice on line 273 in interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/type/GraphTypeInference.java

View check run for this annotation

codefactor.io / CodeFactor

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/type/GraphTypeInference.java#L164-L273

Complex Method
private RelDataType restrictParent(
RelGraph relGraph, List<RelNode> children, RelNode parent, RelDataType parentType) {
for (RelNode child : children) {
Expand All @@ -278,118 +279,118 @@
return parentType;
}

private RelDataType restrictParent(
RelGraph relGraph, RelNode child, RelNode parent, RelDataType parentType) {
if (child instanceof GraphLogicalSource
&& ((GraphLogicalSource) child).getOpt() == GraphOpt.Source.VERTEX
|| child instanceof GraphLogicalGetV) {
if (parent instanceof GraphLogicalExpand) {
GraphLogicalExpand expand = (GraphLogicalExpand) parent;
GraphLabelType childLabelType = ((GraphSchemaType) getType(child)).getLabelType();
GraphLabelType parentLabelType = ((GraphSchemaType) parentType).getLabelType();
List<GraphLabelType.Entry> commonLabels =
commonLabels(
childLabelType, parentLabelType, expand.getOpt(), false, false);
return createSchemaType(
GraphOpt.Source.EDGE, commonLabels, (GraphSchemaType) parentType);
}
if (parent instanceof GraphLogicalPathExpand) {
GraphLogicalPathExpand pxd = (GraphLogicalPathExpand) parent;
int minHop =
(pxd.getOffset() == null)
? 0
: ((Number) ((RexLiteral) pxd.getOffset()).getValue()).intValue();
int maxHop =
pxd.getFetch() == null
? Integer.MAX_VALUE
: ((Number) ((RexLiteral) pxd.getFetch()).getValue()).intValue()
+ minHop
- 1;
GraphPathTypeInference pathTypeInfer =
new GraphPathTypeInference(
((GraphSchemaType) getType(child)).getLabelType(),
((GraphSchemaType) getType(pxd.getGetV())).getLabelType(),
(GraphPathType) parentType,
((GraphLogicalExpand) pxd.getExpand()).getOpt(),
minHop,
maxHop);
return pathTypeInfer.inferPathType();
}
throw new IllegalArgumentException(
"graph generic type error: unable to establish an extension relationship"
+ " between node "
+ child
+ " with node "
+ parent);
}
if (child instanceof GraphLogicalSource
&& ((GraphLogicalSource) child).getOpt() == GraphOpt.Source.EDGE
|| child instanceof GraphLogicalExpand) {
Preconditions.checkArgument(
parent instanceof GraphLogicalGetV,
"graph generic type error: unable to establish an extension relationship"
+ " between node %s with node %s",
child,
parent);
GraphLogicalGetV getV = (GraphLogicalGetV) parent;
GraphLabelType childLabelType = ((GraphSchemaType) getType(child)).getLabelType();
GraphLabelType parentLabelType = ((GraphSchemaType) parentType).getLabelType();
GraphLabelType otherVLabelType = null;
if (getV.getOpt() == GraphOpt.GetV.OTHER) {
RelDataType otherVType = relGraph.getNeighborsType(child);
Preconditions.checkArgument(
otherVType != null && otherVType instanceof GraphSchemaType,
"graph generic type error: invalid opt %s in node %s",
getV.getOpt(),
getV);
otherVLabelType = ((GraphSchemaType) otherVType).getLabelType();
}
List<GraphLabelType.Entry> commonLabels =
commonLabels(
otherVLabelType, childLabelType, parentLabelType, getV.getOpt(), false);
return createSchemaType(
GraphOpt.Source.VERTEX, commonLabels, (GraphSchemaType) parentType);
}
if (child instanceof GraphLogicalPathExpand) {
Preconditions.checkArgument(
parent instanceof GraphLogicalGetV,
"graph generic type error: unable to establish an extension relationship"
+ " between node %s with node %s",
child,
parent);
GraphLabelType outerGetVLabelType = ((GraphSchemaType) parentType).getLabelType();
GraphLogicalPathExpand pxd = (GraphLogicalPathExpand) child;
int minHop =
(pxd.getOffset() == null)
? 0
: ((Number) ((RexLiteral) pxd.getOffset()).getValue()).intValue();
int maxHop =
pxd.getFetch() == null
? Integer.MAX_VALUE
: ((Number) ((RexLiteral) pxd.getFetch()).getValue()).intValue()
+ minHop
- 1;
GraphPathTypeInference pathTypeInfer =
new GraphPathTypeInference(
null,
outerGetVLabelType,
(GraphPathType) getType(pxd),
((GraphLogicalExpand) pxd.getExpand()).getOpt(),
minHop,
maxHop);
return createSchemaType(
GraphOpt.Source.VERTEX,
pathTypeInfer.inferGetVType().getLabelsEntry(),
(GraphSchemaType) parentType);
}
throw new IllegalArgumentException(
"graph generic type error: unable to establish an extension relationship between"
+ " node "
+ child
+ " with node "
+ parent);
}

Check notice on line 393 in interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/type/GraphTypeInference.java

View check run for this annotation

codefactor.io / CodeFactor

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/type/GraphTypeInference.java#L282-L393

Complex Method
private RelDataType restrictShared(
List<RelNode> rels, @Nullable RelNode shared, RelDataType sharedType) {
if (sharedType instanceof GraphSchemaType) {
Expand Down Expand Up @@ -452,76 +453,76 @@
return commonLabels;
}

private List<GraphLabelType.Entry> commonLabels(
@Nullable GraphLabelType otherVType,
GraphLabelType expandType,
GraphLabelType getVType,
GraphOpt.GetV getVOpt,
boolean recordExpand) {
List<GraphLabelType.Entry> commonLabels = Lists.newArrayList();
for (GraphLabelType.Entry entry1 : expandType.getLabelsEntry()) {
for (GraphLabelType.Entry entry2 : getVType.getLabelsEntry()) {
if (getVOpt == GraphOpt.GetV.START || getVOpt == GraphOpt.GetV.BOTH) {
if (entry1.getSrcLabel().equals(entry2.getLabel())) {
if (recordExpand) {
commonLabels.add(entry1);
} else {
commonLabels.add(entry2);
}
}
}
if (getVOpt == GraphOpt.GetV.END || getVOpt == GraphOpt.GetV.BOTH) {
if (entry1.getDstLabel().equals(entry2.getLabel())) {
if (recordExpand) {
commonLabels.add(entry1);
} else {
commonLabels.add(entry2);
}
}
}
if (getVOpt == GraphOpt.GetV.OTHER && otherVType != null) {
for (GraphLabelType.Entry entry3 : otherVType.getLabelsEntry()) {
if (entry1.getSrcLabel().equals(entry3.getLabel())
&& entry1.getDstLabel().equals(entry2.getLabel())
|| entry1.getDstLabel().equals(entry3.getLabel())
&& entry1.getSrcLabel().equals(entry2.getLabel())) {
if (recordExpand) {
commonLabels.add(entry1);
} else {
commonLabels.add(entry2);
}
}
}
}
}
}
commonLabels = commonLabels.stream().distinct().collect(Collectors.toList());
String errorMsg;
if (commonLabels.isEmpty()) {
switch (getVOpt) {
case OTHER:
errorMsg =
String.format(
"graph schema type error: unable to find expand with [type=%s]"
+ " between getV with [type=%s] and getV with [opt=%s,"
+ " type=%s]",
expandType, otherVType, getVOpt, getVType);
break;
case START:
case END:
case BOTH:
default:
errorMsg =
String.format(
"graph schema type error: unable to find getV with [opt=%s,"
+ " type=%s] from expand with [type=%s]",
getVOpt, getVType, expandType);
}
throw new IllegalArgumentException(errorMsg);
}
return commonLabels;
}

Check notice on line 525 in interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/type/GraphTypeInference.java

View check run for this annotation

codefactor.io / CodeFactor

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/type/GraphTypeInference.java#L456-L525

Complex Method
private List<GraphLabelType.Entry> commonLabels(
GraphLabelType getVType,
GraphLabelType expandType,
Expand Down Expand Up @@ -700,7 +701,10 @@
boolean isNullable = originalType == null ? false : originalType.isNullable();
if (newLabels.size() == 1) {
return new GraphSchemaType(
opt, new GraphLabelType(newLabels), ImmutableList.of(), isNullable);
opt,
new GraphLabelType(newLabels),
getOriginalFields(newLabels.get(0), originalType),
isNullable);
} else {
List<GraphSchemaType> fuzzyTypes =
newLabels.stream()
Expand All @@ -709,12 +713,24 @@
new GraphSchemaType(
opt,
new GraphLabelType(ImmutableList.of(k)),
ImmutableList.of()))
getOriginalFields(k, originalType)))
.collect(Collectors.toList());
return GraphSchemaType.create(fuzzyTypes, builder.getTypeFactory(), isNullable);
}
}

private List<RelDataTypeField> getOriginalFields(
GraphLabelType.Entry labelEntry, @Nullable GraphSchemaType originalType) {
if (originalType == null) return ImmutableList.of();
List<GraphSchemaType> candidates = originalType.getSchemaTypeAsList();
for (GraphSchemaType candidate : candidates) {
if (candidate.getLabelType().getLabelsEntry().contains(labelEntry)) {
return candidate.getFieldList();
}
}
return ImmutableList.of();
}

private class RelGraph {
private final Map<String, List<RelNode>> aliasNameToRels;
private final List<RelNode> rels;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.alibaba.graphscope.common.config.Configs;
import com.alibaba.graphscope.common.config.FrontendConfig;
import com.alibaba.graphscope.common.ir.rel.graph.GraphLogicalSource;
import com.alibaba.graphscope.common.ir.tools.GraphBuilder;
import com.alibaba.graphscope.common.ir.tools.LogicalPlan;
import com.google.common.collect.ImmutableMap;

Expand Down Expand Up @@ -504,4 +505,21 @@ public void match_24_test() {
+ "], matchOpt=[INNER])",
node.explain().trim());
}

@Test
public void property_exist_after_type_inference_test() {
GraphBuilder builder =
com.alibaba.graphscope.common.ir.Utils.mockGraphBuilder(
"schema/ldbc_schema_exp_hierarchy.json");
// check property 'creationDate' still exists after type inference has updated the type of
// 'HASCREATOR'
RelNode rel =
com.alibaba.graphscope.cypher.antlr4.Utils.eval(
"Match (a:PERSON)<-[h:HASCREATOR]-(b:COMMENT) Return h;", builder)
.build();
Assert.assertEquals(
"RecordType(Graph_Schema_Type(labels=[EdgeLabel(HASCREATOR, COMMENT, PERSON)],"
+ " properties=[BIGINT creationDate]) h)",
rel.getRowType().toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,16 @@
}
}
],
"columns": []
"columns": [
{
"key": {
"id": 2,
"name": "creationDate"
},
"data_type": 2,
"is_primary_key": false
}
]
},
{
"label": {
Expand Down
Loading