Repository: h2database/h2database

Issue #1383: 'Unknown data type' error performing date arithmetic with parameter
Created: 2018-08-17T11:08:04Z
(From https://stackoverflow.com/questions/51892300)
The following class
import java.sql.*;

public class H2Test {
    public static void main(String[] args) throws Exception {
        Connection conn = DriverManager.getConnection("jdbc:h2:./test.db;MODE=ORACLE");
        PreparedStatement ps = conn.prepareStatement("SELECT SYSDATE - ?");
    }
}

throws the following exception when run:
Exception in thread "main" org.h2.jdbc.JdbcSQLException: Unknown data type: "?"; SQL statement:
SELECT SYSDATE - ? [50004-197]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
        at org.h2.message.DbException.get(DbException.java:179)
        at org.h2.message.DbException.get(DbException.java:155)
        at org.h2.value.DataType.getDataType(DataType.java:827)
        at org.h2.expression.Operation.optimize(Operation.java:312)
        at org.h2.command.dml.Select.prepare(Select.java:858)
        at org.h2.command.Parser.prepareCommand(Parser.java:283)
        at org.h2.engine.Session.prepareLocal(Session.java:611)
        at org.h2.engine.Session.prepareCommand(Session.java:549)
        at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1247)
        at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:76)
        at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:304)
        at H2Test.main(H2Test.java:6)

There is no exception if you replace the parameter ? with a hard-coded integer.
Incidentally (and this may be a separate issue already reported elsewhere), changing the compatibility mode in the connection string to an unrecognised value (e.g. UNKNOWN) changes the exception to the following:
Exception in thread "main" org.h2.jdbc.JdbcSQLException: General error: "java.lang.NullPointerException" [50000-197]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
        at org.h2.message.DbException.get(DbException.java:168)
        at org.h2.message.DbException.convert(DbException.java:307)
        at org.h2.engine.Database.openDatabase(Database.java:319)
        at org.h2.engine.Database.<init>(Database.java:280)
        at org.h2.engine.Engine.openSession(Engine.java:66)
        at org.h2.engine.Engine.openSession(Engine.java:179)
        at org.h2.engine.Engine.createSessionAndValidate(Engine.java:157)
        at org.h2.engine.Engine.createSession(Engine.java:140)
        at org.h2.engine.Engine.createSession(Engine.java:28)
        at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:351)
        at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:124)
        at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:103)
        at org.h2.Driver.connect(Driver.java:69)
        at java.sql/java.sql.DriverManager.getConnection(Unknown Source)
        at java.sql/java.sql.DriverManager.getConnection(Unknown Source)
        at H2Test.main(H2Test.java:5)
Caused by: java.lang.NullPointerException
        at org.h2.command.Parser.read(Parser.java:3731)
        at org.h2.command.Parser.readIf(Parser.java:3525)
        at org.h2.command.Parser.parseCreateUser(Parser.java:5077)
        at org.h2.command.Parser.parseCreate(Parser.java:4564)
        at org.h2.command.Parser.parsePrepared(Parser.java:380)
        at org.h2.command.Parser.parse(Parser.java:335)
        at org.h2.command.Parser.parse(Parser.java:307)
        at org.h2.command.Parser.prepare(Parser.java:262)
        at org.h2.engine.Session.prepare(Session.java:576)
        at org.h2.engine.Session.prepare(Session.java:560)
        at org.h2.engine.MetaRecord.execute(MetaRecord.java:56)
        at org.h2.engine.Database.open(Database.java:775)
        at org.h2.engine.Database.openDatabase(Database.java:286)
        ... 13 more

Duplicate issue #3924: Oracle mode sysdate operation with minus and binding parameter ended up with ERROR
Created: 2023-11-15T14:12:30Z
I am using R2DBC and tried to have a native query using databaseClient. In the query I have something like:
databaseClient.sql("SELECT count(*)" +
            " FROM MY_TABLE" +
            " WHERE COLUMNS_OF_TYPE_TIMESTAMP_ZT BETWEEN (sysdate - :noOfDays) AND sysdate")
    .bind("noOfDays", noOfDays)
    .map(row -> row.get(0, Long.class))
    .one()
It is failing with this error:
Caused by: org.h2.jdbc.JdbcSQLFeatureNotSupportedException: Feature not supported: "TIMESTAMP - UNKNOWN"; SQL statement:
while using the same query and not binding value as the following works:
databaseClient.sql("SELECT count(*)" +
            " FROM MY_TABLE" +
            " WHERE COLUMNS_OF_TYPE_TIMESTAMP_ZT BETWEEN (sysdate - " + noOfDays +") AND sysdate")
    .bind("noOfDays", noOfDays)
    .map(row -> row.get(0, Long.class))
    .one()

Closing comment (2023-11-15T14:57:27Z): Duplicate of #1383.
H2 compiles queries immediately for performance reasons, so it needs to know exact data types of parameters in some cases. You can add use explicit casts around your parameters (CAST(:noOfDays AS BIGINT) etc.) as a workaround.