This is an automated email from the ASF dual-hosted git repository.
airborne pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new b1c63ae1ec8 [fix](ES Catalog)Only push down literal expr in binary
predicate(#39845) (#39844)
b1c63ae1ec8 is described below
commit b1c63ae1ec88e5fdf70ea775fd1cd3d31240d8d2
Author: qiye <[email protected]>
AuthorDate: Thu Aug 29 15:29:45 2024 +0800
[fix](ES Catalog)Only push down literal expr in binary predicate(#39845)
(#39844)
## Proposed changes
This only affect old planner. close #39849
bp #39845
---
.../external/elasticsearch/QueryBuilders.java | 77 +++++++++++++++++-----
.../external/elasticsearch/QueryBuildersTest.java | 27 ++++++++
2 files changed, 86 insertions(+), 18 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
b/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
index 0205aba1287..518f6d93bbd 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/external/elasticsearch/QueryBuilders.java
@@ -31,6 +31,7 @@ import org.apache.doris.analysis.IsNullPredicate;
import org.apache.doris.analysis.LargeIntLiteral;
import org.apache.doris.analysis.LikePredicate;
import org.apache.doris.analysis.LikePredicate.Operator;
+import org.apache.doris.analysis.LiteralExpr;
import org.apache.doris.analysis.SlotRef;
import org.apache.doris.catalog.EsResource;
import org.apache.doris.thrift.TExprOpcode;
@@ -127,9 +128,24 @@ public final class QueryBuilders {
.build());
}
- private static QueryBuilder parseBinaryPredicate(Expr expr, TExprOpcode
opCode, String column,
+ private static TExprOpcode flipOpCode(TExprOpcode opCode) {
+ switch (opCode) {
+ case GE:
+ return TExprOpcode.LE;
+ case GT:
+ return TExprOpcode.LT;
+ case LE:
+ return TExprOpcode.GE;
+ case LT:
+ return TExprOpcode.GT;
+ default:
+ return opCode;
+ }
+ }
+
+ private static QueryBuilder parseBinaryPredicate(LiteralExpr expr,
TExprOpcode opCode, String column,
boolean needDateCompat) {
- Object value = toDorisLiteral(expr.getChild(1));
+ Object value = toDorisLiteral(expr);
if (needDateCompat) {
value = compatDefaultDate(value);
}
@@ -223,6 +239,20 @@ public final class QueryBuilders {
return new QueryBuilders.EsQueryBuilder(stringValue);
}
+ private static String getColumnFromExpr(Expr expr) {
+ // Type transformed cast can not pushdown
+ if (expr instanceof CastExpr) {
+ Expr withoutCastExpr = exprWithoutCast(expr);
+ if (withoutCastExpr.getType().equals(expr.getType())
+ || (withoutCastExpr.getType().isFloatingPointType() &&
expr.getType().isFloatingPointType())) {
+ return ((SlotRef) withoutCastExpr).getColumnName();
+ }
+ } else if (expr instanceof SlotRef) {
+ return ((SlotRef) expr).getColumnName();
+ }
+ return null;
+ }
+
/**
* Doris expr to es dsl.
**/
@@ -241,32 +271,43 @@ public final class QueryBuilders {
return toCompoundEsDsl(expr, notPushDownList, fieldsContext,
builderOptions);
}
TExprOpcode opCode = expr.getOpcode();
- String column;
+ boolean isFlip = false;
Expr leftExpr = expr.getChild(0);
- // Type transformed cast can not pushdown
- if (leftExpr instanceof CastExpr) {
- Expr withoutCastExpr = exprWithoutCast(leftExpr);
- // pushdown col(float) >= 3
- if (withoutCastExpr.getType().equals(leftExpr.getType()) ||
(withoutCastExpr.getType().isFloatingPointType()
- && leftExpr.getType().isFloatingPointType())) {
- column = ((SlotRef) withoutCastExpr).getColumnName();
- } else {
- notPushDownList.add(expr);
- return null;
- }
- } else if (leftExpr instanceof SlotRef) {
- column = ((SlotRef) leftExpr).getColumnName();
- } else {
+ String column = getColumnFromExpr(leftExpr);
+
+ if (StringUtils.isEmpty(column)) {
+ Expr rightExpr = expr.getChild(1);
+ column = getColumnFromExpr(rightExpr);
+ opCode = flipOpCode(opCode);
+ isFlip = true;
+ }
+
+ if (StringUtils.isEmpty(column)) {
notPushDownList.add(expr);
return null;
}
+
// Check whether the date type need compat, it must before keyword
replace.
List<String> needCompatDateFields =
builderOptions.getNeedCompatDateFields();
boolean needDateCompat = needCompatDateFields != null &&
needCompatDateFields.contains(column);
// Replace col with col.keyword if mapping exist.
column = fieldsContext.getOrDefault(column, column);
if (expr instanceof BinaryPredicate) {
- return parseBinaryPredicate(expr, opCode, column, needDateCompat);
+ BinaryPredicate binaryPredicate = (BinaryPredicate) expr;
+ Expr value;
+ if (isFlip) {
+ value = binaryPredicate.getChild(0);
+ } else {
+ value = binaryPredicate.getChild(1);
+ }
+ // only push down literal expr to ES
+ if (value instanceof LiteralExpr) {
+ LiteralExpr literalExpr = (LiteralExpr) value;
+ return parseBinaryPredicate(literalExpr, opCode, column,
needDateCompat);
+ } else {
+ notPushDownList.add(expr);
+ return null;
+ }
}
if (expr instanceof IsNullPredicate) {
return parseIsNullPredicate(expr, column);
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/external/elasticsearch/QueryBuildersTest.java
b/fe/fe-core/src/test/java/org/apache/doris/external/elasticsearch/QueryBuildersTest.java
index 184bf97c505..64f69bb4644 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/external/elasticsearch/QueryBuildersTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/external/elasticsearch/QueryBuildersTest.java
@@ -208,6 +208,33 @@ public class QueryBuildersTest {
new FloatLiteral(3.0, Type.DOUBLE));
QueryBuilders.toEsDsl(castDoublePredicate, notPushDownList,
fieldsContext, builderOptions);
Assertions.assertEquals(3, notPushDownList.size());
+
+ SlotRef k4 = new SlotRef(null, "k4");
+ k4.setType(Type.FLOAT);
+ CastExpr castFloatExpr = new CastExpr(Type.FLOAT, k4);
+ BinaryPredicate castFloatPredicate = new BinaryPredicate(Operator.GE,
new FloatLiteral(3.0, Type.FLOAT),
+ castFloatExpr);
+ QueryBuilders.QueryBuilder queryBuilder =
QueryBuilders.toEsDsl(castFloatPredicate, notPushDownList, fieldsContext,
builderOptions);
+ Assertions.assertEquals("{\"range\":{\"k4\":{\"lte\":3.0}}}",
queryBuilder.toJson());
+ Assertions.assertEquals(3, notPushDownList.size());
+
+ castFloatPredicate = new BinaryPredicate(Operator.LE, new
FloatLiteral(3.0, Type.FLOAT),
+ castFloatExpr);
+ queryBuilder = QueryBuilders.toEsDsl(castFloatPredicate,
notPushDownList, fieldsContext, builderOptions);
+ Assertions.assertEquals("{\"range\":{\"k4\":{\"gte\":3.0}}}",
queryBuilder.toJson());
+ Assertions.assertEquals(3, notPushDownList.size());
+
+ castFloatPredicate = new BinaryPredicate(Operator.LT, new
FloatLiteral(3.0, Type.FLOAT),
+ castFloatExpr);
+ queryBuilder = QueryBuilders.toEsDsl(castFloatPredicate,
notPushDownList, fieldsContext, builderOptions);
+ Assertions.assertEquals("{\"range\":{\"k4\":{\"gt\":3.0}}}",
queryBuilder.toJson());
+ Assertions.assertEquals(3, notPushDownList.size());
+
+ castFloatPredicate = new BinaryPredicate(Operator.GT, new
FloatLiteral(3.0, Type.FLOAT),
+ castFloatExpr);
+ queryBuilder = QueryBuilders.toEsDsl(castFloatPredicate,
notPushDownList, fieldsContext, builderOptions);
+ Assertions.assertEquals("{\"range\":{\"k4\":{\"lt\":3.0}}}",
queryBuilder.toJson());
+ Assertions.assertEquals(3, notPushDownList.size());
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]