Skip to content

Commit

Permalink
[GAIA Compiler] Build algebra layer structures for graph operators (#…
Browse files Browse the repository at this point in the history
…2438)

<!--
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. build algebra layer structures for graph operators :
Source/Expand/GetV/PathExpand/Match
2. introduce interfaces and implementations for fetching schema (under
package of `com.alibaba.graphscope.common.ir.schema`)
3. introduce data types to denote vertex or edge (under package of
`com.alibaba.graphscope.common.ir.type`)
<!-- 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
  • Loading branch information
shirly121 committed Feb 24, 2023
1 parent 8987649 commit 675dc4b
Show file tree
Hide file tree
Showing 25 changed files with 2,516 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* Copyright 2020 Alibaba Group Holding Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.graphscope.common.ir.rel.graph;

import com.alibaba.graphscope.common.ir.rel.type.TableConfig;
import com.alibaba.graphscope.common.ir.type.GraphSchemaType;
import com.alibaba.graphscope.common.ir.type.GraphSchemaTypeList;
import com.google.common.collect.ImmutableList;

import org.apache.calcite.plan.GraphOptCluster;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFieldImpl;
import org.apache.calcite.rel.type.RelRecordType;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableIntList;
import org.apache.commons.lang3.ObjectUtils;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
* A basic structure of graph operators
*/
public abstract class AbstractBindableTableScan extends TableScan {
// for filter fusion
protected ImmutableList<RexNode> filters;
// for field trimmer
protected ImmutableIntList project;

protected @Nullable RelNode input;

protected TableConfig tableConfig;

protected AbstractBindableTableScan(
GraphOptCluster cluster,
List<RelHint> hints,
@Nullable RelNode input,
TableConfig tableConfig) {
super(
cluster,
RelTraitSet.createEmpty(),
hints,
(tableConfig == null || ObjectUtils.isEmpty(tableConfig.getTables()))
? null
: tableConfig.getTables().get(0));
this.input = input;
this.tableConfig = Objects.requireNonNull(tableConfig);
}

protected AbstractBindableTableScan(
GraphOptCluster cluster, List<RelHint> hints, TableConfig tableConfig) {
this(cluster, hints, null, tableConfig);
}

@Override
public RelDataType deriveRowType() {
List<GraphSchemaType> tableTypes = new ArrayList<>();
List<RelOptTable> tables = ObjectUtils.requireNonEmpty(this.tableConfig.getTables());
for (RelOptTable table : tables) {
GraphSchemaType type = (GraphSchemaType) table.getRowType();
// flat fuzzy labels to the list
if (type instanceof GraphSchemaTypeList) {
tableTypes.addAll((GraphSchemaTypeList) type);
} else {
tableTypes.add(type);
}
}
ObjectUtils.requireNonEmpty(tableTypes);
GraphSchemaType graphType =
(tableTypes.size() == 1)
? tableTypes.get(0)
: GraphSchemaTypeList.create(tableTypes);
RelRecordType rowType =
new RelRecordType(
ImmutableList.of(
new RelDataTypeFieldImpl(getAliasName(), getAliasId(), graphType)));
return rowType;
}

public String getAliasName() {
Objects.requireNonNull(hints);
if (hints.size() < 2) {
throw new IllegalArgumentException(
"should have put alias config in the index 1 of the hints list");
}
RelHint aliasHint = hints.get(1);
Objects.requireNonNull(aliasHint.kvOptions);
String aliasName = aliasHint.kvOptions.get("name");
Objects.requireNonNull(aliasName);
return aliasName;
}

public int getAliasId() {
Objects.requireNonNull(hints);
if (hints.size() < 2) {
throw new IllegalArgumentException(
"should have put alias config in the index 1 of the hints list");
}
RelHint aliasHint = hints.get(1);
Objects.requireNonNull(aliasHint.kvOptions);
String aliasId = aliasHint.kvOptions.get("id");
Objects.requireNonNull(aliasId);
return Integer.valueOf(aliasId);
}

// toString

@Override
public RelWriter explainTerms(RelWriter pw) {
return pw.itemIf("input", input, !Objects.isNull(input))
.item("tableConfig", tableConfig)
.item("alias", getAliasName())
.itemIf("fusedProject", project, !ObjectUtils.isEmpty(project))
.itemIf("fusedFilter", filters, !ObjectUtils.isEmpty(filters));
}

@Override
public List<RelNode> getInputs() {
return this.input == null ? ImmutableList.of() : ImmutableList.of(this.input);
}

public void setFilters(ImmutableList<RexNode> filters) {
this.filters = filters;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2020 Alibaba Group Holding Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.graphscope.common.ir.rel.graph;

import com.alibaba.graphscope.common.ir.rel.type.TableConfig;
import com.alibaba.graphscope.common.ir.tools.config.GraphOpt;

import org.apache.calcite.plan.GraphOptCluster;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.hint.RelHint;
import org.apache.commons.lang3.ObjectUtils;

import java.util.List;

public class GraphLogicalExpand extends AbstractBindableTableScan {
private GraphOpt.Expand opt;

protected GraphLogicalExpand(
GraphOptCluster cluster, List<RelHint> hints, RelNode input, TableConfig tableConfig) {
super(cluster, hints, input, tableConfig);
this.opt = directionOpt();
}

public static GraphLogicalExpand create(
GraphOptCluster cluster, List<RelHint> hints, RelNode input, TableConfig tableConfig) {
return new GraphLogicalExpand(cluster, hints, input, tableConfig);
}

private GraphOpt.Expand directionOpt() {
ObjectUtils.requireNonEmpty(hints);
RelHint optHint = hints.get(0);
ObjectUtils.requireNonEmpty(optHint.listOptions);
return GraphOpt.Expand.valueOf(optHint.listOptions.get(0));
}

public GraphOpt.Expand getOpt() {
return opt;
}

@Override
public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw).item("opt", opt);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2020 Alibaba Group Holding Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.graphscope.common.ir.rel.graph;

import com.alibaba.graphscope.common.ir.rel.type.TableConfig;
import com.alibaba.graphscope.common.ir.tools.config.GraphOpt;

import org.apache.calcite.plan.GraphOptCluster;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.hint.RelHint;
import org.apache.commons.lang3.ObjectUtils;

import java.util.List;

public class GraphLogicalGetV extends AbstractBindableTableScan {
private GraphOpt.GetV opt;

protected GraphLogicalGetV(
GraphOptCluster cluster, List<RelHint> hints, RelNode input, TableConfig tableConfig) {
super(cluster, hints, input, tableConfig);
this.opt = getVOpt();
}

public static GraphLogicalGetV create(
GraphOptCluster cluster, List<RelHint> hints, RelNode input, TableConfig tableConfig) {
return new GraphLogicalGetV(cluster, hints, input, tableConfig);
}

private GraphOpt.GetV getVOpt() {
ObjectUtils.requireNonEmpty(hints);
RelHint optHint = hints.get(0);
ObjectUtils.requireNonEmpty(optHint.listOptions);
return GraphOpt.GetV.valueOf(optHint.listOptions.get(0));
}

public GraphOpt.GetV getOpt() {
return opt;
}

@Override
public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw).item("opt", opt);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright 2020 Alibaba Group Holding Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.graphscope.common.ir.rel.graph;

import com.alibaba.graphscope.common.ir.tools.config.GraphOpt;

import org.apache.calcite.plan.GraphOptCluster;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.SingleRel;
import org.apache.calcite.rel.hint.RelHint;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexNode;
import org.apache.commons.lang3.ObjectUtils;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.List;
import java.util.Objects;

public class GraphLogicalPathExpand extends SingleRel {
private final RelNode expand;
private final RelNode getV;

public final @Nullable RexNode offset;
public final @Nullable RexNode fetch;

private final List<RelHint> hints;

protected GraphLogicalPathExpand(
GraphOptCluster cluster,
@Nullable List<RelHint> hints,
RelNode input,
RelNode expand,
RelNode getV,
@Nullable RexNode offset,
@Nullable RexNode fetch) {
super(cluster, RelTraitSet.createEmpty(), input);
this.hints = hints;
this.expand = Objects.requireNonNull(expand);
this.getV = Objects.requireNonNull(getV);
this.offset = offset;
this.fetch = fetch;
}

public static GraphLogicalPathExpand create(
GraphOptCluster cluster,
List<RelHint> hints,
RelNode input,
RelNode expand,
RelNode getV,
@Nullable RexNode offset,
@Nullable RexNode fetch) {
return new GraphLogicalPathExpand(cluster, hints, input, expand, getV, offset, fetch);
}

@Override
public RelDataType deriveRowType() {
return getV.getRowType();
}

@Override
public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw)
.item("expand", RelOptUtil.toString(expand))
.item("getV", RelOptUtil.toString(getV))
.itemIf("offset", offset, offset != null)
.itemIf("fetch", fetch, fetch != null)
.item("path_opt", pathOpt())
.item("result_opt", resultOpt())
.item("alias", getAliasName());
}

public String getAliasName() {
Objects.requireNonNull(hints);
if (hints.size() < 2) {
throw new IllegalArgumentException(
"should have put alias config in the index 1 of the hints list");
}
RelHint aliasHint = hints.get(1);
Objects.requireNonNull(aliasHint.kvOptions);
String aliasName = aliasHint.kvOptions.get("name");
Objects.requireNonNull(aliasName);
return aliasName;
}

public int getAliasId() {
Objects.requireNonNull(hints);
if (hints.size() < 2) {
throw new IllegalArgumentException(
"should have put alias config in the index 1 of the hints list");
}
RelHint aliasHint = hints.get(1);
Objects.requireNonNull(aliasHint.kvOptions);
String aliasId = aliasHint.kvOptions.get("id");
Objects.requireNonNull(aliasId);
return Integer.valueOf(aliasId);
}

private GraphOpt.PathExpandPath pathOpt() {
ObjectUtils.requireNonEmpty(hints);
RelHint optHint = hints.get(0);
ObjectUtils.requireNonEmpty(optHint.kvOptions);
return GraphOpt.PathExpandPath.valueOf(optHint.kvOptions.get("path"));
}

private GraphOpt.PathExpandResult resultOpt() {
ObjectUtils.requireNonEmpty(hints);
RelHint optHint = hints.get(0);
ObjectUtils.requireNonEmpty(optHint.kvOptions);
return GraphOpt.PathExpandResult.valueOf(optHint.kvOptions.get("result"));
}
}

0 comments on commit 675dc4b

Please sign in to comment.