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

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


The following commit(s) were added to refs/heads/kylin5 by this push:
     new 1cff0dcdd4 KYLIN-6067 Keep columns order in select star for ModelView
1cff0dcdd4 is described below

commit 1cff0dcdd41621c8845608be8c500f04a7796593
Author: Yan Xin <[email protected]>
AuthorDate: Fri Jan 17 14:50:50 2025 +0800

    KYLIN-6067 Keep columns order in select star for ModelView
    
    * change order config from int to string
    
    * fix toLowerCase
    
    ---------
    
    Co-authored-by: Pengfei Zhan <[email protected]>
---
 .../org/apache/kylin/common/KylinConfigBase.java   | 20 +++++++++++
 .../apache/kylin/common/KylinConfigBaseTest.java   | 16 +++++++++
 .../query/engine/view/ModelViewGenerator.java      | 39 ++++++++++++++++++++++
 .../kylin/query/engine/view/ModelViewTest.java     | 30 +++++++++++++++++
 4 files changed, 105 insertions(+)

diff --git 
a/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java 
b/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
index 735813be56..ae408e0565 100644
--- a/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
+++ b/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
@@ -2235,6 +2235,26 @@ public abstract class KylinConfigBase implements 
Serializable {
         return 
Boolean.parseBoolean(this.getOptional("kylin.query.auto-model-view-enabled", 
FALSE));
     }
 
+    /**
+        * This method was originally written using integers.
+        * To avoid excessive use of magic numbers, we now use descriptive 
strings.
+        * However, integers are retained to preserve the original behavior.
+     */
+    public String getColOrderForSelectStarInModelView() {
+        String colOrder = 
getOptional("kylin.query.select-star-col-order-in-model-view", "default")
+                .toLowerCase(Locale.ROOT);
+        switch (colOrder) {
+        case "1":
+        case "order-by-model":
+            return "orderByModel";
+        case "2":
+        case "order-by-table":
+            return "orderByTable";
+        default:
+            return "default";
+        }
+    }
+
     public Map<String, String> getUDFs() {
         Map<String, String> udfMap = Maps.newLinkedHashMap();
         udfMap.put("bitmap_function", 
"org.apache.kylin.query.udf.KylinBitmapUDF");
diff --git 
a/src/core-common/src/test/java/org/apache/kylin/common/KylinConfigBaseTest.java
 
b/src/core-common/src/test/java/org/apache/kylin/common/KylinConfigBaseTest.java
index 5bacdfc38e..29a665bb0d 100644
--- 
a/src/core-common/src/test/java/org/apache/kylin/common/KylinConfigBaseTest.java
+++ 
b/src/core-common/src/test/java/org/apache/kylin/common/KylinConfigBaseTest.java
@@ -1644,4 +1644,20 @@ class EnvironmentUpdateUtils {
         config.setProperty("kylin.metadata.ops-cron-timeout", "4h");
         Assert.assertEquals(4 * 60 * 60 * 1000, 
config.getRoutineOpsTaskTimeOut());
     }
+
+    @Test
+    @MetadataInfo(onlyProps = true)
+    void testGetColOrderInModelView() {
+        KylinConfig config = KylinConfig.getInstanceFromEnv();
+        config.setProperty("kylin.query.select-star-col-order-in-model-view", 
"0");
+        Assertions.assertEquals("default", 
config.getColOrderForSelectStarInModelView());
+        config.setProperty("kylin.query.select-star-col-order-in-model-view", 
"1");
+        Assertions.assertEquals("orderByModel", 
config.getColOrderForSelectStarInModelView());
+        config.setProperty("kylin.query.select-star-col-order-in-model-view", 
"2");
+        Assertions.assertEquals("orderByTable", 
config.getColOrderForSelectStarInModelView());
+        config.setProperty("kylin.query.select-star-col-order-in-model-view", 
"order-By-Model");
+        Assertions.assertEquals("orderByModel", 
config.getColOrderForSelectStarInModelView());
+        config.setProperty("kylin.query.select-star-col-order-in-model-view", 
"order-By-Table");
+        Assertions.assertEquals("orderByTable", 
config.getColOrderForSelectStarInModelView());
+    }
 }
diff --git 
a/src/query/src/main/java/org/apache/kylin/query/engine/view/ModelViewGenerator.java
 
b/src/query/src/main/java/org/apache/kylin/query/engine/view/ModelViewGenerator.java
index 23adcadb54..59cff2c0d6 100644
--- 
a/src/query/src/main/java/org/apache/kylin/query/engine/view/ModelViewGenerator.java
+++ 
b/src/query/src/main/java/org/apache/kylin/query/engine/view/ModelViewGenerator.java
@@ -19,8 +19,10 @@
 package org.apache.kylin.query.engine.view;
 
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
@@ -42,6 +44,7 @@ import org.apache.kylin.metadata.model.NDataModel;
 import org.apache.kylin.metadata.model.TableRef;
 import org.apache.kylin.metadata.model.TblColRef;
 import org.apache.kylin.metadata.model.tool.CalciteParser;
