Github user Indhumathi27 commented on a diff in the pull request:
https://github.com/apache/carbondata/pull/2396#discussion_r197645133
--- Diff:
core/src/main/java/org/apache/carbondata/core/scan/model/QueryModelBuilder.java
---
@@ -54,18 +58,134 @@ public QueryModelBuilder projectColumns(String[]
projectionColumns) {
} else {
CarbonMeasure measure = table.getMeasureByName(factTableName,
projectionColumnName);
if (measure == null) {
- throw new RuntimeException(projectionColumnName +
- " column not found in the table " + factTableName);
+ throw new RuntimeException(
+ projectionColumnName + " column not found in the table " +
factTableName);
}
projection.addMeasure(measure, i);
i++;
}
}
-
+ optimizeProjectionForComplexColumns(projection);
this.projection = projection;
return this;
}
+ private void optimizeProjectionForComplexColumns(QueryProjection
projection) {
+ // Get the List of Complex Column Projection.
+ // The optimization techniques which can be applied are
+ // A. Merging in Driver Side
+ // B. Merging in the result Collector side.
+ // Merging is driver side cases are
+ // Driver merging will eliminate one of the CarbonDimension.
+ // Executor merging will merge the column output in Result Collector.
+ // In this routine we are going to do driver merging and leave
executor merging.
+ Map<Integer, List<Integer>> complexColumnMap = new HashMap<>();
+ List<ProjectionDimension> carbonDimensions =
projection.getDimensions();
+ for (ProjectionDimension cols : carbonDimensions) {
+ // get all the Projections with Parent Ordinal Set.
+ if (cols.getDimension().getParentOrdinal() != -1) {
+ if (complexColumnMap.get(cols.getDimension().getParentOrdinal())
!= null) {
+ List<Integer> childColumns =
complexColumnMap.get(cols.getDimension().getParentOrdinal());
+ childColumns.add(cols.getDimension().getOrdinal());
+ complexColumnMap.put(cols.getDimension().getParentOrdinal(),
childColumns);
+ } else {
+ List<Integer> childColumns = new ArrayList<>();
+ childColumns.add(cols.getDimension().getOrdinal());
+ complexColumnMap.put(cols.getDimension().getParentOrdinal(),
childColumns);
+ }
+ }
+ }
+
+ // Traverse the Map to Find any columns are parent.
+ for (Map.Entry<Integer, List<Integer>> entry :
complexColumnMap.entrySet()) {
+ List<Integer> childOrdinals = entry.getValue();
+ if (childOrdinals.size() > 1) {
+ // In case of more that one child, have to check if the child
columns are in the same path
+ // and have a common parent.
+ Collections.sort(childOrdinals);
+ List<Integer> mergedOrdinals = mergeChildColumns(childOrdinals,
entry.getKey());
+ if (mergedOrdinals.size() > 0) {
+ projection = removeDimension(projection, mergedOrdinals);
+ }
+ }
+ }
+ }
+
+ private QueryProjection removeDimension(QueryProjection projection,
+ List<Integer> mergedOrdinals) {
+ List<ProjectionDimension> carbonDimensions =
projection.getDimensions();
+ QueryProjection outputProjection = new QueryProjection();
+ int i = 0;
+ for (ProjectionDimension cols : carbonDimensions) {
+ if (!mergedOrdinals.contains(cols.getDimension().getOrdinal())) {
+ outputProjection.addDimension(cols.getDimension(), i++);
+ }
+ }
+ List<ProjectionMeasure> carbonMeasures = projection.getMeasures();
+ for (ProjectionMeasure cols : carbonMeasures) {
+ outputProjection.addMeasure(cols.getMeasure(), i++);
+ }
+ return outputProjection;
+ }
+
+ private List<Integer> mergeChildColumns(List<Integer> childOrdinals,
Integer key) {
--- End diff --
removed
---