Search in sources :

Example 81 with Pair

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.Pair in project beam by apache.

the class BeamIOPushDownRule method onMatch.

// ~ Methods ----------------------------------------------------------------
@Override
public void onMatch(RelOptRuleCall call) {
    final BeamIOSourceRel ioSourceRel = call.rel(1);
    final BeamSqlTable beamSqlTable = ioSourceRel.getBeamSqlTable();
    if (ioSourceRel instanceof BeamPushDownIOSourceRel) {
        return;
    }
    // Nested rows are not supported at the moment
    for (RelDataTypeField field : ioSourceRel.getRowType().getFieldList()) {
        if (field.getType() instanceof RelRecordType) {
            return;
        }
    }
    final Calc calc = call.rel(0);
    final RexProgram program = calc.getProgram();
    final Pair<ImmutableList<RexNode>, ImmutableList<RexNode>> projectFilter = program.split();
    final RelDataType calcInputRowType = program.getInputRowType();
    // When predicate push-down is not supported - all filters are unsupported.
    final BeamSqlTableFilter tableFilter = beamSqlTable.constructFilter(projectFilter.right);
    if (!beamSqlTable.supportsProjects().isSupported() && tableFilter instanceof DefaultTableFilter) {
        // Either project or filter push-down must be supported by the IO.
        return;
    }
    Set<String> usedFields = new LinkedHashSet<>();
    if (!(tableFilter instanceof DefaultTableFilter) && !beamSqlTable.supportsProjects().isSupported()) {
        // When applying standalone filter push-down all fields must be project by an IO.
        // With a single exception: Calc projects all fields (in the same order) and does nothing
        // else.
        usedFields.addAll(calcInputRowType.getFieldNames());
    } else {
        // Find all input refs used by projects
        for (RexNode project : projectFilter.left) {
            findUtilizedInputRefs(calcInputRowType, project, usedFields);
        }
        // Find all input refs used by filters
        for (RexNode filter : tableFilter.getNotSupported()) {
            findUtilizedInputRefs(calcInputRowType, filter, usedFields);
        }
    }
    if (usedFields.isEmpty()) {
        // No need to do push-down for queries like this: "select UPPER('hello')".
        return;
    }
    // IO only projects fields utilized by a calc.
    if (tableFilter.getNotSupported().containsAll(projectFilter.right) && usedFields.containsAll(ioSourceRel.getRowType().getFieldNames())) {
        return;
    }
    FieldAccessDescriptor resolved = FieldAccessDescriptor.withFieldNames(usedFields);
    resolved = resolved.resolve(beamSqlTable.getSchema());
    if (canDropCalc(program, beamSqlTable.supportsProjects(), tableFilter)) {
        call.transformTo(ioSourceRel.createPushDownRel(calc.getRowType(), resolved.getFieldsAccessed().stream().map(FieldDescriptor::getFieldName).collect(Collectors.toList()), tableFilter));
        return;
    }
    // IO only projects fields utilised by a calc.
    if (tableFilter.getNotSupported().equals(projectFilter.right) && usedFields.containsAll(ioSourceRel.getRowType().getFieldNames())) {
        return;
    }
    RelNode result = constructNodesWithPushDown(resolved, call.builder(), ioSourceRel, tableFilter, calc.getRowType(), projectFilter.left);
    if (tableFilter.getNotSupported().size() <= projectFilter.right.size() || usedFields.size() < calcInputRowType.getFieldCount()) {
        // Smaller Calc programs are indisputably better, as well as IOs with less projected fields.
        // We can consider something with the same number of filters.
        call.transformTo(result);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) BeamPushDownIOSourceRel(org.apache.beam.sdk.extensions.sql.impl.rel.BeamPushDownIOSourceRel) FieldAccessDescriptor(org.apache.beam.sdk.schemas.FieldAccessDescriptor) RexProgram(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexProgram) ImmutableList(org.apache.beam.vendor.calcite.v1_28_0.com.google.common.collect.ImmutableList) Calc(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Calc) RelDataType(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataType) RelRecordType(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelRecordType) RelDataTypeField(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField) BeamSqlTableFilter(org.apache.beam.sdk.extensions.sql.meta.BeamSqlTableFilter) RelNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode) BeamSqlTable(org.apache.beam.sdk.extensions.sql.meta.BeamSqlTable) BeamIOSourceRel(org.apache.beam.sdk.extensions.sql.impl.rel.BeamIOSourceRel) DefaultTableFilter(org.apache.beam.sdk.extensions.sql.meta.DefaultTableFilter) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 82 with Pair

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.Pair in project beam by apache.

