This is an automated email from the ASF dual-hosted git repository. doebele pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/empire-db.git
The following commit(s) were added to refs/heads/master by this push: new ca5ffbc8 EMPIREDB-470 Use DateTimeFormatter instead of SimpleDateFormat new 4bc57ce7 Merge branch 'master' of https://gitbox.apache.org/repos/asf/empire-db ca5ffbc8 is described below commit ca5ffbc81995e0304b90f90dcaa40f3686743c24 Author: Rainer Döbele <doeb...@apache.org> AuthorDate: Thu Jul 10 16:41:09 2025 +0200 EMPIREDB-470 Use DateTimeFormatter instead of SimpleDateFormat --- .../org/apache/empire/commons/StringUtils.java | 10 ++++++- .../java/org/apache/empire/db/DBSQLBuilder.java | 32 ++++++++++++---------- .../java/org/apache/empire/dbms/DBSqlPhrase.java | 10 ++++--- .../apache/empire/dbms/derby/DBMSHandlerDerby.java | 6 ++-- .../org/apache/empire/dbms/h2/DBMSHandlerH2.java | 4 --- .../apache/empire/dbms/hsql/DBMSHandlerHSql.java | 4 --- .../apache/empire/dbms/mysql/DBMSHandlerMySQL.java | 4 --- .../empire/dbms/oracle/DBMSHandlerOracle.java | 4 --- .../dbms/postgresql/DBMSHandlerPostgreSQL.java | 4 --- .../empire/dbms/sqlite/DBMSHandlerSQLite.java | 4 --- .../empire/dbms/sqlserver/DBMSHandlerMSSQL.java | 4 --- 11 files changed, 35 insertions(+), 51 deletions(-) diff --git a/empire-db/src/main/java/org/apache/empire/commons/StringUtils.java b/empire-db/src/main/java/org/apache/empire/commons/StringUtils.java index 972f90f0..3abdeec3 100644 --- a/empire-db/src/main/java/org/apache/empire/commons/StringUtils.java +++ b/empire-db/src/main/java/org/apache/empire/commons/StringUtils.java @@ -640,9 +640,17 @@ public class StringUtils public static String concat(String... parts) { int totalLength=0; + int singleIndex=-1; for (int i=0; i<parts.length; i++) - if (parts[i]!=null) + if (parts[i]!=null && parts[i].length()>0) { totalLength+=parts[i].length(); + singleIndex=(singleIndex==-1 ? i : -2); + } + // optimize + if (totalLength==0) + return EMPTY; + if (singleIndex>=0) + return parts[singleIndex]; // concat now StringBuilder b = new StringBuilder(totalLength); for (int i=0; i<parts.length; i++) diff --git a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java index 192fe1e8..61f4b5bb 100644 --- a/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java +++ b/empire-db/src/main/java/org/apache/empire/db/DBSQLBuilder.java @@ -19,13 +19,14 @@ package org.apache.empire.db; import java.sql.Timestamp; -import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.Collection; import java.util.Date; +import org.apache.empire.commons.DateUtils; import org.apache.empire.commons.ObjectUtils; import org.apache.empire.commons.StringUtils; import org.apache.empire.data.DataType; @@ -363,33 +364,35 @@ public abstract class DBSQLBuilder implements Appendable if (DBDatabase.SYSDATE.equals(value)) return dbms.getSQLPhrase(sqlCurrentDate); // Format the date (ymd) - Timestamp ts; + LocalDateTime ts; + int nanos = 0; if ((value instanceof Timestamp)) - { // We have a timestamp - ts = (Timestamp)value; + { // Convert Timestamp + ts = ((Timestamp)value).toLocalDateTime(); + nanos = (((Timestamp)value).getNanos() % 1000000); } else if ((value instanceof Date)) - { // Convert Date to Timestamp - ts = new Timestamp(((Date)value).getTime()); + { // Convert Date + ts = DateUtils.toLocalDateTime((Date)value); } else if ((value instanceof LocalDate)) - { // Convert LocalDate to Timestamp - ts = java.sql.Timestamp.valueOf(((LocalDate)value).atStartOfDay()); + { // Convert LocalDate + ts = ((LocalDate)value).atStartOfDay(); } else if ((value instanceof LocalDateTime)) { // Convert LocalDateTime to Timestamp - ts = java.sql.Timestamp.valueOf((LocalDateTime)value); + ts = ((LocalDateTime)value); } else if ((value instanceof LocalTime)) { // Convert LocalTime to Timestamp with current date - ts = java.sql.Timestamp.valueOf(((LocalTime)value).atDate(LocalDate.now())); + ts = ((LocalTime)value).atDate(LocalDate.now()); } else { // "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]" String dtValue = value.toString().trim(); try { // parse timestamp - ts = Timestamp.valueOf(dtValue); + ts = Timestamp.valueOf(dtValue).toLocalDateTime(); } catch (Throwable e) { // Invalid date log.error("Unable to parse date value "+dtValue, e); @@ -398,16 +401,17 @@ public abstract class DBSQLBuilder implements Appendable } // Convert to String String pattern = dbms.getSQLPhrase(sqlPattern); - SimpleDateFormat sqlFormat = new SimpleDateFormat(dbms.getSQLPhrase(sqlPattern)); + DateTimeFormatter sqlFormat = DateTimeFormatter.ofPattern(pattern); String datetime = sqlFormat.format(ts); // Add micro / nanoseconds - int nanos = (ts.getNanos() % 1000000); if (pattern.endsWith(".SSS") && nanos>0) { // Add nanoseconds if (((nanos) % 100)>0) datetime += String.format("%06d", nanos); - else + else if (((nanos) % 1000)>0) datetime += String.format("%04d",(nanos/100)); + else + datetime += String.format("%03d",(nanos/1000)); } // Now Build String String template = dbms.getSQLPhrase(sqlTemplate); diff --git a/empire-db/src/main/java/org/apache/empire/dbms/DBSqlPhrase.java b/empire-db/src/main/java/org/apache/empire/dbms/DBSqlPhrase.java index 879e7fe9..8efc281f 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/DBSqlPhrase.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/DBSqlPhrase.java @@ -42,17 +42,19 @@ public enum DBSqlPhrase SQL_BOOLEAN_TRUE ("1"), // Oracle Y SQL_BOOLEAN_FALSE ("0"), // Oracle N SQL_CURRENT_DATE ("CURRENT_DATE"), - SQL_DATE_PATTERN ("yyyy-MM-dd"), // SimpleDateFormat SQL_DATE_TEMPLATE ("TO_DATE('{0}', 'YYYY-MM-DD')"), // MSSql: convert(date, '{0}', 111) SQL_CURRENT_TIME ("CURRENT_TIME"), // MSSql: CONVERT(time, getdate()); - SQL_TIME_PATTERN ("HH:mm:ss"), // SimpleDateFormat SQL_TIME_TEMPLATE ("'{0}'"), // MSSql: convert(time, '{0}') - SQL_DATETIME_PATTERN ("yyyy-MM-dd HH:mm:ss.SSS"), // SimpleDateFormat SQL_DATETIME_TEMPLATE ("TO_DATE('{0}', 'YYYY-MM-DD HH24:MI:SS')"), // Oracle SQL_CURRENT_TIMESTAMP ("systimestamp"), // Oracle - SQL_TIMESTAMP_PATTERN ("yyyy-MM-dd HH:mm:ss.SSS"), // SimpleDateFormat SQL_TIMESTAMP_TEMPLATE ("TO_TIMESTAMP('{0}', 'YYYY.MM.DD HH24:MI:SS.FF')"), // Oracle + // DateTimeFormatter patterns + SQL_DATE_PATTERN ("yyyy-MM-dd"), + SQL_TIME_PATTERN ("HH:mm:ss"), + SQL_DATETIME_PATTERN ("yyyy-MM-dd HH:mm:ss"), + SQL_TIMESTAMP_PATTERN ("yyyy-MM-dd HH:mm:ss.SSS"), // or "yyyy-MM-dd HH:mm:ss.SSS " in order to limit to 3 fractions + // functions SQL_FUNC_COALESCE ("coalesce(?, {0})"), // Oracle: nvl(?, {0}) SQL_FUNC_SUBSTRING ("substring(?, {0:INTEGER})"), diff --git a/empire-db/src/main/java/org/apache/empire/dbms/derby/DBMSHandlerDerby.java b/empire-db/src/main/java/org/apache/empire/dbms/derby/DBMSHandlerDerby.java index 5d91d41a..43d3d881 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/derby/DBMSHandlerDerby.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/derby/DBMSHandlerDerby.java @@ -167,16 +167,14 @@ public class DBMSHandlerDerby extends DBMSHandlerBase case SQL_BOOLEAN_TRUE: return "1"; case SQL_BOOLEAN_FALSE: return "0"; case SQL_CURRENT_DATE: return "CURRENT_DATE"; - case SQL_DATE_PATTERN: return "yyyy-MM-dd"; case SQL_DATE_TEMPLATE: return "'{0}'"; case SQL_CURRENT_TIME: return "CURRENT_TIME"; - case SQL_TIME_PATTERN: return "HH:mm:ss"; case SQL_TIME_TEMPLATE: return "'{0}'"; - case SQL_DATETIME_PATTERN: return "yyyy-MM-dd HH:mm:ss"; case SQL_DATETIME_TEMPLATE: return "'{0}'"; case SQL_CURRENT_TIMESTAMP: return "CURRENT_TIMESTAMP"; - case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd HH:mm:ss"; case SQL_TIMESTAMP_TEMPLATE: return "'{0}'"; + // DateTimeFormatter + case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd HH:mm:ss.SSS "; // limit to 3 fractions // functions case SQL_FUNC_COALESCE: return "coalesce(?, {0})"; case SQL_FUNC_SUBSTRING: return "substr(?, {0})"; diff --git a/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java b/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java index 9abafc99..fe20168d 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java @@ -242,15 +242,11 @@ public class DBMSHandlerH2 extends DBMSHandlerBase case SQL_BOOLEAN_TRUE: return "1"; case SQL_BOOLEAN_FALSE: return "0"; case SQL_CURRENT_DATE: return "CURRENT_DATE"; - case SQL_DATE_PATTERN: return "yyyy-MM-dd"; case SQL_DATE_TEMPLATE: return "'{0}'"; case SQL_CURRENT_TIME: return "CURRENT_TIME"; - case SQL_TIME_PATTERN: return "HH:mm:ss"; case SQL_TIME_TEMPLATE: return "'{0}'"; - case SQL_DATETIME_PATTERN: return "yyyy-MM-dd HH:mm:ss"; case SQL_DATETIME_TEMPLATE: return "'{0}'"; case SQL_CURRENT_TIMESTAMP: return "NOW()"; - case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd HH:mm:ss"; case SQL_TIMESTAMP_TEMPLATE: return "'{0}'"; // functions case SQL_FUNC_COALESCE: return "coalesce(?, {0})"; diff --git a/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java b/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java index fd3abcc8..3a7fdd15 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/hsql/DBMSHandlerHSql.java @@ -120,15 +120,11 @@ public class DBMSHandlerHSql extends DBMSHandlerBase case SQL_BOOLEAN_TRUE: return String.valueOf(Boolean.TRUE); case SQL_BOOLEAN_FALSE: return String.valueOf(Boolean.FALSE); case SQL_CURRENT_DATE: return "CURRENT_DATE"; - case SQL_DATE_PATTERN: return "yyyy-MM-dd"; case SQL_DATE_TEMPLATE: return "TO_DATE('{0}', 'YYYY-MM-DD')"; case SQL_CURRENT_TIME: return "CURRENT_TIME"; - case SQL_TIME_PATTERN: return "HH:mm:ss"; case SQL_TIME_TEMPLATE: return "'{0}'"; - case SQL_DATETIME_PATTERN: return "yyyy-MM-dd HH:mm:ss.S"; case SQL_DATETIME_TEMPLATE: return "TO_DATE('{0}', 'YYYY-MM-DD HH24:MI:SS')"; case SQL_CURRENT_TIMESTAMP: return "CURRENT_TIMESTAMP"; - case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd HH:mm:ss.S"; case SQL_TIMESTAMP_TEMPLATE:return "TO_TIMESTAMP('{0}', 'YYYY-MM-DD HH24:MI:SS.FF')"; // functions case SQL_FUNC_COALESCE: return "coalesce(?, {0})"; diff --git a/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java b/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java index 382bc8ba..a9a92f5a 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java @@ -452,15 +452,11 @@ public class DBMSHandlerMySQL extends DBMSHandlerBase case SQL_BOOLEAN_TRUE: return "1"; case SQL_BOOLEAN_FALSE: return "0"; case SQL_CURRENT_DATE: return "CURRENT_DATE()"; - case SQL_DATE_PATTERN: return "yyyy-MM-dd"; case SQL_DATE_TEMPLATE: return "STR_TO_DATE('{0}','%Y-%m-%d')"; case SQL_CURRENT_TIME: return "CURRENT_TIME()"; - case SQL_TIME_PATTERN: return "HH:mm:ss"; case SQL_TIME_TEMPLATE: return "STR_TO_DATE('{0}','%H:%i:%s')"; - case SQL_DATETIME_PATTERN: return "yyyy-MM-dd HH:mm:ss"; case SQL_DATETIME_TEMPLATE: return "STR_TO_DATE('{0}','%Y-%m-%d %H:%i:%s')"; case SQL_CURRENT_TIMESTAMP: return "CURRENT_TIMESTAMP()"; - case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd HH:mm:ss.SSS"; case SQL_TIMESTAMP_TEMPLATE: return "STR_TO_DATE('{0}','%Y-%m-%d %H:%i:%s.%f')"; // functions case SQL_FUNC_COALESCE: return "coalesce(?, {0})"; diff --git a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java index 459824fc..56a6a533 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java @@ -186,15 +186,11 @@ public class DBMSHandlerOracle extends DBMSHandlerBase case SQL_BOOLEAN_TRUE: return (booleanType==BooleanType.CHAR) ? "'Y'" : "1"; case SQL_BOOLEAN_FALSE: return (booleanType==BooleanType.CHAR) ? "'N'" : "0"; case SQL_CURRENT_DATE: return "sysdate"; - case SQL_DATE_PATTERN: return "YYYY-MM-DD"; case SQL_DATE_TEMPLATE: return "TO_DATE('{0}', 'YYYY-MM-DD')"; - case SQL_DATETIME_PATTERN: return "YYYY-MM-DD HH24:MI:SS"; case SQL_DATETIME_TEMPLATE: return "TO_DATE('{0}', 'YYYY-MM-DD HH24:MI:SS')"; case SQL_CURRENT_TIME: return "TO_DATE('2000-01-01'||TO_CHAR(sysdate, 'HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')"; - case SQL_TIME_PATTERN: return "HH24:MI:SS"; case SQL_TIME_TEMPLATE: return "TO_DATE('2000-01-01 {0}'), 'YYYY-MM-DD HH24:MI:SS')"; case SQL_CURRENT_TIMESTAMP: return "systimestamp"; - case SQL_TIMESTAMP_PATTERN: return "YYYY-MM-DD HH24:MI:SS.FF"; case SQL_TIMESTAMP_TEMPLATE: return "TO_TIMESTAMP('{0}', 'YYYY-MM-DD HH24:MI:SS.FF')"; // functions case SQL_FUNC_COALESCE: return "nvl(?, {0})"; diff --git a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java index f561cf44..ab6e1e6e 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java @@ -189,15 +189,11 @@ public class DBMSHandlerPostgreSQL extends DBMSHandlerBase case SQL_BOOLEAN_TRUE: return "TRUE"; case SQL_BOOLEAN_FALSE: return "FALSE"; case SQL_CURRENT_DATE: return "CURRENT_DATE"; - case SQL_DATE_PATTERN: return "yyyy-MM-dd"; case SQL_DATE_TEMPLATE: return "'{0}'"; case SQL_CURRENT_TIME: return "CURRENT_TIME"; - case SQL_TIME_PATTERN: return "HH:mm:ss"; case SQL_TIME_TEMPLATE: return "'{0}'"; - case SQL_DATETIME_PATTERN: return "yyyy-MM-dd HH:mm:ss.SSS"; case SQL_DATETIME_TEMPLATE: return "'{0}'"; case SQL_CURRENT_TIMESTAMP: return "NOW()"; - case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd HH:mm:ss.SSS"; case SQL_TIMESTAMP_TEMPLATE: return "'{0}'"; // functions case SQL_FUNC_COALESCE: return "coalesce(?, {0})"; diff --git a/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java b/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java index 0772aa57..c2c272ef 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java @@ -191,14 +191,10 @@ public class DBMSHandlerSQLite extends DBMSHandlerBase case SQL_BOOLEAN_TRUE: return "1"; case SQL_BOOLEAN_FALSE: return "0"; case SQL_CURRENT_DATE: return "date('now','localtime');"; - case SQL_DATE_PATTERN: return "yyyy-MM-dd"; case SQL_DATE_TEMPLATE: return "date('{0}')"; case SQL_CURRENT_TIME: return "time('now');"; - case SQL_TIME_TEMPLATE: return "time('{0}')"; - case SQL_DATETIME_PATTERN: return "yyyy-MM-dd hh:mm:ss.sss"; case SQL_DATETIME_TEMPLATE: return "'{0}'"; case SQL_CURRENT_TIMESTAMP: return "NOW()"; - case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd hh:mm:ss.sss"; case SQL_TIMESTAMP_TEMPLATE: return "'{0}'"; // functions case SQL_FUNC_COALESCE: return "coalesce(?, {0})"; diff --git a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java index 2c0bcd11..bc835ddf 100644 --- a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java +++ b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java @@ -395,16 +395,12 @@ public class DBMSHandlerMSSQL extends DBMSHandlerBase case SQL_BOOLEAN_TRUE: return "1"; case SQL_BOOLEAN_FALSE: return "0"; case SQL_CURRENT_DATE: return "convert(char, getdate(), 111)"; - case SQL_DATE_PATTERN: return "yyyy-MM-dd"; case SQL_DATE_TEMPLATE: return "convert(date, '{0}', 111)"; case SQL_CURRENT_TIME: return "convert(time, getdate())"; - case SQL_TIME_PATTERN: return "HH:mm:ss"; case SQL_TIME_TEMPLATE: return "convert(time, '{0}')"; - case SQL_DATETIME_PATTERN: return "yyyy-MM-dd HH:mm:ss.SSS"; case SQL_DATETIME_TEMPLATE: return isUseDateTime2() ? "convert(datetime2, '{0}', 121)" : "convert(datetime, '{0}', 121)"; case SQL_CURRENT_TIMESTAMP: return "getdate()"; - case SQL_TIMESTAMP_PATTERN: return "yyyy-MM-dd HH:mm:ss.SSS"; case SQL_TIMESTAMP_TEMPLATE: return isUseDateTime2() ? "convert(datetime2, '{0}', 121)" : "convert(datetime, '{0}', 121)"; // functions