[#2108] SQLite returns NULL for val(new Date(0)).add(-1) and some other
date time arithmetic expressions
This commit is contained in:
parent
0fb2d950aa
commit
6fefe2afe3
@ -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
|
||||
|
||||
@ -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> {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user