the class BeamJoinRel method extractJoinRexNodes.

static List<Pair<RexNode, RexNode>> extractJoinRexNodes(RexNode condition) {
    // or it's a JOIN ON false because: condition == false
    if (condition instanceof RexLiteral) {
        throw new UnsupportedOperationException("CROSS JOIN, JOIN ON FALSE is not supported!");
    }
    RexCall call = (RexCall) condition;
    List<Pair<RexNode, RexNode>> pairs = new ArrayList<>();
    if ("AND".equals(call.getOperator().getName())) {
        List<RexNode> operands = call.getOperands();
        for (RexNode rexNode : operands) {
            Pair<RexNode, RexNode> pair = extractJoinPairOfRexNodes((RexCall) rexNode);
            pairs.add(pair);
        }
    } else if ("=".equals(call.getOperator().getName())) {
        pairs.add(extractJoinPairOfRexNodes(call));
    } else {
        throw new UnsupportedOperationException("Operator " + call.getOperator().getName() + " is not supported in join condition");
    }
    return pairs;
}
Also used : RexCall(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall) RexLiteral(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral) ArrayList(java.util.ArrayList) Pair(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.Pair) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)

Example 83 with Pair

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.Pair in project hazelcast by hazelcast.

the class HazelcastSqlToRelConverter method constructComparisons.

/**
 * Constructs comparisons between
 * left-hand operand (as a rule, SqlIdentifier) and right-hand list.
 */
