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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]