Skip to content

Commit 8eaa4b0

Browse files
authored
fix(interactive): Convert Schema from Groot Spec to Flex Spec (#4447)
<!-- 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 a39855e commit 8eaa4b0

File tree

8 files changed

+280
-70
lines changed

8 files changed

+280
-70
lines changed

interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/schema/impl/DefaultEdgeRelation.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.alibaba.graphscope.groot.common.schema.api.EdgeRelation;
1919
import com.alibaba.graphscope.groot.common.schema.api.GraphVertex;
2020
import com.google.common.base.MoreObjects;
21+
import com.google.common.base.Objects;
2122

2223
public class DefaultEdgeRelation implements EdgeRelation {
2324
private final GraphVertex source;
@@ -57,4 +58,19 @@ public String toString() {
5758
public long getTableId() {
5859
return this.tableId;
5960
}
61+
62+
@Override
63+
public boolean equals(Object o) {
64+
if (this == o) return true;
65+
if (o == null || getClass() != o.getClass()) return false;
66+
DefaultEdgeRelation that = (DefaultEdgeRelation) o;
67+
return tableId == that.tableId
68+
&& Objects.equal(source, that.source)
69+
&& Objects.equal(target, that.target);
70+
}
71+
72+
@Override
73+
public int hashCode() {
74+
return Objects.hashCode(source, target, tableId);
75+
}
6076
}

interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/schema/impl/DefaultGraphProperty.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.alibaba.graphscope.groot.common.schema.api.GraphProperty;
1919
import com.alibaba.graphscope.groot.common.schema.wrapper.DataType;
2020
import com.google.common.base.MoreObjects;
21+
import com.google.common.base.Objects;
2122

2223
public class DefaultGraphProperty implements GraphProperty {
2324
private final int id;
@@ -71,4 +72,20 @@ public String toString() {
7172
.add("dataType", dataType)
7273
.toString();
7374
}
75+
76+
@Override
77+
public boolean equals(Object o) {
78+
if (this == o) return true;
79+
if (o == null || getClass() != o.getClass()) return false;
80+
DefaultGraphProperty that = (DefaultGraphProperty) o;
81+
return id == that.id
82+
&& Objects.equal(name, that.name)
83+
&& dataType == that.dataType
84+
&& Objects.equal(defaultValue, that.defaultValue);
85+
}
86+
87+
@Override
88+
public int hashCode() {
89+
return Objects.hashCode(id, name, dataType, defaultValue);
90+
}
7491
}

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/schema/GraphOptTable.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ private RelDataType deriveType(GraphProperty property) {
140140
}
141141
RelDataTypeFactory typeFactory = this.schema.getTypeFactory();
142142
requireNonNull(typeFactory, "typeFactory");
143-
IrDataTypeConvertor<DataType> typeConvertor = new IrDataTypeConvertor.Groot(typeFactory);
143+
IrDataTypeConvertor<DataType> typeConvertor =
144+
new IrDataTypeConvertor.Groot(typeFactory, true);
144145
return typeConvertor.convert(property.getDataType());
145146
}
146147

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/schema/IrDataTypeConvertor.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ public interface IrDataTypeConvertor<T> {
5151

5252
class Groot implements IrDataTypeConvertor<DataType> {
5353
private final RelDataTypeFactory typeFactory;
54+
private final boolean throwsOnFail;
5455

55-
public Groot(RelDataTypeFactory typeFactory) {
56+
public Groot(RelDataTypeFactory typeFactory, boolean throwsOnFail) {
5657
this.typeFactory = typeFactory;
58+
this.throwsOnFail = throwsOnFail;
5759
}
5860

5961
@Override
@@ -118,10 +120,13 @@ public RelDataType convert(DataType from) {
118120
case BYTES:
119121
case BYTES_LIST:
120122
default:
121-
throw new UnsupportedOperationException(
122-
"convert GrootDataType ["
123-
+ from.name()
124-
+ "] to RelDataType is unsupported yet");
123+
if (throwsOnFail) {
124+
throw new UnsupportedOperationException(
125+
"convert GrootDataType ["
126+
+ from.name()
127+
+ "] to RelDataType is unsupported yet");
128+
}
129+
return typeFactory.createSqlType(SqlTypeName.ANY);
125130
}
126131
}
127132

@@ -181,8 +186,15 @@ public DataType convert(RelDataType dataFrom) {
181186
}
182187
break;
183188
case UNKNOWN:
189+
return DataType.UNKNOWN;
184190
default:
185191
}
192+
if (throwsOnFail) {
193+
throw new UnsupportedOperationException(
194+
"convert RelDataType ["
195+
+ dataFrom
196+
+ "] to GrootDataType is unsupported yet");
197+
}
186198
return DataType.UNKNOWN;
187199
}
188200
}

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/schema/IrGraphProperty.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,33 @@
1919
package com.alibaba.graphscope.common.ir.meta.schema;
2020