private List<RexNode> constructComparisons(Blackboard bb, List<RexNode> leftKeys, SqlNodeList valuesList) {
    final List<RexNode> comparisons = new ArrayList<>();
    for (SqlNode rightValues : valuesList) {
        RexNode rexComparison;
        final SqlOperator comparisonOp = SqlStdOperatorTable.EQUALS;
        if (leftKeys.size() == 1) {
            rexComparison = rexBuilder.makeCall(comparisonOp, leftKeys.get(0), ensureSqlType(leftKeys.get(0).getType(), bb.convertExpression(rightValues)));
        } else {
            assert rightValues instanceof SqlCall;
            final SqlBasicCall basicCall = (SqlBasicCall) rightValues;
            assert basicCall.getOperator() instanceof SqlRowOperator && basicCall.operandCount() == leftKeys.size();
            rexComparison = RexUtil.composeConjunction(rexBuilder, Pair.zip(leftKeys, basicCall.getOperandList()).stream().map(pair -> rexBuilder.makeCall(comparisonOp, pair.left, ensureSqlType(pair.left.getType(), bb.convertExpression(pair.right)))).collect(Collectors.toList()));
        }
        comparisons.add(rexComparison);
    }
    return comparisons;
}
Also used : RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) CalciteContextException(org.apache.calcite.runtime.CalciteContextException) LiteralUtils(com.hazelcast.jet.sql.impl.validate.literal.LiteralUtils) RelDataTypeFamily(org.apache.calcite.rel.type.RelDataTypeFamily) HazelcastResources(com.hazelcast.jet.sql.impl.validate.HazelcastResources) SqlCall(org.apache.calcite.sql.SqlCall) SqlJsonEmptyOrError(org.apache.calcite.sql.SqlJsonEmptyOrError) BigDecimal(java.math.BigDecimal) RexUtil(org.apache.calcite.rex.RexUtil) SqlNode(org.apache.calcite.sql.SqlNode) SqlUtil(org.apache.calcite.sql.SqlUtil) RexNode(org.apache.calcite.rex.RexNode) Arrays.asList(java.util.Arrays.asList) LocalTime(java.time.LocalTime) TableModify(org.apache.calcite.rel.core.TableModify) DAY(org.apache.calcite.avatica.util.TimeUnit.DAY) SqlValidator(org.apache.calcite.sql.validate.SqlValidator) YEAR(org.apache.calcite.avatica.util.TimeUnit.YEAR) RelOptCluster(org.apache.calcite.plan.RelOptCluster) SqlKind(org.apache.calcite.sql.SqlKind) IdentityHashMap(java.util.IdentityHashMap) HazelcastTypeUtils(com.hazelcast.jet.sql.impl.validate.types.HazelcastTypeUtils) HazelcastJsonParseFunction(com.hazelcast.jet.sql.impl.validate.operators.json.HazelcastJsonParseFunction) SqlOperandTypeChecker(org.apache.calcite.sql.type.SqlOperandTypeChecker) RexLiteral(org.apache.calcite.rex.RexLiteral) Set(java.util.Set) Collectors(java.util.stream.Collectors) InvocationTargetException(java.lang.reflect.InvocationTargetException) HazelcastJsonValueFunction(com.hazelcast.jet.sql.impl.validate.operators.json.HazelcastJsonValueFunction) List(java.util.List) SqlStdOperatorTable(org.apache.calcite.sql.fun.SqlStdOperatorTable) SqlRowOperator(org.apache.calcite.sql.fun.SqlRowOperator) SqlErrorCode(com.hazelcast.sql.impl.SqlErrorCode) MONTH(org.apache.calcite.avatica.util.TimeUnit.MONTH) SqlInsert(org.apache.calcite.sql.SqlInsert) QueryDataType(com.hazelcast.sql.impl.type.QueryDataType) RelOptTable(org.apache.calcite.plan.RelOptTable) ArrayList(java.util.ArrayList) SqlJsonValueReturning(org.apache.calcite.sql.SqlJsonValueReturning) TimeString(org.apache.calcite.util.TimeString) SqlToRelConverter(org.apache.calcite.sql2rel.SqlToRelConverter) Lists(com.google.common.collect.Lists) SqlLiteral(org.apache.calcite.sql.SqlLiteral) ImmutableList(com.google.common.collect.ImmutableList) Pair(org.apache.calcite.util.Pair) Converter(com.hazelcast.sql.impl.type.converter.Converter) SqlOperator(org.apache.calcite.sql.SqlOperator) SqlBetweenOperator(org.apache.calcite.sql.fun.SqlBetweenOperator) QueryException(com.hazelcast.sql.impl.QueryException) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIntervalQualifier(org.apache.calcite.sql.SqlIntervalQualifier) SqlParserPos(org.apache.calcite.sql.parser.SqlParserPos) SqlExtendedInsert(com.hazelcast.jet.sql.impl.parse.SqlExtendedInsert) SqlTypeFamily(org.apache.calcite.sql.type.SqlTypeFamily) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) HazelcastReturnTypeInference(com.hazelcast.jet.sql.impl.validate.operators.typeinference.HazelcastReturnTypeInference) RexBuilder(org.apache.calcite.rex.RexBuilder) Literal(com.hazelcast.jet.sql.impl.validate.literal.Literal) SqlRexConvertletTable(org.apache.calcite.sql2rel.SqlRexConvertletTable) SqlBasicCall(org.apache.calcite.sql.SqlBasicCall) SqlValidatorException(org.apache.calcite.sql.validate.SqlValidatorException) RelNode(org.apache.calcite.rel.RelNode) LogicalTableInsert(com.hazelcast.jet.sql.impl.opt.logical.LogicalTableInsert) Prepare(org.apache.calcite.prepare.Prepare) SECOND(org.apache.calcite.avatica.util.TimeUnit.SECOND) HazelcastBetweenOperator(com.hazelcast.jet.sql.impl.validate.operators.predicate.HazelcastBetweenOperator) SqlJsonValueEmptyOrErrorBehavior(org.apache.calcite.sql.SqlJsonValueEmptyOrErrorBehavior) SqlInOperator(org.apache.calcite.sql.fun.SqlInOperator) Converters(com.hazelcast.sql.impl.type.converter.Converters) Util(org.apache.calcite.util.Util) LogicalTableSink(com.hazelcast.jet.sql.impl.opt.logical.LogicalTableSink) Resources(org.apache.calcite.runtime.Resources) SqlNodeList(org.apache.calcite.sql.SqlNodeList) Collections(java.util.Collections) SqlBasicCall(org.apache.calcite.sql.SqlBasicCall) SqlOperator(org.apache.calcite.sql.SqlOperator) SqlCall(org.apache.calcite.sql.SqlCall) ArrayList(java.util.ArrayList) SqlRowOperator(org.apache.calcite.sql.fun.SqlRowOperator) RexNode(org.apache.calcite.rex.RexNode) SqlNode(org.apache.calcite.sql.SqlNode)

