Changeset: 376a15ce49e3 for monetdb-java
URL: https://dev.monetdb.org/hg/monetdb-java?cmd=changeset;node=376a15ce49e3
Modified Files:
        src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
        tests/Test_Rtimedate.java
Branch: default
Log Message:

Improve parsing negative years.
Also updated and extended test program for those cases.


diffs (truncated from 323 to 300 lines):

diff --git a/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java 
b/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetResultSet.java
@@ -2638,12 +2638,14 @@ public class MonetResultSet
                if (cal == null)
                        throw new IllegalArgumentException("No Calendar object 
given!");
 
+               final String monetDateStr;
                final String monetDate;
                final String MonetDBType;
                int JdbcType;
+               boolean negativeYear = false;
                try {
-                       monetDate = tlp.values[columnIndex - 1];
-                       if (monetDate == null) {
+                       monetDateStr = tlp.values[columnIndex - 1];
+                       if (monetDateStr == null) {
                                lastReadWasNull = true;
                                return -1;
                        }
@@ -2659,6 +2661,14 @@ public class MonetResultSet
                        {
                                JdbcType = type;
                        }
+
+                       if ((JdbcType == Types.DATE || JdbcType == 
Types.TIMESTAMP) && monetDateStr.startsWith("-")) {
+                               // the SimpleDateFormat parsers do not support 
to parse negative year numbers, deal with it separately
+                               negativeYear = true;
+                               monetDate = monetDateStr.substring(1);
+                       } else {
+                               monetDate = monetDateStr;
+                       }
                } catch (IndexOutOfBoundsException e) {
                        throw newSQLInvalidColumnIndexException(columnIndex);
                }
@@ -2702,35 +2712,47 @@ public class MonetResultSet
                                }
                                timestampFormat.setTimeZone(ptz);
                                pdate = timestampFormat.parse(monetDate, ppos);
+                               // if parsing with timestampFormat failed try 
to parse it in dateFormat
+                               if (pdate == null && monetDate.length() <= 10 
&& monetDate.contains("-")) {
+                                       if (dateFormat == null) {
+                                               // first time usage, create and 
keep the dateFormat object for next usage
+                                               dateFormat = new 
SimpleDateFormat("yyyy-MM-dd");
+                                       }
+                                       dateFormat.setTimeZone(ptz);
+                                       pdate = dateFormat.parse(monetDate, 
ppos);
+                               }
                                break;
                        default:
-                               addWarning("unsupported data type", "01M03");
-                               cal.clear();
-                               return 0;
+                               throw new SQLException("Internal error, 
unsupported data type: " + type, "01M03");
                }
                if (pdate == null) {
                        // parsing failed
+                       String errMsg;
                        int epos = ppos.getErrorIndex();
                        if (epos == -1) {
-                               addWarning("parsing '" + monetDate + "' 
failed", "01M10");
+                               errMsg = "parsing '" + monetDateStr + "' 
failed";
                        } else if (epos < monetDate.length()) {
-                               addWarning("parsing failed," +
-                                                " found: '" + 
monetDate.charAt(epos) + "'" +
-                                                " in: \"" + monetDate + "\"" +
-                                                " at pos: " + epos, "01M10");
+                               errMsg = "parsing failed," +
+                                        " found: '" + monetDate.charAt(epos) + 
"'" +
+                                        " in: \"" + monetDateStr + "\"" +
+                                        " at pos: " + (epos + (negativeYear ? 
2 : 1));
                        } else {
-                               addWarning("parsing failed, expected more data 
after '" +
-                                               monetDate + "'", "01M10");
+                               errMsg = "parsing failed, expected more data 
after '" + monetDateStr + "'";
                        }
-                       // default value
-                       cal.clear();
-                       return 0;
+                       throw new SQLException(errMsg, "01M10");
                }
+
                cal.setTime(pdate);
-
-               int nanos = 0;
+               if (negativeYear) {
+                       // System.out.println("Current cal: " + cal.toString());
+                       // using cal.set(Calendar.YEAR, 
-(cal.get(Calendar.YEAR))); does not work. We must set the ERA instead
+                       cal.set(Calendar.ERA, java.util.GregorianCalendar.BC);
+                       // System.out.println("Corrected cal: " + 
cal.toString());
+               }
+
                if (JdbcType == Types.TIME || JdbcType == Types.TIMESTAMP) {
                        // parse additional nanos (if any)
+                       int nanos = 0;
                        int pos = ppos.getIndex();
                        char[] monDate = monetDate.toCharArray();
                        if (pos < monDate.length && monDate[pos] == '.') {
@@ -2760,12 +2782,13 @@ public class MonetResultSet
                                                        " in: \"" + monetDate + 
"\"" +
                                                        " at pos: " + 
e.getErrorOffset(), "01M10");
                                        // default value
-                                       cal.clear();
                                        nanos = 0;
                                }
                        }
