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

wusheng pushed a commit to branch tag-query
in repository https://gitbox.apache.org/repos/asf/skywalking.git


The following commit(s) were added to refs/heads/tag-query by this push:
     new f2e3961  Try to support H2/MySQL case for tags.
f2e3961 is described below

commit f2e3961ab987fdaeb4c272aeb14a5e3d117c153e
Author: Wu Sheng <[email protected]>
AuthorDate: Sat Aug 8 00:06:44 2020 +0800

    Try to support H2/MySQL case for tags.
---
 .../analysis/manual/segment/SegmentDispatcher.java |   1 +
 .../analysis/manual/segment/SegmentRecord.java     |  10 +-
 .../oap/server/core/storage/model/ModelColumn.java |  11 +--
 .../storage-jdbc-hikaricp-plugin/pom.xml           |  10 +-
 .../storage/plugin/jdbc/h2/H2StorageConfig.java    |  20 ++++
 .../storage/plugin/jdbc/h2/H2StorageProvider.java  |   2 +-
 .../storage/plugin/jdbc/h2/dao/H2RecordDAO.java    |  15 ++-
 .../plugin/jdbc/h2/dao/H2SegmentRecordBuilder.java | 108 +++++++++++++++++++++
 .../plugin/jdbc/h2/dao/H2TableInstaller.java       |  45 ++++++---
 .../plugin/jdbc/mysql/MySQLStorageConfig.java      |  10 +-
 .../plugin/jdbc/mysql/MySQLStorageProvider.java    |  14 +--
 .../plugin/jdbc/mysql/MySQLTableInstaller.java     |  55 +++++++----
 12 files changed, 241 insertions(+), 60 deletions(-)

