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());