diff --git a/plugins/org.jkiss.dbeaver.ext.hana/plugin.xml b/plugins/org.jkiss.dbeaver.ext.hana/plugin.xml index e76e4a792bb2..7cafb2af1028 100644 --- a/plugins/org.jkiss.dbeaver.ext.hana/plugin.xml +++ b/plugins/org.jkiss.dbeaver.ext.hana/plugin.xml @@ -165,6 +165,7 @@ + diff --git a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANAConstants.java b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANAConstants.java index 9f2c4035fd3d..10e005331f8d 100644 --- a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANAConstants.java +++ b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANAConstants.java @@ -24,4 +24,9 @@ public class HANAConstants { // pseudo schema for PUBLIC SYNONYMs public static final String SCHEMA_PUBLIC = "PUBLIC"; + + // Data type names + public static final String DATA_TYPE_NAME_REAL_VECTOR = "REAL_VECTOR"; + public static final String DATA_TYPE_NAME_ST_GEOMETRY = "ST_GEOMETRY"; + public static final String DATA_TYPE_NAME_ST_POINT = "ST_POINT"; } diff --git a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANADataSource.java b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANADataSource.java index 702d77be256e..277424cc4ed1 100644 --- a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANADataSource.java +++ b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANADataSource.java @@ -23,6 +23,7 @@ import org.jkiss.dbeaver.ext.generic.model.GenericDataSource; import org.jkiss.dbeaver.ext.generic.model.meta.GenericMetaModel; import org.jkiss.dbeaver.ext.hana.model.plan.HANAPlanAnalyser; +import org.jkiss.dbeaver.model.DBPDataKind; import org.jkiss.dbeaver.model.DBPDataSourceContainer; import org.jkiss.dbeaver.model.DBPDataSourceInfo; import org.jkiss.dbeaver.model.DBUtils; @@ -72,6 +73,14 @@ protected DBPDataSourceInfo createDataSourceInfo(DBRProgressMonitor monitor, @No return info; } + @Override + public DBPDataKind resolveDataKind(String typeName, int valueType) { + if (HANAConstants.DATA_TYPE_NAME_REAL_VECTOR.equalsIgnoreCase(typeName)) { + return DBPDataKind.ARRAY; + } + return super.resolveDataKind(typeName, valueType); + } + /* * search */ diff --git a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANASQLDialect.java b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANASQLDialect.java index 767bd56eee52..ee6db5b973e4 100644 --- a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANASQLDialect.java +++ b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/HANASQLDialect.java @@ -172,7 +172,14 @@ public String getDualTableName() { public String getColumnTypeModifiers(@NotNull DBPDataSource dataSource, @NotNull DBSTypedObject column, @NotNull String typeName, @NotNull DBPDataKind dataKind) { String ucTypeName = CommonUtils.notEmpty(typeName).toUpperCase(Locale.ENGLISH); - if (("ST_POINT".equals(ucTypeName) || "ST_GEOMETRY".equals(ucTypeName)) + if (HANAConstants.DATA_TYPE_NAME_REAL_VECTOR.equals(ucTypeName)) { + long dim = column.getMaxLength(); + if ((dim > 0) && (dim <= 65000)) { + return "(" + Long.toString(dim) + ")"; + } + return ""; + } else if ((HANAConstants.DATA_TYPE_NAME_ST_POINT.equals(ucTypeName) + || HANAConstants.DATA_TYPE_NAME_ST_GEOMETRY.equals(ucTypeName)) && (column instanceof HANATableColumn)) { HANATableColumn hanaColumn = (HANATableColumn) column; try { diff --git a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/data/HANAValueHandlerProvider.java b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/data/HANAValueHandlerProvider.java index 56a00dde6053..18ccf5e4f83c 100644 --- a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/data/HANAValueHandlerProvider.java +++ b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/data/HANAValueHandlerProvider.java @@ -20,6 +20,7 @@ package org.jkiss.dbeaver.ext.hana.model.data; import org.jkiss.code.Nullable; +import org.jkiss.dbeaver.ext.hana.model.HANAConstants; import org.jkiss.dbeaver.model.DBPDataSource; import org.jkiss.dbeaver.model.data.DBDFormatSettings; import org.jkiss.dbeaver.model.data.DBDValueHandler; @@ -33,8 +34,10 @@ public class HANAValueHandlerProvider implements DBDValueHandlerProvider { public DBDValueHandler getValueHandler(DBPDataSource dataSource, DBDFormatSettings preferences, DBSTypedObject typedObject) { switch (typedObject.getTypeName()) { - case "ST_GEOMETRY": - case "ST_POINT": + case HANAConstants.DATA_TYPE_NAME_REAL_VECTOR: + return HANAVectorValueHandler.INSTANCE; + case HANAConstants.DATA_TYPE_NAME_ST_GEOMETRY: + case HANAConstants.DATA_TYPE_NAME_ST_POINT: return HANAGeometryValueHandler.INSTANCE; default: return null; diff --git a/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/data/HANAVectorValueHandler.java b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/data/HANAVectorValueHandler.java new file mode 100644 index 000000000000..7be904c9831f --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.hana/src/org/jkiss/dbeaver/ext/hana/model/data/HANAVectorValueHandler.java @@ -0,0 +1,79 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed 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.jkiss.dbeaver.ext.hana.model.data; + +import java.sql.SQLException; +import java.sql.Types; + +import org.jkiss.dbeaver.model.data.DBDCollection; +import org.jkiss.dbeaver.model.exec.DBCException; +import org.jkiss.dbeaver.model.exec.DBCLogicalOperator; +import org.jkiss.dbeaver.model.exec.DBCSession; +import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement; +import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession; +import org.jkiss.dbeaver.model.impl.jdbc.data.JDBCCollection; +import org.jkiss.dbeaver.model.impl.jdbc.data.handlers.JDBCArrayValueHandler; +import org.jkiss.dbeaver.model.struct.DBSTypedObject; + +public class HANAVectorValueHandler extends JDBCArrayValueHandler { + + public static final HANAVectorValueHandler INSTANCE = new HANAVectorValueHandler(); + + private static DBCLogicalOperator[] SUPPORTED_OPERATORS = { DBCLogicalOperator.IS_NOT_NULL, + DBCLogicalOperator.IS_NULL }; + + @Override + protected boolean useGetArray(DBCSession session, DBSTypedObject type) { + return true; + } + + @Override + protected void bindParameter(JDBCSession session, JDBCPreparedStatement statement, DBSTypedObject paramType, + int paramIndex, Object value) throws DBCException, SQLException { + if (value == null) { + statement.setNull(paramIndex, Types.ARRAY); + } else if (value instanceof DBDCollection) { + DBDCollection collection = (DBDCollection) value; + if (collection.isNull()) { + statement.setNull(paramIndex, Types.ARRAY); + } else if (collection instanceof JDBCCollection) { + JDBCCollection jc = (JDBCCollection) collection; + if (jc.getComponentType().getTypeID() != Types.REAL) { + throw new DBCException("Only REAL numbers are allowed in vectors"); + } + float[] nvals = new float[jc.size()]; + for (int i = 0; i < nvals.length; ++i) { + Float val = (Float) jc.get(i); + if (val == null) { + throw new DBCException("NULL elements are not allowed in vectors"); + } + nvals[i] = val; + } + statement.setObject(paramIndex, nvals); + } else { + throw new DBCException("Array parameter type '" + value.getClass().getName() + "' not supported"); + } + } else { + throw new DBCException("Array parameter type '" + value.getClass().getName() + "' not supported"); + } + } + + @Override + public DBCLogicalOperator[] getSupportedOperators(DBSTypedObject attribute) { + return SUPPORTED_OPERATORS; + } +}