/** * Get the column name referenced in the expression. It must be at the top * level of this expression and there must be exactly one column. * @param expr the expression to look in * @param variable the slot the variable is expected in * @return the column name or null if there isn't exactly one column */ private static string getColumnName(ExprNodeGenericFuncDesc expr, int variable) { List <ExprNodeDesc> children = expr.getChildren(); if (variable < 0 || variable >= children.Count) { return(null); } ExprNodeDesc child = children[variable]; if (child is ExprNodeColumnDesc) { return(((ExprNodeColumnDesc)child).getColumn()); } return(null); }
/** * Get the type of the given expression node. * @param expr the expression to get the type of * @return int, string, or float or null if we don't know the type */ private static PredicateLeaf.Type?getType(ExprNodeDesc expr) { TypeInfo type = expr.getTypeInfo(); if (type.getCategory() == ObjectInspectorCategory.PRIMITIVE) { switch (((PrimitiveTypeInfo)type).getPrimitiveCategory()) { case PrimitiveCategory.BYTE: case PrimitiveCategory.SHORT: case PrimitiveCategory.INT: case PrimitiveCategory.LONG: return(PredicateLeaf.Type.LONG); case PrimitiveCategory.CHAR: case PrimitiveCategory.VARCHAR: case PrimitiveCategory.STRING: return(PredicateLeaf.Type.STRING); case PrimitiveCategory.FLOAT: case PrimitiveCategory.DOUBLE: return(PredicateLeaf.Type.FLOAT); case PrimitiveCategory.DATE: return(PredicateLeaf.Type.DATE); case PrimitiveCategory.TIMESTAMP: return(PredicateLeaf.Type.TIMESTAMP); case PrimitiveCategory.DECIMAL: return(PredicateLeaf.Type.DECIMAL); case PrimitiveCategory.BOOLEAN: return(PredicateLeaf.Type.BOOLEAN); } } return(null); }
/** * Find the variable in the expression. * @param expr the expression to look in * @return the index of the variable or -1 if there is not exactly one * variable. */ private int findVariable(ExprNodeDesc expr) { int result = -1; List <ExprNodeDesc> children = expr.getChildren(); for (int i = 0; i < children.Count; ++i) { ExprNodeDesc child = children[i]; if (child is ExprNodeColumnDesc) { // if we already found a variable, this isn't a sarg if (result != -1) { return(-1); } else { result = i; } } } return(result); }
/** * Do the recursive parse of the Hive ExprNodeDesc into our ExpressionTree. * @param expression the Hive ExprNodeDesc */ private void parse(ExprNodeDesc expression) { // Most of the stuff we can handle are generic function descriptions, so // handle the special cases. if (expression.GetType() != typeof(ExprNodeGenericFuncDesc)) { // if it is a reference to a boolean column, covert it to a truth test. if (expression is ExprNodeColumnDesc) { ExprNodeColumnDesc columnDesc = (ExprNodeColumnDesc)expression; if (columnDesc.getTypeString().Equals("boolean")) { builder.equals(columnDesc.getColumn(), PredicateLeaf.Type.BOOLEAN, true); return; } } // otherwise, we don't know what to do so make it a maybe builder.literal(TruthValue.YES_NO_NULL); return; } // get the kind of expression ExprNodeGenericFuncDesc expr = (ExprNodeGenericFuncDesc)expression; Type op = expr.getGenericUDF().GetType(); // handle the logical operators if (op == typeof(GenericUDFOPOr)) { builder.startOr(); addChildren(expr); builder.end(); } else if (op == typeof(GenericUDFOPAnd)) { builder.startAnd(); addChildren(expr); builder.end(); } else if (op == typeof(GenericUDFOPNot)) { builder.startNot(); addChildren(expr); builder.end(); } else if (op == typeof(GenericUDFOPEqual)) { createLeaf(PredicateLeaf.Operator.EQUALS, expr); } else if (op == typeof(GenericUDFOPNotEqual)) { builder.startNot(); createLeaf(PredicateLeaf.Operator.EQUALS, expr); builder.end(); } else if (op == typeof(GenericUDFOPEqualNS)) { createLeaf(PredicateLeaf.Operator.NULL_SAFE_EQUALS, expr); } else if (op == typeof(GenericUDFOPGreaterThan)) { builder.startNot(); createLeaf(PredicateLeaf.Operator.LESS_THAN_EQUALS, expr); builder.end(); } else if (op == typeof(GenericUDFOPEqualOrGreaterThan)) { builder.startNot(); createLeaf(PredicateLeaf.Operator.LESS_THAN, expr); builder.end(); } else if (op == typeof(GenericUDFOPLessThan)) { createLeaf(PredicateLeaf.Operator.LESS_THAN, expr); } else if (op == typeof(GenericUDFOPEqualOrLessThan)) { createLeaf(PredicateLeaf.Operator.LESS_THAN_EQUALS, expr); } else if (op == typeof(GenericUDFIn)) { createLeaf(PredicateLeaf.Operator.IN, expr, 0); } else if (op == typeof(GenericUDFBetween)) { createLeaf(PredicateLeaf.Operator.BETWEEN, expr, 1); } else if (op == typeof(GenericUDFOPNull)) { createLeaf(PredicateLeaf.Operator.IS_NULL, expr, 0); } else if (op == typeof(GenericUDFOPNotNull)) { builder.startNot(); createLeaf(PredicateLeaf.Operator.IS_NULL, expr, 0); builder.end(); // otherwise, we didn't understand it, so mark it maybe } else { builder.literal(TruthValue.YES_NO_NULL); } }
/** * Find the variable in the expression. * @param expr the expression to look in * @return the index of the variable or -1 if there is not exactly one * variable. */ private int findVariable(ExprNodeDesc expr) { int result = -1; List<ExprNodeDesc> children = expr.getChildren(); for (int i = 0; i < children.Count; ++i) { ExprNodeDesc child = children[i]; if (child is ExprNodeColumnDesc) { // if we already found a variable, this isn't a sarg if (result != -1) { return -1; } else { result = i; } } } return result; }
/** * Get the type of the given expression node. * @param expr the expression to get the type of * @return int, string, or float or null if we don't know the type */ private static PredicateLeaf.Type? getType(ExprNodeDesc expr) { TypeInfo type = expr.getTypeInfo(); if (type.getCategory() == ObjectInspectorCategory.PRIMITIVE) { switch (((PrimitiveTypeInfo)type).getPrimitiveCategory()) { case PrimitiveCategory.BYTE: case PrimitiveCategory.SHORT: case PrimitiveCategory.INT: case PrimitiveCategory.LONG: return PredicateLeaf.Type.LONG; case PrimitiveCategory.CHAR: case PrimitiveCategory.VARCHAR: case PrimitiveCategory.STRING: return PredicateLeaf.Type.STRING; case PrimitiveCategory.FLOAT: case PrimitiveCategory.DOUBLE: return PredicateLeaf.Type.FLOAT; case PrimitiveCategory.DATE: return PredicateLeaf.Type.DATE; case PrimitiveCategory.TIMESTAMP: return PredicateLeaf.Type.TIMESTAMP; case PrimitiveCategory.DECIMAL: return PredicateLeaf.Type.DECIMAL; case PrimitiveCategory.BOOLEAN: return PredicateLeaf.Type.BOOLEAN; } } return null; }