This is an automated email from the ASF dual-hosted git repository. xxyu pushed a commit to branch kylin5 in repository https://gitbox.apache.org/repos/asf/kylin.git
commit 0eea09e8cd369d82ba1dd16c25f2d236db0c66c9 Author: Pengfei Zhan <dethr...@gmail.com> AuthorDate: Sat May 20 13:20:30 2023 +0800 KYLIN-5692 Nested computed columns were incorrectly removed when editing the model --- .../kylin/rest/service/ModelSemanticHelper.java | 3 +- .../service/ModelServiceSemanticUpdateTest.java | 69 ++++++++++++++++++++-- .../org/apache/kylin/query/util/QueryUtilTest.java | 4 +- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/modeling-service/src/main/java/org/apache/kylin/rest/service/ModelSemanticHelper.java b/src/modeling-service/src/main/java/org/apache/kylin/rest/service/ModelSemanticHelper.java index e47bfe2eb6..2b1694501c 100644 --- a/src/modeling-service/src/main/java/org/apache/kylin/rest/service/ModelSemanticHelper.java +++ b/src/modeling-service/src/main/java/org/apache/kylin/rest/service/ModelSemanticHelper.java @@ -1161,8 +1161,9 @@ public class ModelSemanticHelper extends BasicService { List<ComputedColumnDesc> computedColumnDescs) { return computedColumnDescs.stream().map(ccDesc -> { AtomicBoolean isValidCC = new AtomicBoolean(true); + String calciteSyntaxExp = QueryUtil.adaptCalciteSyntax(ccDesc.getInnerExpression()); List<Pair<String, String>> colsWithAlias = ComputedColumnUtil.ExprIdentifierFinder - .getExprIdentifiers(ccDesc.getExpression()); + .getExprIdentifiers(calciteSyntaxExp); colsWithAlias.forEach(c -> { String column = c.getFirst() + "." + c.getSecond(); if (!aliasDotColSet.contains(column)) { diff --git a/src/modeling-service/src/test/java/org/apache/kylin/rest/service/ModelServiceSemanticUpdateTest.java b/src/modeling-service/src/test/java/org/apache/kylin/rest/service/ModelServiceSemanticUpdateTest.java index 3ea5743a42..07fa1fe8bc 100644 --- a/src/modeling-service/src/test/java/org/apache/kylin/rest/service/ModelServiceSemanticUpdateTest.java +++ b/src/modeling-service/src/test/java/org/apache/kylin/rest/service/ModelServiceSemanticUpdateTest.java @@ -45,6 +45,10 @@ import org.apache.kylin.cube.model.SelectRule; import org.apache.kylin.engine.spark.job.ExecutableAddCuboidHandler; import org.apache.kylin.engine.spark.job.NSparkCubingJob; import org.apache.kylin.engine.spark.utils.SparkJobFactoryUtils; +import org.apache.kylin.guava30.shaded.common.collect.ImmutableList; +import org.apache.kylin.guava30.shaded.common.collect.Lists; +import org.apache.kylin.guava30.shaded.common.collect.Maps; +import org.apache.kylin.guava30.shaded.common.collect.Sets; import org.apache.kylin.job.execution.AbstractExecutable; import org.apache.kylin.job.execution.ExecutableState; import org.apache.kylin.job.execution.NExecutableManager; @@ -96,11 +100,6 @@ import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.util.ReflectionTestUtils; -import org.apache.kylin.guava30.shaded.common.collect.ImmutableList; -import org.apache.kylin.guava30.shaded.common.collect.Lists; -import org.apache.kylin.guava30.shaded.common.collect.Maps; -import org.apache.kylin.guava30.shaded.common.collect.Sets; - import lombok.val; import lombok.var; import lombok.extern.slf4j.Slf4j; @@ -476,6 +475,66 @@ public class ModelServiceSemanticUpdateTest extends NLocalFileMetadataTestCase { } } + @Test + public void testModifyNestedComputedColumn() throws IOException { + NDataModelManager modelManager = NDataModelManager.getInstance(getTestConfig(), getProject()); + modelManager.listAllModels().forEach(modelManager::dropModel); + ModelRequest request = JsonUtil.readValue( + getClass().getResourceAsStream("/ut_request/model_update/model_with_measure.json"), ModelRequest.class); + request.setAlias("model_with_measure"); + NDataModel newModel = modelService.createModel(request.getProject(), request); + + NDataModel model = modelManager.getDataModelDesc(newModel.getId()); + List<ComputedColumnDesc> ccList = model.getComputedColumnDescs(); + ComputedColumnDesc cc1 = new ComputedColumnDesc(); + cc1.setExpression("TEST_ORDER.BUYER_ID + 1"); + cc1.setInnerExpression("`TEST_ORDER`.`BUYER_ID` + 1"); + cc1.setColumnName("CC1"); + cc1.setDatatype("bigint"); + cc1.setTableAlias("TEST_ORDER"); + cc1.setTableIdentity("DEFAULT.TEST_ORDER"); + ComputedColumnDesc cc2 = new ComputedColumnDesc(); + cc2.setExpression("TEST_ORDER.BUYER_ID + TEST_ORDER.CC3"); + cc2.setInnerExpression("`TEST_ORDER`.`BUYER_ID` + (`TEST_ORDER`.`BUYER_ID` + 3)"); + cc2.setColumnName("CC2"); + cc2.setDatatype("bigint"); + cc2.setTableAlias("TEST_ORDER"); + cc2.setTableIdentity("DEFAULT.TEST_ORDER"); + ComputedColumnDesc cc3 = new ComputedColumnDesc(); + cc3.setExpression("TEST_ORDER.BUYER_ID + 3"); + cc3.setInnerExpression("`TEST_ORDER`.`BUYER_ID` + 3"); + cc3.setColumnName("CC3"); + cc3.setDatatype("bigint"); + cc3.setTableAlias("TEST_ORDER"); + cc3.setTableIdentity("DEFAULT.TEST_ORDER"); + ccList.add(cc1); + ccList.add(cc2); + ccList.add(cc3); + List<NamedColumn> allNamedColumns = model.getAllNamedColumns(); + NamedColumn col1 = new NamedColumn(); + col1.setStatus(ColumnStatus.DIMENSION); + col1.setName("CC1"); + col1.setAliasDotColumn("TEST_ORDER.CC1"); + col1.setId(10); + NamedColumn col2 = new NamedColumn(); + col2.setStatus(ColumnStatus.DIMENSION); + col2.setName("CC2"); + col2.setAliasDotColumn("TEST_ORDER.CC2"); + col2.setId(11); + NamedColumn col3 = new NamedColumn(); + col3.setStatus(ColumnStatus.DIMENSION); + col3.setName("CC3"); + col3.setAliasDotColumn("TEST_ORDER.CC3"); + col3.setId(12); + allNamedColumns.add(col1); + allNamedColumns.add(col2); + allNamedColumns.add(col3); + + ModelSemanticHelper modelSemanticHelper = new ModelSemanticHelper(); + modelSemanticHelper.discardInvalidColsAndMeasForBrokenModel(getProject(), model); + Assert.assertEquals(3, model.getComputedColumnDescs().size()); + } + @Test public void testMockFixDirtyModelWhenSaving() throws IOException { val modelManager = NDataModelManager.getInstance(getTestConfig(), getProject()); diff --git a/src/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java b/src/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java index faa68d4a19..55f46e9984 100644 --- a/src/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java +++ b/src/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java @@ -27,6 +27,7 @@ import java.util.Properties; import org.apache.kylin.common.KylinConfig; import org.apache.kylin.common.util.NLocalFileMetadataTestCase; +import org.apache.kylin.guava30.shaded.common.collect.Maps; import org.apache.kylin.metadata.model.ComputedColumnDesc; import org.apache.kylin.metadata.model.NDataModelManager; import org.apache.kylin.query.IQueryTransformer; @@ -38,8 +39,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.apache.kylin.guava30.shaded.common.collect.Maps; - public class QueryUtilTest extends NLocalFileMetadataTestCase { @Before @@ -431,6 +430,7 @@ public class QueryUtilTest extends NLocalFileMetadataTestCase { Assert.assertEquals("CEIL(col to year)", QueryUtil.adaptCalciteSyntax("ceil_datetime(col, 'year')")); Assert.assertEquals("CEIL(\"t\".\"col\" to year)", QueryUtil.adaptCalciteSyntax("ceil_datetime(`t`.`col`, 'year')")); + Assert.assertEquals("TIMESTAMPDIFF(day, t1, t2)", QueryUtil.adaptCalciteSyntax("timestampdiff('day', t1, t2)")); } @Test