Permalink
Browse files

perf: cache timezone in statement#setDate, resultSet#getDate, etc

closes #588
  • Loading branch information...
Chrriis authored and vlsi committed Jul 11, 2016
1 parent 79db127 commit d2b86a0a223d1b573bb017172dd4c009c7274a47
@@ -63,6 +63,7 @@
import java.time.OffsetDateTime;
//#endif
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
@@ -83,6 +84,8 @@
*/
protected boolean outParmBeforeFunc = false;
private TimeZone defaultTimeZone;
PgPreparedStatement(PgConnection connection, String sql, int rsType, int rsConcurrency,
int rsHoldability) throws SQLException {
this(connection, sql, false, rsType, rsConcurrency, rsHoldability);
@@ -157,11 +160,15 @@ public boolean execute() throws SQLException {
}
public boolean executeWithFlags(int flags) throws SQLException {
checkClosed();
try {
checkClosed();
execute(preparedQuery.query, preparedParameters, flags);
execute(preparedQuery.query, preparedParameters, flags);
return (result != null && result.getResultSet() != null);
return (result != null && result.getResultSet() != null);
} finally {
defaultTimeZone = null;
}
}
protected boolean isOneShotQuery(Query query) {
@@ -634,7 +641,7 @@ public void setObject(int parameterIndex, Object in, int targetSqlType, int scal
break;
//#endif
} else {
tmpd = connection.getTimestampUtils().toDate(null, in.toString());
tmpd = connection.getTimestampUtils().toDate(getDefaultCalendar(), in.toString());
}
setDate(parameterIndex, tmpd);
}
@@ -652,7 +659,7 @@ public void setObject(int parameterIndex, Object in, int targetSqlType, int scal
break;
//#endif
} else {
tmpt = connection.getTimestampUtils().toTime(null, in.toString());
tmpt = connection.getTimestampUtils().toTime(getDefaultCalendar(), in.toString());
}
setTime(parameterIndex, tmpt);
}
@@ -672,7 +679,7 @@ public void setObject(int parameterIndex, Object in, int targetSqlType, int scal
break;
//#endif
} else {
tmpts = connection.getTimestampUtils().toTimestamp(null, in.toString());
tmpts = connection.getTimestampUtils().toTimestamp(getDefaultCalendar(), in.toString());
}
setTimestamp(parameterIndex, tmpts);
}
@@ -1396,6 +1403,9 @@ public void setDate(int i, java.sql.Date d, java.util.Calendar cal) throws SQLEx
// 2005-01-01 00:00:00+03
// (1 row)
if (cal == null) {
cal = getDefaultCalendar();
}
bindString(i, connection.getTimestampUtils().toString(cal, d), Oid.UNSPECIFIED);
}
@@ -1420,6 +1430,9 @@ public void setTime(int i, Time t, java.util.Calendar cal) throws SQLException {
}
}
if (cal == null) {
cal = getDefaultCalendar();
}
bindString(i, connection.getTimestampUtils().toString(cal, t), oid);
}
@@ -1473,7 +1486,9 @@ public void setTimestamp(int i, Timestamp t, java.util.Calendar cal) throws SQLE
cal = pgTimestamp.getCalendar();
}
}
if (cal == null) {
cal = getDefaultCalendar();
}
bindString(i, connection.getTimestampUtils().toString(cal, t), oid);
}
@@ -1640,6 +1655,23 @@ public void setURL(int parameterIndex, java.net.URL x) throws SQLException {
throw Driver.notImplemented(this.getClass(), "setURL(int,URL)");
}
@Override
public int[] executeBatch() throws SQLException {
try {
return super.executeBatch();
} finally {
defaultTimeZone = null;
}
}
private Calendar getDefaultCalendar() {
Calendar sharedCalendar = connection.getTimestampUtils().getSharedCalendar(defaultTimeZone);
if (defaultTimeZone == null) {
defaultTimeZone = sharedCalendar.getTimeZone();
}
return sharedCalendar;
}
public ParameterMetaData getParameterMetaData() throws SQLException {
int flags = QueryExecutor.QUERY_ONESHOT | QueryExecutor.QUERY_DESCRIBE_ONLY
| QueryExecutor.QUERY_SUPPRESS_BEGIN;
@@ -96,6 +96,7 @@
private final int resultsettype;
private final int resultsetconcurrency;
private int fetchdirection = ResultSet.FETCH_UNKNOWN;
private TimeZone defaultTimeZone;
protected final BaseConnection connection; // the connection we belong to
protected final BaseStatement statement; // the statement we belong to
protected final Field fields[]; // Field metadata for this resultset.
@@ -488,10 +489,13 @@ public int getConcurrency() throws SQLException {
return null;
}
if (cal == null) {
cal = getDefaultCalendar();
}
if (isBinary(i)) {
int col = i - 1;
int oid = fields[col].getOID();
TimeZone tz = cal == null ? null : cal.getTimeZone();
TimeZone tz = cal.getTimeZone();
if (oid == Oid.DATE) {
return connection.getTimestampUtils().toDateBin(tz, this_row[col]);
} else if (oid == Oid.TIMESTAMP || oid == Oid.TIMESTAMPTZ) {
@@ -518,10 +522,13 @@ public Time getTime(int i, java.util.Calendar cal) throws SQLException {
return null;
}
if (cal == null) {
cal = getDefaultCalendar();
}
if (isBinary(i)) {
int col = i - 1;
int oid = fields[col].getOID();
TimeZone tz = cal == null ? null : cal.getTimeZone();
TimeZone tz = cal.getTimeZone();
if (oid == Oid.TIME || oid == Oid.TIMETZ) {
return connection.getTimestampUtils().toTimeBin(tz, this_row[col]);
} else if (oid == Oid.TIMESTAMP || oid == Oid.TIMESTAMPTZ) {
@@ -549,12 +556,15 @@ public Timestamp getTimestamp(int i, java.util.Calendar cal) throws SQLException
return null;
}
if (cal == null) {
cal = getDefaultCalendar();
}
int col = i - 1;
int oid = fields[col].getOID();
if (isBinary(i)) {
if (oid == Oid.TIMESTAMPTZ || oid == Oid.TIMESTAMP) {
boolean hasTimeZone = oid == Oid.TIMESTAMPTZ;
TimeZone tz = cal == null ? null : cal.getTimeZone();
TimeZone tz = cal.getTimeZone();
return connection.getTimestampUtils().toTimestampBin(tz, this_row[col], hasTimeZone);
} else {
// JDBC spec says getTimestamp of Time and Date must be supported
@@ -600,7 +610,8 @@ private LocalDateTime getLocalDateTime(int i) throws SQLException {
PSQLState.DATA_TYPE_MISMATCH);
}
if (isBinary(i)) {
return connection.getTimestampUtils().toLocalDateTimeBin(this_row[col]);
TimeZone timeZone = getDefaultCalendar().getTimeZone();
return connection.getTimestampUtils().toLocalDateTimeBin(timeZone, this_row[col]);
}
String string = getString(i);
@@ -1694,17 +1705,22 @@ private void updateRowBuffer() throws SQLException {
case Types.DATE:
rowBuffer[columnIndex] = connection
.encodeString(connection.getTimestampUtils().toString(null, (Date) valueObject));
.encodeString(
connection.getTimestampUtils().toString(
getDefaultCalendar(), (Date) valueObject));
break;
case Types.TIME:
rowBuffer[columnIndex] = connection
.encodeString(connection.getTimestampUtils().toString(null, (Time) valueObject));
.encodeString(
connection.getTimestampUtils().toString(
getDefaultCalendar(), (Time) valueObject));
break;
case Types.TIMESTAMP:
rowBuffer[columnIndex] = connection.encodeString(
connection.getTimestampUtils().toString(null, (Timestamp) valueObject));
connection.getTimestampUtils().toString(
getDefaultCalendar(), (Timestamp) valueObject));
break;
case Types.NULL:
@@ -3244,7 +3260,7 @@ public void updateArray(String columnName, Array x) throws SQLException {
//#endif
) {
Timestamp timestampValue = getTimestamp(columnIndex);
Calendar calendar = Calendar.getInstance();
Calendar calendar = Calendar.getInstance(getDefaultCalendar().getTimeZone());
calendar.setTimeInMillis(timestampValue.getTime());
return type.cast(calendar);
} else {
@@ -3612,4 +3628,12 @@ public boolean isWrapperFor(Class<?> iface) throws SQLException {
}
throw new SQLException("Cannot unwrap to " + iface.getName());
}
private Calendar getDefaultCalendar() {
Calendar sharedCalendar = connection.getTimestampUtils().getSharedCalendar(defaultTimeZone);
if (defaultTimeZone == null) {
defaultTimeZone = sharedCalendar.getTimeZone();
}
return sharedCalendar;
}
}
@@ -454,8 +454,21 @@ public synchronized Date toDate(Calendar cal, String s) throws SQLException {
}
private Calendar setupCalendar(Calendar cal) {
TimeZone timeZone = cal == null ? null : cal.getTimeZone();
return getSharedCalendar(timeZone);
}
/**
* Get a shared calendar, applying the supplied time zone or the default time zone if null.
*
* @return The shared calendar.
*/
public Calendar getSharedCalendar(TimeZone timeZone) {
if (timeZone == null) {
timeZone = getDefaultTz();
}
Calendar tmp = calendarWithUserTz;
tmp.setTimeZone(cal == null ? getDefaultTz() : cal.getTimeZone());
tmp.setTimeZone(timeZone);
return tmp;
}
@@ -943,9 +956,9 @@ private ParsedBinaryTimestamp toParsedTimestampBin(TimeZone tz, byte[] bytes, bo
* @return The parsed local date time object.
* @throws PSQLException If binary format could not be parsed.
*/
public LocalDateTime toLocalDateTimeBin(byte[] bytes) throws PSQLException {
public LocalDateTime toLocalDateTimeBin(TimeZone tz, byte[] bytes) throws PSQLException {
ParsedBinaryTimestamp parsedTimestamp = this.toParsedTimestampBin(null, bytes, true);
ParsedBinaryTimestamp parsedTimestamp = this.toParsedTimestampBin(tz, bytes, true);
if (parsedTimestamp.infinity == Infinity.POSITIVE) {
return LocalDateTime.MAX;
} else if (parsedTimestamp.infinity == Infinity.NEGATIVE) {
@@ -68,6 +68,7 @@ public static TestSuite suite() throws Exception {
suite.addTestSuite(TimezoneTest.class);
suite.addTestSuite(PGTimeTest.class);
suite.addTestSuite(PGTimestampTest.class);
suite.addTest(new JUnit4TestAdapter(TimezoneCachingTest.class));
// PreparedStatement
suite.addTestSuite(PreparedStatementTest.class);
Oops, something went wrong.

0 comments on commit d2b86a0

Please sign in to comment.