in exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/project/ProjectionMaterializer.java [367:558]
private void classifyExpr(NamedExpression ex, ClassifierResult result) {
NameSegment expr = ((SchemaPath) ex.getExpr()).getRootSegment();
NameSegment ref = ex.getRef().getRootSegment();
boolean exprHasPrefix = expr.getPath()
.contains(StarColumnHelper.PREFIX_DELIMITER);
boolean refHasPrefix = ref.getPath()
.contains(StarColumnHelper.PREFIX_DELIMITER);
boolean exprIsStar = expr.getPath().equals(SchemaPath.DYNAMIC_STAR);
boolean refContainsStar = ref.getPath().contains(SchemaPath.DYNAMIC_STAR);
boolean exprContainsStar = expr.getPath().contains(SchemaPath.DYNAMIC_STAR);
boolean refEndsWithStar = ref.getPath().endsWith(SchemaPath.DYNAMIC_STAR);
String exprPrefix = EMPTY_STRING;
String exprSuffix = expr.getPath();
if (exprHasPrefix) {
// get the prefix of the expr
String[] exprComponents = expr.getPath()
.split(StarColumnHelper.PREFIX_DELIMITER, 2);
assert (exprComponents.length == 2);
exprPrefix = exprComponents[0];
exprSuffix = exprComponents[1];
result.prefix = exprPrefix;
}
boolean exprIsFirstWildcard = false;
if (exprContainsStar) {
result.isStar = true;
Integer value = result.prefixMap.get(exprPrefix);
if (value == null) {
result.prefixMap.put(exprPrefix, 1);
exprIsFirstWildcard = true;
} else {
result.prefixMap.put(exprPrefix, value + 1);
}
}
int incomingSchemaSize = incomingSchema.getFieldCount();
// input is '*' and output is 'prefix_*'
if (exprIsStar && refHasPrefix && refEndsWithStar) {
String[] components = ref.getPath()
.split(StarColumnHelper.PREFIX_DELIMITER, 2);
assert (components.length == 2);
String prefix = components[0];
result.outputNames = new ArrayList<>();
for (MaterializedField field : incomingSchema) {
String name = field.getName();
// add the prefix to the incoming column name
String newName = prefix + StarColumnHelper.PREFIX_DELIMITER + name;
addToResultMaps(newName, result, false);
}
}
// input and output are the same
else if (expr.getPath().equalsIgnoreCase(ref.getPath())
&& (!exprContainsStar || exprIsFirstWildcard)) {
if (exprContainsStar && exprHasPrefix) {
assert exprPrefix != null;
int k = 0;
result.outputNames = new ArrayList<>(incomingSchemaSize);
for (int j = 0; j < incomingSchemaSize; j++) {
result.outputNames.add(EMPTY_STRING); // initialize
}
for (MaterializedField field : incomingSchema) {
String incomingName = field.getName();
// get the prefix of the name
String[] nameComponents = incomingName
.split(StarColumnHelper.PREFIX_DELIMITER, 2);
// if incoming value vector does not have a prefix, ignore it since
// this expression is not referencing it
if (nameComponents.length <= 1) {
k++;
continue;
}
String namePrefix = nameComponents[0];
if (exprPrefix.equalsIgnoreCase(namePrefix)) {
if (!result.outputMap.containsKey(incomingName)) {
result.outputNames.set(k, incomingName);
result.outputMap.put(incomingName, incomingName);
}
}
k++;
}
} else {
result.outputNames = new ArrayList<>();
if (exprContainsStar) {
for (MaterializedField field : incomingSchema) {
String incomingName = field.getName();
if (refContainsStar) {
addToResultMaps(incomingName, result, true); // allow dups since
// this is likely
// top-level project
} else {
addToResultMaps(incomingName, result, false);
}
}
} else {
String newName = expr.getPath();
if (!refHasPrefix && !exprHasPrefix) {
addToResultMaps(newName, result, true); // allow dups since this is
// likely top-level project
} else {
addToResultMaps(newName, result, false);
}
}
}
}
// Input is wildcard and it is not the first wildcard
else if (exprIsStar) {
result.outputNames = new ArrayList<>();
for (MaterializedField field : incomingSchema) {
String incomingName = field.getName();
addToResultMaps(incomingName, result, true); // allow dups since this is
// likely top-level project
}
}
// Only the output has prefix
else if (!exprHasPrefix && refHasPrefix) {
result.outputNames = new ArrayList<>();
String newName = ref.getPath();
addToResultMaps(newName, result, false);
}
// Input has prefix but output does not
else if (exprHasPrefix && !refHasPrefix) {
int k = 0;
result.outputNames = new ArrayList<>(incomingSchemaSize);
for (int j = 0; j < incomingSchemaSize; j++) {
result.outputNames.add(EMPTY_STRING); // initialize
}
for (MaterializedField field : incomingSchema) {
String name = field.getName();
String[] components = name.split(StarColumnHelper.PREFIX_DELIMITER, 2);
if (components.length <= 1) {
k++;
continue;
}
String namePrefix = components[0];
String nameSuffix = components[1];
if (exprPrefix.equalsIgnoreCase(namePrefix)) { // // case insensitive
// matching of prefix.
if (refContainsStar) {
// remove the prefix from the incoming column names
String newName = getUniqueName(nameSuffix, result); // for top level
// we need to
// make names
// unique
result.outputNames.set(k, newName);
} else if (exprSuffix.equalsIgnoreCase(nameSuffix)) { // case
// insensitive
// matching of
// field name.
// example: ref: $f1, expr: T0<PREFIX><column_name>
String newName = ref.getPath();
result.outputNames.set(k, newName);
}
} else {
result.outputNames.add(EMPTY_STRING);
}
k++;
}
}
// input and output have prefixes although they could be different...
else if (exprHasPrefix && refHasPrefix) {
String[] input = expr.getPath().split(StarColumnHelper.PREFIX_DELIMITER,
2);
assert (input.length == 2);
assert false : "Unexpected project expression or reference"; // not
// handled
// yet
} else {
// if the incoming schema's column name matches the expression name of the
// Project,
// then we just want to pick the ref name as the output column name
result.outputNames = new ArrayList<>();
for (MaterializedField field : incomingSchema) {
String incomingName = field.getName();
if (expr.getPath().equalsIgnoreCase(incomingName)) { // case insensitive
// matching of
// field name.
String newName = ref.getPath();
addToResultMaps(newName, result, true);
}
}
}
}