Skip to content

Commit

Permalink
[GIE Compiler] Support dynamic query params in cypher queries (#2874)
Browse files Browse the repository at this point in the history
<!--
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 #2713

---------

Co-authored-by: BingqingLyu <bingqing.lbq@alibaba-inc.com>
Co-authored-by: Longbin Lai <longbin.lailb@alibaba-inc.com>
  • Loading branch information
3 people committed Jun 14, 2023
1 parent ce3e16b commit a18836d
Show file tree
Hide file tree
Showing 28 changed files with 631 additions and 39 deletions.
6 changes: 5 additions & 1 deletion interactive_engine/compiler/src/main/antlr4/CypherGS.g4
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,12 @@ oC_Atom
| oC_Variable
| oC_FunctionInvocation
| oC_CountAny
| oC_Parameter
;

oC_Parameter
: '$' ( oC_SymbolicName ) ;

oC_CountAny
: ( COUNT SP? '(' SP? '*' SP? ')' )
;
Expand Down Expand Up @@ -367,7 +371,7 @@ oC_ListLiteral
: '[' SP? ( oC_Expression SP? ( ',' SP? oC_Expression SP? )* )? ']' ;

oC_MapLiteral
: '{' SP? ( oC_PropertyKeyName SP? ':' SP? oC_StringListNullPredicateExpression SP? ( ',' SP? oC_PropertyKeyName SP? ':' SP? oC_StringListNullPredicateExpression SP? )* )? '}' ;
: '{' SP? ( oC_PropertyKeyName SP? ':' SP? oC_Expression SP? ( ',' SP? oC_PropertyKeyName SP? ':' SP? oC_Expression SP? )* )? '}' ;

oC_PropertyKeyName
: oC_SchemaName ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.google.common.collect.ImmutableList;

import org.apache.calcite.plan.*;
import org.apache.calcite.plan.GraphOptCluster;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.rules.TransformationRule;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.rex;

import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexDynamicParam;

public class RexGraphDynamicParam extends RexDynamicParam {
private final String paramName;

public RexGraphDynamicParam(RelDataType type, String paramName, int index) {
super(type, index);
this.paramName = paramName;
}

@Override
public String getName() {
return paramName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@

package com.alibaba.graphscope.common.ir.rex;

import com.alibaba.graphscope.common.ir.runtime.proto.RexToProtoConverter;
import com.alibaba.graphscope.common.ir.type.GraphProperty;

import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexChecker;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexVisitor;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -81,12 +81,7 @@ public static RexGraphVariable of(

@Override
public <R> R accept(RexVisitor<R> rexVisitor) {
return (rexVisitor instanceof RexVariableAliasCollector
|| rexVisitor instanceof RexVariableAliasConverter
|| rexVisitor instanceof RexTmpVariableConverter
|| rexVisitor instanceof RexToProtoConverter)
? rexVisitor.visitInputRef(this)
: null;
return (rexVisitor instanceof RexChecker) ? null : rexVisitor.visitInputRef(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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.rex;

import com.alibaba.graphscope.common.ir.tools.GraphRexBuilder;

import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.*;

public class RexNodeTypeRefresher extends RexVisitorImpl<RexNode> {
private final RelDataType newType;
private final GraphRexBuilder rexBuilder;

public RexNodeTypeRefresher(RelDataType newType, GraphRexBuilder rexBuilder) {
super(false);
this.newType = newType;
this.rexBuilder = rexBuilder;
}

@Override
public RexNode visitCall(RexCall call) {
return call;
}

@Override
public RexNode visitLiteral(RexLiteral literal) {
return literal;
}

@Override
public RexNode visitInputRef(RexInputRef inputRef) {
return inputRef;
}

@Override
public RexNode visitDynamicParam(RexDynamicParam dynamicParam) {
if (dynamicParam instanceof RexGraphDynamicParam) {
return visitGraphDynamicParam((RexGraphDynamicParam) dynamicParam);
} else {
return dynamicParam;
}
}

private RexNode visitGraphDynamicParam(RexGraphDynamicParam graphDynamicParam) {
return rexBuilder.makeGraphDynamicParam(
newType, graphDynamicParam.getName(), graphDynamicParam.getIndex());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

// build from RexTmpVariable to RexGraphVariable
public class RexTmpVariableConverter extends RexVisitorImpl<RexNode> {
private GraphBuilder builder;
private final GraphBuilder builder;

public RexTmpVariableConverter(boolean deep, GraphBuilder builder) {
super(deep);
Expand Down Expand Up @@ -62,4 +62,9 @@ public RexNode visitTmpVariable(RexTmpVariable tmpVar) {
? builder.variable(tmpVar.getAlias())
: builder.variable(tmpVar.getAlias(), tmpVar.getProperty());
}

@Override
public RexNode visitDynamicParam(RexDynamicParam dynamicParam) {
return dynamicParam;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,9 @@ public List<R> visitInputRef(RexInputRef inputRef) {
public List<R> visitGraphVariable(RexGraphVariable variable) {
return ImmutableList.of(collectFunc.apply(variable));
}

@Override
public List<R> visitDynamicParam(RexDynamicParam dynamicParam) {
return ImmutableList.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,9 @@ public RexNode visitGraphVariable(RexGraphVariable variable) {
return RexGraphVariable.of(
targetAliasId, variable.getProperty(), targetVarName, variable.getType());
}

@Override
public RexNode visitDynamicParam(RexDynamicParam dynamicParam) {
return dynamicParam;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,22 @@ public OuterExpression.Expression visitLiteral(RexLiteral literal) {
.build())
.build();
}

@Override
public OuterExpression.Expression visitDynamicParam(RexDynamicParam dynamicParam) {
DataType.IrDataType paramDataType =
Utils.protoIrDataType(dynamicParam.getType(), isColumnId);
return OuterExpression.Expression.newBuilder()
.addOperators(
OuterExpression.ExprOpr.newBuilder()
.setParam(
OuterExpression.DynamicParam.newBuilder()
.setName(dynamicParam.getName())
.setIndex(dynamicParam.getIndex())
.setDataType(paramDataType)
.build())
.setNodeType(paramDataType)
.build())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

import static java.util.Objects.requireNonNull;

import com.alibaba.graphscope.common.ir.rel.*;
import com.alibaba.graphscope.common.ir.rel.GraphLogicalAggregate;
import com.alibaba.graphscope.common.ir.rel.GraphLogicalProject;
import com.alibaba.graphscope.common.ir.rel.GraphLogicalSort;
import com.alibaba.graphscope.common.ir.rel.graph.*;
import com.alibaba.graphscope.common.ir.rel.graph.match.GraphLogicalMultiMatch;
import com.alibaba.graphscope.common.ir.rel.graph.match.GraphLogicalSingleMatch;
Expand All @@ -41,7 +43,8 @@
import com.google.common.collect.Lists;

import org.apache.calcite.plan.*;
import org.apache.calcite.rel.*;
import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.core.Sort;
Expand Down Expand Up @@ -461,6 +464,7 @@ private RexNode call_(SqlOperator operator, List<RexNode> operandList) {
throw new UnsupportedOperationException(
"operator " + operator.getKind().name() + " not supported");
}
operandList = inferOperandTypes(operator, operandList);
RexCallBinding callBinding =
new RexCallBinding(getTypeFactory(), operator, operandList, ImmutableList.of());
// check count of operands, if fail throw exceptions
Expand All @@ -473,6 +477,28 @@ private RexNode call_(SqlOperator operator, List<RexNode> operandList) {
return builder.makeCall(type, operator, operandList);
}

private List<RexNode> inferOperandTypes(SqlOperator operator, List<RexNode> operandList) {
if (operator.getOperandTypeInference() != null
&& operandList.stream()
.anyMatch((t) -> t.getType().getSqlTypeName() == SqlTypeName.UNKNOWN)) {
RexCallBinding callBinding =
new RexCallBinding(getTypeFactory(), operator, operandList, ImmutableList.of());
RelDataType[] newTypes = callBinding.collectOperandTypes().toArray(new RelDataType[0]);
operator.getOperandTypeInference().inferOperandTypes(callBinding, null, newTypes);
List<RexNode> typeInferredOperands = new ArrayList<>(operandList.size());
GraphRexBuilder rexBuilder = (GraphRexBuilder) this.getRexBuilder();
for (int i = 0; i < operandList.size(); ++i) {
typeInferredOperands.add(
operandList
.get(i)
.accept(new RexNodeTypeRefresher(newTypes[i], rexBuilder)));
}
return typeInferredOperands;
} else {
return operandList;
}
}

private boolean isCurrentSupported(SqlOperator operator) {
SqlKind sqlKind = operator.getKind();
return sqlKind.belongsTo(SqlKind.BINARY_ARITHMETIC)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public GraphPlanner(Configs graphConfig) {
this.graphConfig = graphConfig;
this.plannerConfig = PlannerConfig.create(this.graphConfig);
this.optPlanner = createRelOptPlanner(this.plannerConfig);
this.rexBuilder = new RexBuilder(new JavaTypeFactoryImpl());
this.rexBuilder = new GraphRexBuilder(new JavaTypeFactoryImpl());
this.idGenerator = new AtomicLong(0l);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.tools;

import com.alibaba.graphscope.common.ir.rex.RexGraphDynamicParam;

import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexBuilder;

public class GraphRexBuilder extends RexBuilder {
public GraphRexBuilder(RelDataTypeFactory typeFactory) {
super(typeFactory);
}

public RexGraphDynamicParam makeGraphDynamicParam(String name, int index) {
return makeGraphDynamicParam(getTypeFactory().createUnknownType(), name, index);
}

public RexGraphDynamicParam makeGraphDynamicParam(
RelDataType dataType, String name, int index) {
return new RexGraphDynamicParam(dataType, name, index);
}
}
Loading

0 comments on commit a18836d

Please sign in to comment.