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

nic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kylin.git


The following commit(s) were added to refs/heads/master by this push:
     new d659542  KYLIN-3628 Fix unexpected exception for select from Lookup 
Table
d659542 is described below

commit d659542ed28e6dcb12a9e6944214258f4eefc178
Author: XiaoxiangYu <hit_la...@126.com>
AuthorDate: Wed Jul 3 10:18:25 2019 +0800

    KYLIN-3628 Fix unexpected exception for select from Lookup Table
    
    In some case, cube returned by findLatestSnapshot didn't contains the 
snapshot table
    for what you need. Because some dimension which exists in model but was 
removed in cube design phase, query such as "select * from LookupTable" will 
throw unexpected exception and confused user.
---
 .../java/org/apache/kylin/cube/CubeManager.java    | 38 +++++++++++++++++++---
 .../query/enumerator/LookupTableEnumerator.java    |  2 +-
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java 
b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
index 474c973..86e989a 100755
--- a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
@@ -45,6 +45,7 @@ import org.apache.kylin.common.util.Pair;
 import org.apache.kylin.common.util.RandomUtil;
 import org.apache.kylin.cube.cuboid.Cuboid;
 import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.cube.model.DimensionDesc;
 import org.apache.kylin.cube.model.SnapshotTableDesc;
 import org.apache.kylin.dict.DictionaryInfo;
 import org.apache.kylin.dict.DictionaryManager;
@@ -1227,16 +1228,21 @@ public class CubeManager implements 
IRealizationProvider {
         }
     }
 
-    public CubeInstance findLatestSnapshot(List<RealizationEntry> 
realizationEntries, String lookupTableName) {
+    /**
+     * To keep "select * from LOOKUP_TABLE" has consistent and latest result, 
we manually choose
+     * CubeInstance here to answer such query.
+     */
+    public CubeInstance findLatestSnapshot(List<RealizationEntry> 
realizationEntries, String lookupTableName,
+            CubeInstance cubeInstance) {
         CubeInstance cube = null;
-        if (realizationEntries.size() > 0) {
+        if (!realizationEntries.isEmpty()) {
             long maxBuildTime = Long.MIN_VALUE;
             RealizationRegistry registry = 
RealizationRegistry.getInstance(config);
             for (RealizationEntry entry : realizationEntries) {
                 IRealization realization = 
registry.getRealization(entry.getType(), entry.getRealization());
                 if (realization != null && realization.isReady() && 
realization instanceof CubeInstance) {
-                    if (realization.getModel().isLookupTable(lookupTableName)) 
{
-                        CubeInstance current = (CubeInstance) realization;
+                    CubeInstance current = (CubeInstance) realization;
+                    if (checkMeetSnapshotTable(current, lookupTableName)) {
                         CubeSegment segment = current.getLatestReadySegment();
                         if (segment != null) {
                             long latestBuildTime = segment.getLastBuildTime();
@@ -1249,6 +1255,30 @@ public class CubeManager implements IRealizationProvider 
{
                 }
             }
         }
+        if (!cubeInstance.equals(cube)) {
+            logger.debug("Picked cube {} over {} as it provides a more recent 
snapshot of the lookup table {}", cube,
+                    cubeInstance, lookupTableName);
+        }
         return cube;
     }
+
+    /**
+     * check if {toCheck} has snapshot of {lookupTableName}
+     * @param lookupTableName look like {SCHMEA}.{TABLE}
+     */
+    private boolean checkMeetSnapshotTable(CubeInstance toCheck, String 
lookupTableName) {
+        boolean checkRes = false;
+        String lookupTbl = lookupTableName;
+        String[] strArr = lookupTableName.split("\\.");
+        if (strArr.length > 1) {
+            lookupTbl = strArr[strArr.length - 1];
+        }
+        for (DimensionDesc dimensionDesc : 
toCheck.getDescriptor().getDimensions()) {
+            if (dimensionDesc.getTable().equalsIgnoreCase(lookupTbl)) {
+                checkRes = true;
+                break;
+            }
+        }
+        return checkRes;
+    }
 }
diff --git 
a/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java
 
b/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java
index f8c7ad4..a4f28a8 100644
--- 
a/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java
+++ 
b/query/src/main/java/org/apache/kylin/query/enumerator/LookupTableEnumerator.java
@@ -60,7 +60,7 @@ public class LookupTableEnumerator implements 
Enumerator<Object[]> {
             List<RealizationEntry> realizationEntries = 
project.getRealizationEntries();
             String lookupTableName = olapContext.firstTableScan.getTableName();
             CubeManager cubeMgr = CubeManager.getInstance(cube.getConfig());
-            cube = cubeMgr.findLatestSnapshot(realizationEntries, 
lookupTableName);
+            cube = cubeMgr.findLatestSnapshot(realizationEntries, 
lookupTableName, cube);
             olapContext.realization = cube;
         } else if (olapContext.realization instanceof HybridInstance) {
             final HybridInstance hybridInstance = (HybridInstance) 
olapContext.realization;

Reply via email to