KYLIN-2277 return correct columns for select *

Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/654144f4
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/654144f4
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/654144f4

Branch: refs/heads/master-hbase1.x
Commit: 654144f47ff647bc4b7eac9793d2fa5f88dec372
Parents: e6e330a
Author: Yang Li <liy...@apache.org>
Authored: Tue Dec 13 23:45:55 2016 +0800
Committer: Yang Li <liy...@apache.org>
Committed: Wed Dec 14 21:18:21 2016 +0800

----------------------------------------------------------------------
 .../calcite/sql2rel/SqlToRelConverter.java      | 62 +++++++++++++++++++-
 .../kylin/metadata/model/FunctionDesc.java      |  4 +-
 .../apache/kylin/query/ITKylinQueryTest.java    |  6 ++
 .../org/apache/kylin/query/KylinTestBase.java   | 21 +++++++
 .../resources/query/sql_timeout/query01.sql     |  2 +-
 5 files changed, 91 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/654144f4/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git 
a/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java 
b/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index d223cdf..cf36f61 100644
--- 
a/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ 
b/atopcalcite/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -67,6 +67,7 @@ import org.apache.calcite.rel.stream.Delta;
 import org.apache.calcite.rel.stream.LogicalDelta;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeFactory.FieldInfoBuilder;
 import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexCall;
@@ -194,6 +195,7 @@ import static org.apache.calcite.util.Static.RESOURCE;
  * - getInSubqueryThreshold(), was `20`, now `Integer.MAX_VALUE`
  * - isTrimUnusedFields(), override to false
  * - AggConverter.translateAgg(...), skip column reading for COUNT(COL), for 