+import org.apache.kylin.metadata.project.NProjectManager;
 
 public class ModelViewGenerator {
 
@@ -144,9 +147,45 @@ public class ModelViewGenerator {
         ccTblColRefs.removeIf(tblColRef -> !colRefs.contains(tblColRef));
         colRefs.addAll(ccTblColRefs);
 
+        String order = 
NProjectManager.getProjectConfig(model.getProject()).getColOrderForSelectStarInModelView();
+        if (order.equals("orderByModel")) {
+            return orderByModelColSequence(colRefs);
+        } else if (order.equals("orderByTable")) {
+            return orderByTableColSeq(colRefs, model);
+        }
         return colRefs;
     }
 
+    private Set<TblColRef> orderByTableColSeq(Set<TblColRef> colRefs, 
NDataModel model) {
+        Set<TableRef> linkedTblRefs = model.getAllTableRefs();
+        List<TblColRef> allCols = linkedTblRefs.stream().map(tableRef -> {
+            Collection<TblColRef> columns = tableRef.getColumns();
+            return columns.stream().sorted((Comparator.comparingInt(o -> 
o.getColumnDesc().getZeroBasedIndex())))
+                    .collect(Collectors.toList());
+        }).flatMap(Collection::stream).collect(Collectors.toList());
+        Set<TblColRef> orderedTableRefs = new LinkedHashSet<>();
+        for (TblColRef col : allCols) {
+            if (colRefs.contains(col)) {
+                orderedTableRefs.add(col);
+            }
+        }
+        return orderedTableRefs;
+    }
+
+    private Set<TblColRef> orderByModelColSequence(Set<TblColRef> colRefs) {
+        List<Integer> allExistIds = model.getAllNamedColumns().stream() //
+                .filter(NDataModel.NamedColumn::isExist) //
+                
.map(NDataModel.NamedColumn::getId).collect(Collectors.toList());
+        Set<TblColRef> orderedTableRefs = new LinkedHashSet<>();
+        for (Integer id : allExistIds) {
+            TblColRef tblColRef = model.getEffectiveCols().get(id);
+            if (tblColRef != null && colRefs.contains(tblColRef)) {
+                orderedTableRefs.add(tblColRef);
+            }
+        }
+        return orderedTableRefs;
+    }
+
     /**
      * parse cc expr and find all table columns ref
      * @param ccCols
diff --git 
a/src/query/src/test/java/org/apache/kylin/query/engine/view/ModelViewTest.java 
b/src/query/src/test/java/org/apache/kylin/query/engine/view/ModelViewTest.java
index 1efa5160e2..c6a564d868 100644
--- 
a/src/query/src/test/java/org/apache/kylin/query/engine/view/ModelViewTest.java
+++ 
b/src/query/src/test/java/org/apache/kylin/query/engine/view/ModelViewTest.java
@@ -181,6 +181,36 @@ public class ModelViewTest extends 
NLocalFileMetadataTestCase {
         }
     }
 
+    @Test
+    public void testOrderByModel() throws IOException {
+        overwriteSystemProp("kylin.query.select-star-col-order-in-model-view", 
"1");
+        val projectName = "SSB_TEST";
+        createProject(projectName);
+        val model = createModel(projectName, "model_single_table");
+        val generated = new 
ModelViewGenerator(model).generateViewSQL().replace("  ", " ");
+        val expectedSQL = "SELECT \"LINEORDER\".\"LO_ORDERKEY\" AS 
\"THE_KEY\","
+                + "\"LINEORDER\".\"LO_ORDTOTALPRICE\" AS \"LO_ORDTOTALPRICE\","
+                + "\"LINEORDER\".\"LO_LINENUMBER\" AS \"LO_LINENUMBER\","
+                + "\"LINEORDER\".\"LO_CUSTKEY\" AS \"L O CU ST KEY\" FROM 
\"SSB\".\"LINEORDER\" AS \"LINEORDER\"";
+        Assert.assertEquals(String.format("%s view sql generated unexpected 
sql", "model_single_table"),
+                expectedSQL.trim(), generated);
+    }
+
+    @Test
+    public void testOrderByTable() throws IOException {
+        overwriteSystemProp("kylin.query.select-star-col-order-in-model-view", 
"2");
+        val projectName = "SSB_TEST";
+        createProject(projectName);
+        val model = createModel(projectName, "model_single_table");
+        val generated = new 
ModelViewGenerator(model).generateViewSQL().replace("  ", " ");
+        val expectedSQL = "SELECT \"LINEORDER\".\"LO_ORDERKEY\" AS 
\"THE_KEY\","
+                + "\"LINEORDER\".\"LO_LINENUMBER\" AS \"LO_LINENUMBER\","
+                + "\"LINEORDER\".\"LO_CUSTKEY\" AS \"L O CU ST KEY\","
+                + "\"LINEORDER\".\"LO_ORDTOTALPRICE\" AS \"LO_ORDTOTALPRICE\" 
FROM \"SSB\".\"LINEORDER\" AS \"LINEORDER\"";
+        Assert.assertEquals(String.format("%s view sql generated unexpected 
sql", "model_single_table"),
+                expectedSQL.trim(), generated);
+    }
+
     @Test
     public void testDBNameCollision() throws IOException {
         val projMgr = 
NProjectManager.getInstance(KylinConfig.getInstanceFromEnv());

Reply via email to