diff --git a/interactive_engine/compiler/src/main/antlr4/CypherGS.g4 b/interactive_engine/compiler/src/main/antlr4/CypherGS.g4 index f824138d9440..ce7dd9971d28 100644 --- a/interactive_engine/compiler/src/main/antlr4/CypherGS.g4 +++ b/interactive_engine/compiler/src/main/antlr4/CypherGS.g4 @@ -249,8 +249,12 @@ oC_Atom | oC_Variable | oC_FunctionInvocation | oC_CountAny + | oC_Parameter ; +oC_Parameter + : '$' ( oC_SymbolicName ) ; + oC_CountAny : ( COUNT SP? '(' SP? '*' SP? ')' ) ; @@ -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 ; diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/rules/FilterMatchRule.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/rules/FilterMatchRule.java index 4c95e3ec1273..e9ab4149a99d 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/rules/FilterMatchRule.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/planner/rules/FilterMatchRule.java @@ -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; diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexGraphDynamicParam.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexGraphDynamicParam.java new file mode 100644 index 000000000000..155f3ed76517 --- /dev/null +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexGraphDynamicParam.java @@ -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; + } +} diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexGraphVariable.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexGraphVariable.java index b76c566592c8..32dbcee71563 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexGraphVariable.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexGraphVariable.java @@ -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; @@ -81,12 +81,7 @@ public static RexGraphVariable of( @Override public R accept(RexVisitor 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 diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexNodeTypeRefresher.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexNodeTypeRefresher.java new file mode 100644 index 000000000000..458adb42abc6 --- /dev/null +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexNodeTypeRefresher.java @@ -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 { + 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()); + } +} diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexTmpVariableConverter.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexTmpVariableConverter.java index da69c1b42ac3..eab14c3f10ed 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexTmpVariableConverter.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexTmpVariableConverter.java @@ -25,7 +25,7 @@ // build from RexTmpVariable to RexGraphVariable public class RexTmpVariableConverter extends RexVisitorImpl { - private GraphBuilder builder; + private final GraphBuilder builder; public RexTmpVariableConverter(boolean deep, GraphBuilder builder) { super(deep); @@ -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; + } } diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexVariableAliasCollector.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexVariableAliasCollector.java index 369be7ceeb8c..3ee7546ea92d 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexVariableAliasCollector.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexVariableAliasCollector.java @@ -62,4 +62,9 @@ public List visitInputRef(RexInputRef inputRef) { public List visitGraphVariable(RexGraphVariable variable) { return ImmutableList.of(collectFunc.apply(variable)); } + + @Override + public List visitDynamicParam(RexDynamicParam dynamicParam) { + return ImmutableList.of(); + } } diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexVariableAliasConverter.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexVariableAliasConverter.java index 7fef83c97c9c..13de2b56fe62 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexVariableAliasConverter.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/rex/RexVariableAliasConverter.java @@ -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; + } } diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/runtime/proto/RexToProtoConverter.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/runtime/proto/RexToProtoConverter.java index 47ff08d06b30..8171e6c91a1e 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/runtime/proto/RexToProtoConverter.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/runtime/proto/RexToProtoConverter.java @@ -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(); + } } diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphBuilder.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphBuilder.java index f4afe62e95af..6a42b76908af 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphBuilder.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphBuilder.java @@ -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; @@ -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; @@ -461,6 +464,7 @@ private RexNode call_(SqlOperator operator, List 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 @@ -473,6 +477,28 @@ private RexNode call_(SqlOperator operator, List operandList) { return builder.makeCall(type, operator, operandList); } + private List inferOperandTypes(SqlOperator operator, List 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 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) diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphPlanner.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphPlanner.java index 3c35bc6eea9e..ea4d67e248aa 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphPlanner.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphPlanner.java @@ -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); } diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphRexBuilder.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphRexBuilder.java new file mode 100644 index 000000000000..593ccb25b675 --- /dev/null +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphRexBuilder.java @@ -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); + } +} diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphStdOperatorTable.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphStdOperatorTable.java index 2eff6386e2af..881634898d1d 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphStdOperatorTable.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/common/ir/tools/GraphStdOperatorTable.java @@ -19,9 +19,7 @@ import org.apache.calcite.sql.*; import org.apache.calcite.sql.fun.SqlMonotonicBinaryOperator; import org.apache.calcite.sql.fun.SqlStdOperatorTable; -import org.apache.calcite.sql.type.InferTypes; -import org.apache.calcite.sql.type.ReturnTypes; -import org.apache.calcite.sql.type.RexOperandTypes; +import org.apache.calcite.sql.type.*; /** * Extends {@link org.apache.calcite.sql.fun.SqlStdOperatorTable} to re-implement type checker/inference in some operators @@ -34,8 +32,8 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { 40, true, ReturnTypes.NULLABLE_SUM, - InferTypes.FIRST_KNOWN, - RexOperandTypes.PLUS_OPERATOR); + GraphInferTypes.FIRST_KNOWN, + GraphOperandTypes.PLUS_OPERATOR); public static final SqlBinaryOperator MINUS = new SqlMonotonicBinaryOperator( @@ -46,8 +44,8 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { // Same type inference strategy as sum ReturnTypes.NULLABLE_SUM, - InferTypes.FIRST_KNOWN, - RexOperandTypes.MINUS_OPERATOR); + GraphInferTypes.FIRST_KNOWN, + GraphOperandTypes.MINUS_OPERATOR); public static final SqlBinaryOperator MULTIPLY = new SqlMonotonicBinaryOperator( @@ -56,8 +54,8 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { 60, true, ReturnTypes.PRODUCT_NULLABLE, - InferTypes.FIRST_KNOWN, - RexOperandTypes.MULTIPLY_OPERATOR); + GraphInferTypes.FIRST_KNOWN, + GraphOperandTypes.MULTIPLY_OPERATOR); public static final SqlBinaryOperator DIVIDE = new SqlBinaryOperator( @@ -66,8 +64,8 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { 60, true, ReturnTypes.QUOTIENT_NULLABLE, - InferTypes.FIRST_KNOWN, - RexOperandTypes.DIVISION_OPERATOR); + GraphInferTypes.FIRST_KNOWN, + GraphOperandTypes.DIVISION_OPERATOR); public static final SqlFunction MOD = // Return type is same as divisor (2nd operand) @@ -77,7 +75,7 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { SqlKind.MOD, ReturnTypes.NULLABLE_MOD, null, - RexOperandTypes.EXACT_NUMERIC_EXACT_NUMERIC, + GraphOperandTypes.EXACT_NUMERIC_EXACT_NUMERIC, SqlFunctionCategory.NUMERIC); public static final SqlBinaryOperator AND = @@ -88,7 +86,7 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { true, ReturnTypes.BOOLEAN_NULLABLE_OPTIMIZED, InferTypes.BOOLEAN, - RexOperandTypes.BOOLEAN_BOOLEAN); + GraphOperandTypes.BOOLEAN_BOOLEAN); public static final SqlBinaryOperator OR = new SqlBinaryOperator( @@ -98,7 +96,7 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { true, ReturnTypes.BOOLEAN_NULLABLE_OPTIMIZED, InferTypes.BOOLEAN, - RexOperandTypes.BOOLEAN_BOOLEAN); + GraphOperandTypes.BOOLEAN_BOOLEAN); public static final SqlFunction POWER = new SqlFunction( @@ -106,7 +104,7 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { SqlKind.OTHER_FUNCTION, ReturnTypes.DOUBLE_NULLABLE, null, - RexOperandTypes.NUMERIC_NUMERIC, + GraphOperandTypes.NUMERIC_NUMERIC, SqlFunctionCategory.NUMERIC); public static final SqlPrefixOperator UNARY_MINUS = @@ -116,5 +114,65 @@ public class GraphStdOperatorTable extends SqlStdOperatorTable { 80, ReturnTypes.ARG0, InferTypes.RETURN_TYPE, - RexOperandTypes.NUMERIC_OR_INTERVAL); + GraphOperandTypes.NUMERIC_OR_INTERVAL); + + public static final SqlBinaryOperator EQUALS = + new SqlBinaryOperator( + "=", + SqlKind.EQUALS, + 30, + true, + ReturnTypes.BOOLEAN_NULLABLE, + GraphInferTypes.FIRST_KNOWN, + OperandTypes.COMPARABLE_UNORDERED_COMPARABLE_UNORDERED); + + public static final SqlBinaryOperator NOT_EQUALS = + new SqlBinaryOperator( + "<>", + SqlKind.NOT_EQUALS, + 30, + true, + ReturnTypes.BOOLEAN_NULLABLE, + GraphInferTypes.FIRST_KNOWN, + OperandTypes.COMPARABLE_UNORDERED_COMPARABLE_UNORDERED); + + public static final SqlBinaryOperator GREATER_THAN = + new SqlBinaryOperator( + ">", + SqlKind.GREATER_THAN, + 30, + true, + ReturnTypes.BOOLEAN_NULLABLE, + GraphInferTypes.FIRST_KNOWN, + OperandTypes.COMPARABLE_ORDERED_COMPARABLE_ORDERED); + + public static final SqlBinaryOperator GREATER_THAN_OR_EQUAL = + new SqlBinaryOperator( + ">=", + SqlKind.GREATER_THAN_OR_EQUAL, + 30, + true, + ReturnTypes.BOOLEAN_NULLABLE, + GraphInferTypes.FIRST_KNOWN, + OperandTypes.COMPARABLE_ORDERED_COMPARABLE_ORDERED); + + public static final SqlBinaryOperator LESS_THAN = + new SqlBinaryOperator( + "<", + SqlKind.LESS_THAN, + 30, + true, + ReturnTypes.BOOLEAN_NULLABLE, + GraphInferTypes.FIRST_KNOWN, + OperandTypes.COMPARABLE_ORDERED_COMPARABLE_ORDERED); + + public static final SqlBinaryOperator LESS_THAN_OR_EQUAL = + new SqlBinaryOperator( + "<=", + SqlKind.LESS_THAN_OR_EQUAL, + 30, + true, + ReturnTypes.BOOLEAN_NULLABLE, + GraphInferTypes.FIRST_KNOWN, + OperandTypes.COMPARABLE_ORDERED_COMPARABLE_ORDERED); } diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/cypher/antlr4/visitor/ExpressionVisitor.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/cypher/antlr4/visitor/ExpressionVisitor.java index 6bd05ca81d72..74f8de90c716 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/cypher/antlr4/visitor/ExpressionVisitor.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/cypher/antlr4/visitor/ExpressionVisitor.java @@ -18,7 +18,9 @@ import com.alibaba.graphscope.common.ir.rel.type.group.GraphAggCall; import com.alibaba.graphscope.common.ir.rex.RexTmpVariable; +import com.alibaba.graphscope.common.ir.tools.AliasIdGenerator; import com.alibaba.graphscope.common.ir.tools.GraphBuilder; +import com.alibaba.graphscope.common.ir.tools.GraphRexBuilder; import com.alibaba.graphscope.common.ir.tools.GraphStdOperatorTable; import com.alibaba.graphscope.cypher.antlr4.visitor.type.ExprVisitorResult; import com.alibaba.graphscope.grammar.CypherGSBaseVisitor; @@ -30,16 +32,20 @@ import org.apache.calcite.tools.RelBuilder; import org.apache.commons.lang3.ObjectUtils; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; public class ExpressionVisitor extends CypherGSBaseVisitor { private final GraphBuilderVisitor parent; private final GraphBuilder builder; + private final AliasIdGenerator paramIdGenerator; public ExpressionVisitor(GraphBuilderVisitor parent) { this.parent = parent; this.builder = Objects.requireNonNull(parent).getGraphBuilder(); + this.paramIdGenerator = new AliasIdGenerator(); } @Override @@ -184,6 +190,14 @@ public ExprVisitorResult visitOC_Literal(CypherGSParser.OC_LiteralContext ctx) { } } + @Override + public ExprVisitorResult visitOC_Parameter(CypherGSParser.OC_ParameterContext ctx) { + String paramName = ctx.oC_SymbolicName().getText(); + int paramIndex = this.paramIdGenerator.generate(paramName); + GraphRexBuilder rexBuilder = (GraphRexBuilder) builder.getRexBuilder(); + return new ExprVisitorResult(rexBuilder.makeGraphDynamicParam(paramName, paramIndex)); + } + @Override public ExprVisitorResult visitOC_BooleanLiteral(CypherGSParser.OC_BooleanLiteralContext ctx) { return new ExprVisitorResult( diff --git a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/cypher/antlr4/visitor/Utils.java b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/cypher/antlr4/visitor/Utils.java index e559a75d6dd3..8a9715073ead 100644 --- a/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/cypher/antlr4/visitor/Utils.java +++ b/interactive_engine/compiler/src/main/java/com/alibaba/graphscope/cypher/antlr4/visitor/Utils.java @@ -175,8 +175,7 @@ public static final List propertyFilters( GraphStdOperatorTable.EQUALS, variable, expressionVisitor - .visitOC_StringListNullPredicateExpression( - mapCtx.oC_StringListNullPredicateExpression(i)) + .visitOC_Expression(mapCtx.oC_Expression(i)) .getExpr())); } return filters; diff --git a/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/RexFamilyOperandTypeChecker.java b/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphFamilyOperandTypeChecker.java similarity index 98% rename from interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/RexFamilyOperandTypeChecker.java rename to interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphFamilyOperandTypeChecker.java index f2e98d38762c..23c751314ef7 100644 --- a/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/RexFamilyOperandTypeChecker.java +++ b/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphFamilyOperandTypeChecker.java @@ -34,8 +34,8 @@ * The constructor of {@code FamilyOperandTypeChecker} is protected, To inherit from it, * we have to make the subclass under the same package {@code org.apache.calcite.sql.type} */ -public class RexFamilyOperandTypeChecker extends FamilyOperandTypeChecker { - protected RexFamilyOperandTypeChecker( +public class GraphFamilyOperandTypeChecker extends FamilyOperandTypeChecker { + protected GraphFamilyOperandTypeChecker( List families, Predicate optional) { super(families, optional); } diff --git a/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphInferTypes.java b/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphInferTypes.java new file mode 100644 index 000000000000..8b841b13848e --- /dev/null +++ b/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphInferTypes.java @@ -0,0 +1,47 @@ +/* + * 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 org.apache.calcite.sql.type; + +import com.alibaba.graphscope.common.ir.rex.RexCallBinding; +import com.google.common.base.Preconditions; + +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rex.RexNode; + +import java.util.Arrays; + +public abstract class GraphInferTypes { + private GraphInferTypes() {} + + /** + * Operand type-inference strategy where an unknown operand type is derived + * from the first operand with a known type. + */ + public static final SqlOperandTypeInference FIRST_KNOWN = + (callBinding, returnType, operandTypes) -> { + Preconditions.checkArgument(callBinding instanceof RexCallBinding); + RelDataType unknownType = callBinding.getTypeFactory().createUnknownType(); + RelDataType knownType = unknownType; + for (RexNode rexNode : ((RexCallBinding) callBinding).getRexOperands()) { + knownType = rexNode.getType(); + if (!knownType.equals(unknownType)) { + break; + } + } + Arrays.fill(operandTypes, knownType); + }; +} diff --git a/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphOperandMetaDataImpl.java b/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphOperandMetaDataImpl.java new file mode 100644 index 000000000000..6e7f20874a19 --- /dev/null +++ b/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphOperandMetaDataImpl.java @@ -0,0 +1,58 @@ +/* + * 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 org.apache.calcite.sql.type; + +import org.apache.calcite.linq4j.function.Functions; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; + +import java.util.List; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.Predicate; + +public class GraphOperandMetaDataImpl extends GraphFamilyOperandTypeChecker + implements SqlOperandMetadata { + private final Function> paramTypesFactory; + private final IntFunction paramNameFn; + + GraphOperandMetaDataImpl( + List families, + Function> paramTypesFactory, + IntFunction paramNameFn, + Predicate optional) { + super(families, optional); + this.paramTypesFactory = Objects.requireNonNull(paramTypesFactory, "paramTypesFactory"); + this.paramNameFn = paramNameFn; + } + + @Override + public boolean isFixedParameters() { + return true; + } + + @Override + public List paramTypes(RelDataTypeFactory typeFactory) { + return (List) this.paramTypesFactory.apply(typeFactory); + } + + @Override + public List paramNames() { + return Functions.generate(this.families.size(), this.paramNameFn); + } +} diff --git a/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/RexOperandTypes.java b/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphOperandTypes.java similarity index 82% rename from interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/RexOperandTypes.java rename to interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphOperandTypes.java index 644839ff2a99..0499b4c7a8b5 100644 --- a/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/RexOperandTypes.java +++ b/interactive_engine/compiler/src/main/java/org/apache/calcite/sql/type/GraphOperandTypes.java @@ -18,12 +18,20 @@ import com.google.common.collect.ImmutableList; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; + +import java.util.List; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.Predicate; + /** * Similar to {@link OperandTypes}, but we rewrite some {@link SqlOperandTypeChecker} * to create validation functions based on {@link org.apache.calcite.rex.RexNode}, * Meanwhile, we re-use functions from {@link OperandTypes} as much as possible */ -public abstract class RexOperandTypes { +public abstract class GraphOperandTypes { public static final SqlSingleOperandTypeChecker NUMERIC_NUMERIC = family(SqlTypeFamily.NUMERIC, SqlTypeFamily.NUMERIC); @@ -65,7 +73,7 @@ public abstract class RexOperandTypes { * @return */ public static FamilyOperandTypeChecker family(SqlTypeFamily... families) { - return new RexFamilyOperandTypeChecker(ImmutableList.copyOf(families), i -> false); + return new GraphFamilyOperandTypeChecker(ImmutableList.copyOf(families), i -> false); } public static final SqlSingleOperandTypeChecker PLUS_OPERATOR = @@ -80,4 +88,12 @@ public static FamilyOperandTypeChecker family(SqlTypeFamily... families) { public static final SqlSingleOperandTypeChecker DIVISION_OPERATOR = OperandTypes.or(NUMERIC_NUMERIC, INTERVAL_NUMERIC); + + public static SqlOperandMetadata operandMetadata( + List families, + Function> typesFactory, + IntFunction operandName, + Predicate optional) { + return new GraphOperandMetaDataImpl(families, typesFactory, operandName, optional); + } } diff --git a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/FilterTest.java b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/FilterTest.java index 7c54581b3675..249de44a5756 100644 --- a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/FilterTest.java +++ b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/FilterTest.java @@ -17,6 +17,7 @@ package com.alibaba.graphscope.common.ir; import com.alibaba.graphscope.common.ir.tools.GraphBuilder; +import com.alibaba.graphscope.common.ir.tools.GraphRexBuilder; import com.alibaba.graphscope.common.ir.tools.GraphStdOperatorTable; import com.alibaba.graphscope.common.ir.tools.config.GraphOpt; import com.alibaba.graphscope.common.ir.tools.config.LabelConfig; @@ -24,7 +25,9 @@ import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.logical.LogicalValues; +import org.apache.calcite.rex.RexCall; import org.apache.calcite.rex.RexNode; +import org.apache.calcite.sql.type.SqlTypeName; import org.junit.Assert; import org.junit.Test; @@ -165,6 +168,25 @@ public void greater_4_test() { filter.explain().trim()); } + // Match (:person {age > $age}) + @Test + public void greater_5_test() { + GraphBuilder builder = Utils.mockGraphBuilder(); + SourceConfig sourceConfig = + new SourceConfig(GraphOpt.Source.VERTEX, new LabelConfig(false).addLabel("person")); + RexCall greater = + (RexCall) + builder.source(sourceConfig) + .call( + GraphStdOperatorTable.GREATER_THAN, + builder.variable(null, "age"), + ((GraphRexBuilder) builder.getRexBuilder()) + .makeGraphDynamicParam("age", 0)); + Assert.assertEquals(">(DEFAULT.age, ?0)", greater.toString()); + Assert.assertEquals( + SqlTypeName.INTEGER, greater.getOperands().get(1).getType().getSqlTypeName()); + } + // g.V().hasLabel("person").where(expr("@.age > 20 and @.name == marko")) @Test public void and_1_test() { diff --git a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/Utils.java b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/Utils.java index d0ef86d7ce97..1cdf0f8b21be 100644 --- a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/Utils.java +++ b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/Utils.java @@ -20,6 +20,7 @@ import com.alibaba.graphscope.common.config.GraphConfig; import com.alibaba.graphscope.common.ir.schema.GraphOptSchema; import com.alibaba.graphscope.common.ir.tools.GraphBuilder; +import com.alibaba.graphscope.common.ir.tools.GraphRexBuilder; import com.alibaba.graphscope.common.store.ExperimentalMetaFetcher; import com.alibaba.graphscope.common.store.IrMeta; import com.google.common.collect.ImmutableMap; @@ -38,7 +39,7 @@ public class Utils { public static final RelDataTypeFactory typeFactory = new JavaTypeFactoryImpl(); - public static final RexBuilder rexBuilder = new RexBuilder(typeFactory); + public static final RexBuilder rexBuilder = new GraphRexBuilder(typeFactory); public static final IrMeta schemaMeta = mockSchemaMeta(); public static final GraphBuilder mockGraphBuilder() { diff --git a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/runtime/FfiLogicalPlanTest.java b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/runtime/FfiLogicalPlanTest.java index 1b1e0e85cdbc..462c4ee874ab 100644 --- a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/runtime/FfiLogicalPlanTest.java +++ b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/common/ir/runtime/FfiLogicalPlanTest.java @@ -20,6 +20,7 @@ import com.alibaba.graphscope.common.ir.Utils; import com.alibaba.graphscope.common.ir.runtime.ffi.FfiPhysicalBuilder; import com.alibaba.graphscope.common.ir.tools.GraphBuilder; +import com.alibaba.graphscope.common.ir.tools.GraphRexBuilder; import com.alibaba.graphscope.common.ir.tools.GraphStdOperatorTable; import com.alibaba.graphscope.common.ir.tools.LogicalPlan; import com.alibaba.graphscope.common.ir.tools.config.*; @@ -33,7 +34,7 @@ public class FfiLogicalPlanTest { // Match (x:person)-[:knows*1..3]->(:person {age: 10}) @Test - public void logical_plan_test() throws Exception { + public void logical_plan_1_test() throws Exception { GraphBuilder builder = Utils.mockGraphBuilder(); PathExpandConfig.Builder pxdBuilder = PathExpandConfig.newBuilder(builder); GetVConfig getVConfig = @@ -89,7 +90,38 @@ public void logical_plan_test() throws Exception { Utils.schemaMeta, new LogicalPlan(aggregate, false))) { Assert.assertEquals( - FileUtils.readJsonFromResource("ffi_logical_plan.json"), ffiBuilder.explain()); + FileUtils.readJsonFromResource("ffi_logical_plan_1.json"), + ffiBuilder.explain()); + } + } + + // Match (x:person) where x.age = $age + @Test + public void logical_plan_2_test() throws Exception { + GraphBuilder builder = Utils.mockGraphBuilder(); + RelNode filter = + builder.source( + new SourceConfig( + GraphOpt.Source.VERTEX, + new LabelConfig(false).addLabel("person"), + "x")) + .filter( + builder.call( + GraphStdOperatorTable.EQUALS, + builder.variable("x", "age"), + ((GraphRexBuilder) builder.getRexBuilder()) + .makeGraphDynamicParam("age", 0))) + .build(); + Assert.assertEquals( + "GraphLogicalSource(tableConfig=[{isAll=false, tables=[person]}], alias=[x]," + + " fusedFilter=[[=(DEFAULT.age, ?0)]], opt=[VERTEX])", + filter.explain().trim()); + try (PhysicalBuilder ffiBuilder = + new FfiPhysicalBuilder( + getMockGraphConfig(), Utils.schemaMeta, new LogicalPlan(filter, false))) { + Assert.assertEquals( + FileUtils.readJsonFromResource("ffi_logical_plan_2.json"), + ffiBuilder.explain()); } } diff --git a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/cypher/antlr4/MatchTest.java b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/cypher/antlr4/MatchTest.java index b0580e7b2237..e58a03df404f 100644 --- a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/cypher/antlr4/MatchTest.java +++ b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/cypher/antlr4/MatchTest.java @@ -99,4 +99,14 @@ public void match_4_test() { + "], matchOpt=[INNER])", match.explain().trim()); } + + @Test + public void match_5_test() { + RelNode match = Utils.eval("Match (n:person {age: $age}) Return n").build(); + Assert.assertEquals( + "GraphLogicalProject(n=[n], isAppend=[false])\n" + + " GraphLogicalSource(tableConfig=[{isAll=false, tables=[person]}]," + + " alias=[n], fusedFilter=[[=(DEFAULT.age, ?0)]], opt=[VERTEX])", + match.explain().trim()); + } } diff --git a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/cypher/antlr4/WhereTest.java b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/cypher/antlr4/WhereTest.java index ee0c46f16109..7d9b5d432b60 100644 --- a/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/cypher/antlr4/WhereTest.java +++ b/interactive_engine/compiler/src/test/java/com/alibaba/graphscope/cypher/antlr4/WhereTest.java @@ -58,4 +58,38 @@ public void where_2_test() { + " 1), 29), =(DEFAULT.name, 'marko')))]], opt=[VERTEX])", where.explain().trim()); } + + @Test + public void where_3_test() { + RelNode where = + Utils.eval("Match (n:person) Where n.name = $name1 or n.name = $name2 Return n") + .build(); + Assert.assertEquals( + "GraphLogicalProject(n=[n], isAppend=[false])\n" + + " GraphLogicalSource(tableConfig=[{isAll=false, tables=[person]}]," + + " alias=[n], fusedFilter=[[OR(=(DEFAULT.name, ?0), =(DEFAULT.name, ?1))]]," + + " opt=[VERTEX])", + where.explain().trim()); + } + + @Test + public void where_4_test() { + RelNode where = + Utils.eval( + "Match (n:person)-[]-(m:person) Where n.name = $name and m.name =" + + " $name Return n") + .build(); + Assert.assertEquals( + "GraphLogicalProject(n=[n], isAppend=[false])\n" + + " LogicalFilter(condition=[AND(=(n.name, ?0), =(m.name, ?0))])\n" + + " GraphLogicalSingleMatch(input=[null]," + + " sentence=[GraphLogicalGetV(tableConfig=[{isAll=false, tables=[person]}]," + + " alias=[m], opt=[OTHER])\n" + + " GraphLogicalExpand(tableConfig=[{isAll=true, tables=[created, knows]}]," + + " alias=[DEFAULT], opt=[BOTH])\n" + + " GraphLogicalSource(tableConfig=[{isAll=false, tables=[person]}]," + + " alias=[n], opt=[VERTEX])\n" + + "], matchOpt=[INNER])", + where.explain().trim()); + } } diff --git a/interactive_engine/compiler/src/test/resources/ffi_logical_plan.json b/interactive_engine/compiler/src/test/resources/ffi_logical_plan_1.json similarity index 100% rename from interactive_engine/compiler/src/test/resources/ffi_logical_plan.json rename to interactive_engine/compiler/src/test/resources/ffi_logical_plan_1.json diff --git a/interactive_engine/compiler/src/test/resources/ffi_logical_plan_2.json b/interactive_engine/compiler/src/test/resources/ffi_logical_plan_2.json new file mode 100644 index 000000000000..f3c197fdddf2 --- /dev/null +++ b/interactive_engine/compiler/src/test/resources/ffi_logical_plan_2.json @@ -0,0 +1,96 @@ +{ + "nodes": [ + { + "opr": { + "opr": { + "Scan": { + "scan_opt": 0, + "alias": { + "item": { + "Id": 0 + } + }, + "params": { + "tables": [ + { + "item": { + "Id": 0 + } + } + ], + "columns": [], + "is_all_columns": false, + "limit": null, + "predicate": { + "operators": [ + { + "node_type": { + "type": { + "DataType": 1 + } + }, + "item": { + "Var": { + "tag": null, + "property": { + "item": { + "Key": { + "item": { + "Name": "age" + } + } + } + }, + "node_type": { + "type": { + "DataType": 1 + } + } + } + } + }, + { + "node_type": { + "type": { + "DataType": 0 + } + }, + "item": { + "Logical": 0 + } + }, + { + "node_type": { + "type": { + "DataType": 1 + } + }, + "item": { + "Param": { + "name": "age", + "index": 0, + "data_type": { + "type": { + "DataType": 1 + } + } + } + } + } + ] + }, + "sample_ratio": 1.0, + "extra": {} + }, + "idx_predicate": null, + "meta_data": null + } + } + }, + "children": [] + } + ], + "roots": [ + 0 + ] +} diff --git a/interactive_engine/executor/ir/graph_proxy/src/utils/expr/eval_pred.rs b/interactive_engine/executor/ir/graph_proxy/src/utils/expr/eval_pred.rs index 0b59b73f1a14..578860ddb454 100644 --- a/interactive_engine/executor/ir/graph_proxy/src/utils/expr/eval_pred.rs +++ b/interactive_engine/executor/ir/graph_proxy/src/utils/expr/eval_pred.rs @@ -466,6 +466,9 @@ fn process_predicates( } } Item::Arith(_) => return Ok(None), + Item::Param(param) => { + return Err(ExprError::Unsupported(format!("Dynamic Param {:?}", param))) + } } } } diff --git a/interactive_engine/executor/ir/proto/expr.proto b/interactive_engine/executor/ir/proto/expr.proto index dac8974d3b5c..7f33993f0e29 100644 --- a/interactive_engine/executor/ir/proto/expr.proto +++ b/interactive_engine/executor/ir/proto/expr.proto @@ -117,6 +117,13 @@ message VariableKeys { repeated Variable keys = 1; } +// dynamic param +message DynamicParam { + string name = 1; + int32 index = 2; + common.IrDataType data_type = 3; +} + // An operator of expression is one of Logical, Arithmetic, Const and Variable. message ExprOpr { enum Brace { @@ -131,9 +138,11 @@ message ExprOpr { Brace brace = 6; VariableKeys vars = 7; VariableKeys var_map = 8; + // dynamic param in expression + DynamicParam param = 9; } // The data of type of ExprOpr - common.IrDataType node_type = 9; + common.IrDataType node_type = 10; } // An inner representation of an expression