2121
import com.alibaba.graphscope.groot.common.schema.impl.DefaultGraphProperty;
22+
import com.google.common.base.Objects;
2223

2324
import org.apache.calcite.rel.type.RelDataType;
2425

2526
public class IrGraphProperty extends DefaultGraphProperty {
2627
private final RelDataType relDataType;
2728

2829
public IrGraphProperty(int id, String name, RelDataType relDataType) {
29-
super(id, name, new IrDataTypeConvertor.Groot(null).convert(relDataType));
30+
super(id, name, new IrDataTypeConvertor.Groot(null, false).convert(relDataType));
3031
this.relDataType = relDataType;
3132
}
3233

3334
public RelDataType getRelDataType() {
3435
return this.relDataType;
3536
}
37+
38+
@Override
39+
public boolean equals(Object o) {
40+
if (this == o) return true;
41+
if (o == null || getClass() != o.getClass()) return false;
42+
if (!super.equals(o)) return false;
43+
IrGraphProperty that = (IrGraphProperty) o;
44+
return Objects.equal(relDataType, that.relDataType);
45+
}
46+
47+
@Override
48+
public int hashCode() {
49+
return Objects.hashCode(super.hashCode(), relDataType);
50+
}
3651
}

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/schema/IrGraphSchema.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
import com.alibaba.graphscope.groot.common.exception.PropertyNotFoundException;
2222
import com.alibaba.graphscope.groot.common.exception.TypeNotFoundException;
2323
import com.alibaba.graphscope.groot.common.schema.api.*;
24+
import com.google.common.collect.ImmutableMap;
25+
26+
import org.apache.calcite.rel.type.RelDataTypeFactory;
2427

2528
import java.io.IOException;
2629
import java.nio.charset.StandardCharsets;
@@ -42,14 +45,19 @@ public IrGraphSchema(Configs configs, SchemaInputStream schemaInputStream) throw
4245
schemaInputStream.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
4346
schemaInputStream.getInputStream().close();
4447
SchemaSpec spec = new SchemaSpec(schemaInputStream.getType(), content);
45-
this.graphSchema = spec.convert(new GraphTypeFactoryImpl(configs));
46-
this.specManager = new SchemaSpecManager(this, spec);
48+
RelDataTypeFactory typeFactory = new GraphTypeFactoryImpl(configs);
49+
this.graphSchema = spec.convert(typeFactory);
50+
this.specManager = new SchemaSpecManager(this.graphSchema, false, typeFactory, spec);
4751
}
4852

4953
public IrGraphSchema(GraphSchema graphSchema, boolean isColumnId) {
5054
this.graphSchema = graphSchema;
5155
this.isColumnId = isColumnId;
52-
this.specManager = new SchemaSpecManager(this);
56+
this.specManager =
57+
new SchemaSpecManager(
58+
this.graphSchema,
59+
this.isColumnId,
60+
new GraphTypeFactoryImpl(new Configs(ImmutableMap.of())));
5361
}
5462

