Search in sources :

Example 76 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project drill by apache.

the class ConvertCountToDirectScan method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final DrillAggregateRel agg = (DrillAggregateRel) call.rel(0);
    final DrillScanRel scan = (DrillScanRel) call.rel(call.rels.length - 1);
    final DrillProjectRel proj = call.rels.length == 3 ? (DrillProjectRel) call.rel(1) : null;
    final GroupScan oldGrpScan = scan.getGroupScan();
    final PlannerSettings settings = PrelUtil.getPlannerSettings(call.getPlanner());
    //    4) No distinct agg call.
    if (!(oldGrpScan.getScanStats(settings).getGroupScanProperty().hasExactRowCount() && agg.getGroupCount() == 0 && agg.getAggCallList().size() == 1 && !agg.containsDistinctCall())) {
        return;
    }
    AggregateCall aggCall = agg.getAggCallList().get(0);
    if (aggCall.getAggregation().getName().equals("COUNT")) {
        long cnt = 0;
        //  count(Not-null-input) ==> rowCount
        if (aggCall.getArgList().isEmpty() || (aggCall.getArgList().size() == 1 && !agg.getInput().getRowType().getFieldList().get(aggCall.getArgList().get(0).intValue()).getType().isNullable())) {
            cnt = (long) oldGrpScan.getScanStats(settings).getRecordCount();
        } else if (aggCall.getArgList().size() == 1) {
            // count(columnName) ==> Agg ( Scan )) ==> columnValueCount
            int index = aggCall.getArgList().get(0);
            if (proj != null) {
                if (proj.getProjects().get(index) instanceof RexInputRef) {
                    index = ((RexInputRef) proj.getProjects().get(index)).getIndex();
                } else {
                    // do not apply for all other cases.
                    return;
                }
            }
            String columnName = scan.getRowType().getFieldNames().get(index).toLowerCase();
            cnt = oldGrpScan.getColumnValueCount(SchemaPath.getSimplePath(columnName));
            if (cnt == GroupScan.NO_COLUMN_STATS) {
                // if column stats are not available don't apply this rule
                return;
            }
        } else {
            // do nothing.
            return;
        }
        RelDataType scanRowType = getCountDirectScanRowType(agg.getCluster().getTypeFactory());
        final ScanPrel newScan = ScanPrel.create(scan, scan.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(DrillDistributionTrait.SINGLETON), getCountDirectScan(cnt), scanRowType);
        List<RexNode> exprs = Lists.newArrayList();
        exprs.add(RexInputRef.of(0, scanRowType));
        final ProjectPrel newProj = new ProjectPrel(agg.getCluster(), agg.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(DrillDistributionTrait.SINGLETON), newScan, exprs, agg.getRowType());
        call.transformTo(newProj);
    }
}
Also used : DrillScanRel(org.apache.drill.exec.planner.logical.DrillScanRel) DrillProjectRel(org.apache.drill.exec.planner.logical.DrillProjectRel) DrillAggregateRel(org.apache.drill.exec.planner.logical.DrillAggregateRel) RelDataType(org.apache.calcite.rel.type.RelDataType) DirectGroupScan(org.apache.drill.exec.store.direct.DirectGroupScan) GroupScan(org.apache.drill.exec.physical.base.GroupScan) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 77 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project drill by apache.

the class JoinPrel method rename.

