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

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

commit 0e3354414d89c4b4b81d0ec1db8d39705e760a40
Author: huangsheng <huangshen...@163.com>
AuthorDate: Fri Jun 30 12:10:57 2023 +0800

    KYLIN-5740 Equivalent aggregations matches index failed
    
    Equivalent aggregations matches index failed when using
    the strategy of dimension as measure.
---
 .../kylin/rest/service/AccessServiceTest.java      |  4 +-
 .../kylin/rest/service/AclTCRServiceTest.java      |  2 +-
 .../metadata/cube/cuboid/AggIndexMatcher.java      | 13 ++-
 .../metadata/project/NProjectManagerTest.java      |  2 +-
 .../kylin/metrics/HdfsCapacityMetricsTest.java     |  2 +-
 .../localmeta/data/DEFAULT.TEST_DIM_AS_MEASURE.csv |  3 +
 .../metadata/_global/project/dim_as_measure.json   |  6 ++
 .../f29d1a92-c115-ec68-5575-9cfcc0d65890.json      | 63 ++++++++++++++
 .../4409fb82-8f3a-ba01-9852-0b05f1fe690f.json      | 64 ++++++++++++++
 .../f29d1a92-c115-ec68-5575-9cfcc0d65890.json      | 64 ++++++++++++++
 .../f29d1a92-c115-ec68-5575-9cfcc0d65890.json      | 97 ++++++++++++++++++++++
 .../table/DEFAULT.TEST_DIM_AS_MEASURE.json         | 49 +++++++++++
 .../newten/table/DEFAULT.TEST_DIM_AS_MEASURE.json  | 49 +++++++++++
 .../query/routing/QueryLayoutChooserTest.java      | 47 ++++++++++-
 .../kylin/rest/service/ProjectServiceTest.java     |  6 +-
 .../rest/service/QueryHistoryServiceTest.java      |  2 +-
 .../kylin/query/engine/AsyncQueryJobTest.java      |  2 +-
 17 files changed, 460 insertions(+), 15 deletions(-)

diff --git 
a/src/common-service/src/test/java/org/apache/kylin/rest/service/AccessServiceTest.java
 
