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