[#2108] SQLite returns NULL for val(new Date(0)).add(-1) and some other

date time arithmetic expressions
This commit is contained in:
Lukas Eder 2013-01-08 21:41:11 +01:00
parent 0fb2d950aa
commit 6fefe2afe3
2 changed files with 48 additions and 29 deletions

View File

@ -64,6 +64,7 @@ import static org.jooq.impl.Factory.bitOr;
import static org.jooq.impl.Factory.bitXor;
import static org.jooq.impl.Factory.field;
import static org.jooq.impl.Factory.function;
import static org.jooq.impl.Factory.inline;
import static org.jooq.impl.Factory.two;
import static org.jooq.impl.Factory.val;
@ -403,14 +404,15 @@ class Expression<T> extends AbstractFunction<T> {
}
case SQLITE: {
String prefix = (sign > 0) ? "+" : "-";
boolean ytm = rhs.get(0).getType() == YearToMonth.class;
Field<?> interval = val(ytm ? rhsAsYTM().intValue() : rhsAsDTS().getTotalSeconds());
if (rhs.get(0).getType() == YearToMonth.class) {
return field("{datetime}({0}, '" + prefix + rhsAsYTM().intValue() + " months')", getDataType(), lhs);
}
else {
return field("{datetime}({0}, '" + prefix + rhsAsDTS().getTotalSeconds() + " seconds')", getDataType(), lhs);
if (sign < 0) {
interval = interval.neg();
}
interval = interval.concat(inline(ytm ? " months" : " seconds"));
return field("{datetime}({0}, {1})", getDataType(), lhs, interval);
}
case ORACLE:
@ -509,10 +511,10 @@ class Expression<T> extends AbstractFunction<T> {
case SQLITE:
if (operator == ADD) {
return field("{datetime}({0}, '+" + rhsAsNumber() + " day')", getDataType(), lhs);
return field("{datetime}({0}, {1})", getDataType(), lhs, rhsAsNumber().concat(inline(" day")));
}
else {
return field("{datetime}({0}, '-" + rhsAsNumber() + " day')", getDataType(), lhs);
return field("{datetime}({0}, {1})", getDataType(), lhs, rhsAsNumber().neg().concat(inline(" day")));
}
// These dialects can add / subtract days using +/- operators

View File

@ -35,6 +35,7 @@
*/
package org.jooq.impl;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.impl.Factory.fieldByName;
import java.sql.DatabaseMetaData;
@ -183,26 +184,6 @@ class MetaImpl implements Meta {
}
try {
columnCache = executor
.fetch(
meta().getColumns(null, getName(), "%", "%"),
// Work around a bug in the SQL Server JDBC driver by
// coercing data types to the expected types
// The bug was reported here:
// https://connect.microsoft.com/SQLServer/feedback/details/775425/jdbc-4-0-databasemetadata-getcolumns-returns-a-resultset-whose-resultsetmetadata-is-inconsistent
String.class, // TABLE_CAT
String.class, // TABLE_SCHEM
String.class, // TABLE_NAME
String.class, // COLUMN_NAME
int.class, // DATA_TYPE
String.class, // TYPE_NAME
int.class, // COLUMN_SIZE
String.class, // BUFFER_LENGTH
int.class // DECIMAL_DIGITS
)
.intoGroups(fieldByName(String.class, "TABLE_NAME"));
List<Table<?>> result = new ArrayList<Table<?>>();
Result<Record> tables = executor.fetch(meta().getTables(null, getName(), "%", null));
@ -211,7 +192,7 @@ class MetaImpl implements Meta {
// String schema = table.getValue(1, String.class);
String name = table.getValue(2, String.class);
result.add(new MetaTable(name, this, columnCache.get(name)));
result.add(new MetaTable(name, this, getColumns(name)));
// TODO: Find a more efficient way to do this
// Result<Record> pkColumns = executor.fetch(meta().getPrimaryKeys(catalog, schema, name))
@ -231,6 +212,42 @@ class MetaImpl implements Meta {
throw new DataAccessException("Error while accessing DatabaseMetaData", e);
}
}
private final Result<Record> getColumns(String tableName) throws SQLException {
// SQLite JDBC's DatabaseMetaData.getColumns() can only return a single
// table's columns
if (columnCache == null && executor.getDialect() != SQLITE) {
columnCache = getColumns0("%").intoGroups(fieldByName(String.class, "TABLE_NAME"));
}
if (columnCache != null) {
return columnCache.get(tableName);
}
else {
return getColumns0(tableName);
}
}
private final Result<Record> getColumns0(String tableName) throws SQLException {
return executor.fetch(
meta().getColumns(null, null, tableName, "%"),
// Work around a bug in the SQL Server JDBC driver by
// coercing data types to the expected types
// The bug was reported here:
// https://connect.microsoft.com/SQLServer/feedback/details/775425/jdbc-4-0-databasemetadata-getcolumns-returns-a-resultset-whose-resultsetmetadata-is-inconsistent
String.class, // TABLE_CAT
String.class, // TABLE_SCHEM
String.class, // TABLE_NAME
String.class, // COLUMN_NAME
int.class, // DATA_TYPE
String.class, // TYPE_NAME
int.class, // COLUMN_SIZE
String.class, // BUFFER_LENGTH
int.class // DECIMAL_DIGITS
);
}
}
private class MetaTable extends TableImpl<Record> {