[#2757] Add support for DB2 10.5
This commit is contained in:
parent
1bd1ec210e
commit
e80ee1fcd1
@ -135,6 +135,16 @@ public enum SQLDialect {
|
||||
*/
|
||||
DB2("DB2", true),
|
||||
|
||||
/**
|
||||
* The IBM DB2 9.x SQL dialect.
|
||||
*/
|
||||
DB2_9("DB2", true, DB2),
|
||||
|
||||
/**
|
||||
* The IBM DB2 10.x SQL dialect.
|
||||
*/
|
||||
DB2_10("DB2", true, DB2),
|
||||
|
||||
/**
|
||||
* The Ingres dialect family.
|
||||
*/
|
||||
|
||||
@ -227,7 +227,7 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
|
||||
return executeCallableStatement();
|
||||
}
|
||||
else {
|
||||
switch (configuration.dialect()) {
|
||||
switch (configuration.dialect().family()) {
|
||||
|
||||
// [#852] Some RDBMS don't allow for using JDBC procedure escape
|
||||
// syntax for functions. Select functions from DUAL instead
|
||||
|
||||
@ -92,7 +92,7 @@ class CompareCondition extends AbstractCondition {
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
SQLDialect dialect = context.configuration().dialect();
|
||||
SQLDialect family = context.configuration().dialect().family();
|
||||
Field<?> lhs = field1;
|
||||
Field<?> rhs = field2;
|
||||
Comparator op = comparator;
|
||||
@ -102,7 +102,7 @@ class CompareCondition extends AbstractCondition {
|
||||
// [#293] TODO: This could apply to other operators, too
|
||||
if ((op == LIKE || op == NOT_LIKE)
|
||||
&& field1.getType() != String.class
|
||||
&& asList(ASE, DERBY, POSTGRES).contains(dialect)) {
|
||||
&& asList(ASE, DERBY, POSTGRES).contains(family)) {
|
||||
|
||||
lhs = lhs.cast(String.class);
|
||||
}
|
||||
@ -110,7 +110,7 @@ class CompareCondition extends AbstractCondition {
|
||||
// [#1423] Only Postgres knows a true ILIKE operator. Other dialects
|
||||
// need to simulate this as LOWER(lhs) LIKE LOWER(rhs)
|
||||
else if ((op == LIKE_IGNORE_CASE || op == NOT_LIKE_IGNORE_CASE)
|
||||
&& POSTGRES != dialect) {
|
||||
&& POSTGRES != family) {
|
||||
|
||||
lhs = lhs.lower();
|
||||
rhs = rhs.lower();
|
||||
@ -126,7 +126,7 @@ class CompareCondition extends AbstractCondition {
|
||||
boolean castRhs = false;
|
||||
|
||||
/* [pro] */
|
||||
if (dialect == DB2 && rhs instanceof Concat)
|
||||
if (family == DB2 && rhs instanceof Concat)
|
||||
castRhs = true;
|
||||
/* [/pro] */
|
||||
|
||||
|
||||
@ -171,10 +171,10 @@ class Expression<T> extends AbstractFunction<T> {
|
||||
}
|
||||
|
||||
// Many dialects don't support shifts. Use multiplication/division instead
|
||||
else if (SHL == operator && asList(ASE, DB2, H2, HSQLDB, INGRES, ORACLE, SQLSERVER, SYBASE).contains(family.family())) {
|
||||
else if (SHL == operator && asList(ASE, DB2, H2, HSQLDB, INGRES, ORACLE, SQLSERVER, SYBASE).contains(family)) {
|
||||
return lhs.mul(DSL.power(two(), rhsAsNumber()));
|
||||
}
|
||||
else if (SHR == operator && asList(ASE, DB2, H2, HSQLDB, INGRES, ORACLE, SQLSERVER, SYBASE).contains(family.family())) {
|
||||
else if (SHR == operator && asList(ASE, DB2, H2, HSQLDB, INGRES, ORACLE, SQLSERVER, SYBASE).contains(family)) {
|
||||
return lhs.div(DSL.power(two(), rhsAsNumber()));
|
||||
}
|
||||
|
||||
|
||||
@ -214,7 +214,7 @@ class Function<T> extends AbstractField<T> implements
|
||||
toSQLStringAgg(context);
|
||||
}
|
||||
/* [pro] */
|
||||
else if (term == LIST_AGG && asList(DB2).contains(context.configuration().dialect())) {
|
||||
else if (term == LIST_AGG && asList(DB2).contains(context.configuration().dialect().family())) {
|
||||
toSQLXMLAGG(context);
|
||||
}
|
||||
/* [/pro] */
|
||||
@ -433,7 +433,7 @@ class Function<T> extends AbstractField<T> implements
|
||||
|
||||
if (ignoreNulls) {
|
||||
/* [pro] */
|
||||
if (context.configuration().dialect() == SQLDialect.DB2) {
|
||||
if (context.configuration().dialect().family() == SQLDialect.DB2) {
|
||||
context.sql(", 'IGNORE NULLS'");
|
||||
}
|
||||
else
|
||||
@ -444,7 +444,7 @@ class Function<T> extends AbstractField<T> implements
|
||||
}
|
||||
else if (respectNulls) {
|
||||
/* [pro] */
|
||||
if (context.configuration().dialect() == SQLDialect.DB2) {
|
||||
if (context.configuration().dialect().family() == SQLDialect.DB2) {
|
||||
context.sql(", 'RESPECT NULLS'");
|
||||
}
|
||||
else
|
||||
|
||||
@ -176,7 +176,9 @@ class Limit extends AbstractQueryPart {
|
||||
// Only "TOP" support provided by the following dialects.
|
||||
// "OFFSET" support is simulated with nested selects
|
||||
// -----------------------------------------------------------------
|
||||
case DB2: {
|
||||
case DB2:
|
||||
case DB2_9:
|
||||
case DB2_10: {
|
||||
if (offset != null) {
|
||||
throw new DataAccessException("DB2 does not support offsets in FETCH FIRST ROWS ONLY clause");
|
||||
}
|
||||
@ -294,7 +296,9 @@ class Limit extends AbstractQueryPart {
|
||||
|
||||
// These dialects don't allow bind variables in their TOP clauses
|
||||
// --------------------------------------------------------------
|
||||
case DB2:
|
||||
case DB2:
|
||||
case DB2_9:
|
||||
case DB2_10:
|
||||
case SQLSERVER2008: {
|
||||
|
||||
// TOP clauses without bind variables
|
||||
|
||||
@ -76,21 +76,21 @@ class Neg<T> extends AbstractField<T> {
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
SQLDialect dialect = context.configuration().dialect();
|
||||
SQLDialect family = context.configuration().dialect().family();
|
||||
|
||||
if (operator == BIT_NOT && asList(H2, HSQLDB, INGRES, ORACLE).contains(dialect.family())) {
|
||||
if (operator == BIT_NOT && asList(H2, HSQLDB, INGRES, ORACLE).contains(family)) {
|
||||
context.sql("(0 -")
|
||||
.visit(field)
|
||||
.sql(" - 1)");
|
||||
}
|
||||
/* [pro] */
|
||||
else if (operator == BIT_NOT && dialect == DB2) {
|
||||
else if (operator == BIT_NOT && family == DB2) {
|
||||
context.keyword("bitnot(")
|
||||
.visit(field)
|
||||
.sql(")");
|
||||
}
|
||||
/* [/pro] */
|
||||
else if (operator == BIT_NOT && dialect == FIREBIRD) {
|
||||
else if (operator == BIT_NOT && family == FIREBIRD) {
|
||||
context.keyword("bin_not(")
|
||||
.visit(field)
|
||||
.sql(")");
|
||||
|
||||
@ -224,7 +224,9 @@ class SelectQueryImpl<R extends Record> extends AbstractSelect<R> implements Sel
|
||||
break;
|
||||
|
||||
// With DB2, there are two possibilities
|
||||
case DB2: {
|
||||
case DB2:
|
||||
case DB2_9:
|
||||
case DB2_10: {
|
||||
|
||||
// DB2 natively supports a "FIRST ROWS" clause, without
|
||||
// offset and without bind values
|
||||
|
||||
@ -124,7 +124,7 @@ class TruncateImpl<R extends Record> extends AbstractQuery implements
|
||||
.visit(table);
|
||||
|
||||
/* [pro] */
|
||||
if (context.configuration().dialect() == SQLDialect.DB2) {
|
||||
if (context.configuration().dialect().family() == SQLDialect.DB2) {
|
||||
context.sql(" ").keyword("immediate");
|
||||
}
|
||||
|
||||
|
||||
@ -149,7 +149,7 @@ class Val<T> extends AbstractParam<T> {
|
||||
|
||||
// Generated enums should not be cast...
|
||||
if (!(value instanceof EnumType)) {
|
||||
switch (context.configuration().dialect()) {
|
||||
switch (context.configuration().dialect().family()) {
|
||||
|
||||
// These dialects can hardly detect the type of a bound constant.
|
||||
/* [pro] */
|
||||
@ -200,17 +200,17 @@ class Val<T> extends AbstractParam<T> {
|
||||
private final void toSQLCast(RenderContext context) {
|
||||
DataType<T> dataType = getDataType(context.configuration());
|
||||
DataType<T> type = dataType.getSQLDataType();
|
||||
SQLDialect dialect = context.configuration().dialect();
|
||||
SQLDialect family = context.configuration().dialect().family();
|
||||
|
||||
// [#822] Some RDBMS need precision / scale information on BigDecimals
|
||||
if (value != null && getType() == BigDecimal.class && asList(CUBRID, DB2, DERBY, FIREBIRD, HSQLDB).contains(dialect)) {
|
||||
if (value != null && getType() == BigDecimal.class && asList(CUBRID, DB2, DERBY, FIREBIRD, HSQLDB).contains(family)) {
|
||||
|
||||
// Add precision / scale on BigDecimals
|
||||
int scale = ((BigDecimal) value).scale();
|
||||
int precision = scale + ((BigDecimal) value).precision();
|
||||
|
||||
// Firebird's max precision is 18
|
||||
if (dialect == FIREBIRD) {
|
||||
if (family == FIREBIRD) {
|
||||
precision = Math.min(precision, 18);
|
||||
}
|
||||
|
||||
@ -222,19 +222,19 @@ class Val<T> extends AbstractParam<T> {
|
||||
|
||||
// If the bind value is set, it can be used to derive the cast type
|
||||
if (value != null) {
|
||||
toSQLCast(context, DefaultDataType.getDataType(dialect, value.getClass()), 0, 0, 0);
|
||||
toSQLCast(context, DefaultDataType.getDataType(family, value.getClass()), 0, 0, 0);
|
||||
}
|
||||
|
||||
// [#632] [#722] Current integration tests show that Ingres and
|
||||
// Sybase can do without casting in most cases.
|
||||
else if (asList(INGRES, SYBASE).contains(dialect)) {
|
||||
else if (asList(INGRES, SYBASE).contains(family)) {
|
||||
context.sql(getBindVariable(context));
|
||||
}
|
||||
|
||||
// Derby and DB2 must have a type associated with NULL. Use VARCHAR
|
||||
// as a workaround. That's probably not correct in all cases, though
|
||||
else {
|
||||
toSQLCast(context, DefaultDataType.getDataType(dialect, String.class), 0, 0, 0);
|
||||
toSQLCast(context, DefaultDataType.getDataType(family, String.class), 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,13 +242,13 @@ class Val<T> extends AbstractParam<T> {
|
||||
// above case where the type is OTHER
|
||||
// [#1125] Also with temporal data types, casting is needed some times
|
||||
// [#1130] TODO type can be null for ARRAY types, etc.
|
||||
else if (dialect == POSTGRES && (type == null || !type.isTemporal())) {
|
||||
else if (family == POSTGRES && (type == null || !type.isTemporal())) {
|
||||
toSQL(context, value, getType());
|
||||
}
|
||||
|
||||
// [#1727] VARCHAR types should be cast to their actual lengths in some
|
||||
// dialects
|
||||
else if ((type == SQLDataType.VARCHAR || type == SQLDataType.CHAR) && asList(FIREBIRD).contains(dialect)) {
|
||||
else if ((type == SQLDataType.VARCHAR || type == SQLDataType.CHAR) && asList(FIREBIRD).contains(family)) {
|
||||
toSQLCast(context, dataType, getValueLength(), 0, 0);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user