b/src/common-service/src/test/java/org/apache/kylin/rest/service/AccessServiceTest.java
index f5402d462c..769f1dd326 100644
--- 
a/src/common-service/src/test/java/org/apache/kylin/rest/service/AccessServiceTest.java
+++ 
b/src/common-service/src/test/java/org/apache/kylin/rest/service/AccessServiceTest.java
@@ -606,14 +606,14 @@ public class AccessServiceTest extends 
NLocalFileMetadataTestCase {
     @Test
     public void testGetGrantedProjectsOfUser() throws IOException {
         List<String> result = accessService.getGrantedProjectsOfUser("ADMIN");
-        assertEquals(29, result.size());
+        assertEquals(30, result.size());
     }
 
     @Test
     public void testGetGrantedProjectsOfUserOrGroup() throws IOException {
         // admin user
         List<String> result = 
accessService.getGrantedProjectsOfUserOrGroup("ADMIN", true);
-        assertEquals(29, result.size());
+        assertEquals(30, result.size());
 
         // normal user
         result = accessService.getGrantedProjectsOfUserOrGroup("ANALYST", 
true);
diff --git 
a/src/common-service/src/test/java/org/apache/kylin/rest/service/AclTCRServiceTest.java
 
b/src/common-service/src/test/java/org/apache/kylin/rest/service/AclTCRServiceTest.java
index 803019720d..9af9f92b14 100644
--- 
a/src/common-service/src/test/java/org/apache/kylin/rest/service/AclTCRServiceTest.java
+++ 
b/src/common-service/src/test/java/org/apache/kylin/rest/service/AclTCRServiceTest.java
@@ -1316,7 +1316,7 @@ public class AclTCRServiceTest extends 
NLocalFileMetadataTestCase {
         Mockito.when(userService.isGlobalAdmin("ADMIN")).thenReturn(true);
         List<SidPermissionWithAclResponse> responses = 
accessService.getUserOrGroupAclPermissions(projects, "ADMIN",
                 true);
-        Assert.assertEquals(29, responses.size());
+        Assert.assertEquals(30, responses.size());
         Assert.assertTrue(responses.stream().allMatch(response -> 
"ADMIN".equals(response.getProjectPermission())));
 
         // test normal group
diff --git 
a/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/cuboid/AggIndexMatcher.java
 
b/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/cuboid/AggIndexMatcher.java
index 5561581d72..a7efb17286 100644
--- 
a/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/cuboid/AggIndexMatcher.java
+++ 
b/src/core-metadata/src/main/java/org/apache/kylin/metadata/cube/cuboid/AggIndexMatcher.java
@@ -89,7 +89,7 @@ public class AggIndexMatcher extends IndexMatcher {
             return new MatchResult();
         }
         log.trace("Matching agg index");
-        Set<FunctionDesc> unmatchedMetrics = 
Sets.newHashSet(sqlDigest.aggregations);
+        Collection<FunctionDesc> unmatchedMetrics = 
Lists.newArrayList(sqlDigest.aggregations);
         Set<Integer> unmatchedCols = initUnmatchedColumnIds(layout);
         final Map<Integer, DeriveInfo> needDerive = Maps.newHashMap();
         goThruDerivedDims(layout.getIndex(), needDerive, unmatchedCols);
@@ -140,9 +140,8 @@ public class AggIndexMatcher extends IndexMatcher {
             functionDescs.addAll(cuboidLayout.getStreamingMeasures().values());
         }
         functionDescs.addAll(cuboidLayout.getOrderedMeasures().values());
-
         for (MeasureDesc measureDesc : functionDescs) {
-            aggregations.remove(measureDesc.getFunction());
+            aggregations.removeIf(functionDesc -> 
measureDesc.getFunction().equals(functionDesc));
         }
     }
 
@@ -154,8 +153,15 @@ public class AggIndexMatcher extends IndexMatcher {
             Map<Integer, DeriveInfo> needDeriveCollector, 
List<CapabilityResult.CapabilityInfluence> influences) {
         IndexEntity indexEntity = layoutEntity.getIndex();
         Iterator<FunctionDesc> it = unmatchedAggs.iterator();
+        Set<FunctionDesc> matchedAggs = Sets.newHashSet();
         while (it.hasNext()) {
             FunctionDesc functionDesc = it.next();
+            if (matchedAggs.contains(functionDesc)) {
+                influences.add(new 
CapabilityResult.DimensionAsMeasure(functionDesc));
+                it.remove();
+                continue;
+            }
+
             if (functionDesc.isCountConstant()) {
                 it.remove();
                 continue;
@@ -180,6 +186,7 @@ public class AggIndexMatcher extends IndexMatcher {
 
             if 
(FunctionDesc.DIMENSION_AS_MEASURES.contains(functionDesc.getExpression())) {
                 influences.add(new 
CapabilityResult.DimensionAsMeasure(functionDesc));
+                matchedAggs.add(functionDesc);
                 it.remove();
             }
         }
diff --git 
a/src/core-metadata/src/test/java/org/apache/kylin/metadata/project/NProjectManagerTest.java
 
b/src/core-metadata/src/test/java/org/apache/kylin/metadata/project/NProjectManagerTest.java
index f3ed44b83f..4cfb808f39 100644
--- 
a/src/core-metadata/src/test/java/org/apache/kylin/metadata/project/NProjectManagerTest.java
+++ 
b/src/core-metadata/src/test/java/org/apache/kylin/metadata/project/NProjectManagerTest.java
@@ -68,7 +68,7 @@ public class NProjectManagerTest extends 
NLocalFileMetadataTestCase {
         }
 
         val projects = projectManager.listAllProjects();
-        Assert.assertEquals(29, projects.size());
+        Assert.assertEquals(30, projects.size());
         Assert.assertTrue(projects.stream().noneMatch(p -> 
p.getName().equals("test")));
     }
 
diff --git 
a/src/core-metadata/src/test/java/org/apache/kylin/metrics/HdfsCapacityMetricsTest.java
 
b/src/core-metadata/src/test/java/org/apache/kylin/metrics/HdfsCapacityMetricsTest.java
index 28a8c5fada..500596429a 100644
--- 
a/src/core-metadata/src/test/java/org/apache/kylin/metrics/HdfsCapacityMetricsTest.java
+++ 
b/src/core-metadata/src/test/java/org/apache/kylin/metrics/HdfsCapacityMetricsTest.java
@@ -90,7 +90,7 @@ public class HdfsCapacityMetricsTest extends 
NLocalFileMetadataTestCase {
         }
         
Assert.assertTrue(hdfsCapacityMetrics.getWorkingDirCapacity().isEmpty());
         hdfsCapacityMetrics.writeHdfsMetrics();
-        Assert.assertEquals(29, 
hdfsCapacityMetrics.getWorkingDirCapacity().size());
+        Assert.assertEquals(30, 
hdfsCapacityMetrics.getWorkingDirCapacity().size());
 
     }
 
diff --git 
a/src/examples/test_case_data/localmeta/data/DEFAULT.TEST_DIM_AS_MEASURE.csv 
b/src/examples/test_case_data/localmeta/data/DEFAULT.TEST_DIM_AS_MEASURE.csv
new file mode 100644
index 0000000000..1a1f4e5686
--- /dev/null
+++ b/src/examples/test_case_data/localmeta/data/DEFAULT.TEST_DIM_AS_MEASURE.csv
@@ -0,0 +1,3 @@
+22Q1,150.12,dongqu,huadongqu
+22Q2,200.59,zhongqu,huazhongqu
+22Q3,301.55,shanghaiqu,huadongqu
diff --git 
a/src/examples/test_case_data/localmeta/metadata/_global/project/dim_as_measure.json
 
b/src/examples/test_case_data/localmeta/metadata/_global/project/dim_as_measure.json
new file mode 100644
index 0000000000..942a8244d5
--- /dev/null
+++ 
b/src/examples/test_case_data/localmeta/metadata/_global/project/dim_as_measure.json
@@ -0,0 +1,6 @@
+{
+  "uuid": "c3c755b5-a164-9ae0-e1b2-9a296c3cb5a9",
+  "override_kylin_properties": {
+    "kylin.query.slowquery-detect-interval": "4"
+  }
+}
diff --git 
a/src/examples/test_case_data/localmeta/metadata/dim_as_measure/dataflow/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/dataflow/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
new file mode 100644
index 0000000000..e309636c02
--- /dev/null
+++ 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/dataflow/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
@@ -0,0 +1,63 @@
+{
+  "uuid" : "f29d1a92-c115-ec68-5575-9cfcc0d65890",
+  "last_modified" : 1688008789459,
+  "create_time" : 1688008685970,
+  "version" : "4.0.0.0",
+  "status" : "ONLINE",
+  "last_status" : null,
+  "cost" : 50,
+  "query_hit_count" : 0,
+  "last_query_time" : 0,
+  "layout_query_hit_count" : { },
+  "segments" : [ {
+    "id" : "4409fb82-8f3a-ba01-9852-0b05f1fe690f",
+    "name" : "FULL_BUILD",
+    "create_time_utc" : 1688008750346,
+    "status" : "READY",
+    "segRange" : {
+      "@class" : 
"org.apache.kylin.metadata.model.SegmentRange$TimePartitionedSegmentRange",
+      "date_range_start" : 0,
+      "date_range_end" : 9223372036854775807
+    },
+    "timeRange" : null,
+    "dimension_range_info_map" : {
+      "0" : {
+        "min" : "huadongqu",
+        "max" : "huazhongqu"
+      },
+      "1" : {
+        "min" : "shanghaiqu",
+        "max" : "zhongqu"
+      },
+      "2" : {
+        "min" : "150.1200",
+        "max" : "301.5500"
+      },
+      "3" : {
+        "min" : "22Q1",
+        "max" : "22Q3"
+      }
+    },
+    "parameters" : null,
+    "dictionaries" : null,
+    "snapshots" : null,
+    "last_build_time" : 1688008489488,
+    "source_count" : 3,
+    "source_bytes_size" : 90,
+    "column_source_bytes" : {
+      "DEFAULT.TEST_DIM_AS_MEASURE.REGION_NAME" : 27,
+      "DEFAULT.TEST_DIM_AS_MEASURE.BIG_REGION_NAME" : 21,
+      "DEFAULT.TEST_DIM_AS_MEASURE.ARRIVAL_TRANSIT_IN_PRM_AMT" : 24,
+      "DEFAULT.TEST_DIM_AS_MEASURE.PRO_MT_SEASON" : 12
+    },
+    "ori_snapshot_size" : { },
+    "additionalInfo" : { },
+    "is_realtime_segment" : false,
+    "is_snapshot_ready" : false,
+    "is_dict_ready" : false,
+    "is_flat_table_ready" : true,
+    "is_fact_view_ready" : false,
+    "multi_partitions" : [ ],
+    "max_bucket_id" : -1
+  } ]
+}
diff --git 
a/src/examples/test_case_data/localmeta/metadata/dim_as_measure/dataflow_details/f29d1a92-c115-ec68-5575-9cfcc0d65890/4409fb82-8f3a-ba01-9852-0b05f1fe690f.json
 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/dataflow_details/f29d1a92-c115-ec68-5575-9cfcc0d65890/4409fb82-8f3a-ba01-9852-0b05f1fe690f.json
new file mode 100644
index 0000000000..d917a6c151
--- /dev/null
+++ 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/dataflow_details/f29d1a92-c115-ec68-5575-9cfcc0d65890/4409fb82-8f3a-ba01-9852-0b05f1fe690f.json
@@ -0,0 +1,64 @@
+{
+  "uuid" : "4409fb82-8f3a-ba01-9852-0b05f1fe690f",
+  "last_modified" : 1688008750348,
+  "create_time" : 1688008750347,
+  "version" : "4.0.0.0",
+  "dataflow" : "f29d1a92-c115-ec68-5575-9cfcc0d65890",
+  "layout_instances" : [ {
+    "layout_id" : 180001,
+    "build_job_id" : 
"a6c09d79-a397-74fc-bb64-0d42c3c6ec0f-f29d1a92-c115-ec68-5575-9cfcc0d65890",
+    "rows" : 3,
+    "byte_size" : 1200,
+    "file_count" : 2,
+    "source_rows" : 3,
+    "source_byte_size" : 0,
+    "partition_num" : 1,
+    "partition_values" : [ ],
+    "is_ready" : false,
+    "create_time" : 1688008777804,
+    "multi_partition" : [ ],
+    "abnormal_type" : null
+  }, {
+    "layout_id" : 20000000001,
+    "build_job_id" : 
"a6c09d79-a397-74fc-bb64-0d42c3c6ec0f-f29d1a92-c115-ec68-5575-9cfcc0d65890",
+    "rows" : 3,
+    "byte_size" : 1438,
+    "file_count" : 2,
+    "source_rows" : 3,
+    "source_byte_size" : 0,
+    "partition_num" : 1,
+    "partition_values" : [ ],
+    "is_ready" : false,
+    "create_time" : 1688008783698,
+    "multi_partition" : [ ],
+    "abnormal_type" : null
+  }, {
+    "layout_id" : 190001,
+    "build_job_id" : 
"a6c09d79-a397-74fc-bb64-0d42c3c6ec0f-f29d1a92-c115-ec68-5575-9cfcc0d65890",
+    "rows" : 2,
+    "byte_size" : 844,
+    "file_count" : 2,
+    "source_rows" : 3,
+    "source_byte_size" : 0,
+    "partition_num" : 1,
+    "partition_values" : [ ],
+    "is_ready" : false,
+    "create_time" : 1688008783698,
+    "multi_partition" : [ ],
+    "abnormal_type" : null
+  }, {
+    "layout_id" : 170001,
+    "build_job_id" : 
"a6c09d79-a397-74fc-bb64-0d42c3c6ec0f-f29d1a92-c115-ec68-5575-9cfcc0d65890",
+    "rows" : 3,
+    "byte_size" : 871,
+    "file_count" : 2,
+    "source_rows" : 3,
+    "source_byte_size" : 0,
+    "partition_num" : 1,
+    "partition_values" : [ ],
+    "is_ready" : false,
+    "create_time" : 1688008783698,
+    "multi_partition" : [ ],
+    "abnormal_type" : null
+  } ]
+}
diff --git 
a/src/examples/test_case_data/localmeta/metadata/dim_as_measure/index_plan/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/index_plan/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
new file mode 100644
index 0000000000..bddd047eb8
--- /dev/null
+++ 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/index_plan/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
@@ -0,0 +1,64 @@
+{
+  "uuid" : "f29d1a92-c115-ec68-5575-9cfcc0d65890",
+  "last_modified" : 1688008749087,
+  "create_time" : 1687781017098,
+  "version" : "4.0.0.0",
+  "description" : null,
+  "rule_based_index" : {
+    "dimensions" : [ 0, 1 ],
+    "measures" : [ 100000 ],
+    "global_dim_cap" : null,
+    "aggregation_groups" : [ {
+      "includes" : [ 0, 1 ],
+      "measures" : [ 100000 ],
+      "select_rule" : {
+        "hierarchy_dims" : [ ],
+        "mandatory_dims" : [ ],
+        "joint_dims" : [ ]
+      },
+      "index_range" : "EMPTY"
+    } ],
+    "layout_id_mapping" : [ 170001, 180001, 190001 ],
+    "parent_forward" : 3,
+    "index_start_id" : 170000,
+    "last_modify_time" : 1688008749085,
+    "layout_black_list" : [ ],
+    "scheduler_version" : 2,
+    "index_update_enabled" : true,
+    "base_layout_enabled" : true
+  },
+  "indexes" : [ {
+    "id" : 20000000000,
+    "dimensions" : [ 0, 1, 2, 3 ],
+    "measures" : [ ],
+    "layouts" : [ {
+      "id" : 20000000001,
+      "name" : null,
+      "owner" : null,
+      "col_order" : [ 0, 1, 2, 3 ],
+      "shard_by_columns" : [ ],
+      "partition_by_columns" : [ ],
+      "sort_by_columns" : [ ],
+      "storage_type" : 20,
+      "update_time" : 1687781017119,
+      "manual" : false,
+      "auto" : false,
+      "base" : true,
+      "draft_version" : null,
+      "index_range" : null
+    } ],
+    "next_layout_offset" : 2
+  } ],
+  "override_properties" : { },
+  "to_be_deleted_indexes" : [ ],
+  "auto_merge_time_ranges" : null,
+  "retention_range" : 0,
+  "engine_type" : 80,
+  "next_aggregation_index_id" : 200000,
+  "next_table_index_id" : 20000010000,
+  "agg_shard_by_columns" : [ ],
+  "extend_partition_columns" : [ ],
+  "layout_bucket_num" : { },
+  "approved_additional_recs" : 0,
+  "approved_removal_recs" : 0
+}
diff --git 
a/src/examples/test_case_data/localmeta/metadata/dim_as_measure/model_desc/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/model_desc/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
new file mode 100644
index 0000000000..aff9008536
--- /dev/null
+++ 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/model_desc/f29d1a92-c115-ec68-5575-9cfcc0d65890.json
@@ -0,0 +1,97 @@
+{
+  "uuid" : "f29d1a92-c115-ec68-5575-9cfcc0d65890",
+  "last_modified" : 1688008696062,
+  "create_time" : 1687781016992,
+  "version" : "4.0.0.0",
+  "alias" : "ff_clone3",
+  "owner" : "ADMIN",
+  "config_last_modifier" : null,
+  "config_last_modified" : 0,
+  "description" : "",
+  "fact_table" : "DEFAULT.TEST_DIM_AS_MEASURE",
+  "fact_table_alias" : null,
+  "management_type" : "MODEL_BASED",
+  "join_tables" : [ ],
+  "filter_condition" : "",
+  "partition_desc" : null,
+  "capacity" : "MEDIUM",
+  "segment_config" : {
+    "auto_merge_enabled" : null,
+    "auto_merge_time_ranges" : null,
+    "volatile_range" : null,
+    "retention_range" : null,
+    "create_empty_segment_enabled" : false
+  },
+  "data_check_desc" : null,
+  "semantic_version" : 0,
+  "storage_type" : 0,
+  "model_type" : "BATCH",
+  "all_named_columns" : [ {
+    "id" : 0,
+    "name" : "REGION_NAME",
+    "column" : "TEST_DIM_AS_MEASURE.REGION_NAME",
+    "status" : "DIMENSION"
+  }, {
+    "id" : 1,
+    "name" : "BIG_REGION_NAME",
+    "column" : "TEST_DIM_AS_MEASURE.BIG_REGION_NAME",
+    "status" : "DIMENSION"
+  }, {
+    "id" : 2,
+    "name" : "ARRIVAL_TRANSIT_IN_PRM_AMT",
+    "column" : "TEST_DIM_AS_MEASURE.ARRIVAL_TRANSIT_IN_PRM_AMT",
+    "status" : "DIMENSION"
+  }, {
+    "id" : 3,
+    "name" : "PRO_MT_SEASON",
+    "column" : "TEST_DIM_AS_MEASURE.PRO_MT_SEASON",
+    "status" : "DIMENSION"
+  } ],
+  "all_measures" : [ {
+    "name" : "COUNT_ALL",
+    "function" : {
+      "expression" : "COUNT",
+      "parameters" : [ {
+        "type" : "constant",
+        "value" : "1"
+      } ],
+      "returntype" : "bigint"
+    },
+    "column" : null,
+    "comment" : null,
+    "id" : 100000,
+    "type" : "NORMAL",
+    "internal_ids" : [ ]
+  }, {
+    "name" : "BIG_REGION_NAME",
+    "function" : {
+      "expression" : "MAX",
+      "parameters" : [ {
+        "type" : "column",
+        "value" : "TEST_DIM_AS_MEASURE.BIG_REGION_NAME"
+      } ],
+      "returntype" : "varchar(4096)"
+    },
+    "column" : null,
+    "comment" : "",
+    "id" : 100001,
+    "type" : "NORMAL",
+    "internal_ids" : [ ]
+  } ],
+  "recommendations_count" : 0,
+  "computed_columns" : [ ],
+  "canvas" : {
+    "coordinate" : {
+      "TEST_DIM_AS_MEASURE" : {
+        "x" : 594.3035888671874,
+        "y" : 224.26886664496536,
+        "width" : 200.0,
+        "height" : 487.7777777777778
+      }
+    },
+    "zoom" : 9.0
+  },
+  "multi_partition_desc" : null,
+  "multi_partition_key_mapping" : null,
+  "fusion_id" : null
+}
diff --git 
a/src/examples/test_case_data/localmeta/metadata/dim_as_measure/table/DEFAULT.TEST_DIM_AS_MEASURE.json
 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/table/DEFAULT.TEST_DIM_AS_MEASURE.json
new file mode 100644
index 0000000000..acd6f10a5b
--- /dev/null
+++ 
b/src/examples/test_case_data/localmeta/metadata/dim_as_measure/table/DEFAULT.TEST_DIM_AS_MEASURE.json
@@ -0,0 +1,49 @@
+{
+  "uuid" : "fef38e84-8385-a0e8-3fc3-b515aabbe461",
+  "last_modified" : 0,
+  "create_time" : 1687780438849,
+  "version" : "4.0.0.0",
+  "name" : "TEST_DIM_AS_MEASURE",
+  "columns" : [ {
+    "id" : "1",
+    "name" : "PRO_MT_SEASON",
+    "datatype" : "varchar(4096)",
+    "case_sensitive_name" : "pro_mt_season"
+  }, {
+    "id" : "2",
+    "name" : "ARRIVAL_TRANSIT_IN_PRM_AMT",
+    "datatype" : "decimal(18,4)",
+    "case_sensitive_name" : "arrival_transit_in_prm_amt"
+  }, {
+    "id" : "3",
+    "name" : "BIG_REGION_NAME",
+    "datatype" : "varchar(4096)",
+    "case_sensitive_name" : "big_region_name"
+  }, {
+    "id" : "4",
+    "name" : "REGION_NAME",
+    "datatype" : "varchar(4096)",
+    "case_sensitive_name" : "region_name"
+  } ],
+  "source_type" : 9,
+  "table_type" : "EXTERNAL",
+  "top" : false,
+  "increment_loading" : false,
+  "last_snapshot_path" : null,
+  "last_snapshot_size" : 0,
+  "snapshot_last_modified" : 0,
+  "query_hit_count" : 0,
+  "partition_column" : null,
+  "snapshot_partitions" : { },
+  "snapshot_partitions_info" : { },
+  "snapshot_total_rows" : 0,
+  "snapshot_partition_col" : null,
+  "selected_snapshot_partition_col" : null,
+  "temp_snapshot_path" : null,
+  "snapshot_has_broken" : false,
+  "database" : "default",
+  "transactional" : false,
+  "rangePartition" : false,
+  "partition_desc" : null,
+  "table_comment" : null
+}
diff --git 
a/src/examples/test_case_data/localmeta/metadata/newten/table/DEFAULT.TEST_DIM_AS_MEASURE.json
 
b/src/examples/test_case_data/localmeta/metadata/newten/table/DEFAULT.TEST_DIM_AS_MEASURE.json
new file mode 100644
index 0000000000..acd6f10a5b
--- /dev/null
+++ 
b/src/examples/test_case_data/localmeta/metadata/newten/table/DEFAULT.TEST_DIM_AS_MEASURE.json
@@ -0,0 +1,49 @@
+{
+  "uuid" : "fef38e84-8385-a0e8-3fc3-b515aabbe461",
+  "last_modified" : 0,
+  "create_time" : 1687780438849,
+  "version" : "4.0.0.0",
+  "name" : "TEST_DIM_AS_MEASURE",
+  "columns" : [ {
+    "id" : "1",
+    "name" : "PRO_MT_SEASON",
+    "datatype" : "varchar(4096)",
+    "case_sensitive_name" : "pro_mt_season"
+  }, {
+    "id" : "2",
+    "name" : "ARRIVAL_TRANSIT_IN_PRM_AMT",
+    "datatype" : "decimal(18,4)",
+    "case_sensitive_name" : "arrival_transit_in_prm_amt"
+  }, {
+    "id" : "3",
+    "name" : "BIG_REGION_NAME",
+    "datatype" : "varchar(4096)",
+    "case_sensitive_name" : "big_region_name"
+  }, {
+    "id" : "4",
+    "name" : "REGION_NAME",
+    "datatype" : "varchar(4096)",
+    "case_sensitive_name" : "region_name"
+  } ],
+  "source_type" : 9,
+  "table_type" : "EXTERNAL",
+  "top" : false,
+  "increment_loading" : false,
+  "last_snapshot_path" : null,
+  "last_snapshot_size" : 0,
+  "snapshot_last_modified" : 0,
+  "query_hit_count" : 0,
+  "partition_column" : null,
+  "snapshot_partitions" : { },
+  "snapshot_partitions_info" : { },
+  "snapshot_total_rows" : 0,
+  "snapshot_partition_col" : null,
+  "selected_snapshot_partition_col" : null,
+  "temp_snapshot_path" : null,
+  "snapshot_has_broken" : false,
+  "database" : "default",
+  "transactional" : false,
+  "rangePartition" : false,
+  "partition_desc" : null,
+  "table_comment" : null
+}
diff --git 
a/src/kylin-it/src/test/java/org/apache/kylin/query/routing/QueryLayoutChooserTest.java
 
b/src/kylin-it/src/test/java/org/apache/kylin/query/routing/QueryLayoutChooserTest.java
index 4a47b4db74..7f9408788d 100644
--- 
a/src/kylin-it/src/test/java/org/apache/kylin/query/routing/QueryLayoutChooserTest.java
+++ 
b/src/kylin-it/src/test/java/org/apache/kylin/query/routing/QueryLayoutChooserTest.java
@@ -43,6 +43,7 @@ import org.apache.kylin.metadata.model.NTableMetadataManager;
 import org.apache.kylin.metadata.model.TableDesc;
 import org.apache.kylin.metadata.model.TableExtDesc;
 import org.apache.kylin.metadata.project.EnhancedUnitOfWork;
+import org.apache.kylin.metadata.realization.CapabilityResult;
 import org.apache.kylin.query.relnode.OLAPContext;
 import org.apache.kylin.util.MetadataTestUtils;
 import org.apache.kylin.util.OlapContextTestUtil;
@@ -461,9 +462,9 @@ public class QueryLayoutChooserTest extends 
NLocalWithSparkSessionTest {
             olapContext.fixModel(dataflow.getModel(), sqlAlias2ModelNameMap);
 
             // hit layout 1010002
-            // 1. shardby layout are has higher priority over non-shardby 
layout, 
+            // 1. shardby layout are has higher priority over non-shardby 
layout,
             // so 1010001 is skipped, although it has a better dim order
-            // 2. trans_id has a higher cardinality, so 1010002 with shard on 
trans_id 
+            // 2. trans_id has a higher cardinality, so 1010002 with shard on 
trans_id
             // is preferred over 1010003 with shard on cal_dt
             NLayoutCandidate layoutCandidate = 
QueryLayoutChooser.selectLayoutCandidate(dataflow,
                     dataflow.getQueryableSegments(), 
olapContext.getSQLDigest(), null);
@@ -749,6 +750,48 @@ public class QueryLayoutChooserTest extends 
NLocalWithSparkSessionTest {
         }
     }
 
+    /**
+     * Start with an empty project to get the OlapContexts not pollute is very 
important.
+     */
+    @Test
+    public void testMatchDimAsMeasure() throws SqlParseException {
+        String emptyProject = "newten";
+        overwriteSystemProp("kylin.query.use-tableindex-answer-non-raw-query", 
"true");
+        String project = "dim_as_measure";
+        String modelId = "f29d1a92-c115-ec68-5575-9cfcc0d65890";
+        NDataflow dataflow = NDataflowManager.getInstance(getTestConfig(), 
project).getDataflow(modelId);
+
+        {
+            String sql = "select max(BIG_REGION_NAME) max1, max(case when 1=1 
then BIG_REGION_NAME end) max2 from TEST_DIM_AS_MEASURE";
+            OLAPContext olapContext = 
OlapContextTestUtil.getOlapContexts(emptyProject, sql).get(0);
+            Map<String, String> sqlAlias2ModelNameMap = 
OlapContextTestUtil.matchJoins(dataflow.getModel(),
+                    olapContext);
+            olapContext.fixModel(dataflow.getModel(), sqlAlias2ModelNameMap);
+            NLayoutCandidate layoutCandidate = 
QueryLayoutChooser.selectLayoutCandidate(dataflow,
+                    dataflow.getQueryableSegments(), 
olapContext.getSQLDigest(), null);
+            Assert.assertNotNull(layoutCandidate);
+            
Assert.assertFalse(layoutCandidate.getLayoutEntity().getIndex().isTableIndex());
+            for (CapabilityResult.CapabilityInfluence inf : 
layoutCandidate.getCapabilityResult().influences) {
+                Assert.assertTrue(inf instanceof 
CapabilityResult.DimensionAsMeasure);
+            }
+        }
+
+        {
+            String sql = "select max(REGION_NAME) max1, max(case when 1=1 then 
BIG_REGION_NAME end) max2 from TEST_DIM_AS_MEASURE";
+            OLAPContext olapContext = 
OlapContextTestUtil.getOlapContexts(emptyProject, sql).get(0);
+            Map<String, String> sqlAlias2ModelNameMap = 
OlapContextTestUtil.matchJoins(dataflow.getModel(),
+                    olapContext);
+            olapContext.fixModel(dataflow.getModel(), sqlAlias2ModelNameMap);
+            NLayoutCandidate layoutCandidate = 
QueryLayoutChooser.selectLayoutCandidate(dataflow,
+                    dataflow.getQueryableSegments(), 
olapContext.getSQLDigest(), null);
+            Assert.assertNotNull(layoutCandidate);
+            
Assert.assertFalse(layoutCandidate.getLayoutEntity().getIndex().isTableIndex());
+            for (CapabilityResult.CapabilityInfluence inf : 
layoutCandidate.getCapabilityResult().influences) {
+                Assert.assertTrue(inf instanceof 
CapabilityResult.DimensionAsMeasure);
+            }
+        }
+    }
+
     @Test
     public void testMatchJoinWithEnhancedMode() throws SqlParseException {
         
getTestConfig().setProperty("kylin.query.join-match-optimization-enabled", 
"true");
diff --git 
a/src/modeling-service/src/test/java/org/apache/kylin/rest/service/ProjectServiceTest.java
 
b/src/modeling-service/src/test/java/org/apache/kylin/rest/service/ProjectServiceTest.java
index f47a64020b..054755f307 100644
--- 
a/src/modeling-service/src/test/java/org/apache/kylin/rest/service/ProjectServiceTest.java
+++ 
b/src/modeling-service/src/test/java/org/apache/kylin/rest/service/ProjectServiceTest.java
@@ -235,14 +235,14 @@ public class ProjectServiceTest extends 
NLocalFileMetadataTestCase {
     public void testGetReadableProjects() {
         
Mockito.doReturn(true).when(aclEvaluate).hasProjectAdminPermission(Mockito.any(ProjectInstance.class));
         List<ProjectInstance> projectInstances = 
projectService.getReadableProjects("", false);
-        Assert.assertEquals(29, projectInstances.size());
+        Assert.assertEquals(30, projectInstances.size());
     }
 
     @Test
     public void testGetAdminProjects() throws Exception {
         
Mockito.doReturn(true).when(aclEvaluate).hasProjectAdminPermission(Mockito.any(ProjectInstance.class));
         List<ProjectInstance> projectInstances = 
projectService.getAdminProjects();
-        Assert.assertEquals(29, projectInstances.size());
+        Assert.assertEquals(30, projectInstances.size());
     }
 
     @Test
@@ -256,7 +256,7 @@ public class ProjectServiceTest extends 
NLocalFileMetadataTestCase {
     public void testGetReadableProjectsHasNoPermissionProject() {
         
Mockito.doReturn(true).when(aclEvaluate).hasProjectAdminPermission(Mockito.any(ProjectInstance.class));
         List<ProjectInstance> projectInstances = 
projectService.getReadableProjects("", false);
-        Assert.assertEquals(29, projectInstances.size());
+        Assert.assertEquals(30, projectInstances.size());
 
     }
 
diff --git 
a/src/query-service/src/test/java/org/apache/kylin/rest/service/QueryHistoryServiceTest.java
 
b/src/query-service/src/test/java/org/apache/kylin/rest/service/QueryHistoryServiceTest.java
index 67c2e6c03d..3f2f3cf692 100644
--- 
a/src/query-service/src/test/java/org/apache/kylin/rest/service/QueryHistoryServiceTest.java
+++ 
b/src/query-service/src/test/java/org/apache/kylin/rest/service/QueryHistoryServiceTest.java
@@ -364,7 +364,7 @@ public class QueryHistoryServiceTest extends 
NLocalFileMetadataTestCase {
 
         // get all tables
         tableMap = queryHistoryService.getQueryHistoryTableMap(null);
-        Assert.assertEquals(29, tableMap.size());
+        Assert.assertEquals(30, tableMap.size());
 
         // not existing project
         tableMap = 
queryHistoryService.getQueryHistoryTableMap(Lists.newArrayList("not_existing_project"));
diff --git 
a/src/query/src/test/java/org/apache/kylin/query/engine/AsyncQueryJobTest.java 
b/src/query/src/test/java/org/apache/kylin/query/engine/AsyncQueryJobTest.java
index 4ba275bf48..4c57c0d5eb 100644
--- 
a/src/query/src/test/java/org/apache/kylin/query/engine/AsyncQueryJobTest.java
+++ 
b/src/query/src/test/java/org/apache/kylin/query/engine/AsyncQueryJobTest.java
@@ -218,7 +218,7 @@ public class AsyncQueryJobTest extends 
NLocalFileMetadataTestCase {
                 rawResourceMap.put(zipEntry.getName(), raw);
             }
         }
-        Assert.assertEquals(85, rawResourceMap.size());
+        Assert.assertEquals(86, rawResourceMap.size());
     }
 
     private void testKylinConfig(FileSystem workingFileSystem, FileStatus 
metaFileStatus) throws IOException {

Reply via email to