Class Hana

All Implemented Interfaces:
Backend

@Service(Backend.class) public class Hana extends AbstractSql2003Backend
Backend for SAP HANA.

Requires at least SAP HANA 2.0. SAP HANA Cloud is supported as well.

  • Field Details

    • SQL_LIMIT

      public static final String SQL_LIMIT
      LIMIT string.
      See Also:
    • SQL_OFFSET

      public static final String SQL_OFFSET
      OFFSET string.
      See Also:
    • SQL_LIMIT_PAR

      public static final String SQL_LIMIT_PAR
      LIMIT ? string.
      See Also:
    • SQL_OFFSET_PAR

      public static final String SQL_OFFSET_PAR
      OFFSET ? string.
      See Also:
    • MAX_LIMIT

      public static final int MAX_LIMIT
      the limit used to emulate an OFFSET without a LIMIT (HANA requires both).
      See Also:
    • RESERVED_WORDS_HANA

      public static final String[] RESERVED_WORDS_HANA
      array of additional reserved words (those not already covered by SQL92 and SQL2003).
  • Constructor Details

    • Hana

      public Hana()
      Creates the HANA backend.
  • Method Details

    • getReservedWords

      public Set<String> getReservedWords()
      Description copied from interface: Backend
      Gets the list of reserved words for this backend.
      Specified by:
      getReservedWords in interface Backend
      Overrides:
      getReservedWords in class AbstractSql2003Backend
      Returns:
      the set of reserved words
    • getMaxNameLength

      public int getMaxNameLength(SqlNameType nameType)
      Description copied from interface: Backend
      Gets the maximum allowed length for a name.
      This method is used by Backend.assertValidName(SqlNameType, String).
      Specified by:
      getMaxNameLength in interface Backend
      Overrides:
      getMaxNameLength in class AbstractBackend
      Parameters:
      nameType - the type of the name
      Returns:
      the length
    • isMatchingUrl

      public boolean isMatchingUrl(String url)
      Description copied from interface: Backend
      Checks whether the backend belongs to the given jdbc url.
      If multiple backend implementations are provided for the same database type, only one backend should match the URL. The others must be selected via name.
      Parameters:
      url - the jdbc url
      Returns:
      true if matches
    • getName

      public String getName()
      Description copied from interface: Backend
      Gets the name of the backend.
      Returns:
      the name
    • getDriverClassName

      public String getDriverClassName()
      Description copied from interface: Backend
      Gets the JDBC driver class name.
      Returns:
      the class name
    • validateVersion

      public void validateVersion(BackendVersionInfo versionInfo)
      Description copied from interface: Backend
      Verifies that the major and minor version of the connection's metadata is compatible with this backend.
      If the latest backend is not compatible, the URL may be post-fixed with a backend type for an older version, for example:
        jdbc:oracle:thin:@//localhost:1521/xe|Oracle8
      
      Specified by:
      validateVersion in interface Backend
      Overrides:
      validateVersion in class AbstractBackend
      Parameters:
      versionInfo - the database version
      See Also:
    • getBackendId

      public String getBackendId(Connection connection)
      Description copied from interface: Backend
      Determines the unique id or name used by the backend for a given connection.

      Useful to figure out the corresponding ManagedConnection from the backend's logfiles.

      Parameters:
      connection - the jdbc connection
      Returns:
      the backend id, null if none
    • getDummySelect

      public String getDummySelect()
      Description copied from interface: Backend
      Gets the dummy select to keep/test connections alive.
      Most databases just require a "SELECT 1".
      Specified by:
      getDummySelect in interface Backend
      Overrides:
      getDummySelect in class AbstractBackend
      Returns:
      the select string
    • isReservedSchemaName

      public boolean isReservedSchemaName(String name)
      Description copied from interface: Backend
      Checks whether this is a reserved schema name for this backend.
      Specified by:
      isReservedSchemaName in interface Backend
      Overrides:
      isReservedSchemaName in class AbstractBackend
      Parameters:
      name - the schema name
      Returns:
      true if reserved by backend
    • isAliasRequiredForSubSelect

      public boolean isAliasRequiredForSubSelect()
      Description copied from interface: Backend
      Returns whether the backend requires an alias for a sub-select.
      Specified by:
      isAliasRequiredForSubSelect in interface Backend
      Overrides:
      isAliasRequiredForSubSelect in class AbstractBackend
      Returns:
      true if a sub-select needs an alias.
    • isConstraintException

      public boolean isConstraintException(SQLException ex)
      Description copied from interface: Backend
      Determines whether exception is a constraint violation.
      Specified by:
      isConstraintException in interface Backend
      Overrides:
      isConstraintException in class AbstractBackend
      Parameters:
      ex - the exception
      Returns:
      true if constraint violation
    • isCommunicationLinkException

      public boolean isCommunicationLinkException(SQLException ex)
      Description copied from interface: Backend
      Determines whether the exception is a communication error.
      Specified by:
      isCommunicationLinkException in interface Backend
      Overrides:
      isCommunicationLinkException in class AbstractBackend
      Parameters:
      ex - the exception
      Returns:
      true if comlink down or alike
    • isTransientTransactionException

      public boolean isTransientTransactionException(SQLException ex)
      Description copied from interface: Backend
      Determines whether the exception is transient and retrying the transaction may succeed.
      Typical transient exceptions are thrown when a deadlock is detected or when serialized transaction isolation is used.

      Other transient errors are not covered by this method (e.g., connection timeouts, etc...).

      Specified by:
      isTransientTransactionException in interface Backend
      Overrides:
      isTransientTransactionException in class AbstractBackend
      Parameters:
      ex - the exception
      Returns:
      true if retrying the transaction may succeed
    • buildSelectSql

      public void buildSelectSql(StringBuilder sqlBuilder, boolean writeLock, int limit, int offset)
      Description copied from class: AbstractSql2003Backend
      Creates a select statement string from an inner SQL string.

      sqlBuilder is anything like [SELECT] FROM... WHERE... ORDER BY....
      It is decorated with a leading SELECT, if missing, plus optional LIMIT, OFFSET and FOR UPDATE clauses according to the given parameters.

      Notice that not all backends support a write lock combined with a limit or offset.

      With a limit or offset, the original select is wrapped into an enclosing select that filters by row number. A write lock cannot be combined with a limit or offset, since most databases refuse FOR UPDATE within a nested select.

      Specified by:
      buildSelectSql in interface Backend
      Overrides:
      buildSelectSql in class AbstractSql2003Backend
      Parameters:
      sqlBuilder - the SQL builder, initially containing the inner SQL with or without leading SELECT
      writeLock - true if the select should write-lock
      limit - the limit value, ≤ 0 if no limit clause
      offset - the offset value, ≤ 0 if no offset clause
    • setLeadingSelectParameters

      public int setLeadingSelectParameters(BackendPreparedStatement stmt, int limit, int offset)
      Description copied from interface: Backend
      Sets optional parameters before applying the original parameters.
      Specified by:
      setLeadingSelectParameters in interface Backend
      Overrides:
      setLeadingSelectParameters in class AbstractSql2003Backend
      Parameters:
      stmt - the prepared statement
      limit - the limit value, ≤ 0 if no limit clause
      offset - the offset value, ≤ 0 if no offset clause
      Returns:
      the next parameter index
    • setTrailingSelectParameters

      public int setTrailingSelectParameters(BackendPreparedStatement stmt, int index, int limit, int offset)
      Description copied from class: AbstractSql2003Backend
      Sets optional parameters after applying the original parameters.

      Because the limit is applied as an upper bound of the row number, it is bound as offset + limit.

      Specified by:
      setTrailingSelectParameters in interface Backend
      Overrides:
      setTrailingSelectParameters in class AbstractSql2003Backend
      Parameters:
      stmt - the prepared statement
      index - the first parameter index
      limit - the limit value, ≤ 0 if no limit clause
      offset - the offset value, ≤ 0 if no offset clause
      Returns:
      the next parameter index
    • getMaxSize

      public int getMaxSize(SqlType sqlType)
      Description copied from interface: Backend
      Returns the maximum size for a given SQL type.
      Specified by:
      getMaxSize in interface Backend
      Overrides:
      getMaxSize in class AbstractBackend
      Parameters:
      sqlType - the SQL-type
      Returns:
      the maximum size, 0 if unlimited, -1 for types without a size
    • sqlTypeToString

      public String sqlTypeToString(SqlType sqlType, int size)
      Description copied from interface: Backend
      Converts the java SQL type to the database type name.
      Specified by:
      sqlTypeToString in interface Backend
      Overrides:
      sqlTypeToString in class AbstractBackend
      Parameters:
      sqlType - the java SQL type
      size - the column's size
      Returns:
      the corresponding type string
    • jdbcTypeToSqlType

      public SqlType[] jdbcTypeToSqlType(int jdbcType, int size, int scale)
      Description copied from interface: Backend
      Converts the JDBC data type integer to Tentackle SqlTypes.

      There may be more than one SqlType returned!

      Specified by:
      jdbcTypeToSqlType in interface Backend
      Overrides:
      jdbcTypeToSqlType in class AbstractBackend
      Parameters:
      jdbcType - the jdbc data type
      size - the column size
      scale - the column's scale
      Returns:
      the SqlTypes, empty array if no mapping available or no exact match (not generated by Tentackle)
      See Also:
    • columnTypeNullDefaultToString

      public String columnTypeNullDefaultToString(String columnName, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue)
      Description copied from interface: Backend
      Converts an SqlType, size, scale, nullable, and default value to a database type declaration.
      Specified by:
      columnTypeNullDefaultToString in interface Backend
      Overrides:
      columnTypeNullDefaultToString in class AbstractBackend
      Parameters:
      columnName - the database column name
      sqlType - the SQL type
      size - the optional size
      scale - the optional scale
      nullable - true if NULL, else NOT NULL
      defaultValue - the optional default value
      Returns:
      the SQL code
    • valueToLiteral

      public String valueToLiteral(SqlType sqlType, Object value)
      Description copied from interface: Backend
      Converts a type and value to a literal string.
      Specified by:
      valueToLiteral in interface Backend
      Overrides:
      valueToLiteral in class AbstractBackend
      Parameters:
      sqlType - the SQL type
      value - the value
      Returns:
      the constant
    • sqlNextFromSequence

      public String sqlNextFromSequence(String name)
      Description copied from interface: Backend
      Creates the SQL string to retrieve the next id from a sequence.
      Specified by:
      sqlNextFromSequence in interface Backend
      Overrides:
      sqlNextFromSequence in class AbstractSql2003Backend
      Parameters:
      name - the name of the sequence
      Returns:
      the SQL code
    • sqlCreateTableComment

      public String sqlCreateTableComment(String tableName, String comment)
      Description copied from interface: Backend
      Generates SQL code to create the comment for a table.
      Specified by:
      sqlCreateTableComment in interface Backend
      Overrides:
      sqlCreateTableComment in class AbstractBackend
      Parameters:
      tableName - the table name
      comment - optional comment, null if none
      Returns:
      the SQL code, empty string if the comment is created via Backend.sqlCreateTableIntro(String, String) or Backend.sqlCreateTableClosing(String, String)
    • sqlCreateColumnComment

      public String sqlCreateColumnComment(String tableName, String columnName, String comment)
      Description copied from interface: Backend
      Generates SQL code to create the comment for an attribute.
      Specified by:
      sqlCreateColumnComment in interface Backend
      Overrides:
      sqlCreateColumnComment in class AbstractBackend
      Parameters:
      tableName - the table name
      columnName - the column name
      comment - optional comment, null if none
      Returns:
      the SQL-code, the empty string if comment is created via Backend.sqlCreateColumn(String, String, SqlType, int, int, boolean, Object, boolean, boolean)
    • sqlRenameTable

      public String sqlRenameTable(String tableName, String newTableName)
      Description copied from interface: Backend
      Generates SQL code to rename a table.
      Specified by:
      sqlRenameTable in interface Backend
      Overrides:
      sqlRenameTable in class AbstractBackend
      Parameters:
      tableName - the old table name (with leading schema, if any)
      newTableName - the new table name (without the schema name)
      Returns:
      the SQL code
    • sqlRenameColumn

      public String sqlRenameColumn(String tableName, String oldColumnName, String newColumnName)
      Description copied from interface: Backend
      Generates SQL code to rename a column.
      Specified by:
      sqlRenameColumn in interface Backend
      Overrides:
      sqlRenameColumn in class AbstractBackend
      Parameters:
      tableName - the table name
      oldColumnName - the old column name
      newColumnName - the new column name
      Returns:
      the SQL code, null if Backend.sqlRenameAndAlterColumnType(String, String, String, String, SqlType, int, int, boolean, Object) must be used instead
    • sqlRenameIndex

      public String sqlRenameIndex(String tableName, String oldIndexName, String newIndexName)
      Description copied from interface: Backend
      Generates SQL code to rename an index.
      Specified by:
      sqlRenameIndex in interface Backend
      Overrides:
      sqlRenameIndex in class AbstractBackend
      Parameters:
      tableName - the table name
      oldIndexName - the old index name
      newIndexName - the new index name
      Returns:
      the SQL code, null if not supported by the backend and the index must be dropped and re-created
    • sqlAddColumn

      public String sqlAddColumn(String tableName, String columnName, String comment, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue)
      Description copied from interface: Backend
      Generates SQL code to add a column.
      Specified by:
      sqlAddColumn in interface Backend
      Overrides:
      sqlAddColumn in class AbstractBackend
      Parameters:
      tableName - the table name
      columnName - the new column name
      comment - optional comment, null if none
      sqlType - the SQL type
      size - the optional size
      scale - the optional scale
      nullable - true if NULL, else NOT NULL
      defaultValue - the optional default value
      Returns:
      the SQL code
    • sqlDropColumn

      public String sqlDropColumn(String tableName, String columnName)
      Description copied from interface: Backend
      Generates SQL code to drop a column.
      Specified by:
      sqlDropColumn in interface Backend
      Overrides:
      sqlDropColumn in class AbstractBackend
      Parameters:
      tableName - the table name
      columnName - the column name
      Returns:
      the SQL code
    • sqlAlterColumnType

      public String sqlAlterColumnType(String tableName, String columnName, String comment, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue)
      Generates SQL code to change the datatype of a column.

      HANA alters a column by replacing its whole declaration. Hence, the null constraint and the default value always change along with the type.

      Specified by:
      sqlAlterColumnType in interface Backend
      Overrides:
      sqlAlterColumnType in class AbstractBackend
      Parameters:
      tableName - the table name
      columnName - the column name
      comment - optional comment, null if none
      sqlType - the SQL type
      size - the optional size
      scale - the optional scale
      nullable - true if NULL, else NOT NULL
      defaultValue - the optional default value
      Returns:
      the SQL code
    • sqlAlterColumnNullConstraint

      public String sqlAlterColumnNullConstraint(String tableName, String columnName, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue)
      Description copied from interface: Backend
      Generates SQL code to change the null-constraint of a column, given its full declaration.
      Some backends (MySQL, for example) cannot change a single property of a column: the whole declaration must be repeated. Backends that can change the null-constraint on their own simply ignore the type, size, scale, and default.
      Specified by:
      sqlAlterColumnNullConstraint in interface Backend
      Overrides:
      sqlAlterColumnNullConstraint in class AbstractBackend
      Parameters:
      tableName - the table name
      columnName - the column name
      sqlType - the SQL type
      size - the optional size
      scale - the optional scale
      nullable - true if NULL, else NOT NULL
      defaultValue - the optional default value
      Returns:
      the SQL code, null if need Backend.sqlAlterColumnType(String, String, String, SqlType, int, int, boolean, Object)
      See Also:
    • sqlAlterColumnDefault

      public String sqlAlterColumnDefault(String tableName, String columnName, SqlType sqlType, Object defaultValue)
      Description copied from interface: Backend
      Generates SQL code to change the default value of a column.
      Specified by:
      sqlAlterColumnDefault in interface Backend
      Overrides:
      sqlAlterColumnDefault in class AbstractBackend
      Parameters:
      tableName - the table name
      columnName - the column name
      sqlType - the SQL type
      defaultValue - the optional default value
      Returns:
      the SQL code, null if need Backend.sqlAlterColumnType(String, String, String, SqlType, int, int, boolean, Object)
    • getMigrationStrategy

      public MigrationStrategy[] getMigrationStrategy(ColumnMetaData column, String columnName, String comment, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue)
      Determines the best migration strategy.

      HANA cannot change the default of a column alone: the whole column declaration is repeated instead. Hence, a changed default yields MigrationStrategy.TYPE, and a changed null constraint yields MigrationStrategy.NULL, which carries the type and the default as well. MigrationStrategy.DEFAULT is never returned.

      Specified by:
      getMigrationStrategy in interface Backend
      Overrides:
      getMigrationStrategy in class AbstractBackend
      Parameters:
      column - old column metadata
      columnName - new column name
      comment - new comment
      sqlType - new SQL type
      size - new size
      scale - new scale
      nullable - new nullable
      defaultValue - new default
      Returns:
      the strategies to achieve the migration