private static object boxLiteral(ExprNodeConstantDesc constantDesc, PredicateLeaf.Type type) { object lit = constantDesc.getValue(); if (lit == null) { return null; } switch (type) { case PredicateLeaf.Type.LONG: return ((Number)lit).longValue(); case PredicateLeaf.Type.STRING: if (lit is HiveChar) { return ((HiveChar)lit).getPaddedValue(); } else if (lit is String) { return lit; } else { return lit.toString(); } case PredicateLeaf.Type.FLOAT: if (lit is Float) { // converting a float directly to a double causes annoying conversion // problems return Double.parseDouble(lit.toString()); } else { return ((Number)lit).doubleValue(); } case PredicateLeaf.Type.TIMESTAMP: return Timestamp.valueOf(lit.toString()); case PredicateLeaf.Type.DATE: return Date.valueOf(lit.toString()); case PredicateLeaf.Type.DECIMAL: LOG.warn("boxing " + lit); return new HiveDecimalWritable(lit.toString()); case PredicateLeaf.Type.BOOLEAN: return lit; default: throw new ArgumentException("Unknown literal " + type); } }
/** * Create a leaf expression when we aren't sure where the variable is * located. * @param operator the operator type that was found * @param expression the expression to check */ private void createLeaf(PredicateLeaf.Operator @operator, ExprNodeGenericFuncDesc expression) { createLeaf(@operator, expression, findVariable(expression)); }
private void createLeaf(PredicateLeaf.Operator @operator, ExprNodeGenericFuncDesc expression, int variable) { string columnName = getColumnName(expression, variable); if (columnName == null) { builder.literal(TruthValue.YES_NO_NULL); return; } PredicateLeaf.Type type = getType(expression.getChildren().get(variable)); if (type == null) { builder.literal(TruthValue.YES_NO_NULL); return; } // if the variable was on the right, we need to swap things around bool needSwap = false; if (variable != 0) { if (@operator == PredicateLeaf.Operator.LESS_THAN) { needSwap = true; @operator = PredicateLeaf.Operator.LESS_THAN_EQUALS; } else if (@operator == PredicateLeaf.Operator.LESS_THAN_EQUALS) { needSwap = true; @operator = PredicateLeaf.Operator.LESS_THAN; } } if (needSwap) { builder.startNot(); } switch (@operator) { case PredicateLeaf.Operator.IS_NULL: builder.isNull(columnName, type); break; case PredicateLeaf.Operator.EQUALS: builder.equals(columnName, type, findLiteral(expression, type)); break; case PredicateLeaf.Operator.NULL_SAFE_EQUALS: builder.nullSafeEquals(columnName, type, findLiteral(expression, type)); break; case PredicateLeaf.Operator.LESS_THAN: builder.lessThan(columnName, type, findLiteral(expression, type)); break; case PredicateLeaf.Operator.LESS_THAN_EQUALS: builder.lessThanEquals(columnName, type, findLiteral(expression, type)); break; case PredicateLeaf.Operator.IN: builder.@in(columnName, type, getLiteralList(expression, type, variable + 1)); break; case PredicateLeaf.Operator.BETWEEN: builder.between(columnName, type, getLiteral(expression, type, variable + 1), getLiteral(expression, type, variable + 2)); break; } if (needSwap) { builder.end(); } }
private static object[] getLiteralList(ExprNodeGenericFuncDesc expr, PredicateLeaf.Type type, int start) { List<ExprNodeDesc> children = expr.getChildren(); object[] result = new object[children.Count - start]; // ignore the first child, since it is the variable int posn = 0; foreach (ExprNodeDesc child in children.subList(start, children.Count)) { if (child is ExprNodeConstantDesc) { result[posn++] = boxLiteral((ExprNodeConstantDesc)child, type); } else { // if we get some non-literals, we need to punt return null; } } return result; }
/** * Return the boxed literal at the given position * @param expr the parent node * @param type the type of the expression * @param position the child position to check * @return the boxed literal if found otherwise null */ private static object getLiteral(ExprNodeGenericFuncDesc expr, PredicateLeaf.Type type, int position) { List<ExprNodeDesc> children = expr.getChildren(); object child = children.get(position); if (child is ExprNodeConstantDesc) { return boxLiteral((ExprNodeConstantDesc)child, type); } return null; }
/** * Find the child that is the literal. * @param expr the parent node to check * @param type the type of the expression * @return the literal boxed if found or null */ private static object findLiteral(ExprNodeGenericFuncDesc expr, PredicateLeaf.Type type) { List<ExprNodeDesc> children = expr.getChildren(); if (children.Count != 2) { return null; } object result = null; foreach (ExprNodeDesc child in children) { if (child is ExprNodeConstantDesc) { if (result != null) { return null; } result = boxLiteral((ExprNodeConstantDesc)child, type); } } return result; }