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 7be2871  [GroupingSet] Disable column both in select list and 
aggregate functions when using GROUPING SETS/CUBE/ROLLUP (#2921)
7be2871 is described below

commit 7be2871c368dc8a86d837d91ffd83805833b0665
Author: yangzhg <780531...@qq.com>
AuthorDate: Tue Feb 18 13:56:56 2020 +0800

    [GroupingSet] Disable column both in select list and aggregate functions 
when using GROUPING SETS/CUBE/ROLLUP (#2921)
---
 .../java/org/apache/doris/analysis/SelectStmt.java | 14 +++++-
 .../org/apache/doris/analysis/SelectStmtTest.java  | 52 ++++++++++++++++++++++
 .../org/apache/doris/utframe/AnotherDemoTest.java  | 46 +++++++++++--------
 .../java/org/apache/doris/utframe/DemoTest.java    | 47 +++++++++++--------
 .../org/apache/doris/utframe/UtFrameUtils.java     | 43 ++++++++++++------
 5 files changed, 152 insertions(+), 50 deletions(-)

diff --git a/fe/src/main/java/org/apache/doris/analysis/SelectStmt.java 
b/fe/src/main/java/org/apache/doris/analysis/SelectStmt.java
index a4a92f9..05de06c 100644
--- a/fe/src/main/java/org/apache/doris/analysis/SelectStmt.java
+++ b/fe/src/main/java/org/apache/doris/analysis/SelectStmt.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.analysis;
 
+import org.apache.doris.catalog.AggregateFunction;
 import org.apache.doris.catalog.AggregateType;
 import org.apache.doris.catalog.Catalog;
 import org.apache.doris.catalog.Column;
@@ -334,7 +335,7 @@ public class SelectStmt extends QueryStmt {
                 // of expr child and depth limits (toColumn() label may call 
toSql()).
                 item.getExpr().analyze(analyzer);
                 if 
(item.getExpr().contains(Predicates.instanceOf(Subquery.class))) {
-                    throw new AnalysisException("Subqueries are not supported 
in the select list.");
+                    throw new AnalysisException("Subquery is not supported in 
the select list.");
                 }
                 resultExprs.add(item.getExpr());
                 SlotRef aliasRef = new SlotRef(null, item.toColumnLabel());
@@ -349,6 +350,17 @@ public class SelectStmt extends QueryStmt {
             }
         }
         if (groupByClause != null && groupByClause.isGroupByExtension()) {
+            for (SelectListItem item : selectList.getItems()) {
+                if (item.getExpr() instanceof FunctionCallExpr && 
item.getExpr().fn instanceof AggregateFunction) {
+                    for (Expr expr: groupByClause.getGroupingExprs()) {
+                        if (item.getExpr().contains(expr)) {
+                            throw new AnalysisException("column: " + 
expr.toSql() + " cannot both in select list and "
+                                    + "aggregate functions when using GROUPING 
SETS/CUBE/ROLLUP, please use union"
+                                    + " instead.");
+                        }
+                    }
+                }
+            }
             groupingInfo = new GroupingInfo(analyzer, 
groupByClause.getGroupingType());
             groupingInfo.substituteGroupingFn(resultExprs, analyzer);
         } else {
diff --git a/fe/src/test/java/org/apache/doris/analysis/SelectStmtTest.java 
b/fe/src/test/java/org/apache/doris/analysis/SelectStmtTest.java
new file mode 100644
index 0000000..0e792c1
--- /dev/null
+++ b/fe/src/test/java/org/apache/doris/analysis/SelectStmtTest.java
@@ -0,0 +1,52 @@
+package org.apache.doris.analysis;
+
+import java.util.UUID;
+
+import org.apache.doris.catalog.Catalog;
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.utframe.UtFrameUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class SelectStmtTest {
+    private static String runningDir = "fe/mocked/DemoTest/" + 
UUID.randomUUID().toString() + "/";
+
+    @Rule
+    public ExpectedException expectedEx = ExpectedException.none();
+
+    @Test
+    public void testGroupingSets() throws Exception {
+        ConnectContext ctx = UtFrameUtils.createDefaultCtx();
+        UtFrameUtils.createMinDorisCluster(runningDir);
+        String createDbStmtStr = "create database db1;";
+        CreateDbStmt createDbStmt = (CreateDbStmt) 
UtFrameUtils.parseAndAnalyzeStmt(createDbStmtStr, ctx);
+        Catalog.getCurrentCatalog().createDb(createDbStmt);
+        System.out.println(Catalog.getCurrentCatalog().getDbNames());
+        // 3. create table tbl1
+        String createTblStmtStr = "create table db1.tbl1(k1 varchar(32), k2 
varchar(32), k3 varchar(32), k4 int) "
+                + "AGGREGATE KEY(k1, k2,k3,k4) distributed by hash(k1) buckets 
3 properties('replication_num' = '1');";
+        CreateTableStmt createTableStmt = (CreateTableStmt) 
UtFrameUtils.parseAndAnalyzeStmt(createTblStmtStr, ctx);
+        Catalog.getCurrentCatalog().createTable(createTableStmt);
+        String selectStmtStr = "select k1,k2,MAX(k4) from db1.tbl1 GROUP BY 
GROUPING sets ((k1,k2),(k1),(k2),());";
+        UtFrameUtils.parseAndAnalyzeStmt(selectStmtStr, ctx);
+        String selectStmtStr2 = "select k1,k4,MAX(k4) from db1.tbl1 GROUP BY 
GROUPING sets ((k1,k4),(k1),(k4),());";
+        expectedEx.expect(AnalysisException.class);
+        expectedEx.expectMessage("column: `k4` cannot both in select list and 
aggregate functions when using GROUPING"
+                + " SETS/CUBE/ROLLUP, please use union instead.");
+        UtFrameUtils.parseAndAnalyzeStmt(selectStmtStr2, ctx);
+        String selectStmtStr3 = "select k1,k4,MAX(k4+k4) from db1.tbl1 GROUP 
BY GROUPING sets ((k1,k4),(k1),(k4),());";
+        UtFrameUtils.parseAndAnalyzeStmt(selectStmtStr3, ctx);
+        String selectStmtStr4 = "select k1,k4+k4,MAX(k4+k4) from db1.tbl1 
GROUP BY GROUPING sets ((k1,k4),(k1),(k4),()"
+                + ");";
+        UtFrameUtils.parseAndAnalyzeStmt(selectStmtStr4, ctx);
+
+
+
+
+
+    }
+
+
+}
\ No newline at end of file
diff --git a/fe/src/test/java/org/apache/doris/utframe/AnotherDemoTest.java 
b/fe/src/test/java/org/apache/doris/utframe/AnotherDemoTest.java
index 61a6567..3aa7e74 100644
--- a/fe/src/test/java/org/apache/doris/utframe/AnotherDemoTest.java
+++ b/fe/src/test/java/org/apache/doris/utframe/AnotherDemoTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.utframe;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.doris.analysis.CreateDbStmt;
 import org.apache.doris.analysis.CreateTableStmt;
 import org.apache.doris.catalog.Catalog;
@@ -41,14 +42,16 @@ import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
+import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 import java.util.UUID;
 
 /*
@@ -69,18 +72,19 @@ public class AnotherDemoTest {
 
     // use a unique dir so that it won't be conflict with other unit test which
     // may also start a Mocked Frontend
-    private static String runningDir = "fe/mocked/AnotherDemoTest/" + 
UUID.randomUUID().toString() + "/";
+    private static String runningDirBase = "fe";
+    private static String runningDir = runningDirBase + 
"/mocked/AnotherDemoTest/" + UUID.randomUUID().toString() + "/";
 
     @BeforeClass
     public static void beforeClass() throws EnvVarNotSetException, IOException,
             FeStartException, NotInitException, DdlException, 
InterruptedException {
         // get DORIS_HOME
-        final String dorisHome = System.getenv("DORIS_HOME");
+        String dorisHome = System.getenv("DORIS_HOME");
         if (Strings.isNullOrEmpty(dorisHome)) {
-            throw new EnvVarNotSetException("env DORIS_HOME is not set");
+            dorisHome = 
Files.createTempDirectory("DORIS_HOME").toAbsolutePath().toString();
         }
 
-        getRandomPort();
+        getPorts();
 
         // start fe in "DORIS_HOME/fe/mocked/"
         MockedFrontend frontend = MockedFrontend.getInstance();
@@ -111,19 +115,25 @@ public class AnotherDemoTest {
         Thread.sleep(5000);
     }
 
-    // generate all port from between 20000 ~ 30000
-    private static void getRandomPort() {
-        Random r = new Random(System.currentTimeMillis());
-        int basePort = 20000 + r.nextInt(9000);
-        fe_http_port = basePort + 1;
-        fe_rpc_port = basePort + 2;
-        fe_query_port = basePort + 3;
-        fe_edit_log_port = basePort + 4;
-
-        be_heartbeat_port = basePort + 5;
-        be_thrift_port = basePort + 6;
-        be_brpc_port = basePort + 7;
-        be_http_port = basePort + 8;
+    @AfterClass
+    public static void TearDown() {
+        try {
+            FileUtils.deleteDirectory(new File(runningDirBase));
+        } catch (IOException e) {
+        }
+    }
+
+    // generate all port from valid ports
+    private static void getPorts() {
+        fe_http_port = UtFrameUtils.findValidPort();
+        fe_rpc_port = UtFrameUtils.findValidPort();
+        fe_query_port = UtFrameUtils.findValidPort();
+        fe_edit_log_port = UtFrameUtils.findValidPort();
+
+        be_heartbeat_port = UtFrameUtils.findValidPort();
+        be_thrift_port = UtFrameUtils.findValidPort();
+        be_brpc_port = UtFrameUtils.findValidPort();
+        be_http_port = UtFrameUtils.findValidPort();
     }
 
     @Test
diff --git a/fe/src/test/java/org/apache/doris/utframe/DemoTest.java 
b/fe/src/test/java/org/apache/doris/utframe/DemoTest.java
index a5498be..9bfeb3b 100644
--- a/fe/src/test/java/org/apache/doris/utframe/DemoTest.java
+++ b/fe/src/test/java/org/apache/doris/utframe/DemoTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.utframe;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.doris.alter.AlterJobV2;
 import org.apache.doris.analysis.AlterTableStmt;
 import org.apache.doris.analysis.CreateDbStmt;
@@ -43,14 +44,16 @@ import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
+import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 import java.util.UUID;
 
 /*
@@ -74,18 +77,19 @@ public class DemoTest {
     private static int be_http_port;
     // use a unique dir so that it won't be conflict with other unit test which
     // may also start a Mocked Frontend
-    private static String runningDir = "fe/mocked/DemoTest/" + 
UUID.randomUUID().toString() + "/";
+    private static String runningDirBase = "fe";
+    private static String runningDir = runningDirBase + "/mocked/DemoTest/" + 
UUID.randomUUID().toString() + "/";
 
     @BeforeClass
     public static void beforeClass() throws EnvVarNotSetException, IOException,
             FeStartException, NotInitException, DdlException, 
InterruptedException {
         // get DORIS_HOME
-        final String dorisHome = System.getenv("DORIS_HOME");
+        String dorisHome = System.getenv("DORIS_HOME");
         if (Strings.isNullOrEmpty(dorisHome)) {
-            throw new EnvVarNotSetException("env DORIS_HOME is not set");
+            dorisHome = 
Files.createTempDirectory("DORIS_HOME").toAbsolutePath().toString();
         }
 
-        getRandomPort();
+        getPorts();
 
         // start fe in "DORIS_HOME/fe/mocked/"
         MockedFrontend frontend = MockedFrontend.getInstance();
@@ -116,19 +120,26 @@ public class DemoTest {
         Thread.sleep(6000);
     }
 
-    // generate all port from between 20000 ~ 30000
-    private static void getRandomPort() {
-        Random r = new Random(System.currentTimeMillis());
-        int basePort = 20000 + r.nextInt(9000);
-        fe_http_port = basePort + 1;
-        fe_rpc_port = basePort + 2;
-        fe_query_port = basePort + 3;
-        fe_edit_log_port = basePort + 4;
-
-        be_heartbeat_port = basePort + 5;
-        be_thrift_port = basePort + 6;
-        be_brpc_port = basePort + 7;
-        be_http_port = basePort + 8;
+
+    @AfterClass
+    public static void TearDown() {
+        try {
+            FileUtils.deleteDirectory(new File(runningDirBase));
+        } catch (IOException e) {
+        }
+    }
+
+    // generate all port from valid ports
+    private static void getPorts() {
+        fe_http_port = UtFrameUtils.findValidPort();
+        fe_rpc_port = UtFrameUtils.findValidPort();
+        fe_query_port = UtFrameUtils.findValidPort();
+        fe_edit_log_port = UtFrameUtils.findValidPort();
+
+        be_heartbeat_port = UtFrameUtils.findValidPort();
+        be_thrift_port = UtFrameUtils.findValidPort();
+        be_brpc_port = UtFrameUtils.findValidPort();
+        be_http_port = UtFrameUtils.findValidPort();
     }
 
     @Test
diff --git a/fe/src/test/java/org/apache/doris/utframe/UtFrameUtils.java 
b/fe/src/test/java/org/apache/doris/utframe/UtFrameUtils.java
index f35b1af..388276a 100644
--- a/fe/src/test/java/org/apache/doris/utframe/UtFrameUtils.java
+++ b/fe/src/test/java/org/apache/doris/utframe/UtFrameUtils.java
@@ -42,10 +42,11 @@ import com.google.common.collect.Maps;
 
 import java.io.IOException;
 import java.io.StringReader;
+import java.net.ServerSocket;
 import java.nio.channels.SocketChannel;
+import java.nio.file.Files;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 
 public class UtFrameUtils {
 
@@ -77,22 +78,20 @@ public class UtFrameUtils {
     public static void createMinDorisCluster(String runningDir) throws 
EnvVarNotSetException, IOException,
             FeStartException, NotInitException, DdlException, 
InterruptedException {
         // get DORIS_HOME
-        final String dorisHome = System.getenv("DORIS_HOME");
+        String dorisHome = System.getenv("DORIS_HOME");
         if (Strings.isNullOrEmpty(dorisHome)) {
-            throw new EnvVarNotSetException("env DORIS_HOME is not set");
+            dorisHome = 
Files.createTempDirectory("DORIS_HOME").toAbsolutePath().toString();
         }
 
-        Random r = new Random(System.currentTimeMillis());
-        int basePort = 20000 + r.nextInt(9000);
-        int fe_http_port = basePort + 1;
-        int fe_rpc_port = basePort + 2;
-        int fe_query_port = basePort + 3;
-        int fe_edit_log_port = basePort + 4;
+        int fe_http_port = findValidPort();
+        int fe_rpc_port = findValidPort();
+        int fe_query_port = findValidPort();
+        int fe_edit_log_port = findValidPort();
 
-        int be_heartbeat_port = basePort + 5;
-        int be_thrift_port = basePort + 6;
-        int be_brpc_port = basePort + 7;
-        int be_http_port = basePort + 8;
+        int be_heartbeat_port = findValidPort();
+        int be_thrift_port = findValidPort();
+        int be_brpc_port = findValidPort();
+        int be_http_port = findValidPort();
 
         // start fe in "DORIS_HOME/fe/mocked/"
         MockedFrontend frontend = MockedFrontend.getInstance();
@@ -122,4 +121,22 @@ public class UtFrameUtils {
         // sleep to wait first heartbeat
         Thread.sleep(6000);
     }
+
+    public static int findValidPort() {
+        ServerSocket socket = null;
+        try {
+            socket = new ServerSocket(0);
+            socket.setReuseAddress(true);
+            return socket.getLocalPort();
+        } catch (Exception e) {
+            throw new IllegalStateException("Could not find a free TCP/IP port 
to start HTTP Server on");
+        } finally {
+            if (socket != null) {
+                try {
+                    socket.close();
+                } catch (Exception e) {
+                }
+            }
+        }
+    }
 }


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

Reply via email to