Package de.businesscode.util.jdbc
Class DatabaseCompatibility
java.lang.Object
de.businesscode.util.jdbc.DatabaseCompatibility
This class encapsulates Database specific behavior and settings
-
Field Summary
FieldsModifier and TypeFieldDescription -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedRetrieve a singleton via getInstance() to make your SQl database type dependent -
Method Summary
Modifier and TypeMethodDescriptioncastToVarchar(String jdbcResourceName, int origJdbcDataType, String expr) Wraps the expression so that the result is of type VARCHAR or CHARstatic voidclear()clear cachesdbLikeEscapeBackslash(String jdbcResourceName) Returns true if the database of resultingBindingSet supports GROUPING SETSbooleandbNeedsColumnListForRecursiveWithClause(String jdbcResourceName) If the database used for the selected BindingSet needs an extra column list for with clausesbooleandbNeedsRecursiveInWithClause(String jdbcResourceName) Some databases need WITH RECURSIVE for recursive queries, some do not understand itbooleandbNeedsVarcharCastForConcatInTopN(String jdbcResourceName) intdbOrderByNullsLast(String jdbcResourceName, String colExpr, boolean isDesc, StringBuffer sql) Oracle sorts nulls first in desc (order by and rank order by), tera and sqlserver do this vice versa Sadly, of these, only oracle allows NULLS FIRST/LAST in ORDER BYbooleandbSupportsGroupingSets(String jdbcResourceName) Are we allowed to use GROUPING SETs and GROUPING()?getAggrFktMapping(String jdbcResourceName) For the simple @aggr shortcut this is the mapping to the corresponding SQL expression To check whether @aggr is valid, check with containsKey().byte[]returns the blob column data as a byte arraygetBlobInputStream(String bindingSetName, ResultSet rs, int column) returns the blob column data as an inputstreamgetCalcFktMapping(String jdbcResourceName) returns the clob column data as a stringgetClobInputStream(String bindingSetName, ResultSet rs, int column) returns the clob column data as an inputstreamgetDatabaseProductNameLC(String jdbcResourceName) Does not do much checking, but as all BindingSets are tested on start, the risk is lowstatic DatabaseCompatibilitygetJoinOperator(String jdbcResourceName, String op) Handling of Lateral joins differ from database to database (LATERAL vs.getReservedDBWords(String jdbcResourceName) Standard SQL Set OperatorsgetSpatialFktMapping(String jdbcResourceName) Geo spatial operators differ significantly from database to databasepaginationClause(String jdbcResourceName, int rowStart, int rowEnd, Supplier<String> getOrderBy) Pagination clause We prefer ANSI, while this is the actual support mid 2025: select * from BCDUITEST_DEMO_SHIPMENT order by item_id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY; -- ANSI, Oracle 19, Postgres 16, SnowFlake 9.31, MS SQLAzure 12 (needs OFFSET if FETCH is given), H2 2.1, DuckDB 0.1 select * from BCDUITEST_DEMO_SHIPMENT order by item_id LIMIT 10 OFFSET 20; -- MySQL 8.4.5, Postgres, SnowFlake, H2, DuckDB, Redshift 1.0.117891 select TOP 10 * from BCDUITEST_DEMO_SHIPMENT order by item_id; -- Teradata 16.2, SnowFlake, MS SQLAzure, H2, Redshift select * from BCDUITEST_DEMO_SHIPMENT order by item_id OFFSET 20 LIMIT 10; -- Postgres, DuckDB, Redshift select * from BCDUITEST_DEMO_SHIPMENT QUALIFY ROW_NUMBER() OVER(ORDER BY cost) BETWEEN 10 AND 20; -- Teradata
-
Field Details
-
sqlKeyWordsOracle
-
sqlKeyWordsMysql
-
sqlKeyWordsPostgres
-
sqlKeyWordsSqlServer
-
sqlKeyWordsSnowflake
-
sqlKeyWordsGeneric
-
databaseProduct
-
sqlServerCalcFktMapping
-
oracleCalcFktMapping
-
mysqlCalcFktMapping
-
redshiftCalcFktMapping
-
snowflakeCalcFktMapping
-
aggregationMappingGeneric
-
aggregationMappingMySql
-
spatialFktMapping
-
oracleSpatialFktMapping
-
sqlServerSpatialFktMapping
-
lateralJoinMapping
-
applyJoinMapping
-
sqlSetOperators
-
-
Constructor Details
-
DatabaseCompatibility
protected DatabaseCompatibility()Retrieve a singleton via getInstance() to make your SQl database type dependent
-
-
Method Details
-
getInstance
- Returns:
- Throws:
BindingExceptionRuntimeException
-
clear
public static void clear()clear caches -
getReservedDBWords
- Parameters:
jdbcResourceName-- Returns:
- Set of key-words for the database belonging to the BindingSets connection
-
dbNeedsColumnListForRecursiveWithClause
If the database used for the selected BindingSet needs an extra column list for with clauses- Parameters:
jdbcResourceName-- Returns:
-
dbNeedsRecursiveInWithClause
Some databases need WITH RECURSIVE for recursive queries, some do not understand it- Parameters:
jdbcResourceName-- Returns:
-
dbSupportsGroupingSets
Are we allowed to use GROUPING SETs and GROUPING()?- Parameters:
jdbcResourceName-- Returns:
-
paginationClause
public String paginationClause(String jdbcResourceName, int rowStart, int rowEnd, Supplier<String> getOrderBy) Pagination clause We prefer ANSI, while this is the actual support mid 2025: select * from BCDUITEST_DEMO_SHIPMENT order by item_id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY; -- ANSI, Oracle 19, Postgres 16, SnowFlake 9.31, MS SQLAzure 12 (needs OFFSET if FETCH is given), H2 2.1, DuckDB 0.1 select * from BCDUITEST_DEMO_SHIPMENT order by item_id LIMIT 10 OFFSET 20; -- MySQL 8.4.5, Postgres, SnowFlake, H2, DuckDB, Redshift 1.0.117891 select TOP 10 * from BCDUITEST_DEMO_SHIPMENT order by item_id; -- Teradata 16.2, SnowFlake, MS SQLAzure, H2, Redshift select * from BCDUITEST_DEMO_SHIPMENT order by item_id OFFSET 20 LIMIT 10; -- Postgres, DuckDB, Redshift select * from BCDUITEST_DEMO_SHIPMENT QUALIFY ROW_NUMBER() OVER(ORDER BY cost) BETWEEN 10 AND 20; -- Teradata- Parameters:
jdbcResourceName-rowStart- according to our Wrq conventionrowEnd- according to our Wrq convention- Returns:
-
dbLikeEscapeBackslash
Returns true if the database of resultingBindingSet supports GROUPING SETS- Parameters:
jdbcResourceName-- Returns:
-
dbNeedsVarcharCastForConcatInTopN
- Parameters:
jdbcResourceName-- Returns:
-
dbOrderByNullsLast
public int dbOrderByNullsLast(String jdbcResourceName, String colExpr, boolean isDesc, StringBuffer sql) Oracle sorts nulls first in desc (order by and rank order by), tera and sqlserver do this vice versa Sadly, of these, only oracle allows NULLS FIRST/LAST in ORDER BY- Parameters:
jdbcResourceName-- Returns:
- How often bound variables of the item used for ordering are used in the created expression
-
castToVarchar
Wraps the expression so that the result is of type VARCHAR or CHAR- Parameters:
jdbcResourceName- Used to derive database specific syntaxorigJdbcDataType- Used to skip wrapping if already CHAR/VARCHAR and keep format YYYY-MMM-DDD for type dateexpr- Expression to be wrapped- Returns:
- Wrapped SQL expression
-
getDefaultCalcFktMapping
-
getCalcFktMapping
-
getAggrFktMapping
For the simple @aggr shortcut this is the mapping to the corresponding SQL expression To check whether @aggr is valid, check with containsKey(). -
getSetOperators
Standard SQL Set Operators -
getJoinOperator
Handling of Lateral joins differ from database to database (LATERAL vs. APPLY key word)- Parameters:
jdbcResourceName-op-- Returns:
-
getSpatialFktMapping
Geo spatial operators differ significantly from database to database -
getDatabaseProductNameLC
Does not do much checking, but as all BindingSets are tested on start, the risk is low- Parameters:
jdbcResourceName-- Returns:
-
getClob
returns the clob column data as a string- Parameters:
bindingSetName- the name of the currently used binding setrs- the current result setcolumn- the index of the columns within the result set- Returns:
- clob data as a string
- Throws:
Exception
-
getBlob
returns the blob column data as a byte array- Parameters:
bindingSetName- the name of the currently used binding setrs- the current result setcolumn- the index of the columns within the result set- Returns:
- byte array with data
- Throws:
Exception
-
getClobInputStream
public InputStream getClobInputStream(String bindingSetName, ResultSet rs, int column) throws Exception returns the clob column data as an inputstream- Parameters:
bindingSetName- the name of the currently used binding setrs- the current result setcolumn- the index of the columns within the result set- Returns:
- clob data as an inputstream
- Throws:
Exception
-
getBlobInputStream
public InputStream getBlobInputStream(String bindingSetName, ResultSet rs, int column) throws Exception returns the blob column data as an inputstream- Parameters:
bindingSetName- the name of the currently used binding setrs- the current result setcolumn- the index of the columns within the result set- Returns:
- blob data as an inputstream
- Throws:
Exception
-