You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2021/09/07 04:00:25 UTC

[incubator-doris] branch master updated: [Feature] Support Integer-Types value in like predicate (#6579)

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

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 56b2a33  [Feature] Support Integer-Types value in like predicate (#6579)
56b2a33 is described below

commit 56b2a33a4d07cf36ad16a63bd243b758b2111b22
Author: qiye <ji...@gmail.com>
AuthorDate: Tue Sep 7 11:56:52 2021 +0800

    [Feature] Support Integer-Types value in like predicate (#6579)
    
    The basic idea is adding a rewrite rule to rewriete the expr of `SlotRef`,
    which type is fixedPointValue, aka Integer-Types, to a `CastExpr`, it will cast the fixedPoint value to string.
---
 .../java/org/apache/doris/analysis/Analyzer.java   |  2 +
 .../org/apache/doris/analysis/LikePredicate.java   |  5 +-
 .../doris/rewrite/RewriteLikePredicateRule.java    | 54 ++++++++++++++++
 .../ExtractCommonFactorsRuleFunctionTest.java      | 72 ++++++++++++++++++++++
 4 files changed, 131 insertions(+), 2 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
index 23a8268..1424617 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java
@@ -45,6 +45,7 @@ import org.apache.doris.rewrite.NormalizeBinaryPredicatesRule;
 import org.apache.doris.rewrite.RewriteAliasFunctionRule;
 import org.apache.doris.rewrite.RewriteEncryptKeyRule;
 import org.apache.doris.rewrite.RewriteFromUnixTimeRule;
+import org.apache.doris.rewrite.RewriteLikePredicateRule;
 import org.apache.doris.rewrite.SimplifyInvalidDateBinaryPredicatesDateRule;
 import org.apache.doris.rewrite.mvrewrite.CountDistinctToBitmap;
 import org.apache.doris.rewrite.mvrewrite.CountDistinctToBitmapOrHLLRule;
@@ -273,6 +274,7 @@ public class Analyzer {
             rules.add(SimplifyInvalidDateBinaryPredicatesDateRule.INSTANCE);
             rules.add(RewriteEncryptKeyRule.INSTANCE);
             rules.add(RewriteAliasFunctionRule.INSTANCE);
+            rules.add(RewriteLikePredicateRule.INSTANCE);
             List<ExprRewriteRule> onceRules = Lists.newArrayList();
             onceRules.add(ExtractCommonFactorsRule.INSTANCE);
             exprRewriter_ = new ExprRewriter(rules, onceRules);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/LikePredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/LikePredicate.java
index f25b3ea..a81e3e8 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/LikePredicate.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/LikePredicate.java
@@ -113,9 +113,10 @@ public class LikePredicate extends Predicate {
     @Override
     public void analyzeImpl(Analyzer analyzer) throws AnalysisException {
         super.analyzeImpl(analyzer);
-        if (!getChild(0).getType().isStringType() && !getChild(0).getType().isNull()) {
+        if (!getChild(0).getType().isStringType() && !getChild(0).getType().isFixedPointType()
+                && !getChild(0).getType().isNull()) {
             throw new AnalysisException(
-              "left operand of " + op.toString() + " must be of type STRING: " + toSql());
+              "left operand of " + op.toString() + " must be of type STRING or FIXED_POINT_TYPE: " + toSql());
         }
         if (!getChild(1).getType().isStringType() && !getChild(1).getType().isNull()) {
             throw new AnalysisException(
diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteLikePredicateRule.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteLikePredicateRule.java
new file mode 100644
index 0000000..239d288
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/RewriteLikePredicateRule.java
@@ -0,0 +1,54 @@
+// 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.rewrite;
+
+import org.apache.doris.analysis.Analyzer;
+import org.apache.doris.analysis.CastExpr;
+import org.apache.doris.analysis.Expr;
+import org.apache.doris.analysis.LikePredicate;
+import org.apache.doris.analysis.SlotRef;
+import org.apache.doris.analysis.TypeDef;
+import org.apache.doris.catalog.Type;
+import org.apache.doris.common.AnalysisException;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Rewrite `int` to `string` in like predicate
+ * in order to support `int` in like predicate, same as MySQL
+ */
+public class RewriteLikePredicateRule implements ExprRewriteRule {
+    private final static Logger LOG = LogManager.getLogger(RewriteAliasFunctionRule.class);
+    public static RewriteLikePredicateRule INSTANCE = new RewriteLikePredicateRule();
+
+    @Override
+    public Expr apply(Expr expr, Analyzer analyzer) throws AnalysisException {
+        if (expr instanceof LikePredicate) {
+            Expr leftChild = expr.getChild(0);
+            if (leftChild instanceof SlotRef) {
+                Type type = leftChild.getType();
+                if (type.isFixedPointType()) {
+                    return new LikePredicate(((LikePredicate) expr).getOp(),
+                            new CastExpr(new TypeDef(Type.VARCHAR), leftChild), expr.getChild(1));
+                }
+            }
+        }
+        return expr;
+    }
+}
diff --git a/fe/fe-core/src/test/java/org/apache/doris/rewrite/ExtractCommonFactorsRuleFunctionTest.java b/fe/fe-core/src/test/java/org/apache/doris/rewrite/ExtractCommonFactorsRuleFunctionTest.java
index 0e0036c..a25e035 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/rewrite/ExtractCommonFactorsRuleFunctionTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/rewrite/ExtractCommonFactorsRuleFunctionTest.java
@@ -18,11 +18,14 @@
 
 package org.apache.doris.rewrite;
 
+import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.FeConstants;
 import org.apache.doris.utframe.DorisAssert;
 import org.apache.doris.utframe.UtFrameUtils;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -31,6 +34,7 @@ import org.junit.Test;
 import java.util.UUID;
 
 public class ExtractCommonFactorsRuleFunctionTest {
+    private static final Logger LOG = LogManager.getLogger(ExtractCommonFactorsRuleFunctionTest.class);
     private static String baseDir = "fe";
     private static String runningDir = baseDir + "/mocked/ExtractCommonFactorsRuleFunctionTest/"
             + UUID.randomUUID().toString() + "/";
@@ -38,6 +42,7 @@ public class ExtractCommonFactorsRuleFunctionTest {
     private static final String DB_NAME = "db1";
     private static final String TABLE_NAME_1 = "tb1";
     private static final String TABLE_NAME_2 = "tb2";
+    private static final String TABLE_NAME_3 = "tb3";
 
     @BeforeClass
     public static void beforeClass() throws Exception {
@@ -54,6 +59,10 @@ public class ExtractCommonFactorsRuleFunctionTest {
                 + " (k1 int, k2 int) "
                 + "distributed by hash(k1) buckets 3 properties('replication_num' = '1');";
         dorisAssert.withTable(createTableSQL);
+        createTableSQL = "create table " + DB_NAME + "." + TABLE_NAME_3
+                + " (k1 tinyint, k2 smallint, k3 int, k4 bigint, k5 largeint, k6 date, k7 datetime, k8 float, k9 double) "
+                + "distributed by hash(k1) buckets 3 properties('replication_num' = '1');";
+        dorisAssert.withTable(createTableSQL);
     }
 
     @AfterClass
@@ -242,4 +251,67 @@ public class ExtractCommonFactorsRuleFunctionTest {
                 + "'MED BOX', 'MED PKG', 'MED PACK', 'LG CASE', 'LG BOX', 'LG PACK', 'LG PKG')"));
     }
 
+    @Test
+    public void testRewriteLikePredicate() throws Exception {
+        // tinyint
+        String sql = "select * from tb3 where k1 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainContains("CAST(`k1` AS CHARACTER) LIKE '%4%'");
+
+        // smallint
+        sql = "select * from tb3 where k2 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainContains("CAST(`k2` AS CHARACTER) LIKE '%4%'");
+
+        // int
+        sql = "select * from tb3 where k3 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainContains("CAST(`k3` AS CHARACTER) LIKE '%4%'");
+
+        // bigint
+        sql = "select * from tb3 where k4 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainContains("CAST(`k4` AS CHARACTER) LIKE '%4%'");
+
+        // largeint
+        sql = "select * from tb3 where k5 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainContains("CAST(`k5` AS CHARACTER) LIKE '%4%'");
+    }
+
+    @Test(expected = AnalysisException.class)
+    public void testRewriteLikePredicateDate() throws Exception {
+        // date
+        String sql = "select * from tb3 where k6 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainQuery();
+        Assert.fail("No exception throws.");
+    }
+
+    @Test(expected = AnalysisException.class)
+    public void testRewriteLikePredicateDateTime() throws Exception {
+        // datetime
+        String sql = "select * from tb3 where k7 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainQuery();
+        Assert.fail("No exception throws.");
+    }
+
+    @Test(expected = AnalysisException.class)
+    public void testRewriteLikePredicateFloat() throws Exception {
+        // date
+        String sql = "select * from tb3 where k8 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainQuery();
+        Assert.fail("No exception throws.");
+    }
+
+    @Test(expected = AnalysisException.class)
+    public void testRewriteLikePredicateDouble() throws Exception {
+        // date
+        String sql = "select * from tb3 where k9 like '%4%';";
+        LOG.info("EXPLAIN:{}", dorisAssert.query(sql).explainQuery());
+        dorisAssert.query(sql).explainQuery();
+        Assert.fail("No exception throws.");
+    }
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org