Skip to content

Commit

Permalink
HANA: Add support for REAL_VECTOR type
Browse files Browse the repository at this point in the history
  • Loading branch information
mrylov committed Apr 17, 2024
1 parent c4f94e8 commit 23f84a5
Show file tree
Hide file tree
Showing 8 changed files with 312 additions and 119 deletions.
1 change: 1 addition & 0 deletions src/providers/hana/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ set(HANA_HDRS
qgshanaconnection.h
qgshanaconnectionpool.h
qgshanaconnectionstringbuilder.h
qgshanadatatypes.h
qgshanadriver.h
qgshanaexception.h
qgshanaexpressioncompiler.h
Expand Down
89 changes: 47 additions & 42 deletions src/providers/hana/qgshanaconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "qgsdatasourceuri.h"
#include "qgshanaconnection.h"
#include "qgshanaconnectionstringbuilder.h"
#include "qgshanadatatypes.h"
#include "qgshanadriver.h"
#include "qgshanaexception.h"
#include "qgshanaresultset.h"
Expand Down Expand Up @@ -99,62 +100,66 @@ QgsField AttributeField::toQgsField() const
QVariant::Type fieldType;
switch ( type )
{
case SQLDataTypes::Bit:
case SQLDataTypes::Boolean:
case QgsHanaDataTypes::Bit:
case QgsHanaDataTypes::Boolean:
fieldType = QVariant::Bool;
break;
case SQLDataTypes::TinyInt:
case SQLDataTypes::SmallInt:
case SQLDataTypes::Integer:
case QgsHanaDataTypes::TinyInt:
case QgsHanaDataTypes::SmallInt:
case QgsHanaDataTypes::Integer:
fieldType = isSigned ? QVariant::Int : QVariant::UInt;
break;
case SQLDataTypes::BigInt:
case QgsHanaDataTypes::BigInt:
fieldType = isSigned ? QVariant::LongLong : QVariant::ULongLong;
break;
case SQLDataTypes::Numeric:
case SQLDataTypes::Decimal:
case QgsHanaDataTypes::Numeric:
case QgsHanaDataTypes::Decimal:
fieldType = QVariant::Double;
break;
case SQLDataTypes::Double:
case SQLDataTypes::Float:
case SQLDataTypes::Real:
case QgsHanaDataTypes::Double:
case QgsHanaDataTypes::Float:
case QgsHanaDataTypes::Real:
fieldType = QVariant::Double;
break;
case SQLDataTypes::Char:
case SQLDataTypes::WChar:
case QgsHanaDataTypes::Char:
case QgsHanaDataTypes::WChar:
fieldType = ( size == 1 ) ? QVariant::Char : QVariant::String;
break;
case SQLDataTypes::VarChar:
case SQLDataTypes::WVarChar:
case SQLDataTypes::LongVarChar:
case SQLDataTypes::WLongVarChar:
case QgsHanaDataTypes::VarChar:
case QgsHanaDataTypes::WVarChar:
case QgsHanaDataTypes::LongVarChar:
case QgsHanaDataTypes::WLongVarChar:
fieldType = QVariant::String;
break;
case SQLDataTypes::Binary:
case SQLDataTypes::VarBinary:
case SQLDataTypes::LongVarBinary:
case QgsHanaDataTypes::Binary:
case QgsHanaDataTypes::VarBinary:
case QgsHanaDataTypes::LongVarBinary:
fieldType = QVariant::ByteArray;
break;
case SQLDataTypes::Date:
case SQLDataTypes::TypeDate:
case QgsHanaDataTypes::Date:
case QgsHanaDataTypes::TypeDate:
fieldType = QVariant::Date;
break;
case SQLDataTypes::Time:
case SQLDataTypes::TypeTime:
case QgsHanaDataTypes::Time:
case QgsHanaDataTypes::TypeTime:
fieldType = QVariant::Time;
break;
case SQLDataTypes::Timestamp:
case SQLDataTypes::TypeTimestamp:
case QgsHanaDataTypes::Timestamp:
case QgsHanaDataTypes::TypeTimestamp:
fieldType = QVariant::DateTime;
break;
case QgsHanaDataTypes::Geometry:
// There are two options how to treat ST_GEOMETRY columns that are attributes:
// 1. Type is QVariant::String. The value is provided as WKT and editable.
// 2. Type is QVariant::ByteArray. The value is provided as BLOB and uneditable.
fieldType = QVariant::String;
break;
case QgsHanaDataTypes::RealVector:
// Controls how REAL_VECTOR type is treated, either as QVariant::ByteArray or QVariant::String.
fieldType = QVariant::String;
break;
default:
if ( isGeometry() )
// There are two options how to treat geometry columns that are attributes:
// 1. Type is QVariant::String. The value is provided as WKT and editable.
// 2. Type is QVariant::ByteArray. The value is provided as BLOB and uneditable.
fieldType = QVariant::String;
else
throw QgsHanaException( QString( "Field type '%1' is not supported" ).arg( QString::number( type ) ) );
throw QgsHanaException( QString( "Field type '%1' is not supported" ).arg( QString::number( type ) ) );
break;
}

Expand Down Expand Up @@ -824,19 +829,19 @@ void QgsHanaConnection::readTableFields( const QString &schemaName, const QStrin
field.name = rsColumns->getString( 4/*COLUMN_NAME*/ );
field.type = rsColumns->getShort( 5/*DATA_TYPE*/ );
field.typeName = rsColumns->getString( 6/*TYPE_NAME*/ );
if ( field.type == SQLDataTypes::Unknown )
if ( field.type == QgsHanaDataTypes::Unknown )
throw QgsHanaException( QString( "Type of the column '%1' is unknown" ).arg( field.name ) );
field.size = rsColumns->getInt( 7/*COLUMN_SIZE*/ );
field.precision = static_cast<int>( rsColumns->getShort( 9/*DECIMAL_DIGITS*/ ) );
field.isSigned = field.type == SQLDataTypes::SmallInt || field.type == SQLDataTypes::Integer ||
field.type == SQLDataTypes::BigInt || field.type == SQLDataTypes::Decimal ||
field.type == SQLDataTypes::Numeric || field.type == SQLDataTypes::Real ||
field.type == SQLDataTypes::Float || field.type == SQLDataTypes::Double;
field.isSigned = field.type == QgsHanaDataTypes::SmallInt || field.type == QgsHanaDataTypes::Integer ||
field.type == QgsHanaDataTypes::BigInt || field.type == QgsHanaDataTypes::Decimal ||
field.type == QgsHanaDataTypes::Numeric || field.type == QgsHanaDataTypes::Real ||
field.type == QgsHanaDataTypes::Float || field.type == QgsHanaDataTypes::Double;
QString isNullable = rsColumns->getString( 18/*IS_NULLABLE*/ );
field.isNullable = ( isNullable == QLatin1String( "YES" ) || isNullable == QLatin1String( "TRUE" ) );
field.isAutoIncrement = isColumnAutoIncrement( field.name );
field.isUnique = isColumnUnique( field.name );
if ( field.isGeometry() )
if ( field.type == QgsHanaDataTypes::Geometry )
field.srid = getColumnSrid( schemaName, tableName, field.name );
field.comment = rsColumns->getString( 12/*REMARKS*/ );

Expand Down Expand Up @@ -912,9 +917,9 @@ QStringList QgsHanaConnection::getPrimaryKeyCandidates( const QgsHanaLayerProper
while ( rsColumns->next() )
{
int dataType = rsColumns->getValue( 5/*DATA_TYPE */ ).toInt();
// We exclude GEOMETRY and LOB columns
if ( dataType == 29812 /* GEOMETRY TYPE */ || dataType == SQLDataTypes::LongVarBinary ||
dataType == SQLDataTypes::LongVarChar || dataType == SQLDataTypes::WLongVarChar )
// We exclude ST_GEOMETRY, REAL_VECTOR and LOB columns
if ( dataType == QgsHanaDataTypes::Geometry || dataType == QgsHanaDataTypes::RealVector ||
dataType == QgsHanaDataTypes::LongVarBinary || dataType == QgsHanaDataTypes::LongVarChar || dataType == QgsHanaDataTypes::WLongVarChar )
continue;
ret << rsColumns->getValue( 4/*COLUMN_NAME */ ).toString();
}
Expand Down
2 changes: 0 additions & 2 deletions src/providers/hana/qgshanaconnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ struct AttributeField
bool isUnique = false;
QString comment;

bool isGeometry() const { return type == 29812; /* ST_GEOMETRY, ST_POINT */ }

QgsField toQgsField() const;
};

Expand Down
91 changes: 91 additions & 0 deletions src/providers/hana/qgshanadatatypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/***************************************************************************
qgshanadatatypes.h
--------------------------------------
Date : 10-04-2024
Copyright : (C) SAP SE
Author : Maxim Rylov
***************************************************************************/

/***************************************************************************
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
***************************************************************************/
#ifndef QGSHANADATATYPES_H
#define QGSHANADATATYPES_H

#include "odbc/Types.h"

using namespace NS_ODBC;

class QgsHanaDataTypes
{
QgsHanaDataTypes() = delete;

public:
/// Unknown data type.
static constexpr int Unknown = SQLDataTypes::Unknown;
/// 64-bit integer value.
static constexpr int BigInt = SQLDataTypes::BigInt;
/// Binary data of fixed length.
static constexpr int Binary = SQLDataTypes::Binary;
/// Single bit binary data.
static constexpr int Bit = SQLDataTypes::Bit;
/// Boolean value.
static constexpr int Boolean = SQLDataTypes::Boolean;
/// Character string of fixed string length.
static constexpr int Char = SQLDataTypes::Char;
/// Year, month, and day fields.
static constexpr int Date = SQLDataTypes::Date;
/// Year, month, and day fields.
static constexpr int DateTime = SQLDataTypes::DateTime;
/// Signed, exact, numeric value.
static constexpr int Decimal = SQLDataTypes::Decimal;
/// Double-precision floating point number.
static constexpr int Double = SQLDataTypes::Double;
/// Floating point number with driver-specific precision.
static constexpr int Float = SQLDataTypes::Float;
/// 32-bit integer value.
static constexpr int Integer = SQLDataTypes::Integer;
/// Variable length binary data.
static constexpr int LongVarBinary = SQLDataTypes::LongVarBinary;
/// Variable length character data.
static constexpr int LongVarChar = SQLDataTypes::LongVarChar;
/// Signed, exact, numeric value.
static constexpr int Numeric = SQLDataTypes::Numeric;
/// Single-precision floating point number.
static constexpr int Real = SQLDataTypes::Real;
/// 16-bit integer value.
static constexpr int SmallInt = SQLDataTypes::SmallInt;
/// Hour, minute, and second fields.
static constexpr int Time = SQLDataTypes::Time;
/// Year, month, day, hour, minute, and second fields.
static constexpr int Timestamp = SQLDataTypes::Timestamp;
/// 8-bit integer value.
static constexpr int TinyInt = SQLDataTypes::TinyInt;
/// Year, month, and day fields.
static constexpr int TypeDate = SQLDataTypes::TypeDate;
/// Hour, minute, and second fields.
static constexpr int TypeTime = SQLDataTypes::TypeTime;
/// Year, month, day, hour, minute, and second fields.
static constexpr int TypeTimestamp = SQLDataTypes::TypeTimestamp;
/// Variable length binary data.
static constexpr int VarBinary = SQLDataTypes::VarBinary;
/// Variable-length character string.
static constexpr int VarChar = SQLDataTypes::VarChar;
/// Unicode character string of fixed string length.
static constexpr int WChar = SQLDataTypes::WChar;
/// Unicode variable-length character data.
static constexpr int WLongVarChar = SQLDataTypes::WLongVarChar;
/// Unicode variable-length character string.
static constexpr int WVarChar = SQLDataTypes::WVarChar;
/// ST_GEOMETRY/ST_POINT value.
static constexpr int Geometry = 29812;
/// REAL_VECTOR value.
static constexpr int RealVector = 29814;
};

#endif // QGSHANADATATYPES_H
Loading

0 comments on commit 23f84a5

Please sign in to comment.