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