Github user ijokarumawak commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/1983#discussion_r127387210
  
    --- Diff: 
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/PutSQL.java
 ---
    @@ -828,10 +835,46 @@ private void setParameter(final PreparedStatement 
stmt, final String attrName, f
                         stmt.setBigDecimal(parameterIndex, new 
BigDecimal(parameterValue));
                         break;
                     case Types.DATE:
    -                    stmt.setDate(parameterIndex, new 
Date(Long.parseLong(parameterValue)));
    +                    Date date;
    +
    +                    if (valueFormat.equals("")) {
    +                        if 
(LONG_PATTERN.matcher(parameterValue).matches()) {
    +                            date = new 
Date(Long.parseLong(parameterValue));
    +                        } else {
    +                            String dateFormatString = "yyyy-MM-dd";
    +
    +                            SimpleDateFormat dateFormat = new 
SimpleDateFormat(dateFormatString);
    +                            java.util.Date parsedDate = 
dateFormat.parse(parameterValue);
    +                            date = new Date(parsedDate.getTime());
    +                        }
    +                    } else {
    +                        final DateTimeFormatter dtFormatter = 
getDateTimeFormatter(valueFormat);
    +                        LocalDate parsedDate = 
LocalDate.parse(parameterValue, dtFormatter);
    +                        date = new 
Date(Date.from(parsedDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()).getTime());
    +                    }
    +
    +                    stmt.setDate(parameterIndex, date);
                         break;
                     case Types.TIME:
    -                    stmt.setTime(parameterIndex, new 
Time(Long.parseLong(parameterValue)));
    +                    Time time;
    +
    +                    if (valueFormat.equals("")) {
    +                        if 
(LONG_PATTERN.matcher(parameterValue).matches()) {
    +                            time = new 
Time(Long.parseLong(parameterValue));
    +                        } else {
    +                            String timeFormatString = "HH:mm:ss.SSS";
    +
    +                            SimpleDateFormat dateFormat = new 
SimpleDateFormat(timeFormatString);
    +                            java.util.Date parsedDate = 
dateFormat.parse(parameterValue);
    +                            time = new Time(parsedDate.getTime());
    +                        }
    +                    } else {
    +                        final DateTimeFormatter dtFormatter = 
getDateTimeFormatter(valueFormat);
    +                        LocalTime parsedTime = 
LocalTime.parse(parameterValue, dtFormatter);
    +                        time = Time.valueOf(parsedTime);
    --- End diff --
    
    Some databases support fractional seconds (milli or microseconds). By 
creating java.sql.Time instance from LocalTime, even if the LocalTime has 
fractional seconds, it will be truncated because Time.valueOf only uses hours, 
minutes and seconds as follows:
    
    ```java
    java.sql.Time
        public static Time valueOf(LocalTime time) {
            return new Time(time.getHour(), time.getMinute(), time.getSecond());
        }
    ```
    
    Can we have this like this instead? This way, we can preserve time 
precision at milliseconds if the database driver and database server supports 
it:
    
    ```java
    final DateTimeFormatter dtFormatter = getDateTimeFormatter(valueFormat);
    LocalTime parsedTime = LocalTime.parse(parameterValue, dtFormatter);
    LocalDateTime localDateTime = parsedTime.atDate(LocalDate.ofEpochDay(0));
    Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    time = new Time(instant.toEpochMilli());
    ```
    
    I confirmed this behavior with MySQL and PostgreSQL. With PostgreSQL, 
before changing this, when I passed "18:25:43.511" JSON value with 
ISO_LOCAL_TIME format, it's stored without milliseconds, "18:25:43". With above 
change, using new Time(Long) constructor, I was able to preserve milliseconds 
"18:25:43.511".
    
    Unfortunately MySQL JDBC Driver has a known issue that it truncates 
milliseconds [76775](https://bugs.mysql.com/bug.php?id=76775), so we can't 
store millisecond with MySQL currently (TIMESTAMP works though).


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

Reply via email to