Search in sources :

Example 1 with DesiredField

use of org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField in project drill by axbaretto.

the class DrillFilterItemStarReWriterRule method createNewScan.

/**
 * Creates new scan with fields from original scan and fields used in item star operator.
 *
 * @param scanRel original scan expression
 * @param itemStarFields item star fields
 * @return new scan expression
 */
private static DrillScanRel createNewScan(DrillScanRel scanRel, Map<String, DesiredField> itemStarFields) {
    RelDataType newScanRowType = createNewRowType(scanRel.getCluster().getTypeFactory(), scanRel.getRowType().getFieldList(), itemStarFields.keySet());
    List<SchemaPath> columns = new ArrayList<>(scanRel.getColumns());
    for (DesiredField desiredField : itemStarFields.values()) {
        String name = desiredField.getName();
        PathSegment.NameSegment nameSegment = new PathSegment.NameSegment(name);
        columns.add(new SchemaPath(nameSegment));
    }
    return new DrillScanRel(scanRel.getCluster(), scanRel.getTraitSet().plus(DrillRel.DRILL_LOGICAL), scanRel.getTable(), newScanRowType, columns);
}
Also used : SchemaPath(org.apache.drill.common.expression.SchemaPath) DesiredField(org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) PathSegment(org.apache.drill.common.expression.PathSegment)

Example 2 with DesiredField

use of org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField in project drill by axbaretto.

the class DrillFilterItemStarReWriterRule method transformFilterCall.

/**
 * Removes item star call from filter expression and propagates changes into project (if present) and scan.
 *
 * @param filterRel original filter expression
 * @param projectRel original project expression
 * @param scanRel original scan expression
 * @param call original rule call
 */
