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);
}
}
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;
}
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));
}
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);
}
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);
}
}
Aggregations