+                       return nanos;
                }
-               return nanos;
+
+               return 0;
        }
 
        /**
diff --git a/tests/Test_Rtimedate.java b/tests/Test_Rtimedate.java
--- a/tests/Test_Rtimedate.java
+++ b/tests/Test_Rtimedate.java
@@ -14,110 +14,67 @@ public class Test_Rtimedate {
                Connection con = DriverManager.getConnection(args[0]);
                Statement stmt = con.createStatement();
                ResultSet rs = null;
-               //DatabaseMetaData dbmd = con.getMetaData();
 
                con.setAutoCommit(false);
                // >> false: auto commit should be off now
                System.out.println("false\t" + con.getAutoCommit());
 
                try {
-                       stmt.executeUpdate("CREATE TABLE table_Test_Rtimedate ( 
id int, ts timestamp, t time, d date, vc varchar(30), PRIMARY KEY (id) )");
+                       stmt.executeUpdate("CREATE TABLE table_Test_Rtimedate ( 
id int PRIMARY KEY, ts timestamp, t time, d date, vc varchar(30) )");
 
-                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, ts) VALUES (1, timestamp '2004-04-24 11:43:53.000')");
-                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, t) VALUES (2, time '11:43:53.000')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, ts) VALUES (1, timestamp '2004-04-24 11:43:53.123')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, t) VALUES (2, time '11:43:53.123')");
                        stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, d) VALUES (3, date '2004-04-24')");
-
-                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (4, '2004-04-24 11:43:53.000000')");
+                       // same values but now as strings to test string to 
timestamp / time / date object conversions
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (4, '2004-04-24 11:43:53.654321')");
                        stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (5, '11:43:53')");
                        stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (6, '2004-04-24')");
 
+                       // test also with small years (< 1000) (see bug 6468)
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, ts) VALUES (11, timestamp '904-04-24 11:43:53.567')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, ts) VALUES (12, timestamp '74-04-24 11:43:53.567')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, ts) VALUES (13, timestamp '4-04-24 11:43:53.567')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, d) VALUES (14, date '904-04-24')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, d) VALUES (15, date '74-04-24')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, d) VALUES (16, date '4-04-24')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (17, '904-04-24 11:43:53.567')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (18, '74-04-24 11:43:53.567')");
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (19, '4-04-24 11:43:53.567')");
+
+                       // test also with negative years (see bug 6468)
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, ts) VALUES (21, timestamp '-4-04-24 11:43:53.567')");  
// negative year
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, ts) VALUES (22, timestamp '-2004-04-24 
11:43:53.567')"); // negative year
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, d) VALUES (23, date '-4-04-24')");     // negative year
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, d) VALUES (24, date '-3004-04-24')");  // negative year
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (25, '-2004-04-24 11:43:53.654321')");      
// negative year
+                       stmt.executeUpdate("INSERT INTO 
table_Test_Rtimedate(id, vc) VALUES (26, '-3004-04-24')");      // negative year
+
                        rs = stmt.executeQuery("SELECT * FROM 
table_Test_Rtimedate");
 
-                       rs.next();
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // the next three should all go well
-                       System.out.println("1. " + rs.getString("id") + ", " + 
rs.getString("ts") + ", " + rs.getTimestamp("ts"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       System.out.println("2. " + rs.getString("id") + ", " + 
rs.getString("ts") + ", " + rs.getTime("ts"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       System.out.println("3. " + rs.getString("id") + ", " + 
rs.getString("ts") + ", " + rs.getDate("ts"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       rs.next();
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // the next two should go fine
-                       System.out.println("4. " + rs.getString("id") + ", " + 
rs.getString("t") + ", " + rs.getTimestamp("t"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       System.out.println("5. " + rs.getString("id") + ", " + 
rs.getString("t") + ", " + rs.getTime("t"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // this one should return 0
-                       System.out.println("6. " + rs.getString("id") + ", " + 
rs.getString("t") + ", " + rs.getDate("t"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       rs.next();
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // the next one passes
-                       System.out.println("7. " + rs.getString("id") + ", " + 
rs.getString("d") + ", " + rs.getTimestamp("d"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // this one should return 0
-                       System.out.println("8. " + rs.getString("id") + ", " + 
rs.getString("d") + ", " + rs.getTime("d"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // and this one should pass again
-                       System.out.println("9. " + rs.getString("id") + ", " + 
rs.getString("d") + ", " + rs.getDate("d"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
+                       readNextRow(rs, 1, "ts");
+                       readNextRow(rs, 2, "t");
+                       readNextRow(rs, 3, "d");
+
+                       readNextRow(rs, 4, "vc");
+                       readNextRow(rs, 5, "vc");
+                       readNextRow(rs, 6, "vc");
 
-                       // in the tests below a bare string is parsed
-                       // everything will fail except the ones commented on
-                       rs.next();
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // timestamp -> timestamp should go
-                       System.out.println("1. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getTimestamp("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       System.out.println("2. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getTime("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // timestamp -> date goes because the begin is the same
-                       System.out.println("3. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getDate("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       rs.next();
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       System.out.println("4. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getTimestamp("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // time -> time should fit
-                       System.out.println("5. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getTime("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       System.out.println("6. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getDate("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       rs.next();
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       System.out.println("7. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getTimestamp("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       System.out.println("8. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getTime("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
-                       // date -> date should be fine
-                       System.out.println("9. " + rs.getString("id") + ", " + 
rs.getString("vc") + ", " + rs.getDate("vc"));
-                       readWarnings(rs.getWarnings());
-                       rs.clearWarnings();
+                       readNextRow(rs, 11, "ts");
+                       readNextRow(rs, 12, "ts");
+                       readNextRow(rs, 13, "ts");
+                       readNextRow(rs, 14, "d");
+                       readNextRow(rs, 15, "d");
+                       readNextRow(rs, 16, "d");
+                       readNextRow(rs, 17, "vc");
+                       readNextRow(rs, 18, "vc");
+                       readNextRow(rs, 19, "vc");
+
+                       readNextRow(rs, 21, "ts");
+                       readNextRow(rs, 22, "ts");
+                       readNextRow(rs, 23, "d");
+                       readNextRow(rs, 24, "d");
+                       readNextRow(rs, 25, "vc");
+                       readNextRow(rs, 26, "vc");
 
                        readWarnings(stmt.getWarnings());
                        readWarnings(con.getWarnings());
@@ -130,9 +87,46 @@ public class Test_Rtimedate {
                con.close();
        }
 
+       private static void readNextRow(ResultSet rs, int rowseq, String colnm) 
throws SQLException {
+               rs.next();
+               readWarnings(rs.getWarnings());
+               rs.clearWarnings();
+
+               // fetch the column value using multiple methods: getString(), 
getTimestamp(), getTime() and getDate()
+               // to test proper conversion and error reporting
+               String data = rs.getString("id") + ". " + colnm + " " + 
rs.getString(colnm) + " to ";
+
+               // getTimestamp() may raise a conversion warning when the value 
is of type Time or a String which doesn't match format yyyy-mm-dd hh:mm:ss
+               try {
+                       System.out.println(data + "ts: " + 
rs.getTimestamp(colnm));
+               } catch (SQLException e) {
+                       System.out.println("rs.getTimestamp(colnm) failed with 
error: " + e.getMessage());
+               }
+               readWarnings(rs.getWarnings());
+               rs.clearWarnings();
+
+               // getTime() may raise a conversion warning when the value is 
of type Date or a String which doesn't match format hh:mm:ss
+               try {
+                       System.out.println(data + "tm: " + rs.getTime(colnm));
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to