private static void transformFilterCall(DrillFilterRel filterRel, DrillProjectRel projectRel, DrillScanRel scanRel, RelOptRuleCall call) {
    List<String> fieldNames = projectRel == null ? scanRel.getRowType().getFieldNames() : projectRel.getRowType().getFieldNames();
    ItemStarFieldsVisitor itemStarFieldsVisitor = new ItemStarFieldsVisitor(fieldNames);
    filterRel.getCondition().accept(itemStarFieldsVisitor);
    // if there are no item fields, no need to proceed further
    if (itemStarFieldsVisitor.hasNoItemStarFields()) {
        return;
    }
    Map<String, DesiredField> itemStarFields = itemStarFieldsVisitor.getItemStarFields();
    DrillScanRel newScan = createNewScan(scanRel, itemStarFields);
    // create new project if was present in call
    DrillProjectRel newProject = null;
    if (projectRel != null) {
        // add new projects to the already existing in original project
        int projectIndex = scanRel.getRowType().getFieldCount();
        List<RexNode> newProjects = new ArrayList<>(projectRel.getProjects());
        for (DesiredField desiredField : itemStarFields.values()) {
            newProjects.add(new RexInputRef(projectIndex, desiredField.getType()));
            projectIndex++;
        }
        RelDataType newProjectRowType = createNewRowType(projectRel.getCluster().getTypeFactory(), projectRel.getRowType().getFieldList(), itemStarFields.keySet());
        newProject = new DrillProjectRel(projectRel.getCluster(), projectRel.getTraitSet(), newScan, newProjects, newProjectRowType);
    }
    // transform filter condition
    Map<RexNode, Integer> fieldMapper = createFieldMapper(itemStarFields.values(), scanRel.getRowType().getFieldCount());
    FieldsReWriter fieldsReWriter = new FieldsReWriter(fieldMapper);
    RexNode newCondition = filterRel.getCondition().accept(fieldsReWriter);
    // create new filter
    DrillFilterRel newFilter = DrillFilterRel.create(newProject != null ? newProject : newScan, newCondition);
    // wrap with project to have the same row type as before
    List<RexNode> newProjects = new ArrayList<>();
    RelDataType rowType = filterRel.getRowType();
    List<RelDataTypeField> fieldList = rowType.getFieldList();
    for (RelDataTypeField field : fieldList) {
        RexInputRef inputRef = new RexInputRef(field.getIndex(), field.getType());
        newProjects.add(inputRef);
    }
    DrillProjectRel wrapper = new DrillProjectRel(filterRel.getCluster(), filterRel.getTraitSet(), newFilter, newProjects, filterRel.getRowType());
    call.transformTo(wrapper);
}
Also used : DesiredField(org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RexInputRef(org.apache.calcite.rex.RexInputRef) FieldsReWriter(org.apache.drill.exec.planner.logical.FieldsReWriterUtil.FieldsReWriter) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with DesiredField

use of org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField in project drill by axbaretto.

the class DrillFilterItemStarReWriterRule method createFieldMapper.

/**
 * Creates node mapper to replace item star calls with new input field references.
 * Starting index should be calculated from the last used input expression (i.e. scan expression).
 * NB: field reference index starts from 0 thus original field count can be taken as starting index
 *
 * @param desiredFields list of desired fields
 * @param startingIndex starting index
 * @return field mapper
 */
private static Map<RexNode, Integer> createFieldMapper(Collection<DesiredField> desiredFields, int startingIndex) {
    Map<RexNode, Integer> fieldMapper = new HashMap<>();
    int index = startingIndex;
    for (DesiredField desiredField : desiredFields) {
        for (RexNode node : desiredField.getNodes()) {
            // if field is referenced in more then one call, add each call to field mapper
            fieldMapper.put(node, index);
        }
        // increment index for the next node reference
        index++;
    }
    return fieldMapper;
}
Also used : HashMap(java.util.HashMap) DesiredField(org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField) RexNode(org.apache.calcite.rex.RexNode)

Example 4 with DesiredField

use of org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField in project drill by apache.

the class DrillFilterItemStarReWriterRule method createNewScan.

/**
 * Creates new scan with fields from original scan and fields used in item star operator.
 *
 * @param scanRel original scan expression
 * @param itemStarFields item star fields
 * @return new scan expression
 */
private static DrillScanRel createNewScan(DrillScanRel scanRel, Map<String, DesiredField> itemStarFields) {
    RelDataType newScanRowType = createNewRowType(scanRel.getCluster().getTypeFactory(), scanRel.getRowType().getFieldList(), itemStarFields.keySet());
    List<SchemaPath> columns = new ArrayList<>(scanRel.getColumns());
    for (DesiredField desiredField : itemStarFields.values()) {
        String name = desiredField.getName();
        PathSegment.NameSegment nameSegment = new PathSegment.NameSegment(name);
        columns.add(new SchemaPath(nameSegment));
    }
    return new DrillScanRel(scanRel.getCluster(), scanRel.getTraitSet().plus(DrillRel.DRILL_LOGICAL), scanRel.getTable(), newScanRowType, columns);
}
Also used : SchemaPath(org.apache.drill.common.expression.SchemaPath) DesiredField(org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) PathSegment(org.apache.drill.common.expression.PathSegment)

Example 5 with DesiredField

use of org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField in project drill by apache.

the class DrillFilterItemStarReWriterRule method transformFilterCall.

/**
 * Removes item star call from filter expression and propagates changes into project (if present) and scan.
 *
 * @param filterRel original filter expression
 * @param projectRel original project expression
 * @param scanRel original scan expression
 * @param call original rule call
 */
private static void transformFilterCall(DrillFilterRel filterRel, DrillProjectRel projectRel, DrillScanRel scanRel, RelOptRuleCall call) {
    List<String> fieldNames = projectRel == null ? scanRel.getRowType().getFieldNames() : projectRel.getRowType().getFieldNames();
    ItemStarFieldsVisitor itemStarFieldsVisitor = new ItemStarFieldsVisitor(fieldNames);
    filterRel.getCondition().accept(itemStarFieldsVisitor);
    // if there are no item fields, no need to proceed further
    if (itemStarFieldsVisitor.hasNoItemStarFields()) {
        return;
    }
    Map<String, DesiredField> itemStarFields = itemStarFieldsVisitor.getItemStarFields();
    DrillScanRel newScan = createNewScan(scanRel, itemStarFields);
    // create new project if was present in call
    DrillProjectRel newProject = null;
    if (projectRel != null) {
        // add new projects to the already existing in original project
        int projectIndex = scanRel.getRowType().getFieldCount();
        List<RexNode> newProjects = new ArrayList<>(projectRel.getProjects());
        for (DesiredField desiredField : itemStarFields.values()) {
            newProjects.add(new RexInputRef(projectIndex, desiredField.getType()));
            projectIndex++;
        }
        RelDataType newProjectRowType = createNewRowType(projectRel.getCluster().getTypeFactory(), projectRel.getRowType().getFieldList(), itemStarFields.keySet());
        newProject = new DrillProjectRel(projectRel.getCluster(), projectRel.getTraitSet(), newScan, newProjects, newProjectRowType);
    }
    // transform filter condition
    Map<RexNode, Integer> fieldMapper = createFieldMapper(itemStarFields.values(), scanRel.getRowType().getFieldCount());
    FieldsReWriter fieldsReWriter = new FieldsReWriter(fieldMapper);
    RexNode newCondition = filterRel.getCondition().accept(fieldsReWriter);
    // create new filter
    DrillFilterRel newFilter = DrillFilterRel.create(newProject != null ? newProject : newScan, newCondition);
    // wrap with project to have the same row type as before
    List<RexNode> newProjects = new ArrayList<>();
    RelDataType rowType = filterRel.getRowType();
    List<RelDataTypeField> fieldList = rowType.getFieldList();
    for (RelDataTypeField field : fieldList) {
        RexInputRef inputRef = new RexInputRef(field.getIndex(), field.getType());
        newProjects.add(inputRef);
    }
    DrillProjectRel wrapper = new DrillProjectRel(filterRel.getCluster(), filterRel.getTraitSet(), newFilter, newProjects, filterRel.getRowType());
    call.transformTo(wrapper);
}
Also used : DesiredField(org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RexInputRef(org.apache.calcite.rex.RexInputRef) FieldsReWriter(org.apache.drill.exec.planner.logical.FieldsReWriterUtil.FieldsReWriter) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

DesiredField (org.apache.drill.exec.planner.logical.FieldsReWriterUtil.DesiredField)6 ArrayList (java.util.ArrayList)4 RelDataType (org.apache.calcite.rel.type.RelDataType)4 RexNode (org.apache.calcite.rex.RexNode)4 HashMap (java.util.HashMap)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 RexInputRef (org.apache.calcite.rex.RexInputRef)2 PathSegment (org.apache.drill.common.expression.PathSegment)2 SchemaPath (org.apache.drill.common.expression.SchemaPath)2 FieldsReWriter (org.apache.drill.exec.planner.logical.FieldsReWriterUtil.FieldsReWriter)2