https://jirap.corp.ebay.com/browse/KYLIN-104
+ * - convertQuery(), call hackSelectStar() at the end
  */
 
 /**
@@ -529,6 +531,8 @@ public class SqlToRelConverter {
      *                        the query will be part of a view.
      */
     public RelRoot convertQuery(SqlNode query, final boolean needsValidation, 
final boolean top) {
+        SqlNode origQuery = query; /* OVERRIDE POINT */
+        
         if (needsValidation) {
             query = validator.validate(query);
         }
@@ -553,7 +557,63 @@ public class SqlToRelConverter {
         }
 
         final RelDataType validatedRowType = 
validator.getValidatedNodeType(query);
-        return RelRoot.of(result, validatedRowType, 
query.getKind()).withCollation(collation);
+        return hackSelectStar(origQuery, RelRoot.of(result, validatedRowType, 
query.getKind()).withCollation(collation));
+    }
+
+    /* OVERRIDE POINT */
+    private RelRoot hackSelectStar(SqlNode query, RelRoot root) {
+        /*
+         * Rel tree is like:
+         * 
+         *   LogicalSort (optional)
+         *    |- LogicalProject
+         *        |- OLAPTableScan
+         */
+        LogicalProject rootPrj = null;
+        LogicalSort rootSort = null;
+        if (root.rel instanceof LogicalProject) {
+            rootPrj = (LogicalProject) root.rel;
+        } else if (root.rel instanceof LogicalSort && root.rel.getInput(0) 
instanceof LogicalProject) {
+            rootPrj = (LogicalProject) root.rel.getInput(0);
+            rootSort = (LogicalSort) root.rel;
+        } else {
+            return root;
+        }
+        
+        if 
(!rootPrj.getInput().getClass().getSimpleName().equals("OLAPTableScan"))
+            return root;
+
+        RelNode scan = rootPrj.getInput();
+        if (rootPrj.getRowType().getFieldCount() < 
scan.getRowType().getFieldCount())
+            return root;
+        
+        RelDataType inType = rootPrj.getRowType();
+        List<String> inFields = inType.getFieldNames();
+        List<RexNode> projExp = new ArrayList<>();
+        List<Pair<Integer, String>> projFields = new ArrayList<>();
+        FieldInfoBuilder projTypeBuilder = 
getCluster().getTypeFactory().builder();
+        FieldInfoBuilder validTypeBuilder = 
getCluster().getTypeFactory().builder();
+        for (int i = 0; i < inFields.size(); i++) {
+            if (!inFields.get(i).startsWith("_KY_")) {
+                projExp.add(rootPrj.getProjects().get(i));
+                projFields.add(Pair.of(projFields.size(), inFields.get(i)));
+                projTypeBuilder.add(inType.getFieldList().get(i));
+                
validTypeBuilder.add(root.validatedRowType.getFieldList().get(i));
+            }
+        }
+
+        RelDataType projRowType = 
getCluster().getTypeFactory().createStructType(projTypeBuilder);
+        rootPrj = LogicalProject.create(scan, projExp, projRowType);
+        if (rootSort != null) {
+            rootSort = (LogicalSort) rootSort.copy(rootSort.getTraitSet(), 
rootPrj, rootSort.collation, rootSort.offset, rootSort.fetch);
+        }
+        
+        RelDataType validRowType = 
getCluster().getTypeFactory().createStructType(validTypeBuilder);
+        root = new RelRoot(rootSort == null ? rootPrj : rootSort, 
validRowType, root.kind, projFields, root.collation);
+        
+        validator.setValidatedNodeType(query, validRowType);
+        
+        return root;
     }
 
     private static boolean isStream(SqlNode query) {

http://git-wip-us.apache.org/repos/asf/kylin/blob/654144f4/core-metadata/src/main/java/org/apache/kylin/metadata/model/FunctionDesc.java
----------------------------------------------------------------------
diff --git 
a/core-metadata/src/main/java/org/apache/kylin/metadata/model/FunctionDesc.java 
b/core-metadata/src/main/java/org/apache/kylin/metadata/model/FunctionDesc.java
index ac13f40..4d89e1a 100644
--- 
a/core-metadata/src/main/java/org/apache/kylin/metadata/model/FunctionDesc.java
+++ 
b/core-metadata/src/main/java/org/apache/kylin/metadata/model/FunctionDesc.java
@@ -138,9 +138,9 @@ public class FunctionDesc {
         if (isSum()) {
             return getParameter().getValue();
         } else if (isCount()) {
-            return "COUNT__"; // ignores parameter, count(*), count(1), 
count(col) are all the same
+            return "_KY_" + "COUNT__"; // ignores parameter, count(*), 
count(1), count(col) are all the same
         } else {
-            return getFullExpression().replaceAll("[(),. ]", "_");
+            return "_KY_" + getFullExpression().replaceAll("[(),. ]", "_");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/654144f4/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java
----------------------------------------------------------------------
diff --git 
a/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java 
b/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java
index d485955..7f04bbb 100644
--- a/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java
+++ b/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java
@@ -379,4 +379,10 @@ public class ITKylinQueryTest extends KylinTestBase {
         // compare the result
         Assert.assertEquals(expectVersion, queriedVersion);
     }
+    
+    @Test
+    public void testSelectStarColumnCount() throws Exception {
+        execAndCompColumnCount("select * from test_kylin_fact limit 10", 9);
+        execAndCompColumnCount("select * from test_kylin_fact", 9);
+    }
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/654144f4/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java 
b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
index bcf55e5..ddb996c 100644
--- a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
+++ b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
@@ -67,6 +67,7 @@ import org.dbunit.ext.h2.H2Connection;
 import org.dbunit.ext.h2.H2DataTypeFactory;
 import org.junit.Assert;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.io.Files;
 
 /**
@@ -422,6 +423,26 @@ public class KylinTestBase {
         }
     }
 
+    protected void execAndCompColumnCount(String input, int 
expectedColumnCount) throws Exception {
+        printInfo("---------- test column count: " + input);
+        Set<String> sqlSet = ImmutableSet.of(input);
+        
+        for (String sql : sqlSet) {
+            // execute Kylin
+            printInfo("Query Result from Kylin - " + sql);
+            IDatabaseConnection kylinConn = new 
DatabaseConnection(cubeConnection);
+            ITable kylinTable = executeQuery(kylinConn, sql, sql, false);
+            
+            try {
+                // compare the result
+                Assert.assertEquals(expectedColumnCount, 
kylinTable.getTableMetaData().getColumns().length);
+            } catch (Throwable t) {
+                printInfo("execAndCompColumnCount failed on: " + sql);
+                throw t;
+            }
+        }
+    }
+    
     protected void execLimitAndValidate(String queryFolder) throws Exception {
         printInfo("---------- test folder: " + new 
File(queryFolder).getAbsolutePath());
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/654144f4/kylin-it/src/test/resources/query/sql_timeout/query01.sql
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/resources/query/sql_timeout/query01.sql 
b/kylin-it/src/test/resources/query/sql_timeout/query01.sql
index 3b9a837..eaff396 100644
--- a/kylin-it/src/test/resources/query/sql_timeout/query01.sql
+++ b/kylin-it/src/test/resources/query/sql_timeout/query01.sql
@@ -16,4 +16,4 @@
 -- limitations under the License.
 --
 
-select * from test_kylin_fact limit 1200
+select seller_id,lstg_format_name from test_kylin_fact limit 1200

Reply via email to