KYLIN-1965 Check duplicated measure name Signed-off-by: Hongbin Ma <mahong...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/46be8055 Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/46be8055 Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/46be8055 Branch: refs/heads/1.5.x-CDH5.7 Commit: 46be80550e4cbd3403756d615d170dc244c97976 Parents: 1d04642 Author: kangkaisen <kangkai...@live.com> Authored: Thu Aug 18 19:17:37 2016 +0800 Committer: Hongbin Ma <mahong...@apache.org> Committed: Sun Aug 28 14:19:07 2016 +0800 ---------------------------------------------------------------------- .../model/validation/rule/FunctionRule.java | 20 ++++++ .../model/validation/rule/FunctionRuleTest.java | 68 ++++++++++++++++++++ webapp/app/js/controllers/cubeMeasures.js | 16 +++++ 3 files changed, 104 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/46be8055/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/FunctionRule.java ---------------------------------------------------------------------- diff --git a/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/FunctionRule.java b/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/FunctionRule.java index 44b0be0..792f18d 100644 --- a/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/FunctionRule.java +++ b/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/FunctionRule.java @@ -62,6 +62,10 @@ public class FunctionRule implements IValidatorRule<CubeDesc> { public void validate(CubeDesc cube, ValidateContext context) { List<MeasureDesc> measures = cube.getMeasures(); + if (validateMeasureNamesDuplicated(measures, context)) { + return; + } + List<FunctionDesc> countFuncs = new ArrayList<FunctionDesc>(); Iterator<MeasureDesc> it = measures.iterator(); @@ -185,4 +189,20 @@ public class FunctionRule implements IValidatorRule<CubeDesc> { } } + + /** + * @param measures + */ + private boolean validateMeasureNamesDuplicated(List<MeasureDesc> measures, ValidateContext context) { + Set<String> nameSet = new HashSet<>(); + for (MeasureDesc measure: measures){ + if (nameSet.contains(measure.getName())){ + context.addResult(ResultLevel.ERROR, "There is duplicated measure's name: " + measure.getName()); + return true; + } else { + nameSet.add(measure.getName()); + } + } + return false; + } } http://git-wip-us.apache.org/repos/asf/kylin/blob/46be8055/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/FunctionRuleTest.java ---------------------------------------------------------------------- diff --git a/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/FunctionRuleTest.java b/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/FunctionRuleTest.java new file mode 100644 index 0000000..48e01e3 --- /dev/null +++ b/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/FunctionRuleTest.java @@ -0,0 +1,68 @@ +package org.apache.kylin.cube.model.validation.rule; + +import org.apache.kylin.common.KylinConfig; +import org.apache.kylin.common.util.JsonUtil; +import org.apache.kylin.common.util.LocalFileMetadataTestCase; +import org.apache.kylin.cube.model.CubeDesc; +import org.apache.kylin.cube.model.validation.ValidateContext; +import org.apache.kylin.metadata.MetadataManager; +import org.apache.kylin.metadata.model.MeasureDesc; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class FunctionRuleTest extends LocalFileMetadataTestCase { + private static KylinConfig config; + private static MetadataManager metadataManager; + + @Before + public void setUp() throws Exception { + this.createTestMetadata(); + config = KylinConfig.getInstanceFromEnv(); + metadataManager = MetadataManager.getInstance(config); + } + + @After + public void after() throws Exception { + this.cleanupTestMetadata(); + } + + @Test + public void testGoodDesc() throws IOException { + FunctionRule rule = new FunctionRule(); + + File f = new File(LocalFileMetadataTestCase.LOCALMETA_TEST_DATA + "/cube_desc/ssb.json"); + CubeDesc desc = JsonUtil.readValue(new FileInputStream(f), CubeDesc.class); + desc.init(config, metadataManager.getAllTablesMap()); + ValidateContext vContext = new ValidateContext(); + rule.validate(desc, vContext); + vContext.print(System.out); + assertTrue(vContext.getResults().length == 0); + } + + @Test + public void testValidateMeasureNamesDuplicated() throws IOException { + FunctionRule rule = new FunctionRule(); + + File f = new File(LocalFileMetadataTestCase.LOCALMETA_TEST_DATA + "/cube_desc/ssb.json"); + CubeDesc desc = JsonUtil.readValue(new FileInputStream(f), CubeDesc.class); + + MeasureDesc measureDescDuplicated = desc.getMeasures().get(1); + desc.getMeasures().add(measureDescDuplicated); + + desc.init(config, metadataManager.getAllTablesMap()); + ValidateContext vContext = new ValidateContext(); + rule.validate(desc, vContext); + + vContext.print(System.out); + assertTrue(vContext.getResults().length >= 1); + assertEquals("There is duplicated measure's name: " + measureDescDuplicated.getName(), vContext.getResults()[0].getMessage()); + } +} http://git-wip-us.apache.org/repos/asf/kylin/blob/46be8055/webapp/app/js/controllers/cubeMeasures.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeMeasures.js b/webapp/app/js/controllers/cubeMeasures.js index 8db1356..9dec379 100644 --- a/webapp/app/js/controllers/cubeMeasures.js +++ b/webapp/app/js/controllers/cubeMeasures.js @@ -107,6 +107,12 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes SweetAlert.swal('', '[TOP_N] Group by Column is required', 'warning'); return false; } + + if ($scope.isNameDuplicated($scope.cubeMetaFrame.measures, $scope.newMeasure) == true) { + SweetAlert.swal('', 'The measure name: ' + $scope.newMeasure.name + ' is duplicated', 'warning'); + return false; + } + if($scope.nextPara.value!=="" && ($scope.newMeasure.function.expression == 'EXTENDED_COLUMN' || $scope.newMeasure.function.expression == 'TOP_N')){ $scope.newMeasure.function.parameter.next_parameter = jQuery.extend(true,{},$scope.nextPara); } @@ -117,12 +123,22 @@ KylinApp.controller('CubeMeasuresCtrl', function ($scope, $modal,MetaModel,cubes else { $scope.cubeMetaFrame.measures.push($scope.newMeasure); } + $scope.newMeasure = null; $scope.initUpdateMeasureStatus(); $scope.nextParameterInit(); return true; }; + $scope.isNameDuplicated = function (measures, newMeasure) { + var names = []; + for(var i = 0;i < measures.length; i++){ + names.push(measures[i].name); + } + var index = names.indexOf(newMeasure.name); + return index > -1; + } + $scope.nextParameterInit = function(){ $scope.nextPara = { "type":"column",