15 package com.cloudera.impala.analysis;
17 import java.util.ArrayList;
18 import java.util.List;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
28 import com.cloudera.impala.common.Pair;
29 import com.cloudera.impala.common.Reference;
30 import com.cloudera.impala.extdatasource.thrift.TComparisonOp;
31 import com.cloudera.impala.thrift.TExprNode;
32 import com.cloudera.impala.thrift.TExprNodeType;
33 import com.google.common.base.Objects;
34 import com.google.common.base.Preconditions;
35 import com.google.common.base.Predicates;
36 import com.google.common.collect.Lists;
43 private final static Logger
LOG = LoggerFactory.getLogger(BinaryPredicate.class);
46 EQ(
"=",
"eq", TComparisonOp.EQ),
47 NE(
"!=",
"ne", TComparisonOp.NE),
48 LE(
"<=",
"le", TComparisonOp.LE),
49 GE(
">=",
"ge", TComparisonOp.GE),
50 LT(
"<",
"lt", TComparisonOp.LT),
51 GT(
">",
"gt", TComparisonOp.GT),
61 private Operator(String description, String
name, TComparisonOp thriftOp) {
62 this.description_ = description;
64 this.thriftOp_ = thriftOp;
68 public String
toString() {
return description_; }
80 case NULL_MATCHING_EQ:
81 throw new IllegalStateException(
"Not implemented");
82 default:
throw new IllegalStateException(
"Invalid operator");
89 if (t.isNull())
continue;
90 db.addBuiltin(ScalarFunction.createBuiltinOperator(
91 Operator.EQ.getName(), Lists.newArrayList(t, t),
Type.BOOLEAN));
92 db.addBuiltin(ScalarFunction.createBuiltinOperator(
93 Operator.NE.getName(), Lists.newArrayList(t, t),
Type.BOOLEAN));
94 db.addBuiltin(ScalarFunction.createBuiltinOperator(
95 Operator.LE.getName(), Lists.newArrayList(t, t),
Type.BOOLEAN));
96 db.addBuiltin(ScalarFunction.createBuiltinOperator(
97 Operator.GE.getName(), Lists.newArrayList(t, t),
Type.BOOLEAN));
98 db.addBuiltin(ScalarFunction.createBuiltinOperator(
99 Operator.LT.getName(), Lists.newArrayList(t, t),
Type.BOOLEAN));
100 db.addBuiltin(ScalarFunction.createBuiltinOperator(
101 Operator.GT.getName(), Lists.newArrayList(t, t),
Type.BOOLEAN));
113 Preconditions.checkNotNull(e1);
115 Preconditions.checkNotNull(e2);
128 return getChild(0).toSql() +
" " +
op_.
toString() +
" " + getChild(1).toSql();
133 Preconditions.checkState(children_.size() == 2);
135 Preconditions.checkState(!contains(
Subquery.class));
139 Preconditions.checkState(getChild(0).getType().getPrimitiveType() ==
140 getChild(1).getType().getPrimitiveType(),
141 "child 0 type: " + getChild(0).getType() +
142 " child 1 type: " + getChild(1).getType());
143 msg.node_type = TExprNodeType.FUNCTION_CALL;
148 return Objects.toStringHelper(
this)
150 .addValue(super.debugString())
157 super.analyze(analyzer);
160 String opName = op_.getName().
equals(
"null_matching_eq") ?
"eq" : op_.getName();
165 String errMsg =
"operands of type " + getChild(0).getType().
toSql() +
" and " +
166 getChild(1).getType().
toSql() +
" are not comparable: " +
toSql();
170 for (
Expr expr: children_) {
172 errMsg =
"Subquery must return a single row: " + expr.toSql();
179 Preconditions.checkState(fn_.getReturnType().isBoolean());
181 ArrayList<Expr> subqueries = Lists.newArrayList();
182 collectAll(Predicates.instanceOf(
Subquery.class), subqueries);
183 if (subqueries.size() > 1) {
187 "predicates: " +
toSql());
191 "supported in binary predicates: " +
toSql());
194 List<InPredicate> inPredicates = Lists.newArrayList();
197 if (inPredicate.contains(
Subquery.class)) {
199 "binary predicates: " +
toSql());
209 Reference<SlotRef> slotRefRef =
new Reference<SlotRef>();
213 Preconditions.checkState(slotRefRef.getRef() != null);
229 SlotRef slotRef = getChild(0).unwrapSlotRef(
false);
230 if (slotRef != null && slotRef.
getSlotId() == id)
return getChild(1);
232 slotRef = getChild(1).unwrapSlotRef(
false);
233 if (slotRef != null && slotRef.
getSlotId() == id)
return getChild(0);
243 return ((BinaryPredicate) e).getEqSlots();
253 SlotRef lhs = getChild(0).unwrapSlotRef(
true);
254 if (lhs == null)
return null;
255 SlotRef rhs = getChild(1).unwrapSlotRef(
true);
256 if (rhs == null)
return null;
257 return new Pair<SlotId, SlotId>(lhs.getSlotId(), rhs.
getSlotId());
266 SlotRef slotRef = getChild(0).unwrapSlotRef(
true);
267 if (slotRef != null)
return slotRef;
268 return getChild(1).unwrapSlotRef(
true);
296 case NULL_MATCHING_EQ:
297 throw new IllegalStateException(
"Not implemented");
304 if (!super.equals(obj))
return false;
306 return op_.equals(other.op_);
boolean equals(Object obj)
void castForFunctionCall(boolean ignoreWildcardDecimals)
BinaryPredicate(Operator op, Expr e1, Expr e2)
Expr getSlotBinding(SlotId id)
Pair< SlotId, SlotId > getEqSlots()
void convertNumericLiteralsFromDecimal(Analyzer analyzer)
void analyze(Analyzer analyzer)
static final ScalarType BOOLEAN
Operator(String description, String name, TComparisonOp thriftOp)
Type[] collectChildReturnTypes()
long getNumDistinctValues()
BinaryPredicate(BinaryPredicate other)
Function getBuiltinFunction(Analyzer analyzer, String name, Type[] argTypes, CompareMode mode)
final String description_
static void initBuiltins(Db db)
boolean isNullMatchingEq()
TComparisonOp getThriftOp()
boolean isSingleColumnPredicate(Reference< SlotRef > slotRefRef, Reference< Integer > idxRef)
void toThrift(TExprNode msg)
static ArrayList< ScalarType > getSupportedTypes()
static double DEFAULT_SELECTIVITY
final TComparisonOp thriftOp_
static Pair< SlotId, SlotId > getEqSlots(Expr e)