Description:
Using MySQL 5.7 with SQL Mode STRICT_ALL_TABLES, NO_ZERO_DATE, NO_ZERO_IN_DATE and inserting a 0-year value (e.g. 0000-01-01) into a DATE field yields this stacktrace:
java.sql.SQLException: YEAR
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:85)
at com.mysql.cj.jdbc.result.ResultSetImpl.getDate(ResultSetImpl.java:847)
at testsuite.simple.DateTest.testZeroYearBehavior(DateTest.java:189)
Caused by: com.mysql.cj.exceptions.WrongArgumentException: YEAR
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
at com.mysql.cj.result.SqlDateValueFactory.createFromDate(SqlDateValueFactory.java:108)
at com.mysql.cj.result.SqlDateValueFactory.createFromDate(SqlDateValueFactory.java:49)
at com.mysql.cj.result.BaseDecoratingValueFactory.createFromDate(BaseDecoratingValueFactory.java:53)
at com.mysql.cj.result.BaseDecoratingValueFactory.createFromDate(BaseDecoratingValueFactory.java:53)
at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeDate(MysqlTextValueDecoder.java:72)
at com.mysql.cj.protocol.result.AbstractResultsetRow.decodeAndCreateReturnValue(AbstractResultsetRow.java:90)
at com.mysql.cj.protocol.result.AbstractResultsetRow.getValueFromBytes(AbstractResultsetRow.java:250)
at com.mysql.cj.protocol.a.result.ByteArrayRow.getValue(ByteArrayRow.java:91)
at com.mysql.cj.jdbc.result.ResultSetImpl.getNonStringValueFromRow(ResultSetImpl.java:656)
at com.mysql.cj.jdbc.result.ResultSetImpl.getDateOrTimestampValueFromRow(ResultSetImpl.java:679)
Caused by: java.lang.IllegalArgumentException: YEAR
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2648)
at java.util.Calendar.updateTime(Calendar.java:3393)
at java.util.Calendar.getTimeInMillis(Calendar.java:1782)
at com.mysql.cj.result.SqlDateValueFactory.createFromDate(SqlDateValueFactory.java:103)
How to repeat:
Add this to e.g. testsuite/simple/DateTest.java:
public void testZeroYearBehavior() throws Exception {
Connection testConn = this.conn;
try {
this.stmt.executeUpdate("DROP TABLE IF EXISTS testZeroYearBehavior");
this.stmt.executeUpdate("CREATE TABLE testZeroYearBehavior(field DATE)");
this.stmt.executeUpdate("INSERT INTO testZeroYearBehavior VALUES ('0000-01-01')");
Statement stmt = testConn.createStatement();
this.rs = stmt.executeQuery("SELECT field FROM testZeroYearBehavior");
this.rs.next();
assertEquals("0000-01-01", this.rs.getDate(1).toString());
} finally {
this.stmt.executeUpdate("DROP TABLE IF EXISTS testZeroYearBehavior");
if (testConn != this.conn) {
testConn.close();
}
}
}
Suggested fix:
I tried around this, but as a non Java coder it appears to me that java.sql.Date itself doesn't support year 0 and below. I'll keep digging, but I'm happy for any hints.