22
33import com .databend .client .QueryResults ;
44import com .databend .client .QueryRowField ;
5- import com .databend .client .data .ColumnTypeHandler ;
6- import com .databend .client .data .ColumnTypeHandlerFactory ;
7- import com .databend .client .data .DatabendRawType ;
85import com .databend .client .errors .QueryErrors ;
96import com .databend .jdbc .annotation .NotImplemented ;
107import com .databend .jdbc .exception .DatabendUnsupportedOperationException ;
118import com .databend .jdbc .exception .DatabendWithQueryIdSqlException ;
129import com .google .common .collect .ImmutableList ;
1310import com .google .common .collect .ImmutableMap ;
1411import com .google .common .collect .Maps ;
15- import org .joda .time .DateTimeZone ;
16- import org .joda .time .LocalDate ;
17- import org .joda .time .format .DateTimeFormatter ;
18- import org .joda .time .format .ISODateTimeFormat ;
1912
2013import java .io .ByteArrayInputStream ;
2114import java .io .InputStream ;
4134import java .sql .Statement ;
4235import java .sql .Time ;
4336import java .sql .Timestamp ;
37+ import java .time .LocalDate ;
4438import java .time .LocalDateTime ;
4539import java .time .ZoneId ;
4640import java .time .ZoneOffset ;
4741import java .time .ZonedDateTime ;
48- import java .util .*;
42+ import java .time .format .DateTimeFormatter ;
43+ import java .util .Calendar ;
44+ import java .util .GregorianCalendar ;
45+ import java .util .Iterator ;
46+ import java .util .List ;
47+ import java .util .Map ;
48+ import java .util .Objects ;
49+ import java .util .Optional ;
50+ import java .util .TimeZone ;
4951import java .util .concurrent .atomic .AtomicBoolean ;
5052import java .util .concurrent .atomic .AtomicLong ;
5153import java .util .concurrent .atomic .AtomicReference ;
5860import static java .lang .String .format ;
5961import static java .util .Locale .ENGLISH ;
6062import static java .util .Objects .requireNonNull ;
61- import static org .joda .time .DateTimeConstants .SECONDS_PER_DAY ;
6263
6364abstract class AbstractDatabendResultSet implements ResultSet {
6465 protected AtomicLong lastRequestTime = new AtomicLong ();
6566
66- static final DateTimeFormatter DATE_FORMATTER = ISODateTimeFormat . date () ;
67+ static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter . ISO_LOCAL_DATE ;
6768 private static final int MAX_DATETIME_PRECISION = 12 ;
69+ private static final long SECONDS_PER_DAY = 86_400L ;
6870 private static final long [] POWERS_OF_TEN = {
6971 1L ,
7072 10L ,
@@ -99,7 +101,7 @@ abstract class AbstractDatabendResultSet implements ResultSet {
99101 private final Map <String , Integer > fieldMap ;
100102 private final List <DatabendColumnInfo > databendColumnInfoList ;
101103 private final ResultSetMetaData resultSetMetaData ;
102- private final DateTimeZone resultTimeZone ;
104+ private final ZoneId resultTimeZone ;
103105 private final boolean isResultTimeZoneFromServer ;
104106
105107 private final String queryId ;
@@ -110,12 +112,12 @@ abstract class AbstractDatabendResultSet implements ResultSet {
110112 this .databendColumnInfoList = getColumnInfo (schema );
111113 this .results = requireNonNull (results , "results is null" );
112114 this .resultSetMetaData = new DatabendResultSetMetaData (databendColumnInfoList );
113- DateTimeZone timeZone = DateTimeZone . forTimeZone ( TimeZone .getDefault ());
115+ ZoneId timeZone = TimeZone .getDefault (). toZoneId ( );
114116 boolean timeZoneFromServer = false ;
115117 if (resultSetting != null ) {
116118 String tz = resultSetting .get ("timezone" );
117119 if (tz != null ) {
118- timeZone = DateTimeZone . forID (tz );
120+ timeZone = ZoneId . of (tz );
119121 timeZoneFromServer = true ;
120122 }
121123 }
@@ -176,27 +178,11 @@ static SQLException resultsException(QueryResults results, String originalSQL) {
176178 return new SQLException (message , String .valueOf (error .getCode ()));
177179 }
178180
179- private static Date parseDate (String value , DateTimeZone localTimeZone ) {
180- if (localTimeZone == null ) {
181- return java .sql .Date .valueOf (value );
182- }
183- long millis = DATE_FORMATTER .withZone (localTimeZone ).parseMillis (String .valueOf (value ));
184- if (millis >= START_OF_MODERN_ERA_SECONDS * MILLISECONDS_PER_SECOND ) {
185- return new Date (millis );
186- }
187-
188- // The chronology used by default by Joda is not historically accurate for dates
189- // preceding the introduction of the Gregorian calendar and is not consistent with
190- // java.sql.Date (the same millisecond value represents a different year/month/day)
191- // before the 20th century. For such dates we are falling back to using the more
192- // expensive GregorianCalendar; note that Joda also has a chronology that works for
193- // older dates, but it uses a slightly different algorithm and yields results that
194- // are not compatible with java.sql.Date.
195- LocalDate localDate = DATE_FORMATTER .parseLocalDate (String .valueOf (value ));
196- Calendar calendar = new GregorianCalendar (localDate .getYear (), localDate .getMonthOfYear () - 1 , localDate .getDayOfMonth ());
197- calendar .setTimeZone (TimeZone .getTimeZone (ZoneId .of (localTimeZone .getID ())));
198-
199- return new Date (calendar .getTimeInMillis ());
181+ private static Date parseDate (String value , ZoneId localTimeZone ) {
182+ LocalDate localDate = LocalDate .parse (String .valueOf (value ), DATE_FORMATTER );
183+ ZoneId zone = localTimeZone == null ? ZoneId .systemDefault () : localTimeZone ;
184+ long millis = localDate .atStartOfDay (zone ).toInstant ().toEpochMilli ();
185+ return new Date (millis );
200186 }
201187
202188 private static long rescale (long value , int fromPrecision , int toPrecision ) {
@@ -565,10 +551,10 @@ public byte[] getBytes(int columnIndex)
565551 @ Override
566552 public Date getDate (int columnIndex )
567553 throws SQLException {
568- return getDate (columnIndex , (DateTimeZone ) null );
554+ return getDate (columnIndex , (ZoneId ) null );
569555 }
570556
571- private Date getDate (int columnIndex , DateTimeZone userTimeZone )
557+ private Date getDate (int columnIndex , ZoneId userTimeZone )
572558 throws SQLException {
573559 Object value = column (columnIndex );
574560 if (value == null ) {
@@ -588,15 +574,15 @@ public Time getTime(int columnIndex)
588574 return getTime (columnIndex , resultTimeZone );
589575 }
590576
591- private Time getTime (int columnIndex , DateTimeZone localTimeZone )
577+ private Time getTime (int columnIndex , ZoneId localTimeZone )
592578 throws SQLException {
593579 Object value = column (columnIndex );
594580 if (value == null ) {
595581 return null ;
596582 }
597583
598584 try {
599- return parseTime ((String ) value , ZoneId . of ( localTimeZone . getID ()) );
585+ return parseTime ((String ) value , localTimeZone );
600586 } catch (IllegalArgumentException e ) {
601587 throw new SQLException ("Invalid time from server: " + value , e );
602588 }
@@ -608,19 +594,16 @@ public Timestamp getTimestamp(int columnIndex)
608594 return getTimestamp (columnIndex , resultTimeZone );
609595 }
610596
611- private Timestamp getTimestamp (int columnIndex , DateTimeZone localTimeZone )
597+ private Timestamp getTimestamp (int columnIndex , ZoneId localTimeZone )
612598 throws SQLException {
613599 Object value = column (columnIndex );
614600
615601 if (value == null || "null" .equalsIgnoreCase (value .toString ())) {
616602 return null ;
617603 }
618604
619- if (localTimeZone == null || localTimeZone .getID () == null ) {
620- return parseTimestampAsSqlTimestamp ((String ) value , ZoneId .systemDefault ());
621- }
622-
623- return parseTimestampAsSqlTimestamp ((String ) value , ZoneId .of (localTimeZone .getID ()));
605+ ZoneId zone = localTimeZone == null ? ZoneId .systemDefault () : localTimeZone ;
606+ return parseTimestampAsSqlTimestamp ((String ) value , zone );
624607 }
625608
626609 @ Override
@@ -1309,6 +1292,7 @@ public Statement getStatement()
13091292 throw new SQLException ("Statement not available" );
13101293 }
13111294
1295+ // it’s legacy, rarely supported
13121296 @ Override
13131297 public Object getObject (int columnIndex , Map <String , Class <?>> map )
13141298 throws SQLException {
@@ -1373,8 +1357,7 @@ public Array getArray(String columnLabel)
13731357 @ Override
13741358 public Date getDate (int columnIndex , Calendar cal )
13751359 throws SQLException {
1376- // cal into joda local timezone
1377- DateTimeZone timeZone = DateTimeZone .forTimeZone (cal .getTimeZone ());
1360+ ZoneId timeZone = cal == null ? null : cal .getTimeZone ().toZoneId ();
13781361 return getDate (columnIndex , timeZone );
13791362 }
13801363
@@ -1387,8 +1370,7 @@ public Date getDate(String columnLabel, Calendar cal)
13871370 @ Override
13881371 public Time getTime (int columnIndex , Calendar cal )
13891372 throws SQLException {
1390- // cal into joda local timezone
1391- DateTimeZone timeZone = DateTimeZone .forTimeZone (cal .getTimeZone ());
1373+ ZoneId timeZone = cal == null ? null : cal .getTimeZone ().toZoneId ();
13921374 return getTime (columnIndex , timeZone );
13931375 }
13941376
@@ -1405,8 +1387,7 @@ public Timestamp getTimestamp(int columnIndex, Calendar cal)
14051387 if (isResultTimeZoneFromServer ) {
14061388 return getTimestamp (columnIndex , resultTimeZone );
14071389 }
1408- // cal into joda local timezone
1409- DateTimeZone timeZone = DateTimeZone .forTimeZone (cal .getTimeZone ());
1390+ ZoneId timeZone = cal == null ? null : cal .getTimeZone ().toZoneId ();
14101391 return getTimestamp (columnIndex , timeZone );
14111392 }
14121393
@@ -1772,15 +1753,17 @@ public <T> T getObject(int columnIndex, Class<T> type)
17721753 if (type == null ) {
17731754 throw new SQLException ("type is null" );
17741755 }
1775- String columnTypeStr = this .resultSetMetaData .getColumnTypeName (columnIndex );
1776- DatabendRawType databendRawType = new DatabendRawType (columnTypeStr );
1777- ColumnTypeHandler columnTypeHandler = ColumnTypeHandlerFactory .getTypeHandler (databendRawType );
17781756
1779- Object object = column (columnIndex );
1780- if (object == null ) {
1757+ Object value = column (columnIndex );
1758+ if (value == null ) {
17811759 return null ;
17821760 }
1783- return (T ) object ;
1761+
1762+ if (type == java .time .LocalDate .class ) {
1763+ value = LocalDate .parse ((String ) value );
1764+ }
1765+
1766+ return (T ) value ;
17841767 }
17851768
17861769 @ Override
0 commit comments