[#2757] Add support for DB2 10.5

This commit is contained in:
Lukas Eder 2013-09-19 17:30:27 +02:00
parent 1bd1ec210e
commit e80ee1fcd1
10 changed files with 43 additions and 27 deletions

View File

@ -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.
*/

View File

@ -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

View File

@ -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] */

View File

@ -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()));
}

View File

@ -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

View File

@ -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

View File

@ -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(")");

View File

@ -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

View File

@ -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");
}

View File

@ -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);
}