Example 84 with Pair

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.Pair in project beam by apache.

the class IOPushDownRuleTest method testFindUtilisedInputRefs.

@Test
public void testFindUtilisedInputRefs() {
    String sqlQuery = "select id+10 from TEST where name='one'";
    BeamRelNode basicRel = sqlEnv.parseQuery(sqlQuery);
    assertThat(basicRel, instanceOf(Calc.class));
    Calc calc = (Calc) basicRel;
    final Pair<ImmutableList<RexNode>, ImmutableList<RexNode>> projectFilter = calc.getProgram().split();
    final ImmutableList<RexNode> projects = projectFilter.left;
    final ImmutableList<RexNode> filters = projectFilter.right;
    Set<String> usedFields = new HashSet<>();
    BeamIOPushDownRule.INSTANCE.findUtilizedInputRefs(calc.getProgram().getInputRowType(), projects.get(0), usedFields);
    assertThat(usedFields, containsInAnyOrder("id"));
    BeamIOPushDownRule.INSTANCE.findUtilizedInputRefs(calc.getProgram().getInputRowType(), filters.get(0), usedFields);
    assertThat(usedFields, containsInAnyOrder("id", "name"));
}
Also used : BeamRelNode(org.apache.beam.sdk.extensions.sql.impl.rel.BeamRelNode) ImmutableList(org.apache.beam.vendor.calcite.v1_28_0.com.google.common.collect.ImmutableList) Calc(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Calc) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 85 with Pair

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.util.Pair in project beam by apache.

the class IOPushDownRuleTest method testReMapRexNodeToNewInputs.

@Test
public void testReMapRexNodeToNewInputs() {
    String sqlQuery = "select id+10 from TEST where name='one'";
    BeamRelNode basicRel = sqlEnv.parseQuery(sqlQuery);
    assertThat(basicRel, instanceOf(Calc.class));
    Calc calc = (Calc) basicRel;
    final Pair<ImmutableList<RexNode>, ImmutableList<RexNode>> projectFilter = calc.getProgram().split();
    final ImmutableList<RexNode> projects = projectFilter.left;
    final ImmutableList<RexNode> filters = projectFilter.right;
    List<Integer> mapping = ImmutableList.of(1, 2);
    RexNode newProject = BeamIOPushDownRule.INSTANCE.reMapRexNodeToNewInputs(projects.get(0), mapping);
    assertThat(newProject.toString(), equalTo("+($0, 10)"));
    RexNode newFilter = BeamIOPushDownRule.INSTANCE.reMapRexNodeToNewInputs(filters.get(0), mapping);
    assertThat(newFilter.toString(), equalTo("=($1, 'one')"));
}
Also used : BeamRelNode(org.apache.beam.sdk.extensions.sql.impl.rel.BeamRelNode) ImmutableList(org.apache.beam.vendor.calcite.v1_28_0.com.google.common.collect.ImmutableList) Calc(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Calc) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode) Test(org.junit.Test)

Aggregations

Pair (org.apache.calcite.util.Pair)112 RexNode (org.apache.calcite.rex.RexNode)72 ArrayList (java.util.ArrayList)70 RelNode (org.apache.calcite.rel.RelNode)59 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)55 RexInputRef (org.apache.calcite.rex.RexInputRef)29 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)29 HashMap (java.util.HashMap)26 RexBuilder (org.apache.calcite.rex.RexBuilder)23 Map (java.util.Map)21 AggregateCall (org.apache.calcite.rel.core.AggregateCall)20 List (java.util.List)19 RelDataType (org.apache.calcite.rel.type.RelDataType)19 ImmutableList (com.google.common.collect.ImmutableList)18 JoinRelType (org.apache.calcite.rel.core.JoinRelType)16 TreeMap (java.util.TreeMap)14 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)13 RelBuilder (org.apache.calcite.tools.RelBuilder)13 ImmutableMap (com.google.common.collect.ImmutableMap)12 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)12