diff --git a/fe/fe-core/pom.xml b/fe/fe-core/pom.xml
index 4b7452fccb5081..d6ba4a0b7f9421 100644
--- a/fe/fe-core/pom.xml
+++ b/fe/fe-core/pom.xml
@@ -156,6 +156,12 @@ under the License.
guava-testlib
test
+
+
+ com.googlecode.java-ipv6
+ java-ipv6
+ 0.17
+
com.fasterxml.jackson.core
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java
index 6cf83f5147655d..0ea9a5dc23e912 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java
@@ -670,7 +670,7 @@ public int compareLiteral(LiteralExpr expr) {
return diff < 0 ? -1 : (diff == 0 ? 0 : 1);
}
// date time will not overflow when doing addition and subtraction
- return getStringValue().compareTo(expr.getStringValue());
+ return Integer.signum(getStringValue().compareTo(expr.getStringValue()));
}
@Override
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DecimalLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DecimalLiteral.java
index f084658936d6fe..6fbfc175ea039f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DecimalLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DecimalLiteral.java
@@ -249,6 +249,9 @@ public int compareLiteral(LiteralExpr expr) {
if (expr instanceof NullLiteral) {
return 1;
}
+ if (expr == MaxLiteral.MAX_VALUE) {
+ return -1;
+ }
if (expr instanceof DecimalLiteral) {
return this.value.compareTo(((DecimalLiteral) expr).value);
} else {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FloatLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FloatLiteral.java
index 8d4a9ef576523e..645afe52f99491 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FloatLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FloatLiteral.java
@@ -126,6 +126,9 @@ public int compareLiteral(LiteralExpr expr) {
if (expr instanceof NullLiteral) {
return 1;
}
+ if (expr == MaxLiteral.MAX_VALUE) {
+ return -1;
+ }
return Double.compare(value, expr.getDoubleValue());
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java
index 34006c51710231..978c864434dce4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/IntLiteral.java
@@ -261,17 +261,13 @@ public int compareLiteral(LiteralExpr expr) {
if (expr instanceof NullLiteral) {
return 1;
}
- if (expr instanceof StringLiteral) {
- return ((StringLiteral) expr).compareLiteral(this);
- }
if (expr == MaxLiteral.MAX_VALUE) {
return -1;
}
- if (value == expr.getLongValue()) {
- return 0;
- } else {
- return value > expr.getLongValue() ? 1 : -1;
+ if (expr instanceof StringLiteral) {
+ return - ((StringLiteral) expr).compareLiteral(this);
}
+ return Long.compare(value, expr.getLongValue());
}
@Override
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/AddMinMax.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/AddMinMax.java
index 80d245c37800c1..891f04dcfd90b3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/AddMinMax.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/AddMinMax.java
@@ -36,6 +36,7 @@
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.util.ExpressionUtils;
@@ -93,7 +94,7 @@ private enum MatchMinMax {
private static class MinMaxValue {
// min max range, if range = null means empty
- Range range;
+ Range range;
// expression in range is discrete value
boolean isDiscrete;
@@ -101,7 +102,7 @@ private static class MinMaxValue {
// expr relative order, for keep order after add min-max to the expression
int exprOrderIndex;
- public MinMaxValue(Range range, boolean isDiscrete, int exprOrderIndex) {
+ public MinMaxValue(Range range, boolean isDiscrete, int exprOrderIndex) {
this.range = range;
this.isDiscrete = isDiscrete;
this.exprOrderIndex = exprOrderIndex;
@@ -171,25 +172,27 @@ private Expression addExprMinMaxValues(Expression expr, ExpressionRewriteContext
List addExprs = Lists.newArrayListWithExpectedSize(minMaxExprs.size() * 2);
for (Map.Entry entry : minMaxExprs) {
Expression targetExpr = entry.getKey();
- Range range = entry.getValue().range;
+ Range range = entry.getValue().range;
if (range.hasLowerBound() && range.hasUpperBound()
&& range.lowerEndpoint().equals(range.upperEndpoint())
&& range.lowerBoundType() == BoundType.CLOSED
&& range.upperBoundType() == BoundType.CLOSED) {
- Expression cmp = new EqualTo(targetExpr, range.lowerEndpoint());
+ Expression cmp = new EqualTo(targetExpr, (Literal) range.lowerEndpoint());
addExprs.add(cmp);
continue;
}
if (range.hasLowerBound()) {
- Literal literal = range.lowerEndpoint();
+ ComparableLiteral literal = range.lowerEndpoint();
Expression cmp = range.lowerBoundType() == BoundType.CLOSED
- ? new GreaterThanEqual(targetExpr, literal) : new GreaterThan(targetExpr, literal);
+ ? new GreaterThanEqual(targetExpr, (Literal) literal)
+ : new GreaterThan(targetExpr, (Literal) literal);
addExprs.add(cmp);
}
if (range.hasUpperBound()) {
- Literal literal = range.upperEndpoint();
+ ComparableLiteral literal = range.upperEndpoint();
Expression cmp = range.upperBoundType() == BoundType.CLOSED
- ? new LessThanEqual(targetExpr, literal) : new LessThan(targetExpr, literal);
+ ? new LessThanEqual(targetExpr, (Literal) literal)
+ : new LessThan(targetExpr, (Literal) literal);
addExprs.add(cmp);
}
}
@@ -243,7 +246,7 @@ private MatchMinMax getExprMatchMinMax(Expression expr,
ComparisonPredicate cp = (ComparisonPredicate) expr;
Expression left = cp.left();
Expression right = cp.right();
- if (!(right instanceof Literal)) {
+ if (!(right instanceof ComparableLiteral)) {
return MatchMinMax.MATCH_NONE;
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/ColumnBound.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/ColumnBound.java
index 1012708bc37c5d..808a706ae71370 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/ColumnBound.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/ColumnBound.java
@@ -18,6 +18,7 @@
package org.apache.doris.nereids.rules.expression.rules;
import org.apache.doris.catalog.PartitionKey;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import com.google.common.base.MoreObjects;
@@ -36,7 +37,13 @@ private ColumnBound(Literal value) {
@Override
public int compareTo(ColumnBound o) {
- return value.toLegacyLiteral().compareTo(o.value.toLegacyLiteral());
+ if (!(value instanceof ComparableLiteral)) {
+ throw new RuntimeException("'" + value + "' (" + value.getDataType() + ") is not comparable");
+ }
+ if (!(o.value instanceof ComparableLiteral)) {
+ throw new RuntimeException("'" + o.value + "' (" + o.value.getDataType() + ") is not comparable");
+ }
+ return ((ComparableLiteral) value).compareTo((ComparableLiteral) o.value);
}
public static ColumnBound of(Literal expr) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
index c4dd18acaa2ef5..bfb5defbdf6ebd 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
@@ -80,6 +80,7 @@
import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
@@ -266,7 +267,12 @@ public Expression visitEqualTo(EqualTo equalTo, ExpressionRewriteContext context
if (checkedExpr.isPresent()) {
return checkedExpr.get();
}
- return BooleanLiteral.of(((Literal) equalTo.left()).compareTo((Literal) equalTo.right()) == 0);
+ if (equalTo.left() instanceof ComparableLiteral && equalTo.right() instanceof ComparableLiteral) {
+ return BooleanLiteral.of(((ComparableLiteral) equalTo.left())
+ .compareTo((ComparableLiteral) equalTo.right()) == 0);
+ } else {
+ return BooleanLiteral.of(equalTo.left().equals(equalTo.right()));
+ }
}
@Override
@@ -276,7 +282,8 @@ public Expression visitGreaterThan(GreaterThan greaterThan, ExpressionRewriteCon
if (checkedExpr.isPresent()) {
return checkedExpr.get();
}
- return BooleanLiteral.of(((Literal) greaterThan.left()).compareTo((Literal) greaterThan.right()) > 0);
+ return BooleanLiteral.of(((ComparableLiteral) greaterThan.left())
+ .compareTo((ComparableLiteral) greaterThan.right()) > 0);
}
@Override
@@ -286,8 +293,8 @@ public Expression visitGreaterThanEqual(GreaterThanEqual greaterThanEqual, Expre
if (checkedExpr.isPresent()) {
return checkedExpr.get();
}
- return BooleanLiteral.of(((Literal) greaterThanEqual.left())
- .compareTo((Literal) greaterThanEqual.right()) >= 0);
+ return BooleanLiteral.of(((ComparableLiteral) greaterThanEqual.left())
+ .compareTo((ComparableLiteral) greaterThanEqual.right()) >= 0);
}
@Override
@@ -297,7 +304,8 @@ public Expression visitLessThan(LessThan lessThan, ExpressionRewriteContext cont
if (checkedExpr.isPresent()) {
return checkedExpr.get();
}
- return BooleanLiteral.of(((Literal) lessThan.left()).compareTo((Literal) lessThan.right()) < 0);
+ return BooleanLiteral.of(((ComparableLiteral) lessThan.left())
+ .compareTo((ComparableLiteral) lessThan.right()) < 0);
}
@Override
@@ -307,7 +315,8 @@ public Expression visitLessThanEqual(LessThanEqual lessThanEqual, ExpressionRewr
if (checkedExpr.isPresent()) {
return checkedExpr.get();
}
- return BooleanLiteral.of(((Literal) lessThanEqual.left()).compareTo((Literal) lessThanEqual.right()) <= 0);
+ return BooleanLiteral.of(((ComparableLiteral) lessThanEqual.left())
+ .compareTo((ComparableLiteral) lessThanEqual.right()) <= 0);
}
@Override
@@ -322,7 +331,13 @@ public Expression visitNullSafeEqual(NullSafeEqual nullSafeEqual, ExpressionRewr
if (l.isNullLiteral() && r.isNullLiteral()) {
return BooleanLiteral.TRUE;
} else if (!l.isNullLiteral() && !r.isNullLiteral()) {
- return BooleanLiteral.of(l.compareTo(r) == 0);
+ if (nullSafeEqual.left() instanceof ComparableLiteral
+ && nullSafeEqual.right() instanceof ComparableLiteral) {
+ return BooleanLiteral.of(((ComparableLiteral) nullSafeEqual.left())
+ .compareTo((ComparableLiteral) nullSafeEqual.right()) == 0);
+ } else {
+ return BooleanLiteral.of(l.equals(r));
+ }
} else {
return BooleanLiteral.FALSE;
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/RangeInference.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/RangeInference.java
index 7c23ce36a3dbf4..d0ae0a18d4567b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/RangeInference.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/RangeInference.java
@@ -29,7 +29,7 @@
import org.apache.doris.nereids.trees.expressions.LessThan;
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
import org.apache.doris.nereids.trees.expressions.Or;
-import org.apache.doris.nereids.trees.expressions.literal.Literal;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.util.ExpressionUtils;
@@ -76,7 +76,8 @@ private ValueDesc buildRange(ExpressionRewriteContext context, ComparisonPredica
return new UnknownValue(context, predicate);
}
// only handle `NumericType` and `DateLikeType`
- if (right.isLiteral() && (right.getDataType().isNumericType() || right.getDataType().isDateLikeType())) {
+ if (right instanceof ComparableLiteral
+ && (right.getDataType().isNumericType() || right.getDataType().isDateLikeType())) {
return ValueDesc.range(context, predicate);
}
return new UnknownValue(context, predicate);
@@ -111,7 +112,7 @@ public ValueDesc visitEqualTo(EqualTo equalTo, ExpressionRewriteContext context)
public ValueDesc visitInPredicate(InPredicate inPredicate, ExpressionRewriteContext context) {
// only handle `NumericType` and `DateLikeType`
if (inPredicate.getOptions().size() <= InPredicateDedup.REWRITE_OPTIONS_MAX_SIZE
- && ExpressionUtils.isAllNonNullLiteral(inPredicate.getOptions())
+ && ExpressionUtils.isAllNonNullComparableLiteral(inPredicate.getOptions())
&& (ExpressionUtils.matchNumericType(inPredicate.getOptions())
|| ExpressionUtils.matchDateLikeType(inPredicate.getOptions()))) {
return ValueDesc.discrete(context, inPredicate);
@@ -216,7 +217,7 @@ public static ValueDesc union(ExpressionRewriteContext context,
/** merge discrete and ranges only, no merge other value desc */
public static List unionDiscreteAndRange(ExpressionRewriteContext context,
Expression reference, List valueDescs) {
- Set discreteValues = Sets.newHashSet();
+ Set discreteValues = Sets.newHashSet();
for (ValueDesc valueDesc : valueDescs) {
if (valueDesc instanceof DiscreteValue) {
discreteValues.addAll(((DiscreteValue) valueDesc).getValues());
@@ -224,10 +225,10 @@ public static List unionDiscreteAndRange(ExpressionRewriteContext con
}
// for 'a > 8 or a = 8', then range (8, +00) can convert to [8, +00)
- RangeSet rangeSet = TreeRangeSet.create();
+ RangeSet rangeSet = TreeRangeSet.create();
for (ValueDesc valueDesc : valueDescs) {
if (valueDesc instanceof RangeValue) {
- Range range = ((RangeValue) valueDesc).range;
+ Range range = ((RangeValue) valueDesc).range;
rangeSet.add(range);
if (range.hasLowerBound()
&& range.lowerBoundType() == BoundType.OPEN
@@ -250,7 +251,7 @@ public static List unionDiscreteAndRange(ExpressionRewriteContext con
if (!discreteValues.isEmpty()) {
result.add(new DiscreteValue(context, reference, discreteValues));
}
- for (Range range : rangeSet.asRanges()) {
+ for (Range range : rangeSet.asRanges()) {
result.add(new RangeValue(context, reference, range));
}
for (ValueDesc valueDesc : valueDescs) {
@@ -267,7 +268,7 @@ public static List unionDiscreteAndRange(ExpressionRewriteContext con
/** intersect */
public static ValueDesc intersect(ExpressionRewriteContext context, RangeValue range, DiscreteValue discrete) {
- Set newValues = discrete.values.stream().filter(x -> range.range.contains(x))
+ Set newValues = discrete.values.stream().filter(x -> range.range.contains(x))
.collect(Collectors.toSet());
if (newValues.isEmpty()) {
return new EmptyValue(context, range.reference);
@@ -277,11 +278,11 @@ public static ValueDesc intersect(ExpressionRewriteContext context, RangeValue r
}
private static ValueDesc range(ExpressionRewriteContext context, ComparisonPredicate predicate) {
- Literal value = (Literal) predicate.right();
+ ComparableLiteral value = (ComparableLiteral) predicate.right();
if (predicate instanceof EqualTo) {
return new DiscreteValue(context, predicate.left(), Sets.newHashSet(value));
}
- Range range = null;
+ Range range = null;
if (predicate instanceof GreaterThanEqual) {
range = Range.atLeast(value);
} else if (predicate instanceof GreaterThan) {
@@ -296,8 +297,9 @@ private static ValueDesc range(ExpressionRewriteContext context, ComparisonPredi
}
public static ValueDesc discrete(ExpressionRewriteContext context, InPredicate in) {
- // Set literals = (Set) Utils.fastToImmutableSet(in.getOptions());
- Set literals = in.getOptions().stream().map(Literal.class::cast).collect(Collectors.toSet());
+ // Set literals = (Set) Utils.fastToImmutableSet(in.getOptions());
+ Set literals = in.getOptions().stream()
+ .map(ComparableLiteral.class::cast).collect(Collectors.toSet());
return new DiscreteValue(context, in.getCompareExpr(), literals);
}
}
@@ -328,14 +330,14 @@ public ValueDesc intersect(ValueDesc other) {
* a > 1 => (1...+∞)
*/
public static class RangeValue extends ValueDesc {
- Range range;
+ Range range;
- public RangeValue(ExpressionRewriteContext context, Expression reference, Range range) {
+ public RangeValue(ExpressionRewriteContext context, Expression reference, Range range) {
super(context, reference);
this.range = range;
}
- public Range getRange() {
+ public Range getRange() {
return range;
}
@@ -387,15 +389,15 @@ public String toString() {
* a in (1,2,3) => [1,2,3]
*/
public static class DiscreteValue extends ValueDesc {
- final Set values;
+ final Set values;
public DiscreteValue(ExpressionRewriteContext context,
- Expression reference, Set values) {
+ Expression reference, Set values) {
super(context, reference);
this.values = values;
}
- public Set getValues() {
+ public Set getValues() {
return values;
}
@@ -405,7 +407,7 @@ public ValueDesc union(ValueDesc other) {
return other.union(this);
}
if (other instanceof DiscreteValue) {
- Set newValues = Sets.newHashSet();
+ Set newValues = Sets.newHashSet();
newValues.addAll(((DiscreteValue) other).values);
newValues.addAll(this.values);
return new DiscreteValue(context, reference, newValues);
@@ -422,7 +424,7 @@ public ValueDesc intersect(ValueDesc other) {
return other.intersect(this);
}
if (other instanceof DiscreteValue) {
- Set newValues = Sets.newHashSet();
+ Set newValues = Sets.newHashSet();
newValues.addAll(((DiscreteValue) other).values);
newValues.retainAll(this.values);
if (newValues.isEmpty()) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyArithmeticComparisonRule.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyArithmeticComparisonRule.java
index 853b5a3dfc98c0..c08f3aafea6bc3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyArithmeticComparisonRule.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyArithmeticComparisonRule.java
@@ -37,6 +37,7 @@
import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondsSub;
import org.apache.doris.nereids.trees.expressions.functions.scalar.WeeksAdd;
import org.apache.doris.nereids.trees.expressions.functions.scalar.WeeksSub;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.util.TypeCoercionUtils;
@@ -124,7 +125,7 @@ private static List tryRearrangeChildren(Expression left, Expression
if (!left.child(1).isConstant()) {
throw new RuntimeException(String.format("Expected literal when arranging children for Expr %s", left));
}
- Literal leftLiteral = (Literal) FoldConstantRule.evaluate(left.child(1), context);
+ ComparableLiteral leftLiteral = (ComparableLiteral) FoldConstantRule.evaluate(left.child(1), context);
Expression leftExpr = left.child(0);
Class extends Expression> oppositeOperator = REARRANGEMENT_MAP.get(left.getClass());
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java
index 6ac69f1eb56375..097214e50b7c68 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/SimplifyRange.java
@@ -32,6 +32,7 @@
import org.apache.doris.nereids.trees.expressions.GreaterThanEqual;
import org.apache.doris.nereids.trees.expressions.LessThan;
import org.apache.doris.nereids.trees.expressions.LessThanEqual;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.util.ExpressionUtils;
@@ -43,6 +44,7 @@
import org.apache.commons.lang3.NotImplementedException;
import java.util.List;
+import java.util.stream.Collectors;
/**
* This class implements the function to simplify expression range.
@@ -104,20 +106,20 @@ private Expression getExpression(EmptyValue value) {
private Expression getExpression(RangeValue value) {
Expression reference = value.getReference();
- Range range = value.getRange();
+ Range range = value.getRange();
List result = Lists.newArrayList();
if (range.hasLowerBound()) {
if (range.lowerBoundType() == BoundType.CLOSED) {
- result.add(new GreaterThanEqual(reference, range.lowerEndpoint()));
+ result.add(new GreaterThanEqual(reference, (Literal) range.lowerEndpoint()));
} else {
- result.add(new GreaterThan(reference, range.lowerEndpoint()));
+ result.add(new GreaterThan(reference, (Literal) range.lowerEndpoint()));
}
}
if (range.hasUpperBound()) {
if (range.upperBoundType() == BoundType.CLOSED) {
- result.add(new LessThanEqual(reference, range.upperEndpoint()));
+ result.add(new LessThanEqual(reference, (Literal) range.upperEndpoint()));
} else {
- result.add(new LessThan(reference, range.upperEndpoint()));
+ result.add(new LessThan(reference, (Literal) range.upperEndpoint()));
}
}
if (!result.isEmpty()) {
@@ -128,7 +130,8 @@ private Expression getExpression(RangeValue value) {
}
private Expression getExpression(DiscreteValue value) {
- return ExpressionUtils.toInPredicateOrEqualTo(value.getReference(), value.getValues());
+ return ExpressionUtils.toInPredicateOrEqualTo(value.getReference(),
+ value.getValues().stream().map(Literal.class::cast).collect(Collectors.toList()));
}
private Expression getExpression(UnknownValue value) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
index d343f6f93566cd..8c760ed55c7fed 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java
@@ -64,6 +64,8 @@ public void checkLegalityBeforeTypeCoercion() {
for (Expression c : children) {
if (c.getDataType().isComplexType() && !c.getDataType().isArrayType()) {
throw new AnalysisException("comparison predicate could not contains complex type: " + this.toSql());
+ } else if (c.getDataType().isJsonType()) {
+ throw new AnalysisException("comparison predicate could not contains json type: " + this.toSql());
}
}
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InPredicate.java
index 57cc8c73c8b6c9..5a9c9aaecc172a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InPredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/InPredicate.java
@@ -19,16 +19,16 @@
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.exceptions.UnboundException;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.BooleanType;
import org.apache.doris.nereids.types.DataType;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.List;
@@ -168,11 +168,22 @@ public boolean isLiteralChildren() {
return true;
}
- //use for ut
+ /**
+ * sort options, only use in ut
+ */
+ @VisibleForTesting
public Expression sortOptions() {
- if (isLiteralChildren()) {
- List values = options.stream().map(e -> (Literal) e).collect(Collectors.toList());
- return new InPredicate(compareExpr, Lists.newArrayList(Sets.newTreeSet(values)));
+ if (options.stream().allMatch(x -> x instanceof ComparableLiteral)) {
+ try {
+ List values = options.stream().map(e -> (ComparableLiteral) e)
+ .sorted()
+ .distinct()
+ .map(Literal.class::cast)
+ .collect(Collectors.toList());
+ return new InPredicate(compareExpr, values);
+ } catch (Exception e) {
+ return this;
+ }
}
return this;
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UnixTimestamp.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UnixTimestamp.java
index 178187ad9cbc65..9a968c189c4dc8 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UnixTimestamp.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/UnixTimestamp.java
@@ -21,6 +21,7 @@
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import org.apache.doris.nereids.trees.expressions.functions.Monotonic;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
@@ -176,7 +177,8 @@ public boolean isMonotonic(Literal lower, Literal upper) {
if (null == upper) {
upper = DateTimeLiteral.MAX_DATETIME;
}
- if (lower.compareTo(MAX) <= 0 && upper.compareTo(MAX) > 0) {
+ if (((ComparableLiteral) lower).compareTo(MAX) <= 0
+ && ((ComparableLiteral) upper).compareTo(MAX) > 0) {
return false;
} else {
return true;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ArrayLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ArrayLiteral.java
index be84a5b32e35cf..e5d3b38b2f914b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ArrayLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ArrayLiteral.java
@@ -36,7 +36,7 @@
/**
* ArrayLiteral
*/
-public class ArrayLiteral extends Literal {
+public class ArrayLiteral extends Literal implements ComparableLiteral {
private final List items;
@@ -70,6 +70,39 @@ public LiteralExpr toLegacyLiteral() {
return new org.apache.doris.analysis.ArrayLiteral(getDataType().toCatalogDataType(), itemExprs);
}
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof ArrayLiteral) {
+ ArrayLiteral otherArray = (ArrayLiteral) other;
+ int size = Math.min(otherArray.items.size(), this.items.size());
+ for (int i = 0; i < size; i++) {
+ Literal thisItem = items.get(i);
+ Literal otherItem = otherArray.items.get(i);
+ if (!(thisItem instanceof ComparableLiteral)) {
+ throw new RuntimeException(
+ "array item '" + thisItem + "' (" + thisItem.dataType + ") is not comparable");
+ }
+ if (!(otherItem instanceof ComparableLiteral)) {
+ throw new RuntimeException(
+ "array item '" + otherItem + "' (" + otherItem.dataType + ") is not comparable");
+ }
+ int cmp = ((ComparableLiteral) thisItem).compareTo((ComparableLiteral) otherItem);
+ if (cmp != 0) {
+ return cmp;
+ }
+ }
+ return Integer.compare(this.items.size(), otherArray.items.size());
+ }
+ if (other instanceof NullLiteral) {
+ return 1;
+ }
+ if (other instanceof MaxLiteral) {
+ return -1;
+ }
+ throw new RuntimeException("Cannot compare two values with different data types: "
+ + this + " (" + dataType + ") vs " + other + " (" + ((Literal) other).dataType + ")");
+ }
+
@Override
protected Expression uncheckedCastTo(DataType targetType) throws AnalysisException {
if (this.dataType.equals(targetType)) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/BooleanLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/BooleanLiteral.java
index f3b884dc15b3a7..210fe4c891216e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/BooleanLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/BooleanLiteral.java
@@ -25,7 +25,7 @@
/**
* Represents Boolean literal
*/
-public class BooleanLiteral extends Literal {
+public class BooleanLiteral extends Literal implements ComparableLiteral {
public static final BooleanLiteral TRUE = new BooleanLiteral(true);
public static final BooleanLiteral FALSE = new BooleanLiteral(false);
@@ -69,6 +69,21 @@ public LiteralExpr toLegacyLiteral() {
return new BoolLiteral(value);
}
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof BooleanLiteral) {
+ return Boolean.compare(value, ((BooleanLiteral) other).value);
+ }
+ if (other instanceof NullLiteral) {
+ return 1;
+ }
+ if (other instanceof MaxLiteral) {
+ return -1;
+ }
+ throw new RuntimeException("Cannot compare two values with different data types: "
+ + this + " (" + dataType + ") vs " + other + " (" + ((Literal) other).dataType + ")");
+ }
+
@Override
public double getDouble() {
if (value) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/CharLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/CharLiteral.java
index e1ca1fa3cebbc3..10e276b4abdca1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/CharLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/CharLiteral.java
@@ -17,8 +17,6 @@
package org.apache.doris.nereids.trees.expressions.literal;
-import org.apache.doris.analysis.LiteralExpr;
-import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.CharType;
@@ -31,18 +29,8 @@ public CharLiteral(String value, int len) {
super(len >= 0 ? value.substring(0, Math.min(value.length(), len)) : value, CharType.createCharType(len));
}
- @Override
- public String getValue() {
- return value;
- }
-
@Override
public R accept(ExpressionVisitor visitor, C context) {
return visitor.visitCharLiteral(this, context);
}
-
- @Override
- public LiteralExpr toLegacyLiteral() {
- return new StringLiteral(value);
- }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ComparableLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ComparableLiteral.java
new file mode 100644
index 00000000000000..00f734fd66bc8f
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ComparableLiteral.java
@@ -0,0 +1,24 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.literal;
+
+/**
+ * comparable literal
+ */
+public interface ComparableLiteral extends Comparable {
+}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java
index 3bfc4a7dc81436..d6dc97343faa1e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DateLiteral.java
@@ -42,7 +42,7 @@
/**
* Date literal in Nereids.
*/
-public class DateLiteral extends Literal {
+public class DateLiteral extends Literal implements ComparableLiteral {
public static final String JAVA_DATE_FORMAT = "yyyy-MM-dd";
public static final Set punctuations = ImmutableSet.of('!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
@@ -458,6 +458,30 @@ public LiteralExpr toLegacyLiteral() {
return new org.apache.doris.analysis.DateLiteral(year, month, day, Type.DATE);
}
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof DateLiteral) {
+ int cmp = Long.compare(getValue(), ((DateLiteral) other).getValue());
+ if (cmp != 0) {
+ return cmp;
+ }
+
+ long thisMicrosecond = this instanceof DateTimeV2Literal ? ((DateTimeV2Literal) this).getMicroSecond() : 0L;
+ long otherMicrosecond = other instanceof DateTimeV2Literal
+ ? ((DateTimeV2Literal) other).getMicroSecond() : 0L;
+ return Long.compare(thisMicrosecond, otherMicrosecond);
+ }
+ if (other instanceof NullLiteral) {
+ return 1;
+ }
+ if (other instanceof MaxLiteral) {
+ return -1;
+ }
+
+ throw new RuntimeException("Cannot compare two values with different data types: "
+ + this + " (" + dataType + ") vs " + other + " (" + ((Literal) other).dataType + ")");
+ }
+
public long getYear() {
return year;
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalLiteral.java
index 1f0aa788cdc641..6b02ce002f8fcd 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalLiteral.java
@@ -51,6 +51,11 @@ public DecimalLiteral(DecimalV2Type dataType, BigDecimal value) {
this.value = Objects.requireNonNull(adjustedValue);
}
+ @Override
+ protected BigDecimal getBigDecimalValue() {
+ return value;
+ }
+
@Override
public BigDecimal getValue() {
return value;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalV3Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalV3Literal.java
index 045da28bdb38a4..8067070a1812b1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalV3Literal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DecimalV3Literal.java
@@ -77,6 +77,11 @@ public double getDouble() {
return value.doubleValue();
}
+ @Override
+ protected BigDecimal getBigDecimalValue() {
+ return value;
+ }
+
/**
* get ceiling of a decimal v3 literal
* @param newScale scale we want to cast to
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DoubleLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DoubleLiteral.java
index bc7b356c3762fe..7c2141818d7acb 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DoubleLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/DoubleLiteral.java
@@ -23,6 +23,8 @@
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DoubleType;
+import java.math.BigDecimal;
+
/**
* Double literal
*/
@@ -35,6 +37,11 @@ public DoubleLiteral(double value) {
this.value = value;
}
+ @Override
+ protected BigDecimal getBigDecimalValue() {
+ return new BigDecimal(String.valueOf(value));
+ }
+
@Override
public Double getValue() {
return value;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/FloatLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/FloatLiteral.java
index df75bbcfc5c440..7af1e196fa02db 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/FloatLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/FloatLiteral.java
@@ -22,6 +22,8 @@
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.FloatType;
+import java.math.BigDecimal;
+
/**
* float type literal
*/
@@ -34,6 +36,11 @@ public FloatLiteral(float value) {
this.value = value;
}
+ @Override
+ protected BigDecimal getBigDecimalValue() {
+ return new BigDecimal(String.valueOf(value));
+ }
+
@Override
public Float getValue() {
return value;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv4Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv4Literal.java
index e4e931738b02a2..a5bfdb1a671f8a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv4Literal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv4Literal.java
@@ -27,7 +27,7 @@
/**
* Represents IPv4 literal
*/
-public class IPv4Literal extends Literal {
+public class IPv4Literal extends Literal implements ComparableLiteral {
private static final Pattern IPV4_STD_REGEX =
Pattern.compile("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
@@ -59,6 +59,21 @@ public LiteralExpr toLegacyLiteral() {
return new org.apache.doris.analysis.IPv4Literal(value);
}
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof IPv4Literal) {
+ return Long.compare(value, ((IPv4Literal) other).value);
+ }
+ if (other instanceof NullLiteral) {
+ return 1;
+ }
+ if (other instanceof MaxLiteral) {
+ return -1;
+ }
+ throw new RuntimeException("Cannot compare two values with different data types: "
+ + this + " (" + dataType + ") vs " + other + " (" + ((Literal) other).dataType + ")");
+ }
+
void init(String ipv4) throws AnalysisException {
checkValueValid(ipv4);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv6Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv6Literal.java
index 0ac12ae85e477a..c26cc9b707297c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv6Literal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IPv6Literal.java
@@ -22,28 +22,30 @@
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.IPv6Type;
+import com.googlecode.ipv6.IPv6Address;
+
import java.util.regex.Pattern;
/**
* Represents IPv6 literal
*/
-public class IPv6Literal extends Literal {
+public class IPv6Literal extends Literal implements ComparableLiteral {
private static final Pattern IPV6_STD_REGEX =
Pattern.compile("^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
private static final Pattern IPV6_COMPRESS_REGEX =
Pattern.compile("^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4})*)?)::((([0-9A-Fa-f]{1,4}:)*[0-9A-Fa-f]{1,4})?)$");
- private final String value;
+ private final IPv6Address value;
public IPv6Literal(String ipv6) throws AnalysisException {
super(IPv6Type.INSTANCE);
checkValueValid(ipv6);
- this.value = ipv6;
+ this.value = IPv6Address.fromString(ipv6);
}
@Override
- public String getValue() {
+ public IPv6Address getValue() {
return value;
}
@@ -55,12 +57,27 @@ public R accept(ExpressionVisitor visitor, C context) {
@Override
public LiteralExpr toLegacyLiteral() {
try {
- return new org.apache.doris.analysis.IPv6Literal(value);
+ return new org.apache.doris.analysis.IPv6Literal(value.toString());
} catch (Exception e) {
throw new AnalysisException("Invalid IPv6 format.");
}
}
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof IPv6Literal) {
+ return value.compareTo(((IPv6Literal) other).value);
+ }
+ if (other instanceof NullLiteral) {
+ return 1;
+ }
+ if (other instanceof MaxLiteral) {
+ return -1;
+ }
+ throw new RuntimeException("Cannot compare two values with different data types: "
+ + this + " (" + dataType + ") vs " + other + " (" + ((Literal) other).dataType + ")");
+ }
+
public void checkValueValid(String ipv6) throws AnalysisException {
if (ipv6.length() > 39) {
throw new AnalysisException("The length of IPv6 must not exceed 39.");
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IntegerLikeLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IntegerLikeLiteral.java
index 54456bd9493564..8fe34c3ece055f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IntegerLikeLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/IntegerLikeLiteral.java
@@ -19,6 +19,8 @@
import org.apache.doris.nereids.types.DataType;
+import java.math.BigDecimal;
+
/** IntegralLiteral */
public abstract class IntegerLikeLiteral extends NumericLiteral {
/**
@@ -38,5 +40,10 @@ public long getLongValue() {
return getNumber().longValue();
}
+ @Override
+ protected BigDecimal getBigDecimalValue() {
+ return new BigDecimal(getLongValue());
+ }
+
public abstract Number getNumber();
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/LargeIntLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/LargeIntLiteral.java
index 5f9d60a2ff72b5..bdefdafad1df4d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/LargeIntLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/LargeIntLiteral.java
@@ -22,6 +22,7 @@
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.LargeIntType;
+import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Objects;
@@ -62,6 +63,11 @@ public double getDouble() {
return value.doubleValue();
}
+ @Override
+ protected BigDecimal getBigDecimalValue() {
+ return new BigDecimal(value);
+ }
+
@Override
public Number getNumber() {
return value;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java
index bb6bbe62a6c292..60ffedcedbe755 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java
@@ -54,7 +54,7 @@
* All data type literal expression in Nereids.
* TODO: Increase the implementation of sub expression. such as Integer.
*/
-public abstract class Literal extends Expression implements LeafExpression, Comparable {
+public abstract class Literal extends Expression implements LeafExpression {
protected final DataType dataType;
@@ -157,14 +157,6 @@ public R accept(ExpressionVisitor visitor, C context) {
return visitor.visitLiteral(this, context);
}
- /**
- * literal expr compare.
- */
- @Override
- public int compareTo(Literal other) {
- return toLegacyLiteral().compareLiteral(other.toLegacyLiteral());
- }
-
/**
* literal expr compare.
*/
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MaxLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MaxLiteral.java
index 763fdfb1f4f1f8..8d688feefde01a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MaxLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MaxLiteral.java
@@ -22,7 +22,7 @@
import org.apache.doris.nereids.types.DataType;
/** MaxLiteral */
-public class MaxLiteral extends Literal {
+public class MaxLiteral extends Literal implements ComparableLiteral {
public MaxLiteral(DataType dataType) {
super(dataType);
}
@@ -37,6 +37,14 @@ public LiteralExpr toLegacyLiteral() {
return org.apache.doris.analysis.MaxLiteral.MAX_VALUE;
}
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof MaxLiteral) {
+ return 0;
+ }
+ return 1;
+ }
+
@Override
public String computeToSql() {
return "MAX_VALUE";
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/NullLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/NullLiteral.java
index 5af08e6d130a43..80f7514e0f90b9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/NullLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/NullLiteral.java
@@ -27,7 +27,7 @@
/**
* Represents Null literal
*/
-public class NullLiteral extends Literal {
+public class NullLiteral extends Literal implements ComparableLiteral {
public static final NullLiteral INSTANCE = new NullLiteral();
@@ -59,6 +59,14 @@ public LiteralExpr toLegacyLiteral() {
return org.apache.doris.analysis.NullLiteral.create(dataType.toCatalogDataType());
}
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof NullLiteral) {
+ return 0;
+ }
+ return -1;
+ }
+
@Override
public double getDouble() {
return 0;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/NumericLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/NumericLiteral.java
index 93b03e4fafaf02..b22c9e3a6fc039 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/NumericLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/NumericLiteral.java
@@ -19,10 +19,13 @@
import org.apache.doris.nereids.types.DataType;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
/**
* numeric literal
*/
-public abstract class NumericLiteral extends Literal {
+public abstract class NumericLiteral extends Literal implements ComparableLiteral {
/**
* Constructor for NumericLiteral.
*
@@ -31,4 +34,39 @@ public abstract class NumericLiteral extends Literal {
public NumericLiteral(DataType dataType) {
super(dataType);
}
+
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof NumericLiteral) {
+ if (this instanceof IntegerLikeLiteral && other instanceof IntegerLikeLiteral) {
+ IntegerLikeLiteral thisInteger = (IntegerLikeLiteral) this;
+ IntegerLikeLiteral otherInteger = (IntegerLikeLiteral) other;
+ if (this instanceof LargeIntLiteral || other instanceof LargeIntLiteral) {
+ BigInteger leftValue = this instanceof LargeIntLiteral ? ((LargeIntLiteral) this).getValue()
+ : new BigInteger(String.valueOf(thisInteger.getLongValue()));
+ BigInteger rightValue = other instanceof LargeIntLiteral ? ((LargeIntLiteral) other).getValue()
+ : new BigInteger(String.valueOf(otherInteger.getLongValue()));
+ return leftValue.compareTo(rightValue);
+ } else {
+ return Long.compare(((IntegerLikeLiteral) this).getLongValue(),
+ ((IntegerLikeLiteral) other).getLongValue());
+ }
+ }
+ if (this instanceof DecimalLiteral || this instanceof DecimalV3Literal
+ || other instanceof DecimalLiteral || other instanceof DecimalV3Literal) {
+ return this.getBigDecimalValue().compareTo(((NumericLiteral) other).getBigDecimalValue());
+ }
+ return Double.compare(this.getDouble(), ((Literal) other).getDouble());
+ }
+ if (other instanceof NullLiteral) {
+ return 1;
+ }
+ if (other instanceof MaxLiteral) {
+ return -1;
+ }
+ throw new RuntimeException("Cannot compare two values with different data types: "
+ + this + " (" + dataType + ") vs " + other + " (" + ((Literal) other).dataType + ")");
+ }
+
+ protected abstract BigDecimal getBigDecimalValue();
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StringLikeLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StringLikeLiteral.java
index dba9247fe70213..546e0ab64c9684 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StringLikeLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StringLikeLiteral.java
@@ -17,14 +17,17 @@
package org.apache.doris.nereids.trees.expressions.literal;
+import org.apache.doris.analysis.LiteralExpr;
+import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.types.DataType;
+import java.io.UnsupportedEncodingException;
import java.util.Objects;
/**
* StringLikeLiteral.
*/
-public abstract class StringLikeLiteral extends Literal {
+public abstract class StringLikeLiteral extends Literal implements ComparableLiteral {
public static final int CHINESE_CHAR_BYTE_LENGTH = 4;
public final String value;
@@ -62,6 +65,59 @@ public String getValue() {
return value;
}
+ @Override
+ public LiteralExpr toLegacyLiteral() {
+ return new org.apache.doris.analysis.StringLiteral(value);
+ }
+
+ @Override
+ public int compareTo(ComparableLiteral other) {
+ if (other instanceof StringLikeLiteral) {
+ // compare string with utf-8 byte array, same with DM,BE,StorageEngine
+ byte[] thisBytes = null;
+ byte[] otherBytes = null;
+ try {
+ thisBytes = getStringValue().getBytes("UTF-8");
+ otherBytes = ((Literal) other).getStringValue().getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new AnalysisException(e.getMessage(), e);
+ }
+
+ int minLength = Math.min(thisBytes.length, otherBytes.length);
+ int i = 0;
+ for (i = 0; i < minLength; i++) {
+ if (Byte.toUnsignedInt(thisBytes[i]) < Byte.toUnsignedInt(otherBytes[i])) {
+ return -1;
+ } else if (Byte.toUnsignedInt(thisBytes[i]) > Byte.toUnsignedInt(otherBytes[i])) {
+ return 1;
+ }
+ }
+ if (thisBytes.length > otherBytes.length) {
+ if (thisBytes[i] == 0x00) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else if (thisBytes.length < otherBytes.length) {
+ if (otherBytes[i] == 0x00) {
+ return 0;
+ } else {
+ return -1;
+ }
+ } else {
+ return 0;
+ }
+ }
+ if (other instanceof NullLiteral) {
+ return 1;
+ }
+ if (other instanceof MaxLiteral) {
+ return -1;
+ }
+ throw new RuntimeException("Cannot compare two values with different data types: "
+ + this + " (" + dataType + ") vs " + other + " (" + ((Literal) other).dataType + ")");
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StringLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StringLiteral.java
index 603749c60b376d..4971248ad70140 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StringLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StringLiteral.java
@@ -17,7 +17,6 @@
package org.apache.doris.nereids.trees.expressions.literal;
-import org.apache.doris.analysis.LiteralExpr;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.StringType;
@@ -26,8 +25,6 @@
*/
public class StringLiteral extends StringLikeLiteral {
- private final String value;
-
/**
* Constructor for Literal.
*
@@ -35,21 +32,10 @@ public class StringLiteral extends StringLikeLiteral {
*/
public StringLiteral(String value) {
super(value, StringType.INSTANCE);
- this.value = value;
- }
-
- @Override
- public String getValue() {
- return value;
}
@Override
public R accept(ExpressionVisitor visitor, C context) {
return visitor.visitStringLiteral(this, context);
}
-
- @Override
- public LiteralExpr toLegacyLiteral() {
- return new org.apache.doris.analysis.StringLiteral(value);
- }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/VarcharLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/VarcharLiteral.java
index 75161dd00042a8..e2860fcf027c74 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/VarcharLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/VarcharLiteral.java
@@ -17,8 +17,6 @@
package org.apache.doris.nereids.trees.expressions.literal;
-import org.apache.doris.analysis.LiteralExpr;
-import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.VarcharType;
@@ -36,18 +34,8 @@ public VarcharLiteral(String value, int len) {
super(len >= 0 ? value.substring(0, Math.min(value.length(), len)) : value, VarcharType.createVarcharType(len));
}
- @Override
- public String getValue() {
- return getStringValue();
- }
-
@Override
public R accept(ExpressionVisitor visitor, C context) {
return visitor.visitVarcharLiteral(this, context);
}
-
- @Override
- public LiteralExpr toLegacyLiteral() {
- return new StringLiteral(value);
- }
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java
index 3d8aef2c8428ab..d26f73195f79c4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/ExpressionUtils.java
@@ -56,6 +56,7 @@
import org.apache.doris.nereids.trees.expressions.functions.agg.Min;
import org.apache.doris.nereids.trees.expressions.functions.agg.Sum;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
@@ -585,9 +586,9 @@ public static boolean isAllLiteral(List children) {
/**
* return true if all children are literal but not null literal.
*/
- public static boolean isAllNonNullLiteral(List children) {
+ public static boolean isAllNonNullComparableLiteral(List children) {
for (Expression child : children) {
- if ((!(child instanceof Literal)) || (child instanceof NullLiteral)) {
+ if ((!(child instanceof ComparableLiteral)) || (child instanceof NullLiteral)) {
return false;
}
}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
index 624a47f11bd132..fd522512ef5caf 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
@@ -64,6 +64,7 @@
import org.apache.doris.nereids.trees.expressions.functions.scalar.ToDays;
import org.apache.doris.nereids.trees.expressions.functions.scalar.UnixTimestamp;
import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.ComparableLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
@@ -280,11 +281,11 @@ void testFoldString() {
ConvertTz c = new ConvertTz(DateTimeV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
StringLiteral.of("Asia/Shanghai"), StringLiteral.of("GMT"));
Expression rewritten = executor.rewrite(c, context);
- Assertions.assertTrue(new DateTimeV2Literal("0000-12-31 16:55:18.000000").compareTo((Literal) rewritten) == 0);
+ Assertions.assertTrue(new DateTimeV2Literal("0000-12-31 16:55:18.000000").compareTo((ComparableLiteral) rewritten) == 0);
c = new ConvertTz(DateTimeV2Literal.fromJavaDateType(LocalDateTime.of(9999, 12, 31, 23, 59, 59, 999999000)),
StringLiteral.of("Pacific/Galapagos"), StringLiteral.of("Pacific/Galapagos"));
rewritten = executor.rewrite(c, context);
- Assertions.assertTrue(new DateTimeV2Literal("9999-12-31 23:59:59.999999").compareTo((Literal) rewritten) == 0);
+ Assertions.assertTrue(new DateTimeV2Literal("9999-12-31 23:59:59.999999").compareTo((ComparableLiteral) rewritten) == 0);
DateFormat d = new DateFormat(DateTimeLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
StringLiteral.of("%y %m %d"));
@@ -310,7 +311,7 @@ void testFoldString() {
t = new DateTrunc(DateTimeV2Literal.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
StringLiteral.of("week"));
rewritten = executor.rewrite(t, context);
- Assertions.assertTrue(((Literal) rewritten).compareTo(new DateTimeV2Literal("0001-01-01 00:00:00.000000")) == 0);
+ Assertions.assertTrue(((ComparableLiteral) rewritten).compareTo(new DateTimeV2Literal("0001-01-01 00:00:00.000000")) == 0);
t = new DateTrunc(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
StringLiteral.of("week"));
rewritten = executor.rewrite(t, context);
@@ -862,9 +863,9 @@ void testDateTimeV2TypeDateTimeArithmeticFunctions() {
new DateTimeLiteral("2023-05-07 02:41:42"),
new VarcharLiteral("%x %v %X %V")).toSql());
- Assertions.assertTrue(new DateTimeV2Literal("2021-01-01 12:12:14.000000").compareTo((Literal) TimeRoundSeries
+ Assertions.assertTrue(new DateTimeV2Literal("2021-01-01 12:12:14.000000").compareTo((ComparableLiteral) TimeRoundSeries
.secondCeil(new DateTimeV2Literal("2021-01-01 12:12:12.123"), new IntegerLiteral(2))) == 0);
- Assertions.assertTrue(new DateTimeV2Literal("2021-01-01 12:12:12.000000").compareTo((Literal) TimeRoundSeries
+ Assertions.assertTrue(new DateTimeV2Literal("2021-01-01 12:12:12.000000").compareTo((ComparableLiteral) TimeRoundSeries
.secondFloor(new DateTimeV2Literal("2021-01-01 12:12:12.123"), new IntegerLiteral(2))) == 0);
}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/CompareLiteralTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/CompareLiteralTest.java
new file mode 100644
index 00000000000000..887b7673877b78
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/CompareLiteralTest.java
@@ -0,0 +1,326 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.literal;
+
+import org.apache.doris.common.ExceptionChecker;
+import org.apache.doris.nereids.types.IntegerType;
+import org.apache.doris.utframe.TestWithFeService;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+class CompareLiteralTest extends TestWithFeService {
+
+ @Test
+ public void testScalar() {
+ // boolean type
+ checkCompareSameType(0, BooleanLiteral.of(true), BooleanLiteral.of(true));
+ checkCompareSameType(1, BooleanLiteral.of(true), BooleanLiteral.of(false));
+ checkCompareDiffType(BooleanLiteral.of(true), new IntegerLiteral(0));
+ checkCompareDiffType(BooleanLiteral.of(true), new DoubleLiteral(0.5));
+ checkCompareDiffType(BooleanLiteral.of(true), new DecimalLiteral(new BigDecimal("0.5")));
+ checkCompareDiffType(BooleanLiteral.of(true), new IntegerLiteral(1));
+ checkCompareDiffType(BooleanLiteral.of(true), new DoubleLiteral(1.0));
+ checkCompareDiffType(BooleanLiteral.of(true), new DecimalLiteral(new BigDecimal("1.0")));
+ checkCompareDiffType(BooleanLiteral.of(true), new StringLiteral("tru"));
+ checkCompareDiffType(BooleanLiteral.of(true), new StringLiteral("true"));
+ checkCompareDiffType(BooleanLiteral.of(true), new StringLiteral("truea"));
+ checkCompareSameType(0, BooleanLiteral.of(false), BooleanLiteral.of(false));
+ checkCompareDiffType(BooleanLiteral.of(false), new IntegerLiteral(0));
+ checkCompareDiffType(BooleanLiteral.of(false), new DoubleLiteral(0.5));
+ checkCompareDiffType(BooleanLiteral.of(false), new DecimalLiteral(new BigDecimal("0.5")));
+ checkCompareDiffType(BooleanLiteral.of(false), new IntegerLiteral(1));
+ checkCompareDiffType(BooleanLiteral.of(false), new DoubleLiteral(1.0));
+ checkCompareDiffType(BooleanLiteral.of(false), new DecimalLiteral(new BigDecimal("1.0")));
+ checkCompareDiffType(BooleanLiteral.of(false), new StringLiteral("fals"));
+ checkCompareDiffType(BooleanLiteral.of(false), new StringLiteral("false"));
+ checkCompareDiffType(BooleanLiteral.of(false), new StringLiteral("falsea"));
+
+ // numeric type
+ checkCompareSameType(0, new TinyIntLiteral((byte) 127), new TinyIntLiteral((byte) 127));
+ checkCompareSameType(0, new TinyIntLiteral((byte) 127), new DoubleLiteral(127.0));
+ checkCompareSameType(0, new TinyIntLiteral((byte) 127), new DecimalLiteral(new BigDecimal("127.0")));
+ checkCompareSameType(0, new TinyIntLiteral((byte) 127), new DecimalV3Literal(new BigDecimal("127.0")));
+ checkCompareDiffType(new TinyIntLiteral((byte) 127), new StringLiteral("12"));
+ checkCompareDiffType(new TinyIntLiteral((byte) 127), new StringLiteral("127"));
+ checkCompareDiffType(new TinyIntLiteral((byte) 127), new StringLiteral("127.0"));
+ checkCompareSameType(-1, new TinyIntLiteral((byte) 127), new SmallIntLiteral((short) 32767));
+ checkCompareSameType(-1, new TinyIntLiteral((byte) 127), new DoubleLiteral(32767.0));
+ checkCompareSameType(-1, new TinyIntLiteral((byte) 127), new DecimalLiteral(new BigDecimal("32767")));
+ checkCompareSameType(-1, new TinyIntLiteral((byte) 127), new DecimalV3Literal(new BigDecimal("32767")));
+ checkCompareSameType(-1, new TinyIntLiteral((byte) 127), new IntegerLiteral(2147483647));
+ checkCompareSameType(-1, new TinyIntLiteral((byte) 127), new BigIntLiteral(9223372036854775807L));
+ checkCompareSameType(-1, new TinyIntLiteral((byte) 127), new LargeIntLiteral(new BigInteger("9223372036854775808")));
+
+ checkCompareSameType(0, new SmallIntLiteral((short) 32767), new SmallIntLiteral((short) 32767));
+ checkCompareSameType(0, new SmallIntLiteral((short) 32767), new DoubleLiteral(32767.0));
+ checkCompareSameType(0, new SmallIntLiteral((short) 32767), new DecimalLiteral(new BigDecimal("32767.0")));
+ checkCompareSameType(0, new SmallIntLiteral((short) 32767), new DecimalV3Literal(new BigDecimal("32767.0")));
+ checkCompareDiffType(new SmallIntLiteral((short) 32767), new StringLiteral("3276"));
+ checkCompareDiffType(new SmallIntLiteral((short) 32767), new StringLiteral("32767"));
+ checkCompareDiffType(new SmallIntLiteral((short) 32767), new StringLiteral("32767.0"));
+ checkCompareSameType(-1, new SmallIntLiteral((short) 32767), new IntegerLiteral(2147483647));
+ checkCompareSameType(-1, new SmallIntLiteral((short) 32767), new DoubleLiteral(2147483647.0));
+ checkCompareSameType(-1, new SmallIntLiteral((short) 32767), new DecimalLiteral(new BigDecimal("2147483647")));
+ checkCompareSameType(-1, new SmallIntLiteral((short) 32767), new DecimalV3Literal(new BigDecimal("2147483647")));
+ checkCompareSameType(-1, new SmallIntLiteral((short) 32767), new BigIntLiteral(9223372036854775807L));
+ checkCompareSameType(-1, new SmallIntLiteral((short) 32767), new LargeIntLiteral(new BigInteger("9223372036854775808")));
+
+ checkCompareSameType(0, new IntegerLiteral(2147483647), new IntegerLiteral(2147483647));
+ checkCompareSameType(0, new IntegerLiteral(2147483647), new DoubleLiteral(2147483647.0));
+ checkCompareSameType(0, new IntegerLiteral(2147483647), new DecimalLiteral(new BigDecimal("2147483647.0")));
+ checkCompareSameType(0, new IntegerLiteral(2147483647), new DecimalV3Literal(new BigDecimal("2147483647.0")));
+ checkCompareDiffType(new IntegerLiteral(2147483647), new StringLiteral("214748364"));
+ checkCompareDiffType(new IntegerLiteral(2147483647), new StringLiteral("2147483647"));
+ checkCompareDiffType(new IntegerLiteral(2147483647), new StringLiteral("2147483647.0"));
+ checkCompareSameType(-1, new IntegerLiteral(2147483647), new DecimalLiteral(new BigDecimal("922337203685477580")));
+ checkCompareSameType(-1, new IntegerLiteral(2147483647), new DecimalV3Literal(new BigDecimal("9223372036854775807")));
+ checkCompareSameType(-1, new IntegerLiteral(2147483647), new BigIntLiteral(9223372036854775807L));
+ checkCompareSameType(-1, new IntegerLiteral(2147483647), new LargeIntLiteral(new BigInteger("9223372036854775808")));
+
+ checkCompareSameType(0, new BigIntLiteral(9223372036854775807L), new BigIntLiteral(9223372036854775807L));
+ checkCompareSameType(0, new BigIntLiteral(922337203685477580L), new DecimalLiteral(new BigDecimal("922337203685477580.0")));
+ checkCompareSameType(0, new BigIntLiteral(9223372036854775807L), new DecimalV3Literal(new BigDecimal("9223372036854775807.0")));
+ checkCompareDiffType(new BigIntLiteral(9223372036854775807L), new StringLiteral("922337203685477580"));
+ checkCompareDiffType(new BigIntLiteral(9223372036854775807L), new StringLiteral("9223372036854775807"));
+ checkCompareDiffType(new BigIntLiteral(9223372036854775807L), new StringLiteral("9223372036854775807.0"));
+ checkCompareSameType(-1, new BigIntLiteral(922337203685477587L), new DecimalLiteral(new BigDecimal("922337203685477588")));
+ checkCompareSameType(-1, new BigIntLiteral(9223372036854775807L), new DecimalV3Literal(new BigDecimal("9223372036854775808")));
+ checkCompareSameType(-1, new BigIntLiteral(9223372036854775807L), new LargeIntLiteral(new BigInteger("9223372036854775808")));
+
+ checkCompareSameType(0, new LargeIntLiteral(new BigInteger("9223372036854775808")), new LargeIntLiteral(new BigInteger("9223372036854775808")));
+ checkCompareSameType(0, new LargeIntLiteral(new BigInteger("922337203685477588")), new DecimalLiteral(new BigDecimal("922337203685477588.0")));
+ checkCompareSameType(0, new LargeIntLiteral(new BigInteger("9223372036854775808")), new DecimalV3Literal(new BigDecimal("9223372036854775808.0")));
+ checkCompareDiffType(new LargeIntLiteral(new BigInteger("9223372036854775808")), new StringLiteral("922337203685477580"));
+ checkCompareDiffType(new LargeIntLiteral(new BigInteger("9223372036854775808")), new StringLiteral("9223372036854775808"));
+ checkCompareDiffType(new LargeIntLiteral(new BigInteger("9223372036854775808")), new StringLiteral("9223372036854775808.0"));
+ checkCompareSameType(-1, new LargeIntLiteral(new BigInteger("922337203685477588")), new DecimalLiteral(new BigDecimal("922337203685477589")));
+ checkCompareSameType(-1, new LargeIntLiteral(new BigInteger("9223372036854775808")), new DecimalV3Literal(new BigDecimal("9223372036854775809")));
+
+ checkCompareSameType(0, new FloatLiteral(100.5f), new FloatLiteral(100.5f));
+ checkCompareSameType(0, new FloatLiteral(100.5f), new DoubleLiteral(100.5));
+ checkCompareSameType(0, new FloatLiteral(100.5f), new DecimalLiteral(new BigDecimal("100.5")));
+ checkCompareSameType(0, new FloatLiteral(100.5f), new DecimalV3Literal(new BigDecimal("100.5")));
+ checkCompareDiffType(new FloatLiteral(100.0f), new StringLiteral("100"));
+ checkCompareDiffType(new FloatLiteral(100.0f), new StringLiteral("100.0"));
+ checkCompareDiffType(new FloatLiteral(100.0f), new StringLiteral("100.00"));
+ checkCompareSameType(-1, new FloatLiteral(100.5f), new FloatLiteral(100.6f));
+ checkCompareSameType(-1, new FloatLiteral(100.5f), new DoubleLiteral(100.6));
+ checkCompareSameType(-1, new FloatLiteral(100.5f), new DecimalLiteral(new BigDecimal("100.6")));
+ checkCompareSameType(-1, new FloatLiteral(100.5f), new DecimalV3Literal(new BigDecimal("100.6")));
+
+ checkCompareSameType(0, new DoubleLiteral(100.5), new DoubleLiteral(100.5));
+ checkCompareSameType(0, new DoubleLiteral(100.5), new DoubleLiteral(100.5));
+ checkCompareSameType(0, new DoubleLiteral(100.5), new DecimalLiteral(new BigDecimal("100.5")));
+ checkCompareSameType(0, new DoubleLiteral(100.5), new DecimalV3Literal(new BigDecimal("100.5")));
+ checkCompareDiffType(new DoubleLiteral(100.0), new StringLiteral("100"));
+ checkCompareDiffType(new DoubleLiteral(100.0), new StringLiteral("100.0"));
+ checkCompareDiffType(new DoubleLiteral(100.0), new StringLiteral("100.00"));
+ checkCompareSameType(-1, new DoubleLiteral(100.5), new FloatLiteral(100.6f));
+ checkCompareSameType(-1, new DoubleLiteral(100.5), new DoubleLiteral(100.6));
+ checkCompareSameType(-1, new DoubleLiteral(100.5), new DecimalLiteral(new BigDecimal("100.6")));
+ checkCompareSameType(-1, new DoubleLiteral(100.5), new DecimalV3Literal(new BigDecimal("100.6")));
+
+ checkCompareSameType(0, new DecimalLiteral(new BigDecimal("100.5")), new DoubleLiteral(100.5));
+ checkCompareSameType(0, new DecimalLiteral(new BigDecimal("100.5")), new DecimalLiteral(new BigDecimal("100.5")));
+ checkCompareSameType(0, new DecimalLiteral(new BigDecimal("100.5")), new DecimalV3Literal(new BigDecimal("100.5")));
+ checkCompareDiffType(new DecimalLiteral(new BigDecimal("100.0")), new StringLiteral("100"));
+ checkCompareDiffType(new DecimalLiteral(new BigDecimal("100.0")), new StringLiteral("100.0"));
+ checkCompareDiffType(new DecimalLiteral(new BigDecimal("100.0")), new StringLiteral("100.00"));
+ checkCompareSameType(-1, new DecimalLiteral(new BigDecimal("100.5")), new FloatLiteral(100.6f));
+ checkCompareSameType(-1, new DecimalLiteral(new BigDecimal("100.5")), new DoubleLiteral(100.6));
+ checkCompareSameType(-1, new DecimalLiteral(new BigDecimal("100.5")), new DecimalLiteral(new BigDecimal("100.6")));
+ checkCompareSameType(-1, new DecimalLiteral(new BigDecimal("100.5")), new DecimalV3Literal(new BigDecimal("100.6")));
+
+ checkCompareSameType(0, new DecimalV3Literal(new BigDecimal("100.5")), new DoubleLiteral(100.5));
+ checkCompareSameType(0, new DecimalV3Literal(new BigDecimal("100.5")), new DecimalLiteral(new BigDecimal("100.5")));
+ checkCompareSameType(0, new DecimalV3Literal(new BigDecimal("100.5")), new DecimalV3Literal(new BigDecimal("100.5")));
+ checkCompareDiffType(new DecimalV3Literal(new BigDecimal("100.0")), new StringLiteral("100"));
+ checkCompareDiffType(new DecimalV3Literal(new BigDecimal("100.0")), new StringLiteral("100.0"));
+ checkCompareDiffType(new DecimalV3Literal(new BigDecimal("100.0")), new StringLiteral("100.00"));
+ checkCompareSameType(-1, new DecimalV3Literal(new BigDecimal("100.5")), new FloatLiteral(100.6f));
+ checkCompareSameType(-1, new DecimalV3Literal(new BigDecimal("100.5")), new DoubleLiteral(100.6));
+ checkCompareSameType(-1, new DecimalV3Literal(new BigDecimal("100.5")), new DecimalLiteral(new BigDecimal("100.6")));
+ checkCompareSameType(-1, new DecimalV3Literal(new BigDecimal("100.5")), new DecimalV3Literal(new BigDecimal("100.6")));
+
+ // date type
+ checkCompareSameType(0, new DateLiteral("2020-01-10"), new DateLiteral("2020-01-10"));
+ checkCompareSameType(0, new DateLiteral("2020-01-10"), new DateV2Literal("2020-01-10"));
+ checkCompareSameType(0, new DateLiteral("2020-01-10"), new DateTimeLiteral("2020-01-10 00:00:00"));
+ checkCompareSameType(0, new DateLiteral("2020-01-10"), new DateTimeV2Literal("2020-01-10 00:00:00.00"));
+ checkCompareSameType(1, new DateLiteral("2020-01-10"), new DateLiteral("2020-01-09"));
+ checkCompareSameType(1, new DateLiteral("2020-01-10"), new DateV2Literal("2020-01-09"));
+ checkCompareSameType(1, new DateLiteral("2020-01-10"), new DateTimeLiteral("2020-01-09 00:00:00"));
+ checkCompareSameType(1, new DateLiteral("2020-01-10"), new DateTimeV2Literal("2020-01-09 00:00:00.00"));
+ checkCompareSameType(-1, new DateLiteral("2020-01-10"), new DateLiteral("2020-01-11"));
+ checkCompareSameType(-1, new DateLiteral("2020-01-10"), new DateV2Literal("2020-01-11"));
+ checkCompareSameType(-1, new DateLiteral("2020-01-10"), new DateTimeLiteral("2020-01-10 00:00:01"));
+ checkCompareSameType(-1, new DateLiteral("2020-01-10"), new DateTimeV2Literal("2020-01-10 00:00:00.01"));
+ checkCompareDiffType(new DateLiteral("2020-01-10"), new StringLiteral("2020-01-1"));
+ checkCompareDiffType(new DateLiteral("2020-01-10"), new StringLiteral("2020-01-10"));
+ checkCompareDiffType(new DateLiteral("2020-01-10"), new StringLiteral("2020-01-10 "));
+ checkCompareSameType(0, new DateV2Literal("2020-01-10"), new DateLiteral("2020-01-10"));
+ checkCompareSameType(0, new DateV2Literal("2020-01-10"), new DateV2Literal("2020-01-10"));
+ checkCompareSameType(0, new DateV2Literal("2020-01-10"), new DateTimeLiteral("2020-01-10 00:00:00"));
+ checkCompareSameType(0, new DateV2Literal("2020-01-10"), new DateTimeV2Literal("2020-01-10 00:00:00.00"));
+ checkCompareSameType(1, new DateV2Literal("2020-01-10"), new DateLiteral("2020-01-09"));
+ checkCompareSameType(1, new DateV2Literal("2020-01-10"), new DateV2Literal("2020-01-09"));
+ checkCompareSameType(1, new DateV2Literal("2020-01-10"), new DateTimeLiteral("2020-01-09 00:00:00"));
+ checkCompareSameType(1, new DateV2Literal("2020-01-10"), new DateTimeV2Literal("2020-01-09 00:00:00.00"));
+ checkCompareSameType(-1, new DateV2Literal("2020-01-10"), new DateLiteral("2020-01-11"));
+ checkCompareSameType(-1, new DateV2Literal("2020-01-10"), new DateV2Literal("2020-01-11"));
+ checkCompareSameType(-1, new DateV2Literal("2020-01-10"), new DateTimeLiteral("2020-01-10 00:00:01"));
+ checkCompareSameType(-1, new DateV2Literal("2020-01-10"), new DateTimeV2Literal("2020-01-10 00:00:00.01"));
+ checkCompareDiffType(new DateV2Literal("2020-01-10"), new StringLiteral("2020-01-1"));
+ checkCompareDiffType(new DateV2Literal("2020-01-10"), new StringLiteral("2020-01-10"));
+ checkCompareDiffType(new DateV2Literal("2020-01-10"), new StringLiteral("2020-01-10 "));
+ checkCompareSameType(0, new DateTimeLiteral("2020-01-10"), new DateLiteral("2020-01-10"));
+ checkCompareSameType(0, new DateTimeLiteral("2020-01-10"), new DateV2Literal("2020-01-10"));
+ checkCompareSameType(0, new DateTimeLiteral("2020-01-10"), new DateTimeLiteral("2020-01-10 00:00:00"));
+ checkCompareSameType(0, new DateTimeLiteral("2020-01-10"), new DateTimeV2Literal("2020-01-10 00:00:00.00"));
+ checkCompareSameType(1, new DateTimeLiteral("2020-01-10"), new DateLiteral("2020-01-09"));
+ checkCompareSameType(1, new DateTimeLiteral("2020-01-10"), new DateV2Literal("2020-01-09"));
+ checkCompareSameType(1, new DateTimeLiteral("2020-01-10"), new DateTimeLiteral("2020-01-09 00:00:00"));
+ checkCompareSameType(1, new DateTimeLiteral("2020-01-10"), new DateTimeV2Literal("2020-01-09 00:00:00.00"));
+ checkCompareSameType(-1, new DateTimeLiteral("2020-01-10"), new DateLiteral("2020-01-11"));
+ checkCompareSameType(-1, new DateTimeLiteral("2020-01-10"), new DateV2Literal("2020-01-11"));
+ checkCompareSameType(-1, new DateTimeLiteral("2020-01-10"), new DateTimeLiteral("2020-01-10 00:00:01"));
+ checkCompareSameType(-1, new DateTimeLiteral("2020-01-10"), new DateTimeV2Literal("2020-01-10 00:00:00.01"));
+ checkCompareDiffType(new DateTimeLiteral("2020-01-10"), new StringLiteral("2020-01-10 00:00"));
+ checkCompareDiffType(new DateTimeLiteral("2020-01-10"), new StringLiteral("2020-01-10 00:00:00"));
+ checkCompareDiffType(new DateTimeLiteral("2020-01-10"), new StringLiteral("2020-01-10 00:00:00.000"));
+ checkCompareSameType(0, new DateTimeV2Literal("2020-01-10"), new DateLiteral("2020-01-10"));
+ checkCompareSameType(0, new DateTimeV2Literal("2020-01-10"), new DateV2Literal("2020-01-10"));
+ checkCompareSameType(0, new DateTimeV2Literal("2020-01-10"), new DateTimeLiteral("2020-01-10 00:00:00"));
+ checkCompareSameType(0, new DateTimeV2Literal("2020-01-10"), new DateTimeV2Literal("2020-01-10 00:00:00.00"));
+ checkCompareSameType(1, new DateTimeV2Literal("2020-01-10"), new DateLiteral("2020-01-09"));
+ checkCompareSameType(1, new DateTimeV2Literal("2020-01-10"), new DateV2Literal("2020-01-09"));
+ checkCompareSameType(1, new DateTimeV2Literal("2020-01-10"), new DateTimeLiteral("2020-01-09 00:00:00"));
+ checkCompareSameType(1, new DateTimeV2Literal("2020-01-10"), new DateTimeV2Literal("2020-01-09 00:00:00.00"));
+ checkCompareSameType(-1, new DateTimeV2Literal("2020-01-10"), new DateLiteral("2020-01-11"));
+ checkCompareSameType(-1, new DateTimeV2Literal("2020-01-10"), new DateV2Literal("2020-01-11"));
+ checkCompareSameType(-1, new DateTimeV2Literal("2020-01-10"), new DateTimeLiteral("2020-01-10 00:00:01"));
+ checkCompareSameType(-1, new DateTimeV2Literal("2020-01-10"), new DateTimeV2Literal("2020-01-10 00:00:00.01"));
+ checkCompareDiffType(new DateTimeV2Literal("2020-01-10"), new StringLiteral("2020-01-10 00:00:0"));
+ checkCompareDiffType(new DateTimeV2Literal("2020-01-10"), new StringLiteral("2020-01-10 00:00:00"));
+ checkCompareDiffType(new DateTimeV2Literal("2020-01-10"), new StringLiteral("2020-01-10 00:00:00.00"));
+
+ // string type
+ checkCompareSameType(0, new CharLiteral("abc", -1), new CharLiteral("abc", -1));
+ checkCompareSameType(1, new CharLiteral("abc", -1), new CharLiteral("abc", 1));
+ checkCompareSameType(0, new CharLiteral("abc", -1), new StringLiteral("abc"));
+ checkCompareSameType(0, new CharLiteral("abc", -1), new VarcharLiteral("abc"));
+ checkCompareSameType(0, new CharLiteral("abc", -1), new VarcharLiteral("abc", -1));
+ checkCompareSameType(1, new CharLiteral("abc", -1), new VarcharLiteral("abc", 1));
+ checkCompareSameType(1, new CharLiteral("abc", -1), new CharLiteral("ab", -1));
+ checkCompareSameType(1, new CharLiteral("abc", -1), new StringLiteral("ab"));
+ checkCompareSameType(1, new CharLiteral("abc", -1), new VarcharLiteral("ab"));
+ checkCompareSameType(1, new CharLiteral("abc", -1), new VarcharLiteral("ab", -1));
+ checkCompareSameType(-1, new CharLiteral("abc", -1), new CharLiteral("abcd", -1));
+ checkCompareSameType(0, new CharLiteral("abc", -1), new CharLiteral("abcd", 3));
+ checkCompareSameType(-1, new CharLiteral("abc", -1), new StringLiteral("abcd"));
+ checkCompareSameType(-1, new CharLiteral("abc", -1), new VarcharLiteral("abcd"));
+ checkCompareSameType(-1, new CharLiteral("abc", -1), new VarcharLiteral("abcd", -1));
+ checkCompareSameType(0, new CharLiteral("abc", -1), new VarcharLiteral("abcd", 3));
+
+ // ip type
+ checkCompareSameType(0, new IPv4Literal("170.0.0.100"), new IPv4Literal("170.0.0.100"));
+ checkCompareSameType(1, new IPv4Literal("170.0.0.100"), new IPv4Literal("160.0.0.200"));
+ checkCompareDiffType(new IPv4Literal("172.0.0.100"), new IPv6Literal("1080:0:0:0:8:800:200C:417A"));
+ checkCompareSameType(0, new IPv6Literal("1080:0:0:0:8:800:200C:417A"), new IPv6Literal("1080:0:0:0:8:800:200C:417A"));
+ checkCompareSameType(1, new IPv6Literal("1080:0:0:0:8:800:200C:417A"), new IPv6Literal("1000:0:0:0:8:800:200C:41AA"));
+ IPv4Literal ipv4 = new IPv4Literal("170.0.0.100");
+ Assertions.assertEquals(ipv4, new IPv4Literal(ipv4.toLegacyLiteral().getStringValue()));
+ IPv6Literal ipv6 = new IPv6Literal("1080:0:0:0:8:800:200C:417A");
+ Assertions.assertEquals(ipv6, new IPv6Literal(ipv6.toLegacyLiteral().getStringValue()));
+
+ // null type and max type
+ Assertions.assertEquals(0, (new NullLiteral(IntegerType.INSTANCE)).compareTo(new NullLiteral(IntegerType.INSTANCE)));
+ Assertions.assertEquals(-1, (new NullLiteral(IntegerType.INSTANCE)).compareTo(new MaxLiteral(IntegerType.INSTANCE)));
+ Assertions.assertEquals(0, (new MaxLiteral(IntegerType.INSTANCE)).compareTo(new MaxLiteral(IntegerType.INSTANCE)));
+ }
+
+ @Test
+ public void testComplex() throws Exception {
+ // array type
+ checkCompareSameType(0,
+ new ArrayLiteral(ImmutableList.of(new IntegerLiteral(100), new IntegerLiteral(200))),
+ new ArrayLiteral(ImmutableList.of(new IntegerLiteral(100), new IntegerLiteral(200))));
+ checkCompareSameType(1,
+ new ArrayLiteral(ImmutableList.of(new IntegerLiteral(200))),
+ new ArrayLiteral(ImmutableList.of(new IntegerLiteral(100), new IntegerLiteral(200))));
+ checkCompareSameType(1,
+ new ArrayLiteral(ImmutableList.of(new IntegerLiteral(100), new IntegerLiteral(200), new IntegerLiteral(1))),
+ new ArrayLiteral(ImmutableList.of(new IntegerLiteral(100), new IntegerLiteral(200))));
+ checkComparableNoException("select array(1,2) = array(1, 2)");
+ checkComparableNoException("select array(1,2) > array(1, 2)");
+
+ // json type
+ checkNotComparable("select cast ('[1, 2]' as json) = cast('[1, 2]' as json)",
+ "comparison predicate could not contains json type");
+ checkNotComparable("select cast('[1, 2]' as json) > cast('[1, 2]' as json)",
+ "comparison predicate could not contains json type");
+
+ // map type
+ checkNotComparable("select map(1, 2) = map(1, 2)",
+ "comparison predicate could not contains complex type");
+ checkNotComparable("select map(1, 2) > map(1, 2)",
+ "comparison predicate could not contains complex type");
+ checkNotComparable("select cast('(1, 2)' as map) = cast('(1, 2)' as map)",
+ "comparison predicate could not contains complex type");
+
+ // struct type
+ checkNotComparable("select struct(1, 2) = struct(1, 2)",
+ "comparison predicate could not contains complex type");
+ checkNotComparable("select struct(1, 2) > struct(1, 2)",
+ "comparison predicate could not contains complex type");
+ }
+
+ private void checkCompareSameType(int expect, ComparableLiteral left, ComparableLiteral right) {
+ Assertions.assertEquals(expect, left.compareTo(right));
+ Assertions.assertEquals(- expect, right.compareTo(left));
+ if (((Literal) left).dataType.equals(((Literal) right).dataType)
+ && !(left instanceof IPv4Literal) && !(left instanceof IPv6Literal)) {
+ Assertions.assertEquals(expect, ((Literal) left).toLegacyLiteral()
+ .compareTo(((Literal) right).toLegacyLiteral()));
+ Assertions.assertEquals(- expect, ((Literal) right).toLegacyLiteral()
+ .compareTo(((Literal) left).toLegacyLiteral()));
+ }
+
+ Assertions.assertEquals(1, left.compareTo(new NullLiteral(IntegerType.INSTANCE)));
+ Assertions.assertEquals(-1, left.compareTo(new MaxLiteral(IntegerType.INSTANCE)));
+ }
+
+ private void checkCompareDiffType(ComparableLiteral left, ComparableLiteral right) {
+ Assertions.assertThrowsExactly(RuntimeException.class, () -> left.compareTo(right));
+ Assertions.assertThrowsExactly(RuntimeException.class, () -> right.compareTo(left));
+ }
+
+ private void checkComparableNoException(String sql) throws Exception {
+ ExceptionChecker.expectThrowsNoException(() -> executeSql(sql));
+ }
+
+ private void checkNotComparable(String sql, String expectErrMsg) throws Exception {
+ ExceptionChecker.expectThrowsWithMsg(IllegalStateException.class, expectErrMsg,
+ () -> executeSql(sql));
+ }
+}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java b/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java
index 35ac71314d414e..9b51382cb9fe7c 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/utframe/TestWithFeService.java
@@ -616,6 +616,16 @@ public StmtExecutor getSqlStmtExecutor(String queryStr) throws Exception {
}
}
+ public void executeSql(String queryStr) throws Exception {
+ connectContext.getState().reset();
+ StmtExecutor stmtExecutor = new StmtExecutor(connectContext, queryStr);
+ stmtExecutor.execute();
+ if (connectContext.getState().getStateType() == QueryState.MysqlStateType.ERR
+ || connectContext.getState().getErrorCode() != null) {
+ throw new IllegalStateException(connectContext.getState().getErrorMessage());
+ }
+ }
+
public void createDatabase(String db) throws Exception {
String createDbStmtStr = "CREATE DATABASE " + db;
CreateDbStmt createDbStmt = (CreateDbStmt) parseAndAnalyzeStmt(createDbStmtStr);
diff --git a/regression-test/suites/nereids_p0/literal/test_compare_literal.groovy b/regression-test/suites/nereids_p0/literal/test_compare_literal.groovy
new file mode 100644
index 00000000000000..eb66cf8790287c
--- /dev/null
+++ b/regression-test/suites/nereids_p0/literal/test_compare_literal.groovy
@@ -0,0 +1,153 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite('test_compare_literal') {
+ for (def val in [true, false]) {
+ sql "set debug_skip_fold_constant=${val}"
+
+ // ipv4
+ test {
+ sql "select cast('170.0.0.100' as ipv4) = cast('170.0.0.100' as ipv4)"
+ result([[true]])
+ }
+ test {
+ sql "select cast('170.0.0.100' as ipv4) >= cast('170.0.0.100' as ipv4)"
+ result([[true]])
+ }
+ test {
+ sql "select cast('170.0.0.100' as ipv4) > cast('170.0.0.100' as ipv4)"
+ result([[false]])
+ }
+ test {
+ sql "select cast('170.0.0.100' as ipv4) = cast('160.0.0.200' as ipv4)"
+ result([[false]])
+ }
+ test {
+ sql "select cast('170.0.0.100' as ipv4) >= cast('160.0.0.200' as ipv4)"
+ result([[true]])
+ }
+ test {
+ sql "select cast('170.0.0.100' as ipv4) > cast('160.0.0.200' as ipv4)"
+ result([[true]])
+ }
+ test {
+ sql "select cast('170.0.0.100' as ipv4) < cast('160.0.0.200' as ipv4)"
+ result([[false]])
+ }
+
+ // ipv6
+ test {
+ sql "select cast('1080:0:0:0:8:800:200C:417A' as ipv6) = cast('1080:0:0:0:8:800:200C:417A' as ipv6)"
+ result([[true]])
+ }
+ test {
+ sql "select cast('1080:0:0:0:8:800:200C:417A' as ipv6) >= cast('1080:0:0:0:8:800:200C:417A' as ipv6)"
+ result([[true]])
+ }
+ test {
+ sql "select cast('1080:0:0:0:8:800:200C:417A' as ipv6) > cast('1080:0:0:0:8:800:200C:417A' as ipv6)"
+ result([[false]])
+ }
+ test {
+ sql "select cast('1080:0:0:0:8:800:200C:417A' as ipv6) = cast('1000:0:0:0:8:800:200C:41AA' as ipv6)"
+ result([[false]])
+ }
+ test {
+ sql "select cast('1080:0:0:0:8:800:200C:417A' as ipv6) >= cast('1000:0:0:0:8:800:200C:41AA' as ipv6)"
+ result([[true]])
+ }
+ test {
+ sql "select cast('1080:0:0:0:8:800:200C:417A' as ipv6) > cast('1000:0:0:0:8:800:200C:41AA' as ipv6)"
+ result([[true]])
+ }
+ test {
+ sql "select cast('1080:0:0:0:8:800:200C:417A' as ipv6) < cast('1000:0:0:0:8:800:200C:41AA' as ipv6)"
+ result([[false]])
+ }
+
+ // array
+ test {
+ sql 'select array(5, 6) = array(5, 6)'
+ result([[true]])
+ }
+ test {
+ sql 'select array(5, 6) >= array(5, 6)'
+ result([[true]])
+ }
+ test {
+ sql 'select array(5, 6) > array(5, 6)'
+ result([[false]])
+ }
+ test {
+ sql 'select array(5, 6) = array(5, 7)'
+ result([[false]])
+ }
+ test {
+ sql 'select array(5, 6) >= array(5, 7)'
+ result([[false]])
+ }
+ test {
+ sql 'select array(5, 6) > array(5, 7)'
+ result([[false]])
+ }
+ test {
+ sql 'select array(5, 6) < array(5, 7)'
+ result([[true]])
+ }
+ test {
+ sql 'select array(5, 6) < array(5, 6, 1)'
+ result([[true]])
+ }
+ test {
+ sql 'select array(5, 6) < array(6)'
+ result([[true]])
+ }
+ }
+
+ // test not comparable
+ sql 'set debug_skip_fold_constant=false'
+
+ // json
+ test {
+ sql "select cast('[1, 2]' as json) = cast('[1, 2]' as json)"
+ exception 'comparison predicate could not contains json type'
+ }
+ test {
+ sql "select cast('[1, 2]' as json) > cast('[1, 2]' as json)"
+ exception 'comparison predicate could not contains json type'
+ }
+
+ // map
+ test {
+ sql 'select map(1, 2) = map(1, 2)'
+ exception 'comparison predicate could not contains complex type'
+ }
+ test {
+ sql 'select map(1, 2) > map(1, 2)'
+ exception 'comparison predicate could not contains complex type'
+ }
+
+ // struct
+ test {
+ sql 'select struct(1, 2) = struct(1, 2)'
+ exception 'comparison predicate could not contains complex type'
+ }
+ test {
+ sql 'select struct(1, 2) > struct(1, 2)'
+ exception 'comparison predicate could not contains complex type'
+ }
+}