use of org.apache.calcite.rel.type.RelRecordType in project hive by apache.
the class HiveUnionSimpleSelectsToInlineTableRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
RexBuilder rexBuilder = call.builder().getRexBuilder();
final HiveUnion union = call.rel(0);
if (!union.all) {
return;
}
List<RelNode> inputs = new ArrayList<RelNode>();
List<Project> projects = new ArrayList<>();
List<HiveTableFunctionScan> inlineTables = new ArrayList<>();
for (RelNode input : union.getInputs()) {
input = HiveRelDecorrelator.stripHep(input);
if (isPlainProject(input)) {
projects.add((Project) input);
continue;
}
if (isInlineTableOperand(input)) {
inlineTables.add((HiveTableFunctionScan) input);
continue;
}
inputs.add(input);
}
if (projects.size() + inlineTables.size() <= 1) {
// nothing to do
return;
}
RowStorage newRows = new RowStorage();
for (HiveTableFunctionScan rel : inlineTables) {
// inline(array(row1,row2,...))
RexCall rex = (RexCall) ((RexCall) rel.getCall()).operands.get(0);
for (RexNode row : rex.operands) {
if (!(row.getType() instanceof RelRecordType)) {
return;
}
newRows.addRow(row);
}
}
for (Project proj : projects) {
RexNode row = rexBuilder.makeCall(SqlStdOperatorTable.ROW, proj.getProjects());
if (!(row.getType() instanceof RelRecordType)) {
return;
}
newRows.addRow(row);
}
if (newRows.keySet().size() + inputs.size() == union.getInputs().size()) {
// nothing to do
return;
}
if (dummyTable == null) {
LOG.warn("Unexpected; rule would match - but dummyTable is not available");
return;
}
for (RelRecordType type : newRows.keySet()) {
List<RexNode> rows = newRows.get(type);
RelDataType arrayType = rexBuilder.getTypeFactory().createArrayType(type, -1);
try {
SqlOperator inlineFn = SqlFunctionConverter.getCalciteFn("inline", Collections.singletonList(arrayType), type, true, false);
SqlOperator arrayFn = SqlFunctionConverter.getCalciteFn("array", Collections.nCopies(rows.size(), type), arrayType, true, false);
RexNode expr = rexBuilder.makeCall(arrayFn, rows);
expr = rexBuilder.makeCall(inlineFn, expr);
RelNode newInlineTable = buildTableFunctionScan(expr, union.getCluster());
inputs.add(newInlineTable);
} catch (CalciteSemanticException e) {
LOG.debug("Conversion failed with exception", e);
return;
}
}
if (inputs.size() > 1) {
HiveUnion newUnion = (HiveUnion) union.copy(union.getTraitSet(), inputs, true);
call.transformTo(newUnion);
} else {
call.transformTo(inputs.get(0));
}
}
use of org.apache.calcite.rel.type.RelRecordType in project drill by apache.
the class ConvertCountToDirectScan method getCountDirectScanRowType.
private RelDataType getCountDirectScanRowType(RelDataTypeFactory typeFactory) {
List<RelDataTypeField> fields = Lists.newArrayList();
fields.add(new RelDataTypeFieldImpl("count", 0, typeFactory.createSqlType(SqlTypeName.BIGINT)));
return new RelRecordType(fields);
}
use of org.apache.calcite.rel.type.RelRecordType in project drill by axbaretto.
the class ConvertCountToDirectScan method constructDataType.
/**
* For each aggregate call creates field based on its name with bigint type.
* Constructs record type for created fields.
*
* @param aggregateRel aggregate relation expression
* @param fieldNames field names
* @return record type
*/
private RelDataType constructDataType(DrillAggregateRel aggregateRel, Collection<String> fieldNames) {
List<RelDataTypeField> fields = new ArrayList<>();
Iterator<String> filedNamesIterator = fieldNames.iterator();
int fieldIndex = 0;
while (filedNamesIterator.hasNext()) {
RelDataTypeField field = new RelDataTypeFieldImpl(filedNamesIterator.next(), fieldIndex++, aggregateRel.getCluster().getTypeFactory().createSqlType(SqlTypeName.BIGINT));
fields.add(field);
}
return new RelRecordType(fields);
}
use of org.apache.calcite.rel.type.RelRecordType in project drill by axbaretto.
the class DrillProjectRel method convert.
public static DrillProjectRel convert(Project project, ConversionContext context) throws InvalidRelException {
RelNode input = context.toRel(project.getInput());
List<RelDataTypeField> fields = Lists.newArrayList();
List<RexNode> exps = Lists.newArrayList();
for (NamedExpression expr : project.getSelections()) {
fields.add(new RelDataTypeFieldImpl(expr.getRef().getRootSegment().getPath(), fields.size(), context.getTypeFactory().createSqlType(SqlTypeName.ANY)));
exps.add(context.toRex(expr.getExpr()));
}
return new DrillProjectRel(context.getCluster(), context.getLogicalTraits(), input, exps, new RelRecordType(fields));
}
use of org.apache.calcite.rel.type.RelRecordType in project drill by axbaretto.
the class SplitUpComplexExpressions method visitProject.
@Override
public Prel visitProject(ProjectPrel project, Object unused) throws RelConversionException {
// Apply the rule to the child
RelNode originalInput = ((Prel) project.getInput(0)).accept(this, null);
project = (ProjectPrel) project.copy(project.getTraitSet(), Lists.newArrayList(originalInput));
List<RexNode> exprList = new ArrayList<>();
List<RelDataTypeField> relDataTypes = new ArrayList<>();
List<RelDataTypeField> origRelDataTypes = new ArrayList<>();
int i = 0;
final int lastColumnReferenced = PrelUtil.getLastUsedColumnReference(project.getProjects());
if (lastColumnReferenced == -1) {
return project;
}
final int lastRexInput = lastColumnReferenced + 1;
RexVisitorComplexExprSplitter exprSplitter = new RexVisitorComplexExprSplitter(factory, funcReg, lastRexInput);
for (RexNode rex : project.getChildExps()) {
origRelDataTypes.add(project.getRowType().getFieldList().get(i));
i++;
exprList.add(rex.accept(exprSplitter));
}
List<RexNode> complexExprs = exprSplitter.getComplexExprs();
if (complexExprs.size() == 1 && findTopComplexFunc(project.getChildExps()).size() == 1) {
return project;
}
ProjectPrel childProject;
List<RexNode> allExprs = new ArrayList<>();
int exprIndex = 0;
List<String> fieldNames = originalInput.getRowType().getFieldNames();
for (int index = 0; index < lastRexInput; index++) {
RexBuilder builder = new RexBuilder(factory);
allExprs.add(builder.makeInputRef(new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory), index));
if (fieldNames.get(index).contains(SchemaPath.DYNAMIC_STAR)) {
relDataTypes.add(new RelDataTypeFieldImpl(fieldNames.get(index), allExprs.size(), factory.createSqlType(SqlTypeName.ANY)));
} else {
relDataTypes.add(new RelDataTypeFieldImpl("EXPR$" + exprIndex, allExprs.size(), factory.createSqlType(SqlTypeName.ANY)));
exprIndex++;
}
}
RexNode currRexNode;
int index = lastRexInput - 1;
// if the projection expressions contained complex outputs, split them into their own individual projects
if (complexExprs.size() > 0) {
while (complexExprs.size() > 0) {
if (index >= lastRexInput) {
allExprs.remove(allExprs.size() - 1);
RexBuilder builder = new RexBuilder(factory);
allExprs.add(builder.makeInputRef(new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory), index));
}
index++;
exprIndex++;
currRexNode = complexExprs.remove(0);
allExprs.add(currRexNode);
relDataTypes.add(new RelDataTypeFieldImpl("EXPR$" + exprIndex, allExprs.size(), factory.createSqlType(SqlTypeName.ANY)));
childProject = new ProjectPrel(project.getCluster(), project.getTraitSet(), originalInput, ImmutableList.copyOf(allExprs), new RelRecordType(relDataTypes));
originalInput = childProject;
}
// copied from above, find a better way to do this
allExprs.remove(allExprs.size() - 1);
RexBuilder builder = new RexBuilder(factory);
allExprs.add(builder.makeInputRef(new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory), index));
relDataTypes.add(new RelDataTypeFieldImpl("EXPR$" + index, allExprs.size(), factory.createSqlType(SqlTypeName.ANY)));
}
return (Prel) project.copy(project.getTraitSet(), originalInput, exprList, new RelRecordType(origRelDataTypes));
}
Aggregations