Repository: dbeaver/dbeaver
Issue: Support JSONExtractKeysAndValuesRaw feature in Clickhouse

Hello! I use DBeaver 21.1.3.202107181810 with ClickHouse.
And I have  a problem with JSONExtractKeysAndValuesRaw feature:
`SELECT JSONExtractKeysAndValuesRaw('{"id":67}')`

Error:
```
org.jkiss.dbeaver.model.exec.DBCException: Can't extract array data from JDBC array
	at org.jkiss.dbeaver.model.impl.jdbc.data.JDBCCollection.makeCollectionFromArray(JDBCCollection.java:267)
	at org.jkiss.dbeaver.model.impl.jdbc.data.handlers.JDBCArrayValueHandler.getValueFromObject(JDBCArrayValueHandler.java:64)
	at org.jkiss.dbeaver.model.impl.jdbc.data.handlers.JDBCArrayValueHandler.getValueFromObject(JDBCArrayValueHandler.java:1)
	at org.jkiss.dbeaver.model.impl.jdbc.data.handlers.JDBCComplexValueHandler.fetchColumnValue(JDBCComplexValueHandler.java:50)
	at org.jkiss.dbeaver.model.impl.jdbc.data.handlers.JDBCAbstractValueHandler.fetchValueObject(JDBCAbstractValueHandler.java:49)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetDataReceiver.fetchRow(ResultSetDataReceiver.java:125)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.fetchQueryData(SQLQueryJob.java:721)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.executeStatement(SQLQueryJob.java:544)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.lambda$0(SQLQueryJob.java:444)
	at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:171)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.executeSingleQuery(SQLQueryJob.java:431)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.extractData(SQLQueryJob.java:816)
	at org.jkiss.dbeaver.ui.editors.sql.SQLEditor$QueryResultsContainer.readData(SQLEditor.java:3435)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.lambda$0(ResultSetJobDataRead.java:118)
	at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:171)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.run(ResultSetJobDataRead.java:116)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetViewer$ResultSetDataPumpJob.run(ResultSetViewer.java:4686)
	at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:105)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.jkiss.dbeaver.model.exec.DBCException: SQL Error
	at org.jkiss.dbeaver.model.impl.jdbc.data.JDBCCollection.makeCollectionFromArray(JDBCCollection.java:251)
	... 18 more
Caused by: java.sql.SQLFeatureNotSupportedException
	at ru.yandex.clickhouse.ClickHouseArray.getResultSet(ClickHouseArray.java:65)
	at org.jkiss.dbeaver.model.impl.jdbc.data.JDBCCollection.makeCollectionFromResultSet(JDBCCollection.java:367)
	at org.jkiss.dbeaver.model.impl.jdbc.data.JDBCCollection.makeCollectionFromArray(JDBCCollection.java:249)
	... 18 more
```

Are there any plans to add support of this feature? It would be very useful.
Thank you

Changed files:
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/handlers/JDBCArrayValueHandler.java
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/JDBCCollection.java

diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/JDBCCollection.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/JDBCCollection.java
index d2104bf043..b947bbd148 100644
--- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/JDBCCollection.java
+++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/JDBCCollection.java
@@ -237,30 +237,32 @@ public class JDBCCollection extends AbstractDatabaseList implements DBDValueClon
         }
 
         try {
-            if (elementType == null) {
-                if (array == null) {
-                    // Null array of unknown type. Just make NULL read-only array
-                    String defDataTypeName = dataSource.getDefaultDataTypeName(DBPDataKind.OBJECT);
-                    DBSDataType defDataType = dataSource.getLocalDataType(defDataTypeName);
-                    DBDValueHandler defValueHandler = session.getDefaultValueHandler();
-                    return new JDBCCollection(defDataType, defValueHandler, null);
-                }
+            if (elementType == null && array == null) {
+                // Null array of unknown type. Just make NULL read-only array
+                String defDataTypeName = dataSource.getDefaultDataTypeName(DBPDataKind.OBJECT);
+                DBSDataType defDataType = dataSource.getLocalDataType(defDataTypeName);
+                DBDValueHandler defValueHandler = session.getDefaultValueHandler();
+                return new JDBCCollection(defDataType, defValueHandler, null);
+            }
+
+            if (elementType != null) {
                 try {
-                    return makeCollectionFromResultSet(session, array, null);
+                    return makeCollectionFromArray(session, array, elementType);
                 } catch (SQLException e) {
-                    throw new DBCException(e, session.getExecutionContext());
+                    if (array == null) {
+                        throw new DBCException(e, session.getExecutionContext());
+                    }
                 }
             }
+
             try {
-                return makeCollectionFromArray(session, array, elementType);
+                return makeCollectionFromResultSet(session, array, null);
             } catch (SQLException e) {
-                if (array == null) {
-                    throw new DBCException(e, session.getExecutionContext());
-                }
                 try {
-                    return makeCollectionFromResultSet(session, array, elementType);
-                } catch (SQLException e1) {
-                    throw new DBCException(e1, session.getExecutionContext());
+                    // Array of unknown type.
+                    return makeCollectionFromJavaArray(session, array.getArray());
+                } catch (SQLException ex) {
+                    throw new DBCException(ex, session.getExecutionContext());
                 }
             }
         } catch (DBException e) {
@@ -269,7 +271,7 @@ public class JDBCCollection extends AbstractDatabaseList implements DBDValueClon
     }
 
     @NotNull
-    public static JDBCCollection makeCollectionFromJavaArray(@NotNull JDBCSession session, @NotNull DBSTypedObject column, Object array) throws DBCException {
+    public static JDBCCollection makeCollectionFromJavaArray(@NotNull JDBCSession session, Object array) throws DBCException {
         DBSDataType elementType;
         DBPDataKind dataKind;
         DBPDataTypeProvider dataTypeProvider = session.getDataSource();
diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/handlers/JDBCArrayValueHandler.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/handlers/JDBCArrayValueHandler.java
index 6d1b96a928..7f51dbb2a1 100644
--- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/handlers/JDBCArrayValueHandler.java
+++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/data/handlers/JDBCArrayValueHandler.java
@@ -65,7 +65,7 @@ public class JDBCArrayValueHandler extends JDBCComplexValueHandler {
         } else if (object instanceof String) {
             return JDBCCollection.makeCollectionFromString((JDBCSession) session, (String)object);
         } else if (object.getClass().isArray()) {
-            return JDBCCollection.makeCollectionFromJavaArray((JDBCSession) session, type, object);
+            return JDBCCollection.makeCollectionFromJavaArray((JDBCSession) session, object);
         } else if (object instanceof Collection) {
             return JDBCCollection.makeCollectionFromJavaCollection((JDBCSession) session, type, (Collection) object);
         } else {