}
protected Object processExpression(ExprNodeGenericFuncDesc func, Object[] nodeOutputs)
throws SemanticException {
// a binary operator (gt, lt, ge, le, eq, ne)
GenericUDF genericUdf = func.getGenericUDF();
// Find the argument to the operator which is a constant
ExprNodeConstantDesc constantDesc = null;
ExprNodeColumnDesc columnDesc = null;
ExprNodeDesc leftHandNode = null;
for (Object nodeOutput : nodeOutputs) {
if (nodeOutput instanceof ExprNodeConstantDesc) {
// Ordering of constant and column in expression is important in correct range generation
if (null == leftHandNode) {
leftHandNode = (ExprNodeDesc) nodeOutput;
}
constantDesc = (ExprNodeConstantDesc) nodeOutput;
} else if (nodeOutput instanceof ExprNodeColumnDesc) {
// Ordering of constant and column in expression is important in correct range generation
if (null == leftHandNode) {
leftHandNode = (ExprNodeDesc) nodeOutput;
}
columnDesc = (ExprNodeColumnDesc) nodeOutput;
}
}
// If it's constant = constant or column = column, we can't fetch any ranges
// TODO We can try to be smarter and push up the value to some node which
// we can generate ranges from e.g. rowid > (4 + 5)
if (null == constantDesc || null == columnDesc) {
return null;
}
// Reject any clauses that are against a column that isn't the rowId mapping
if (!this.hiveRowIdColumnName.equals(columnDesc.getColumn())) {
return null;
}
ConstantObjectInspector objInspector = constantDesc.getWritableObjectInspector();
Text constText;
switch (rowIdMapping.getEncoding()) {
case STRING:
constText = getUtf8Value(objInspector);
break;
case BINARY:
try {
constText = getBinaryValue(objInspector);
} catch (IOException e) {
throw new SemanticException(e);
}
break;
default:
throw new SemanticException("Unable to parse unknown encoding: "
+ rowIdMapping.getEncoding());
}
Class<? extends CompareOp> opClz;
try {
opClz = predicateHandler.getCompareOpClass(genericUdf.getUdfName());
} catch (NoSuchCompareOpException e) {
throw new IllegalArgumentException("Unhandled UDF class: " + genericUdf.getUdfName());
}
if (leftHandNode instanceof ExprNodeConstantDesc) {
return getConstantOpColumnRange(opClz, constText);
} else if (leftHandNode instanceof ExprNodeColumnDesc) {