This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new 34d95cef1fc [improve](ES Catalog)Only push down literal expr in binary 
predicate(#39845) (#39847)
34d95cef1fc is described below

commit 34d95cef1fcfd352d595332ed8c52ef7c2095dd5
Author: qiye <jianliang5...@gmail.com>
AuthorDate: Thu Aug 29 14:07:17 2024 +0800

    [improve](ES Catalog)Only push down literal expr in binary 
predicate(#39845) (#39847)
    
    ## Proposed changes
    
    bp #39845
---
 .../apache/doris/datasource/es/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/datasource/es/QueryBuilders.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/es/QueryBuilders.java
index 3a54e012a32..19930bb2b14 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/es/QueryBuilders.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/es/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 3cf9261b932..ca5344990e7 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
@@ -209,6 +209,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: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to