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

xiangfu pushed a commit to branch support_alias_phase_1
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git

commit 5e0a8e3b5f4e69f767acd51d4a1f9707effff804
Author: Xiang Fu <fx19880...@gmail.com>
AuthorDate: Sat Jan 25 01:52:06 2020 -0800

    Support alias replacement in PinotQuery
---
 .../apache/pinot/sql/parsers/CalciteSqlParser.java | 47 +++++++++++++++-
 .../pinot/sql/parsers/CalciteSqlCompilerTest.java  | 62 ++++++++++++++++++++++
 2 files changed, 108 insertions(+), 1 deletion(-)

diff --git 
a/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java 
b/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
index b0070b0..584a722 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/sql/parsers/CalciteSqlParser.java
@@ -47,6 +47,7 @@ import org.apache.pinot.common.request.DataSource;
 import org.apache.pinot.common.request.Expression;
 import org.apache.pinot.common.request.ExpressionType;
 import org.apache.pinot.common.request.Function;
+import org.apache.pinot.common.request.Identifier;
 import org.apache.pinot.common.request.PinotQuery;
 import org.apache.pinot.common.utils.request.RequestUtils;
 import org.apache.pinot.pql.parsers.Pql2Compiler;
@@ -101,7 +102,7 @@ public class CalciteSqlParser {
 
   private static void validateGroupByClause(PinotQuery pinotQuery)
       throws SqlCompilationException {
-    if(pinotQuery.getGroupByList() == null) {
+    if (pinotQuery.getGroupByList() == null) {
       return;
     }
     // Sanity check group by query: All identifiers in selection list should 
be also included in group by list.
@@ -234,10 +235,54 @@ public class CalciteSqlParser {
         throw new RuntimeException(
             "Unable to convert SqlNode: " + sqlNode + " to PinotQuery. Unknown 
node type: " + sqlNode.getKind());
     }
+    Map<Identifier, Expression> aliasMap = 
extractAlias(pinotQuery.getSelectList());
+    applyAlias(aliasMap, pinotQuery);
     validate(pinotQuery);
     return pinotQuery;
   }
 
+  private static void applyAlias(Map<Identifier, Expression> aliasMap, 
PinotQuery pinotQuery) {
+    applyAlias(aliasMap, pinotQuery.getFilterExpression());
+    for (Expression groupByExpr : pinotQuery.getGroupByList()) {
+      applyAlias(aliasMap, groupByExpr);
+    }
+    for (Expression orderByExpr : pinotQuery.getOrderByList()) {
+      applyAlias(aliasMap, orderByExpr);
+    }
+  }
+
+  private static void applyAlias(Map<Identifier, Expression> aliasMap, 
Expression expression) {
+    if (expression == null) {
+      return;
+    }
+    Identifier identifierKey = expression.getIdentifier();
+    if ((identifierKey != null) && (aliasMap.containsKey(identifierKey))) {
+      Expression aliasExpression = aliasMap.get(identifierKey);
+      
expression.setType(aliasExpression.getType()).setIdentifier(aliasExpression.getIdentifier())
+          
.setFunctionCall(aliasExpression.getFunctionCall()).setLiteral(aliasExpression.getLiteral());
+    }
+    if (expression.getFunctionCall() != null) {
+      for (Expression operand : expression.getFunctionCall().getOperands()) {
+        applyAlias(aliasMap, operand);
+      }
+    }
+  }
+
+  private static Map<Identifier, Expression> extractAlias(List<Expression> 
expressions) {
+    Map<Identifier, Expression> aliasMap = new HashMap<>();
+    for (Expression expression : expressions) {
+      Function functionCall = expression.getFunctionCall();
+      if (functionCall == null) {
+        continue;
+      }
+      if (functionCall.getOperator().equalsIgnoreCase("AS")) {
+        Expression identifierExpr = functionCall.getOperands().get(1);
+        aliasMap.put(identifierExpr.getIdentifier(), 
functionCall.getOperands().get(0));
+      }
+    }
+    return aliasMap;
+  }
+
   private static List<String> extractOptionsFromSql(String sql) {
     List<String> results = new ArrayList<>();
     Matcher matcher = OPTIONS_REGEX_PATTEN.matcher(sql);
diff --git 
a/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
 
b/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
index 383863d..3b771ca 100644
--- 
a/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
+++ 
b/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
@@ -887,4 +887,66 @@ public class CalciteSqlCompilerTest {
       Assert.assertTrue(e.getMessage().contains("is not allowed in GROUP BY 
clause."));
     }
   }
+
+  @Test
+  public void testAliasQuery() {
+    String sql;
+    PinotQuery pinotQuery;
+    // Valid alias in query.
+    sql =
+        "select secondsSinceEpoch, sum(rsvp_count) as sum_rsvp_count, count(*) 
as cnt from meetupRsvp group by dateConvert(secondsSinceEpoch) order by cnt, 
sum_rsvp_count DESC limit 50";
+    pinotQuery = CalciteSqlParser.compileToPinotQuery(sql);
+    Assert.assertEquals(pinotQuery.getSelectListSize(), 3);
+    Assert.assertEquals(pinotQuery.getGroupByListSize(), 1);
+    Assert.assertEquals(pinotQuery.getOrderByListSize(), 2);
+    
Assert.assertEquals(pinotQuery.getOrderByList().get(0).getFunctionCall().getOperator(),
 "ASC");
+    Assert.assertEquals(
+        
pinotQuery.getOrderByList().get(0).getFunctionCall().getOperands().get(0).getFunctionCall().getOperator(),
+        "COUNT");
+    Assert.assertEquals(
+        
pinotQuery.getOrderByList().get(0).getFunctionCall().getOperands().get(0).getFunctionCall().getOperands().get(0)
+            .getIdentifier().getName(), "*");
+    
Assert.assertEquals(pinotQuery.getOrderByList().get(1).getFunctionCall().getOperator(),
 "DESC");
+    Assert.assertEquals(
+        
pinotQuery.getOrderByList().get(1).getFunctionCall().getOperands().get(0).getFunctionCall().getOperator(),
+        "SUM");
+    Assert.assertEquals(
+        
pinotQuery.getOrderByList().get(1).getFunctionCall().getOperands().get(0).getFunctionCall().getOperands().get(0)
+            .getIdentifier().getName(), "rsvp_count");
+
+    sql =
+        "select secondsSinceEpoch/86400 AS daysSinceEpoch, sum(rsvp_count) as 
sum_rsvp_count, count(*) as cnt from meetupRsvp where daysSinceEpoch = 18523 
group by daysSinceEpoch order by cnt, sum_rsvp_count DESC limit 50";
+    pinotQuery = CalciteSqlParser.compileToPinotQuery(sql);
+    Assert.assertEquals(pinotQuery.getSelectListSize(), 3);
+    
Assert.assertEquals(pinotQuery.getFilterExpression().getFunctionCall().getOperator(),
 "EQUALS");
+    Assert.assertEquals(
+        
pinotQuery.getFilterExpression().getFunctionCall().getOperands().get(0).getFunctionCall().getOperator(),
+        "DIVIDE");
+    Assert.assertEquals(
+        
pinotQuery.getFilterExpression().getFunctionCall().getOperands().get(0).getFunctionCall().getOperands().get(0)
+            .getIdentifier().getName(), "secondsSinceEpoch");
+    Assert.assertEquals(
+        
pinotQuery.getFilterExpression().getFunctionCall().getOperands().get(0).getFunctionCall().getOperands().get(1)
+            .getLiteral().getLongValue(), 86400);
+    Assert.assertEquals(
+        
pinotQuery.getFilterExpression().getFunctionCall().getOperands().get(1).getLiteral().getLongValue(),
 18523);
+    Assert.assertEquals(pinotQuery.getGroupByListSize(), 1);
+    
Assert.assertEquals(pinotQuery.getGroupByList().get(0).getFunctionCall().getOperator(),
 "DIVIDE");
+    Assert.assertEquals(
+        
pinotQuery.getGroupByList().get(0).getFunctionCall().getOperands().get(0).getIdentifier().getName(),
+        "secondsSinceEpoch");
+    Assert.assertEquals(
+        
pinotQuery.getGroupByList().get(0).getFunctionCall().getOperands().get(1).getLiteral().getLongValue(),
 86400);
+    Assert.assertEquals(pinotQuery.getOrderByListSize(), 2);
+
+    // Invalid groupBy clause shouldn't contain aggregate expression, like 
sum(rsvp_count), count(*).
+    try {
+      sql = "select  sum(rsvp_count), count(*) as cnt from meetupRsvp group by 
group_country, cnt limit 50";
+      CalciteSqlParser.compileToPinotQuery(sql);
+      Assert.fail("Query should have failed compilation");
+    } catch (Exception e) {
+      Assert.assertTrue(e instanceof SqlCompilationException);
+      Assert.assertTrue(e.getMessage().contains("is not allowed in GROUP BY 
clause."));
+    }
+  }
 }


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

Reply via email to