Repository: apache/skywalking (language: python)

Issue:
Support isEmptyValue flag for metrics query.
And Fix `NPE` when query the not exist series indexes in ElasticSearch storage.

- [ ] If this is non-trivial feature, paste the links/URLs to the design doc.
- [ ] Update the documentation to include this new feature.
- [X] Tests(including UT, IT, E2E) are added to verify the new feature.
- [ ] If it's UI related, attach the screenshots below.

- [ ] If this pull request closes/resolves/fixes an existing issue, replace the issue number. Closes #10501.
- [X] Update the [`CHANGES` log](https://github.com/apache/skywalking/blob/master/docs/en/changes/changes.md).



Discussion / hints:

Fix patch:
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 2720ea37aaf0..8fbf58f6ceb2 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -40,6 +40,8 @@
 * [Breaking change] Change the default label name in MQE from `labe`l to `_`.
 * Bump up grpc version to 1.53.0.
 * [Breaking change] Removed '&' symbols from shell scripts to avoid OAP server process running as a background process.
+* Revert part of #10616 to fix the unexpected changes: if there is no data we should return an array with `0`s,
+  but in #10616, an empty array is returned.
 * Cache all service entity in memory for query.
 
 #### UI
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetricsQueryDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetricsQueryDAO.java
index b09726276a55..cea806e2c5a2 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetricsQueryDAO.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetricsQueryDAO.java
@@ -90,6 +90,7 @@ public static List<MetricsValues> sortValues(List<MetricsValues> origin,
          */
         public static List<MetricsValues> composeLabelValue(final MetricsCondition condition,
             final List<String> labels,
+            final List<String> ids,
             final Map<String, DataTable> idMap) {
             List<String> allLabels;
             if (Objects.isNull(labels) || labels.size() < 1 || labels.stream().allMatch(Strings::isNullOrEmpty)) {
@@ -100,17 +101,20 @@ public static List<MetricsValues> composeLabelValue(final MetricsCondition condi
                 allLabels = labels;
             }
             final int defaultValue = ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName());
-            List<LabeledValue> labeledValues = new TreeSet<>(allLabels).stream()
-                .flatMap(label -> idMap.entrySet().stream().map(kv -> Objects.nonNull(kv.getValue().get(label)) ?
-                    new LabeledValue(
-                        label,
-                        kv.getKey(),
-                        kv.getValue().get(label), false) :
-                    new LabeledValue(
-                        label,
-                        kv.getKey(),
-                        defaultValue, true)
-                )).collect(toList());
+            final var labeledValues = new TreeSet<>(allLabels).stream()
+                                                              .flatMap(label -> ids.stream().map(id -> {
+                                                                  final var value = idMap.getOrDefault(id, new DataTable());
+                                                                  return Objects.nonNull(value.get(label)) ?
+                                                                      new LabeledValue(
+                                                                          label,
+                                                                          id,
+                                                                          value.get(label), false) :
+                                                                      new LabeledValue(
+                                                                          label,
+                                                                          id,
+                                                                          defaultValue, true);
+                                                              }))
+                                                              .collect(toList());
             MetricsValues current = new MetricsValues();
             List<MetricsValues> result = new ArrayList<>();
             for (LabeledValue each : labeledValues) {
diff --git a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBMetricsQueryDAO.java b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBMetricsQueryDAO.java
index 2d2edc7d3e5c..d37bd1d92810 100644
--- a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBMetricsQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBMetricsQueryDAO.java
@@ -172,7 +172,7 @@ public List<MetricsValues> readLabeledMetricsValues(MetricsCondition condition,
         }
 
         return Util.sortValues(
-                Util.composeLabelValue(condition, labels, dataTableMap),
+                Util.composeLabelValue(condition, labels, ids, dataTableMap),
                 ids,
                 ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName())
         );
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetricsQueryEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetricsQueryEsDAO.java
index 160bb78f34f7..274854b1d284 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetricsQueryEsDAO.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetricsQueryEsDAO.java
@@ -192,7 +192,7 @@ public List<MetricsValues> readLabeledMetricsValues(final MetricsCondition condi
             }
         }
         return Util.sortValues(
-            Util.composeLabelValue(condition, labels, idMap),
+            Util.composeLabelValue(condition, labels, ids, idMap),
             ids,
             ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName())
         );
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCMetricsQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCMetricsQueryDAO.java
index b58f05374bf0..aa9d29878ad0 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCMetricsQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/dao/JDBCMetricsQueryDAO.java
@@ -220,7 +220,7 @@ public List<MetricsValues> readLabeledMetricsValues(final MetricsCondition condi
         }
 
         return Util.sortValues(
-            Util.composeLabelValue(condition, labels, idMap),
+            Util.composeLabelValue(condition, labels, ids, idMap),
             ids,
             ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName())
         );


Test patch:
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/query/MetricsQueryUtilTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/query/MetricsQueryUtilTest.java
index 51d6267be34f..22e72af21cb4 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/query/MetricsQueryUtilTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/query/MetricsQueryUtilTest.java
@@ -109,7 +109,7 @@ public void testComposeLabelValue(final List<String> queryConditionLabels,
         MetricsCondition condition = new MetricsCondition();
         condition.setName(MODULE_NAME);
         List<MetricsValues> result = IMetricsQueryDAO.Util.sortValues(
-            IMetricsQueryDAO.Util.composeLabelValue(condition, queryConditionLabels, valueColumnData),
+            IMetricsQueryDAO.Util.composeLabelValue(condition, queryConditionLabels, datePoints, valueColumnData),
             datePoints, DEFAULT_VALUE
         );
         assertThat(new Gson().toJson(result)).isEqualTo(expectedResult);