private RelNode rename(RelNode input, List<RelDataTypeField> inputFields, List<String> outputFieldNames) {
    List<RexNode> exprs = Lists.newArrayList();
    for (RelDataTypeField field : inputFields) {
        RexNode expr = input.getCluster().getRexBuilder().makeInputRef(field.getType(), field.getIndex());
        exprs.add(expr);
    }
    RelDataType rowType = RexUtil.createStructType(input.getCluster().getTypeFactory(), exprs, outputFieldNames);
    ProjectPrel proj = new ProjectPrel(input.getCluster(), input.getTraitSet(), input, exprs, rowType);
    return proj;
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 78 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project drill by apache.

the class RewriteCombineBinaryOperators method visitCall.

@Override
public RexNode visitCall(RexCall call) {
    SqlOperator op = call.getOperator();
    SqlKind kind = op.getKind();
    RelDataType type = call.getType();
    if (kind == SqlKind.AND) {
        List<RexNode> conjuncts = Lists.newArrayList();
        for (RexNode child : call.getOperands()) {
            conjuncts.addAll(RelOptUtil.conjunctions(child.accept(this)));
        }
        return RexUtil.composeConjunction(builder, conjuncts, true);
    }
    if (kind == SqlKind.OR) {
        List<RexNode> disjuncts = Lists.newArrayList();
        for (RexNode child : call.getOperands()) {
            disjuncts.addAll(RelOptUtil.disjunctions(child.accept(this)));
        }
        return RexUtil.composeDisjunction(builder, disjuncts, true);
    }
    return builder.makeCall(type, op, visitChildren(call));
}
Also used : SqlOperator(org.apache.calcite.sql.SqlOperator) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlKind(org.apache.calcite.sql.SqlKind) RexNode(org.apache.calcite.rex.RexNode)

Example 79 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project drill by apache.

the class RecordDataType method getRowType.

/**
   * This method constructs a {@link org.apache.calcite.rel.type.RelDataType} based on the
   * {@link org.apache.drill.exec.store.RecordDataType}'s field sql types and field names.
   *
   * @param factory helps construct a {@link org.apache.calcite.rel.type.RelDataType}
   * @return the constructed type
   */
public final RelDataType getRowType(RelDataTypeFactory factory) {
    final List<SqlTypeName> types = getFieldSqlTypeNames();
    final List<String> names = getFieldNames();
    final List<RelDataType> fields = Lists.newArrayList();
    for (final SqlTypeName typeName : types) {
        switch(typeName) {
            case VARCHAR:
                fields.add(factory.createSqlType(typeName, Integer.MAX_VALUE));
                break;
            default:
                fields.add(factory.createSqlType(typeName));
        }
    }
    return factory.createStructType(fields, names);
}
Also used : SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 80 with RelDataType

use of org.apache.calcite.rel.type.RelDataType in project drill by apache.

the class SqlHandlerUtil method qualifyPartitionCol.

/**
   *  Resolve the partition columns specified in "PARTITION BY" clause of CTAS statement.
   *
   *  A partition column is resolved, either (1) the same column appear in the select list of CTAS
   *  or (2) CTAS has a * in select list.
   *
   *  In the second case, a PROJECT with ITEM expression would be created and returned.
   *  Throw validation error if a partition column is not resolved correctly.
   *
   * @param input : the RelNode represents the select statement in CTAS.
   * @param partitionColumns : the list of partition columns.
   * @return : 1) the original RelNode input, if all partition columns are in select list of CTAS
   *           2) a New Project, if a partition column is resolved to * column in select list
   *           3) validation error, if partition column is not resolved.
   */
public static RelNode qualifyPartitionCol(RelNode input, List<String> partitionColumns) {
    final RelDataType inputRowType = input.getRowType();
    final List<RexNode> colRefStarExprs = Lists.newArrayList();
    final List<String> colRefStarNames = Lists.newArrayList();
    final RexBuilder builder = input.getCluster().getRexBuilder();
    final int originalFieldSize = inputRowType.getFieldCount();
    for (final String col : partitionColumns) {
        final RelDataTypeField field = inputRowType.getField(col, false, false);
        if (field == null) {
            throw UserException.validationError().message("Partition column %s is not in the SELECT list of CTAS!", col).build(logger);
        } else {
            if (field.getName().startsWith(StarColumnHelper.STAR_COLUMN)) {
                colRefStarNames.add(col);
                final List<RexNode> operands = Lists.newArrayList();
                operands.add(new RexInputRef(field.getIndex(), field.getType()));
                operands.add(builder.makeLiteral(col));
                final RexNode item = builder.makeCall(SqlStdOperatorTable.ITEM, operands);
                colRefStarExprs.add(item);
            }
        }
    }
    if (colRefStarExprs.isEmpty()) {
        return input;
    } else {
        final List<String> names = new AbstractList<String>() {

            @Override
            public String get(int index) {
                if (index < originalFieldSize) {
                    return inputRowType.getFieldNames().get(index);
                } else {
                    return colRefStarNames.get(index - originalFieldSize);
                }
            }

            @Override
            public int size() {
                return originalFieldSize + colRefStarExprs.size();
            }
        };
        final List<RexNode> refs = new AbstractList<RexNode>() {

            public int size() {
                return originalFieldSize + colRefStarExprs.size();
            }

            public RexNode get(int index) {
                if (index < originalFieldSize) {
                    return RexInputRef.of(index, inputRowType.getFieldList());
                } else {
                    return colRefStarExprs.get(index - originalFieldSize);
                }
            }
        };
        return RelOptUtil.createProject(input, refs, names, false);
    }
}
Also used : AbstractList(java.util.AbstractList) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RelDataType (org.apache.calcite.rel.type.RelDataType)88 RexNode (org.apache.calcite.rex.RexNode)48 RexBuilder (org.apache.calcite.rex.RexBuilder)28 RelNode (org.apache.calcite.rel.RelNode)27 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)25 ArrayList (java.util.ArrayList)21 RexInputRef (org.apache.calcite.rex.RexInputRef)16 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)14 AggregateCall (org.apache.calcite.rel.core.AggregateCall)13 ImmutableList (com.google.common.collect.ImmutableList)9 BigDecimal (java.math.BigDecimal)8 CalciteSemanticException (org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSemanticException)8 SqlAggFunction (org.apache.calcite.sql.SqlAggFunction)7 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)7 RelOptCluster (org.apache.calcite.plan.RelOptCluster)6 RelBuilder (org.apache.calcite.tools.RelBuilder)6 Prel (org.apache.drill.exec.planner.physical.Prel)6 ProjectPrel (org.apache.drill.exec.planner.physical.ProjectPrel)6 Builder (com.google.common.collect.ImmutableList.Builder)5 LinkedList (java.util.LinkedList)5