This is an automated email from the ASF dual-hosted git repository. hui pushed a commit to branch lmh/IOTDB_5764_1.1 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 1d76880174277423bd5a6a3dd8a063159e7824cb Author: liuminghui233 <[email protected]> AuthorDate: Wed Apr 12 10:05:42 2023 +0800 [IOTDB-5764] Fix that cannot specify alias successfully when the FROM clause contains multiple path suffixes (cherry picked from commit 5b1d362f7bb2c9e79d26777595250d4891aa4f92) --- .../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java | 20 +++++++----- .../db/mpp/plan/analyze/ConcatPathRewriter.java | 8 ----- .../iotdb/db/mpp/plan/analyze/AnalyzeTest.java | 36 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java index d46dfc0e9b..78aae8c424 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java @@ -429,26 +429,23 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> private Map<Integer, List<Pair<Expression, String>>> analyzeSelect( Analysis analysis, QueryStatement queryStatement, ISchemaTree schemaTree) { Map<Integer, List<Pair<Expression, String>>> outputExpressionMap = new HashMap<>(); + boolean isGroupByLevel = queryStatement.isGroupByLevel(); ColumnPaginationController paginationController = new ColumnPaginationController( queryStatement.getSeriesLimit(), queryStatement.getSeriesOffset(), queryStatement.isLastQuery() || isGroupByLevel); + + Set<String> aliasSet = new HashSet<>(); + int columnIndex = 0; for (ResultColumn resultColumn : queryStatement.getSelectComponent().getResultColumns()) { List<Pair<Expression, String>> outputExpressions = new ArrayList<>(); + boolean hasAlias = resultColumn.hasAlias(); List<Expression> resultExpressions = ExpressionAnalyzer.removeWildcardInExpression(resultColumn.getExpression(), schemaTree); - if (hasAlias - && !queryStatement.isGroupByLevel() - && !queryStatement.isGroupByTag() - && resultExpressions.size() > 1) { - throw new SemanticException( - String.format( - "alias '%s' can only be matched with one time series", resultColumn.getAlias())); - } for (Expression expression : resultExpressions) { if (paginationController.hasCurOffset()) { paginationController.consumeOffset(); @@ -469,6 +466,13 @@ public class AnalyzeVisitor extends StatementVisitor<Analysis, MPPQueryContext> ? expression.getExpressionString() : null; alias = hasAlias ? resultColumn.getAlias() : alias; + if (hasAlias) { + if (aliasSet.contains(alias)) { + throw new SemanticException( + String.format("alias '%s' can only be matched with one time series", alias)); + } + aliasSet.add(alias); + } analyzeExpression(analysis, expressionWithoutAlias); outputExpressions.add(new Pair<>(expressionWithoutAlias, alias)); } diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ConcatPathRewriter.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ConcatPathRewriter.java index e5ffd54285..1dca937376 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ConcatPathRewriter.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/ConcatPathRewriter.java @@ -20,7 +20,6 @@ package org.apache.iotdb.db.mpp.plan.analyze; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.commons.path.PathPatternTree; -import org.apache.iotdb.db.exception.sql.SemanticException; import org.apache.iotdb.db.exception.sql.StatementAnalyzeException; import org.apache.iotdb.db.mpp.plan.expression.Expression; import org.apache.iotdb.db.mpp.plan.statement.Statement; @@ -105,16 +104,9 @@ public class ConcatPathRewriter { // resultColumns after concat List<ResultColumn> resultColumns = new ArrayList<>(); for (ResultColumn resultColumn : selectComponent.getResultColumns()) { - boolean needAliasCheck = resultColumn.hasAlias() && !isGroupByLevel; List<Expression> resultExpressions = ExpressionAnalyzer.concatExpressionWithSuffixPaths( resultColumn.getExpression(), prefixPaths, patternTree); - if (needAliasCheck && resultExpressions.size() > 1) { - throw new SemanticException( - String.format( - "alias '%s' can only be matched with one time series", resultColumn.getAlias())); - } - for (Expression resultExpression : resultExpressions) { resultColumns.add( new ResultColumn( diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeTest.java index 3fbf8f44c1..ac16f04ec3 100644 --- a/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeTest.java +++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeTest.java @@ -758,6 +758,42 @@ public class AnalyzeTest { } } + @Test + public void testAlias1() { + Analysis analysis = analyzeSQL("select s1 as a, s2 as b from root.sg.d2.a, root.sg.d2.b"); + assert analysis != null; + Assert.assertEquals( + analysis.getRespDatasetHeader(), + new DatasetHeader( + Arrays.asList( + new ColumnHeader("root.sg.d2.a.s1", TSDataType.INT32, "a"), + new ColumnHeader("root.sg.d2.a.s2", TSDataType.DOUBLE, "b")), + false)); + } + + @Test + public void testAlias2() { + assertTestFail( + "select s1 as a from root.sg.*", "alias 'a' can only be matched with one time series"); + assertTestFail( + "select s1 as a from root.sg.d1, root.sg.d2", + "alias 'a' can only be matched with one time series"); + } + + private void assertTestFail(String sql, String errMsg) { + try { + Statement statement = + StatementGenerator.createStatement(sql, ZonedDateTime.now().getOffset()); + MPPQueryContext context = new MPPQueryContext(new QueryId("test_query")); + Analyzer analyzer = + new Analyzer(context, new FakePartitionFetcherImpl(), new FakeSchemaFetcherImpl()); + analyzer.analyze(statement); + fail("No exception!"); + } catch (Exception e) { + Assert.assertTrue(e.getMessage(), e.getMessage().contains(errMsg)); + } + } + private Analysis analyzeSQL(String sql) { try { Statement statement =