5563
public boolean isColumnId() {

interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/meta/schema/SchemaSpecManager.java

Lines changed: 117 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,47 @@
1818

1919
package com.alibaba.graphscope.common.ir.meta.schema;
2020

21+
import com.alibaba.graphscope.groot.common.schema.api.*;
2122
import com.alibaba.graphscope.groot.common.util.IrSchemaParser;
22-
import com.fasterxml.jackson.databind.JsonNode;
23+
import com.fasterxml.jackson.core.JsonProcessingException;
2324
import com.fasterxml.jackson.databind.ObjectMapper;
25+
import com.google.common.base.Preconditions;
26+
import com.google.common.collect.ImmutableMap;
2427
import com.google.common.collect.Lists;
2528

26-
import org.checkerframework.checker.nullness.qual.Nullable;
29+
import org.apache.calcite.rel.type.RelDataType;
30+
import org.apache.calcite.rel.type.RelDataTypeFactory;
2731
import org.slf4j.Logger;
2832
import org.slf4j.LoggerFactory;
2933
import org.yaml.snakeyaml.Yaml;
3034

3135
import java.util.List;
3236
import java.util.Map;
37+
import java.util.stream.Collectors;
3338

3439
public class SchemaSpecManager {
3540
private static final Logger logger = LoggerFactory.getLogger(SchemaSpecManager.class);
36-
private final IrGraphSchema parent;
41+
private final GraphSchema rootSchema;
42+
private final boolean isColumnId;
43+
private final RelDataTypeFactory typeFactory;
3744
private final List<SchemaSpec> specifications;
3845

39-
public SchemaSpecManager(IrGraphSchema parent) {
40-
this.parent = parent;
41-
this.specifications = Lists.newArrayList(convert(null, SchemaSpec.Type.IR_CORE_IN_JSON));
46+
public SchemaSpecManager(
47+
GraphSchema rootSchema, boolean isColumnId, RelDataTypeFactory typeFactory) {
48+
this.rootSchema = rootSchema;
49+
this.isColumnId = isColumnId;
50+
this.typeFactory = typeFactory;
51+
this.specifications = Lists.newArrayList();
4252
}
4353

44-
public SchemaSpecManager(IrGraphSchema parent, SchemaSpec input) {
45-
this.parent = parent;
54+
public SchemaSpecManager(
55+
GraphSchema rootSchema,
56+
boolean isColumnId,
57+
RelDataTypeFactory typeFactory,
58+
SchemaSpec input) {
59+
this.rootSchema = rootSchema;
60+
this.isColumnId = isColumnId;
61+
this.typeFactory = typeFactory;
4662
this.specifications = Lists.newArrayList(input);
4763
}
4864

@@ -52,62 +68,103 @@ public SchemaSpec getSpec(SchemaSpec.Type type) {
5268
return spec;
5369
}
5470
}
55-
// if not exist, try to create a new JsonSpecification with content converted from others
5671
SchemaSpec newSpec;
57-
List<SchemaSpec.Type> existing = Lists.newArrayList();
58-
for (SchemaSpec spec : specifications) {
59-
if ((newSpec = convert(spec, type)) != null) {
60-
specifications.add(newSpec);
61-
return newSpec;
62-
}
63-
existing.add(spec.getType());
72+
switch (type) {
73+
case IR_CORE_IN_JSON:
74+
newSpec =
75+
new SchemaSpec(
76+
type, IrSchemaParser.getInstance().parse(rootSchema, isColumnId));
77+
break;
78+
case FLEX_IN_JSON:
79+
SchemaSpec yamlSpec = getSpec(SchemaSpec.Type.FLEX_IN_YAML);
80+
Preconditions.checkArgument(
81+
yamlSpec != null,
82+
"cannot get schema specification of type " + SchemaSpec.Type.FLEX_IN_YAML);
83+
Yaml yaml = new Yaml();
84+
Map yamlMap = yaml.load(yamlSpec.getContent());
85+
ObjectMapper mapper = new ObjectMapper();
86+
try {
87+
newSpec = new SchemaSpec(type, mapper.writeValueAsString(yamlMap));
88+
} catch (JsonProcessingException e) {
89+
throw new RuntimeException(e);
90+
}
91+
break;
92+
case FLEX_IN_YAML:
93+
default:
94+
newSpec = convertToFlex(rootSchema);
95+
break;
6496
}
65-
throw new IllegalArgumentException(
66-
"spec type ["
67-
+ type
68-
+ "] cannot be converted from any existing spec types "
69-
+ existing);
97+
this.specifications.add(newSpec);
98+
return newSpec;
7099
}
71100

72-
private @Nullable SchemaSpec convert(@Nullable SchemaSpec source, SchemaSpec.Type target) {
73-
try {
74-
if (source != null && source.getType() == target) {
75-
return source;
76-
}
77-
switch (target) {
78-
case IR_CORE_IN_JSON:
79-
return new SchemaSpec(
80-
target,
81-
IrSchemaParser.getInstance()
82-
.parse(parent.getGraphSchema(), parent.isColumnId()));
83-
case FLEX_IN_JSON:
84-
if (source != null && source.getType() == SchemaSpec.Type.FLEX_IN_YAML) {
85-
Yaml yaml = new Yaml();
86-
Map rootMap = yaml.load(source.getContent());
87-
ObjectMapper mapper = new ObjectMapper();
88-
return new SchemaSpec(target, mapper.writeValueAsString(rootMap));
89-
}
90-
// todo: convert from JSON in IR_CORE to JSON in FLEX
91-
return null;
92-
case FLEX_IN_YAML:
93-
default:
94-
if (source != null && source.getType() == SchemaSpec.Type.FLEX_IN_JSON) {
95-
ObjectMapper mapper = new ObjectMapper();
96-
JsonNode rootNode = mapper.readTree(source.getContent());
97-
Map rootMap = mapper.convertValue(rootNode, Map.class);
98-
Yaml yaml = new Yaml();
99-
return new SchemaSpec(target, yaml.dump(rootMap));
100-
}
101-
// todo: convert from JSON in IR_CORE to YAML in FlEX
102-
return null;
103-
}
104-
} catch (Exception e) {
105-
logger.warn(
106-
"can not convert from {} to {} due to some unexpected exception:",
107-
source == null ? null : source.getType(),
108-
target,
109-
e);
110-
return null;
101+
private SchemaSpec convertToFlex(GraphSchema schema) {
102+
List<Map> vertices =
103+
schema.getVertexList().stream()
104+
.map(this::convertVertex)
105+
.collect(Collectors.toList());
106+
List<Map> edges =
107+
schema.getEdgeList().stream().map(this::convertEdge).collect(Collectors.toList());
108+
Map<String, Object> flexMap =
109+
ImmutableMap.of(
110+
"schema", ImmutableMap.of("vertex_types", vertices, "edge_types", edges));
111+
Yaml yaml = new Yaml();
112+
return new SchemaSpec(SchemaSpec.Type.FLEX_IN_YAML, yaml.dump(flexMap));
113+
}
114+
115+
private Map<String, Object> convertVertex(GraphVertex vertex) {
116+
return ImmutableMap.of(
117+
"type_name", vertex.getLabel(),
118+
"type_id", vertex.getLabelId(),
119+
"properties",
120+
vertex.getPropertyList().stream()
121+
.map(this::convertProperty)
122+
.collect(Collectors.toList()),
123+
"primary_keys",
124+
vertex.getPrimaryKeyList().stream()
125+
.map(GraphProperty::getName)
126+
.collect(Collectors.toList()));
127+
}
128+
129+
private Map<String, Object> convertEdge(GraphEdge edge) {
130+
return ImmutableMap.of(
131+
"type_name", edge.getLabel(),
132+
"type_id", edge.getLabelId(),
133+
"vertex_type_pair_relations",
134+
edge.getRelationList().stream()
135+
.map(this::convertRelation)
136+
.collect(Collectors.toList()),
137+
"properties",
138+
edge.getPropertyList().stream()
139+
.map(this::convertProperty)
140+
.collect(Collectors.toList()),
141+
"primary_keys",
142+
edge.getPrimaryKeyList().stream()
143+
.map(GraphProperty::getName)
144+
.collect(Collectors.toList()));
145+
}
146+
147+
private Map<String, Object> convertRelation(EdgeRelation relation) {
148+
return ImmutableMap.of(
149+
"source_vertex", relation.getSource().getLabel(),
150+
"destination_vertex", relation.getTarget().getLabel());
151+
}
152+
153+
private Map<String, Object> convertProperty(GraphProperty property) {
154+
RelDataType propertyType;
155+
if (property instanceof IrGraphProperty) {
156+
propertyType = ((IrGraphProperty) property).getRelDataType();
157+
} else {
158+
propertyType =
159+
(new IrDataTypeConvertor.Groot(typeFactory, false))
160+
.convert(property.getDataType());
111161
}
162+
// convert property type to flex format
163+
IrDataTypeConvertor.Flex flexConvertor = new IrDataTypeConvertor.Flex(typeFactory, false);
164+
GSDataTypeDesc typeDesc = flexConvertor.convert(propertyType);
165+
return ImmutableMap.of(
166+
"property_id", property.getId(),
167+
"property_name", property.getName(),
168+
"property_type", typeDesc.getYamlDesc());
112169
}
113170
}

0 commit comments

Comments
 (0)