diff --git 
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentDispatcher.java
 
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentDispatcher.java
index ec9ced1..69036ba 100644
--- 
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentDispatcher.java
+++ 
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentDispatcher.java
@@ -40,6 +40,7 @@ public class SegmentDispatcher implements 
SourceDispatcher<Segment> {
         segment.setDataBinary(source.getDataBinary());
         segment.setTimeBucket(source.getTimeBucket());
         segment.setVersion(source.getVersion());
+        segment.setTagsRawData(source.getTags());
         segment.setTags(SpanTag.Util.toStringList(source.getTags()));
 
         RecordStreamProcessor.getInstance().in(segment);
diff --git 
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentRecord.java
 
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentRecord.java
index 9ed37dd..bf7369e 100644
--- 
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentRecord.java
+++ 
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/segment/SegmentRecord.java
@@ -18,7 +18,6 @@
 
 package org.apache.skywalking.oap.server.core.analysis.manual.segment;
 
-import java.util.ArrayList;
 import java.util.Base64;
 import java.util.HashMap;
 import java.util.List;
@@ -112,7 +111,14 @@ public class SegmentRecord extends Record {
     @Setter
     @Getter
     @Column(columnName = TAGS)
-    private List<String> tags = new ArrayList<>();
+    private List<String> tags;
+    /**
+     * Tags raw data is a duplicate field of {@link #tags}. Some storage don't 
support array values in a single column.
+     * Then, those implementations could use this raw data to generate 
necessary data structures.
+     */
+    @Setter
+    @Getter
+    private List<SpanTag> tagsRawData;
 
     @Override
     public String id() {
diff --git 
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumn.java
 
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumn.java
index 85db211..0d0c2bd 100644
--- 
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumn.java
+++ 
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumn.java
@@ -18,7 +18,6 @@
 
 package org.apache.skywalking.oap.server.core.storage.model;
 
-import com.google.gson.JsonObject;
 import java.lang.reflect.Type;
 import lombok.Getter;
 import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
@@ -43,15 +42,7 @@ public class ModelColumn {
         this.type = type;
         this.genericType = genericType;
         this.matchQuery = matchQuery;
-
-        /*
-         * Only accept length in the String/JsonObject definition.
-         */
-        if (type.equals(String.class) || type.equals(JsonObject.class)) {
-            this.length = length;
-        } else {
-            this.length = 0;
-        }
+        this.length = length;
         /*
          * byte[] and {@link IntKeyLongValueHashMap} could never be query.
          */
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/pom.xml 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/pom.xml
index ffcbdda..ce63362 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/pom.xml
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/pom.xml
@@ -43,11 +43,11 @@
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
         </dependency>
-<!--        <dependency>-->
-<!--        <groupId>mysql</groupId>-->
-<!--        <artifactId>mysql-connector-java</artifactId>-->
-<!--        <version>8.0.13</version>-->
-<!--        </dependency>-->
+        <dependency>
+        <groupId>mysql</groupId>
+        <artifactId>mysql-connector-java</artifactId>
+        <version>8.0.13</version>
+        </dependency>
     </dependencies>
 
 </project>
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageConfig.java
 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageConfig.java
index b39c2f2..bb151d9 100644
--- 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageConfig.java
+++ 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageConfig.java
@@ -30,4 +30,24 @@ public class H2StorageConfig extends ModuleConfig {
     private String user = "";
     private String password = "";
     private int metadataQueryMaxSize = 5000;
+    /**
+     * Some entity, such as trace segment, include the logic column with 
multiple values. Some storage support this kind
+     * of data structure, but H2 doesn't.
+     *
+     * In the H2, we use multiple physical columns to host the values, such as,
+     *
+     * Change column_a with values [1,2,3,4,5] to
+     * <p>
+     * column_a_0 = 1, column_a_1 = 2, column_a_2 = 3 , column_a_3 = 4, 
column_a_4 = 5
+     * </p>
+     *
+     * This configuration controls the threshold about how many physical 
columns should to be added, also limit the max
+     * values of this kind of column.
+     *
+     * SkyWalking don't create a new table for indexing, because it would 
amplify the size of data set to dozens time,
+     * which is not practical in the production environment.
+     *
+     * @since 8.2.0
+     */
+    private int maxSizeOfArrayColumn = 20;
 }
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageProvider.java
 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageProvider.java
index 2653522..cf335f8 100644
--- 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageProvider.java
+++ 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/H2StorageProvider.java
@@ -141,7 +141,7 @@ public class H2StorageProvider extends ModuleProvider {
         try {
             h2Client.connect();
 
-            H2TableInstaller installer = new H2TableInstaller(h2Client, 
getManager());
+            H2TableInstaller installer = new H2TableInstaller(h2Client, 
getManager(), config.getMaxSizeOfArrayColumn());
             
getManager().find(CoreModule.NAME).provider().getService(ModelCreator.class).addModelListener(installer);
         } catch (StorageException e) {
             throw new ModuleStartException(e.getMessage(), e);
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2RecordDAO.java
 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2RecordDAO.java
index c0c08eb..91d4815 100644
--- 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2RecordDAO.java
+++ 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2RecordDAO.java
@@ -19,6 +19,9 @@
 package org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao;
 
 import java.io.IOException;
+import java.util.Map;
+import org.apache.skywalking.oap.server.core.UnexpectedException;
+import 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
 import org.apache.skywalking.oap.server.core.analysis.record.Record;
 import org.apache.skywalking.oap.server.core.storage.IRecordDAO;
 import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
@@ -33,7 +36,17 @@ public class H2RecordDAO extends H2SQLExecutor implements 
IRecordDAO {
 
     public H2RecordDAO(JDBCHikariCPClient h2Client, StorageBuilder<Record> 
storageBuilder) {
         this.h2Client = h2Client;
-        this.storageBuilder = storageBuilder;
+        try {
+            if (SegmentRecord.class.equals(
+                storageBuilder.getClass().getMethod("map2Data", 
Map.class).getReturnType())
+            ) {
+                this.storageBuilder = new H2SegmentRecordBuilder();
+            } else {
+                this.storageBuilder = storageBuilder;
+            }
+        } catch (NoSuchMethodException e) {
+            throw new UnexpectedException("Can't find the 
SegmentRecord$Builder.map2Data method.");
+        }
     }
 
     @Override
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SegmentRecordBuilder.java
 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SegmentRecordBuilder.java
new file mode 100644
index 0000000..03b08ce
--- /dev/null
+++ 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SegmentRecordBuilder.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao;
+
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import joptsimple.internal.Strings;
+import org.apache.skywalking.apm.util.StringUtil;
+import org.apache.skywalking.oap.server.core.Const;
+import 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord;
+import org.apache.skywalking.oap.server.core.analysis.record.Record;
+import org.apache.skywalking.oap.server.core.analysis.topn.TopN;
+import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
+import org.apache.skywalking.oap.server.library.util.CollectionUtils;
+
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.DATA_BINARY;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.ENDPOINT_ID;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.ENDPOINT_NAME;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.END_TIME;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.IS_ERROR;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.LATENCY;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.SEGMENT_ID;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.SERVICE_ID;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.SERVICE_INSTANCE_ID;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.START_TIME;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.TAGS;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.TIME_BUCKET;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.TRACE_ID;
+import static 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.VERSION;
+
+/**
+ * H2/MySQL is different from standard {@link 
org.apache.skywalking.oap.server.core.analysis.manual.segment.SegmentRecord.Builder},
+ * this maps the tags into multiple columns.
+ */
+public class H2SegmentRecordBuilder implements StorageBuilder<Record> {
+
+    @Override
+    public Map<String, Object> data2Map(Record record) {
+        SegmentRecord storageData = (SegmentRecord) record;
+        storageData.setStatement(Strings.join(new String[] {
+            storageData.getEndpointName(),
+            storageData.getTraceId()
+        }, " - "));
+        Map<String, Object> map = new HashMap<>();
+        map.put(SEGMENT_ID, storageData.getSegmentId());
+        map.put(TRACE_ID, storageData.getTraceId());
+        map.put(TopN.STATEMENT, storageData.getStatement());
+        map.put(SERVICE_ID, storageData.getServiceId());
+        map.put(SERVICE_INSTANCE_ID, storageData.getServiceInstanceId());
+        map.put(ENDPOINT_NAME, storageData.getEndpointName());
+        map.put(ENDPOINT_ID, storageData.getEndpointId());
+        map.put(START_TIME, storageData.getStartTime());
+        map.put(END_TIME, storageData.getEndTime());
+        map.put(LATENCY, storageData.getLatency());
+        map.put(IS_ERROR, storageData.getIsError());
+        map.put(TIME_BUCKET, storageData.getTimeBucket());
+        if (CollectionUtils.isEmpty(storageData.getDataBinary())) {
+            map.put(DATA_BINARY, Const.EMPTY_STRING);
+        } else {
+            map.put(DATA_BINARY, new 
String(Base64.getEncoder().encode(storageData.getDataBinary())));
+        }
+        map.put(VERSION, storageData.getVersion());
+        map.put(TAGS, storageData.getTags());
+        return map;
+    }
+
+    @Override
+    public Record map2Data(Map<String, Object> dbMap) {
+        SegmentRecord record = new SegmentRecord();
+        record.setSegmentId((String) dbMap.get(SEGMENT_ID));
+        record.setTraceId((String) dbMap.get(TRACE_ID));
+        record.setStatement((String) dbMap.get(TopN.STATEMENT));
+        record.setServiceId((String) dbMap.get(SERVICE_ID));
+        record.setServiceInstanceId((String) dbMap.get(SERVICE_INSTANCE_ID));
+        record.setEndpointName((String) dbMap.get(ENDPOINT_NAME));
+        record.setEndpointId((String) dbMap.get(ENDPOINT_ID));
+        record.setStartTime(((Number) dbMap.get(START_TIME)).longValue());
+        record.setEndTime(((Number) dbMap.get(END_TIME)).longValue());
+        record.setLatency(((Number) dbMap.get(LATENCY)).intValue());
+        record.setIsError(((Number) dbMap.get(IS_ERROR)).intValue());
+        record.setTimeBucket(((Number) dbMap.get(TIME_BUCKET)).longValue());
+        if (StringUtil.isEmpty((String) dbMap.get(DATA_BINARY))) {
+            record.setDataBinary(new byte[] {});
+        } else {
+            record.setDataBinary(Base64.getDecoder().decode((String) 
dbMap.get(DATA_BINARY)));
+        }
+        record.setVersion(((Number) dbMap.get(VERSION)).intValue());
+        // Don't read the tags as they has been in the data binary already.
+        return record;
+    }
+}
\ No newline at end of file
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
index ebbd958..f00df59 100644
--- 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
+++ 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
@@ -19,8 +19,11 @@
 package org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao;
 
 import com.google.gson.JsonObject;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.List;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.skywalking.oap.server.core.analysis.NodeType;
 import org.apache.skywalking.oap.server.core.storage.StorageException;
@@ -44,8 +47,11 @@ import 
org.apache.skywalking.oap.server.storage.plugin.jdbc.TableMetaInfo;
 public class H2TableInstaller extends ModelInstaller {
     public static final String ID_COLUMN = "id";
 
-    public H2TableInstaller(Client client, ModuleManager moduleManager) {
+    protected final int maxSizeOfArrayColumn;
+
+    public H2TableInstaller(Client client, ModuleManager moduleManager, int 
maxSizeOfArrayColumn) {
         super(client, moduleManager);
+        this.maxSizeOfArrayColumn = maxSizeOfArrayColumn;
     }
 
     @Override
@@ -67,9 +73,7 @@ public class H2TableInstaller extends ModelInstaller {
                 ModelColumn column = model.getColumns().get(i);
                 ColumnName name = column.getColumnName();
                 tableCreateSQL.appendLine(
-                    name.getStorageName() + " " + getColumnType(column) + (i 
!= model
-                        .getColumns()
-                        .size() - 1 ? "," : ""));
+                    getColumn(column) + (i != model.getColumns().size() - 1 ? 
"," : ""));
             }
             tableCreateSQL.appendLine(")");
 
@@ -88,22 +92,37 @@ public class H2TableInstaller extends ModelInstaller {
     /**
      * Set up the data type mapping between Java type and H2 database type
      */
-    protected String getColumnType(ModelColumn column) {
-        final Class<?> type = column.getType();
+    protected String getColumn(ModelColumn column) {
+        return transform(column, column.getType(), column.getGenericType());
+    }
+
+    protected String transform(ModelColumn column, Class<?> type, Type 
genericType) {
+        final String storageName = column.getColumnName().getStorageName();
         if (Integer.class.equals(type) || int.class.equals(type) || 
NodeType.class.equals(type)) {
-            return "INT";
+            return storageName + " INT";
         } else if (Long.class.equals(type) || long.class.equals(type)) {
-            return "BIGINT";
+            return storageName + " BIGINT";
         } else if (Double.class.equals(type) || double.class.equals(type)) {
-            return "DOUBLE";
+            return storageName + " DOUBLE";
         } else if (String.class.equals(type)) {
-            return "VARCHAR(" + column.getLength() + ")";
+            return storageName + " VARCHAR(" + column.getLength() + ")";
         } else if (StorageDataComplexObject.class.isAssignableFrom(type)) {
-            return "VARCHAR(20000)";
+            return storageName + " VARCHAR(20000)";
         } else if (byte[].class.equals(type)) {
-            return "MEDIUMTEXT";
+            return storageName + " MEDIUMTEXT";
         } else if (JsonObject.class.equals(type)) {
-            return "VARCHAR(" + column.getLength() + ")";
+            return storageName + " VARCHAR(" + column.getLength() + ")";
+        } else if (List.class.isAssignableFrom(type)) {
+            final Type elementType = ((ParameterizedType) 
genericType).getActualTypeArguments()[0];
+            String oneColumnType = transform(column, (Class<?>) elementType, 
elementType);
+            // Remove the storageName as prefix
+            oneColumnType = oneColumnType.substring(storageName.length());
+            StringBuilder columns = new StringBuilder();
+            for (int i = 0; i < maxSizeOfArrayColumn; i++) {
+                
columns.append(storageName).append("_").append(i).append(oneColumnType)
+                       .append(i == maxSizeOfArrayColumn - 1 ? "" : ",");
+            }
+            return columns.toString();
         } else {
             throw new IllegalArgumentException("Unsupported data type: " + 
type.getName());
         }
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageConfig.java
 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageConfig.java
index 1b44b1d..f593ec2 100644
--- 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageConfig.java
+++ 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageConfig.java
@@ -18,16 +18,20 @@
 
 package org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql;
 
+import java.util.Properties;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.skywalking.oap.server.library.module.ModuleConfig;
 
-import java.util.Properties;
-
 @Setter
 @Getter
 public final class MySQLStorageConfig extends ModuleConfig {
-
     private int metadataQueryMaxSize = 5000;
+    /**
+     * Inherit from {@link 
org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2StorageConfig#getMaxSizeOfArrayColumn()}
+     *
+     * @since 8.2.0
+     */
+    private int maxSizeOfArrayColumn = 20;
     private Properties properties;
 }
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageProvider.java
 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageProvider.java
index 11a39bc..0845b25 100644
--- 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageProvider.java
+++ 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageProvider.java
@@ -98,24 +98,24 @@ public class MySQLStorageProvider extends ModuleProvider {
         this.registerServiceImplementation(IBatchDAO.class, new 
H2BatchDAO(mysqlClient));
         this.registerServiceImplementation(StorageDAO.class, new 
H2StorageDAO(mysqlClient));
         this.registerServiceImplementation(
-                INetworkAddressAliasDAO.class, new 
H2NetworkAddressAliasDAO(mysqlClient));
+            INetworkAddressAliasDAO.class, new 
H2NetworkAddressAliasDAO(mysqlClient));
 
         this.registerServiceImplementation(ITopologyQueryDAO.class, new 
H2TopologyQueryDAO(mysqlClient));
         this.registerServiceImplementation(IMetricsQueryDAO.class, new 
H2MetricsQueryDAO(mysqlClient));
         this.registerServiceImplementation(ITraceQueryDAO.class, new 
MySQLTraceQueryDAO(mysqlClient));
         this.registerServiceImplementation(
-                IMetadataQueryDAO.class, new H2MetadataQueryDAO(mysqlClient, 
config.getMetadataQueryMaxSize()));
+            IMetadataQueryDAO.class, new H2MetadataQueryDAO(mysqlClient, 
config.getMetadataQueryMaxSize()));
         this.registerServiceImplementation(IAggregationQueryDAO.class, new 
MySQLAggregationQueryDAO(mysqlClient));
         this.registerServiceImplementation(IAlarmQueryDAO.class, new 
MySQLAlarmQueryDAO(mysqlClient));
         this.registerServiceImplementation(
-                IHistoryDeleteDAO.class, new H2HistoryDeleteDAO(mysqlClient));
+            IHistoryDeleteDAO.class, new H2HistoryDeleteDAO(mysqlClient));
         this.registerServiceImplementation(ITopNRecordsQueryDAO.class, new 
H2TopNRecordsQueryDAO(mysqlClient));
         this.registerServiceImplementation(ILogQueryDAO.class, new 
MySQLLogQueryDAO(mysqlClient));
 
         this.registerServiceImplementation(IProfileTaskQueryDAO.class, new 
H2ProfileTaskQueryDAO(mysqlClient));
         this.registerServiceImplementation(IProfileTaskLogQueryDAO.class, new 
H2ProfileTaskLogQueryDAO(mysqlClient));
         this.registerServiceImplementation(
-                IProfileThreadSnapshotQueryDAO.class, new 
H2ProfileThreadSnapshotQueryDAO(mysqlClient));
+            IProfileThreadSnapshotQueryDAO.class, new 
H2ProfileThreadSnapshotQueryDAO(mysqlClient));
         this.registerServiceImplementation(UITemplateManagementDAO.class, new 
H2UITemplateManagementDAO(mysqlClient));
     }
 
@@ -124,7 +124,9 @@ public class MySQLStorageProvider extends ModuleProvider {
         try {
             mysqlClient.connect();
 
-            MySQLTableInstaller installer = new 
MySQLTableInstaller(mysqlClient, getManager());
+            MySQLTableInstaller installer = new MySQLTableInstaller(
+                mysqlClient, getManager(), config.getMaxSizeOfArrayColumn()
+            );
             
getManager().find(CoreModule.NAME).provider().getService(ModelCreator.class).addModelListener(installer);
         } catch (StorageException e) {
             throw new ModuleStartException(e.getMessage(), e);
@@ -138,6 +140,6 @@ public class MySQLStorageProvider extends ModuleProvider {
 
     @Override
     public String[] requiredModules() {
-        return new String[]{CoreModule.NAME};
+        return new String[] {CoreModule.NAME};
     }
 }
diff --git 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
index 55a6b51..72d535f 100644
--- 
a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
+++ 
b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
@@ -21,6 +21,7 @@ package 
org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql;
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.List;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.skywalking.oap.server.core.storage.StorageException;
 import org.apache.skywalking.oap.server.core.storage.model.ExtraQueryIndex;
@@ -40,8 +41,8 @@ import 
org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TableInstal
  */
 @Slf4j
 public class MySQLTableInstaller extends H2TableInstaller {
-    public MySQLTableInstaller(Client client, ModuleManager moduleManager) {
-        super(client, moduleManager);
+    public MySQLTableInstaller(Client client, ModuleManager moduleManager, int 
maxSizeOfArrayColumn) {
+        super(client, moduleManager, maxSizeOfArrayColumn);
         /*
          * Override column because the default column names in core have 
syntax conflict with MySQL.
          */
@@ -72,24 +73,39 @@ public class MySQLTableInstaller extends H2TableInstaller {
         int indexSeq = 0;
         for (final ModelColumn modelColumn : model.getColumns()) {
             if (!modelColumn.isStorageOnly()) {
-                SQLBuilder tableIndexSQL = new SQLBuilder("CREATE INDEX ");
-                tableIndexSQL.append(model.getName().toUpperCase())
-                        .append("_")
-                        .append(String.valueOf(indexSeq++))
-                        .append("_IDX ");
-                tableIndexSQL.append("ON ").append(model.getName()).append("(")
-                        .append(modelColumn.getColumnName().getStorageName())
-                        .append(")");
-                createIndex(client, connection, model, tableIndexSQL);
+                final Class<?> type = modelColumn.getType();
+                if (List.class.isAssignableFrom(type)) {
+                    for (int i = 0; i < maxSizeOfArrayColumn; i++) {
+                        SQLBuilder tableIndexSQL = new SQLBuilder("CREATE 
INDEX ");
+                        tableIndexSQL.append(model.getName().toUpperCase())
+                                     .append("_")
+                                     .append(String.valueOf(indexSeq++))
+                                     .append("_IDX ");
+                        tableIndexSQL.append("ON 
").append(model.getName()).append("(")
+                                     
.append(modelColumn.getColumnName().getStorageName() + "_" + i)
+                                     .append(")");
+                        createIndex(client, connection, model, tableIndexSQL);
+                    }
+                } else {
+                    SQLBuilder tableIndexSQL = new SQLBuilder("CREATE INDEX ");
+                    tableIndexSQL.append(model.getName().toUpperCase())
+                                 .append("_")
+                                 .append(String.valueOf(indexSeq++))
+                                 .append("_IDX ");
+                    tableIndexSQL.append("ON 
").append(model.getName()).append("(")
+                                 
.append(modelColumn.getColumnName().getStorageName())
+                                 .append(")");
+                    createIndex(client, connection, model, tableIndexSQL);
+                }
             }
         }
 
         for (final ExtraQueryIndex extraQueryIndex : 
model.getExtraQueryIndices()) {
             SQLBuilder tableIndexSQL = new SQLBuilder("CREATE INDEX ");
             tableIndexSQL.append(model.getName().toUpperCase())
-                    .append("_")
-                    .append(String.valueOf(indexSeq++))
-                    .append("_IDX ");
+                         .append("_")
+                         .append(String.valueOf(indexSeq++))
+                         .append("_IDX ");
             tableIndexSQL.append(" ON ").append(model.getName()).append("(");
             final String[] columns = extraQueryIndex.getColumns();
             for (int i = 0; i < columns.length; i++) {
@@ -104,17 +120,18 @@ public class MySQLTableInstaller extends H2TableInstaller 
{
     }
 
     @Override
-    protected String getColumnType(final ModelColumn column) {
+    protected String getColumn(final ModelColumn column) {
+        final String storageName = column.getColumnName().getStorageName();
         final Class<?> type = column.getType();
         if (StorageDataComplexObject.class.isAssignableFrom(type)) {
-            return "MEDIUMTEXT";
+            return storageName + " MEDIUMTEXT";
         } else if (String.class.equals(type)) {
             if (column.getLength() > 16383) {
-                return "MEDIUMTEXT";
+                return storageName + " MEDIUMTEXT";
             } else {
-                return "VARCHAR(" + column.getLength() + ")";
+                return storageName + " VARCHAR(" + column.getLength() + ")";
             }
         }
-        return super.getColumnType(column);
+        return super.getColumn(column);
     }
 }

Reply via email to