Fix bug that <=> operator and in operator get wrong result (#1516)
* Fix bug that <=> operator and in operator get wrong result * Add some comment to get_result_for_null * Add an new Binary Operator to replace is_safe_for_null for handleing '<=>' operator * Add EQ_FOR_NULL to TExprOpcode * Remove macro definition last backslash
This commit is contained in:
@ -3640,7 +3640,7 @@ comparison_predicate ::=
|
||||
| expr:e1 GREATERTHAN:op expr:e2
|
||||
{: RESULT = new BinaryPredicate(BinaryPredicate.Operator.GT, e1, e2); :}
|
||||
| expr:e1 LESSTHAN EQUAL GREATERTHAN:op expr:e2
|
||||
{: RESULT = new BinaryPredicate(BinaryPredicate.Operator.EQ, e1, e2); :}
|
||||
{: RESULT = new BinaryPredicate(BinaryPredicate.Operator.EQ_FOR_NULL, e1, e2); :}
|
||||
;
|
||||
|
||||
like_predicate ::=
|
||||
|
||||
@ -56,7 +56,8 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
LE("<=", "le", TExprOpcode.LE),
|
||||
GE(">=", "ge", TExprOpcode.GE),
|
||||
LT("<", "lt", TExprOpcode.LT),
|
||||
GT(">", "gt", TExprOpcode.GT);
|
||||
GT(">", "gt", TExprOpcode.GT),
|
||||
EQ_FOR_NULL("<=>", "eq_for_null", TExprOpcode.EQ_FOR_NULL);
|
||||
|
||||
private final String description;
|
||||
private final String name;
|
||||
@ -97,6 +98,8 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
return GT;
|
||||
case GT:
|
||||
return LE;
|
||||
case EQ_FOR_NULL:
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -115,6 +118,8 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
return GT;
|
||||
case GT:
|
||||
return LT;
|
||||
case EQ_FOR_NULL:
|
||||
return EQ_FOR_NULL;
|
||||
// case DISTINCT_FROM: return DISTINCT_FROM;
|
||||
// case NOT_DISTINCT: return NOT_DISTINCT;
|
||||
// case NULL_MATCHING_EQ:
|
||||
@ -124,7 +129,7 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEquivalence() { return this == EQ; };
|
||||
public boolean isEquivalence() { return this == EQ || this == EQ_FOR_NULL; };
|
||||
|
||||
public boolean isUnequivalence() { return this == NE; }
|
||||
}
|
||||
@ -132,7 +137,7 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
private Operator op;
|
||||
// check if left is slot and right isnot slot.
|
||||
private Boolean slotIsleft = null;
|
||||
|
||||
|
||||
// for restoring
|
||||
public BinaryPredicate() {
|
||||
super();
|
||||
@ -172,6 +177,8 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
Operator.LT.getName(), Lists.newArrayList(t, t), Type.BOOLEAN));
|
||||
functionSet.addBuiltin(ScalarFunction.createBuiltinOperator(
|
||||
Operator.GT.getName(), Lists.newArrayList(t, t), Type.BOOLEAN));
|
||||
functionSet.addBuiltin(ScalarFunction.createBuiltinOperator(
|
||||
Operator.EQ_FOR_NULL.getName(), Lists.newArrayList(t, t), Type.BOOLEAN));
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,6 +375,7 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
slotRef = (SlotRef) getChild(1).getChild(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (slotRef != null && slotRef.getSlotId() == id) {
|
||||
slotIsleft = false;
|
||||
return getChild(0);
|
||||
@ -507,13 +515,24 @@ public class BinaryPredicate extends Predicate implements Writable {
|
||||
}
|
||||
|
||||
private Expr compareLiteral(LiteralExpr first, LiteralExpr second) throws AnalysisException {
|
||||
if (first instanceof NullLiteral || second instanceof NullLiteral) {
|
||||
return new NullLiteral();
|
||||
final boolean isFirstNull = (first instanceof NullLiteral);
|
||||
final boolean isSecondNull = (second instanceof NullLiteral);
|
||||
if (op == Operator.EQ_FOR_NULL) {
|
||||
if (isFirstNull && isSecondNull) {
|
||||
return new BoolLiteral(true);
|
||||
} else if (isFirstNull || isSecondNull) {
|
||||
return new BoolLiteral(false);
|
||||
}
|
||||
} else {
|
||||
if (isFirstNull || isSecondNull){
|
||||
return new NullLiteral();
|
||||
}
|
||||
}
|
||||
|
||||
final int compareResult = first.compareLiteral(second);
|
||||
switch(op) {
|
||||
case EQ:
|
||||
case EQ_FOR_NULL:
|
||||
return new BoolLiteral(compareResult == 0);
|
||||
case GE:
|
||||
return new BoolLiteral(compareResult == 1 || compareResult == 0);
|
||||
|
||||
@ -248,10 +248,18 @@ public class InPredicate extends Predicate {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (leftChildValue instanceof NullLiteral) {
|
||||
return leftChildValue;
|
||||
}
|
||||
|
||||
List<Expr> inListChildren = children.subList(1, children.size());
|
||||
if (inListChildren.contains(leftChildValue)) {
|
||||
return new BoolLiteral(true);
|
||||
} else {
|
||||
final NullLiteral nullLiteral = new NullLiteral();
|
||||
if (inListChildren.contains(nullLiteral)) {
|
||||
return nullLiteral;
|
||||
}
|
||||
return new BoolLiteral(false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user