Modified:
branches/branch_5_0/connector-j/src/com/mysql/jdbc/Connection.java
branches/branch_5_0/connector-j/src/com/mysql/jdbc/EscapeProcessor.java
branches/branch_5_0/connector-j/src/com/mysql/jdbc/Statement.java
branches/branch_5_0/connector-j/src/testsuite/simple/EscapeProcessingTest.java
Log:
If the connection "useTimezone" is set to "true", then also respect timezone
conversions in escape-processed string literals (e.g. "{ts ...}" and
"{t ...}").
Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/Connection.java
===================================================================
--- branches/branch_5_0/connector-j/src/com/mysql/jdbc/Connection.java 2005-09-07 16:52:54 UTC (rev 4215)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/Connection.java 2005-09-07 17:12:34 UTC (rev 4216)
@@ -1381,6 +1381,8 @@
private LRUCache serverSideStatementCache;
+ private Calendar sessionCalendar;
+
/**
* Creates a connection to a MySQL Server.
*
@@ -4080,7 +4082,8 @@
Object escapedSqlResult = EscapeProcessor.escapeSQL(sql,
serverSupportsConvertFn(),
- this);
+ this,
+ getCalendarInstanceForSessionOrNew());
if (escapedSqlResult instanceof String) {
return (String) escapedSqlResult;
@@ -4092,7 +4095,8 @@
private CallableStatement parseCallableStatement(String sql)
throws SQLException {
Object escapedSqlResult = EscapeProcessor.escapeSQL(sql,
- serverSupportsConvertFn(), this);
+ serverSupportsConvertFn(), this,
+ getCalendarInstanceForSessionOrNew());
boolean isFunctionCall = false;
String parsedSql = null;
@@ -5376,4 +5380,20 @@
protected boolean isCursorFetchEnabled() throws SQLException {
return (versionMeetsMinimum(5, 0, 2) && getUseCursorFetch());
}
+
+ /**
+ * Optimization to only use one calendar per-session, or calculate it for
+ * each call, depending on user configuration
+ */
+ protected synchronized Calendar getCalendarInstanceForSessionOrNew() {
+ if (getDynamicCalendars()) {
+ return Calendar.getInstance();
+ }
+
+ if (this.sessionCalendar == null) {
+ this.sessionCalendar = Calendar.getInstance();
+ }
+
+ return this.sessionCalendar;
+ }
}
Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/EscapeProcessor.java
===================================================================
--- branches/branch_5_0/connector-j/src/com/mysql/jdbc/EscapeProcessor.java 2005-09-07 16:52:54 UTC (rev 4215)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/EscapeProcessor.java 2005-09-07 17:12:34 UTC (rev 4216)
@@ -30,6 +30,7 @@
package com.mysql.jdbc;
import java.sql.SQLException;
+import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
@@ -97,7 +98,9 @@
* DOCUMENT ME!
*/
public static final Object escapeSQL(String sql,
- boolean serverSupportsConvertFn, Connection conn) throws java.sql.SQLException {
+ boolean serverSupportsConvertFn,
+ Connection conn,
+ Calendar sessionCalendar) throws java.sql.SQLException {
boolean replaceEscapeSequence = false;
String escapeSequence = null;
@@ -144,7 +147,8 @@
Object remainingResults = escapeSQL(token
.substring(1, token.length() - 1),
- serverSupportsConvertFn, conn);
+ serverSupportsConvertFn, conn,
+ sessionCalendar);
String remaining = null;
@@ -293,8 +297,11 @@
.append(minute).append(":").append(second)
.append("'");
} else {
- Calendar localTzCal = Calendar.getInstance();
+ if (sessionCalendar == null) {
+ sessionCalendar = Calendar.getInstance();
+ }
+
try {
int year4Int = Integer.parseInt(year4);
int month2Int = Integer.parseInt(month2);
@@ -305,7 +312,7 @@
Timestamp toBeAdjusted = TimeUtil.fastTimestampCreate(
- localTzCal,
+ sessionCalendar,
year4Int,
month2Int,
day2Int,
@@ -317,7 +324,7 @@
Timestamp inServerTimezone = TimeUtil.changeTimezone(
conn,
toBeAdjusted,
- localTzCal.getTimeZone(),
+ sessionCalendar.getTimeZone(),
conn.getServerTimezoneTZ(),
false);
@@ -364,9 +371,45 @@
String hour = st.nextToken();
String minute = st.nextToken();
String second = st.nextToken();
- String timeString = "'" + hour + ":" + minute + ":"
+
+ if (!conn.getUseTimezone()) {
+ String timeString = "'" + hour + ":" + minute + ":"
+ second + "'";
- newSql.append(timeString);
+ newSql.append(timeString);
+ } else {
+ if (sessionCalendar == null) {
+ sessionCalendar = Calendar.getInstance();
+ }
+
+ try {
+ int hourInt = Integer.parseInt(hour);
+ int minuteInt = Integer.parseInt(minute);
+ int secondInt = Integer.parseInt(second);
+
+
+ Time toBeAdjusted = TimeUtil.fastTimeCreate(
+ sessionCalendar,
+ hourInt,
+ minuteInt,
+ secondInt);
+
+ Time inServerTimezone = TimeUtil.changeTimezone(
+ conn,
+ toBeAdjusted,
+ sessionCalendar.getTimeZone(),
+ conn.getServerTimezoneTZ(),
+ false);
+
+ newSql.append("'");
+ newSql.append(inServerTimezone.toString());
+ newSql.append("'");
+
+ } catch (NumberFormatException nfe) {
+ throw new SQLException("Syntax error in TIMESTAMP escape sequence '"
+ + token + "'.",
+ SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+ }
+ }
} catch (java.util.NoSuchElementException e) {
throw new SQLException(
"Syntax error for escape sequence '"
Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/Statement.java
===================================================================
--- branches/branch_5_0/connector-j/src/com/mysql/jdbc/Statement.java 2005-09-07 16:52:54 UTC (rev 4215)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/Statement.java 2005-09-07 17:12:34 UTC (rev 4216)
@@ -34,6 +34,7 @@
import java.sql.Types;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -165,6 +166,8 @@
/** The warnings chain. */
protected SQLWarning warningChain = null;
+ private Calendar sessionCalendar;
+
/**
* Constructor for a Statement.
*
@@ -451,7 +454,8 @@
if (this.doEscapeProcessing) {
Object escapedSqlResult = EscapeProcessor.escapeSQL(sql,
this.connection.serverSupportsConvertFn(),
- this.connection);
+ this.connection,
+ getCalendarInstanceForSessionOrNew());
if (escapedSqlResult instanceof String) {
sql = (String) escapedSqlResult;
@@ -749,7 +753,8 @@
if (this.doEscapeProcessing) {
Object escapedSqlResult = EscapeProcessor.escapeSQL(sql,
this.connection.serverSupportsConvertFn(),
- this.connection);
+ this.connection,
+ getCalendarInstanceForSessionOrNew());
if (escapedSqlResult instanceof String) {
sql = (String) escapedSqlResult;
@@ -907,7 +912,8 @@
if (this.doEscapeProcessing) {
Object escapedSqlResult = EscapeProcessor.escapeSQL(sql,
this.connection.serverSupportsConvertFn(),
- this.connection);
+ this.connection,
+ getCalendarInstanceForSessionOrNew());
if (escapedSqlResult instanceof String) {
sql = (String) escapedSqlResult;
@@ -1880,4 +1886,20 @@
protected synchronized ResultSet getResultSetInternal() {
return this.results;
}
+
+ /**
+ * Optimization to only use one calendar per-session, or calculate it for
+ * each call, depending on user configuration
+ */
+ protected synchronized Calendar getCalendarInstanceForSessionOrNew() {
+ if (this.connection.getDynamicCalendars()) {
+ return Calendar.getInstance();
+ }
+
+ if (this.sessionCalendar == null) {
+ this.sessionCalendar = Calendar.getInstance();
+ }
+
+ return this.sessionCalendar;
+ }
}
Modified: branches/branch_5_0/connector-j/src/testsuite/simple/EscapeProcessingTest.java
===================================================================
--- branches/branch_5_0/connector-j/src/testsuite/simple/EscapeProcessingTest.java 2005-09-07 16:52:54 UTC (rev 4215)
+++ branches/branch_5_0/connector-j/src/testsuite/simple/EscapeProcessingTest.java 2005-09-07 17:12:34 UTC (rev 4216)
@@ -24,6 +24,10 @@
*/
package testsuite.simple;
+import java.sql.Connection;
+import java.util.Properties;
+import java.util.TimeZone;
+
import testsuite.BaseTestCase;
/**
@@ -94,4 +98,39 @@
assertEquals(conn.nativeSQL("{fn convert(abcd, SQL_INTEGER)}"), conn
.nativeSQL("{fn convert(abcd, INTEGER)}"));
}
+
+ /**
+ * Tests that the escape tokenizer converts timestamp values
+ * wrt. timezones when useTimezone=true.
+ *
+ * @throws Exception if the test fails.
+ */
+ public void testTimestampConversion() throws Exception {
+ TimeZone currentTimezone = TimeZone.getDefault();
+ String[] availableIds = TimeZone.getAvailableIDs(currentTimezone.getRawOffset() + (3600 * 1000 * 2));
+ String newTimezone = null;
+
+ if (availableIds.length > 0) {
+ newTimezone = availableIds[0];
+ } else {
+ newTimezone = "UTC"; // punt
+ }
+
+ Properties props = new Properties();
+
+ props.setProperty("useTimezone", "true");
+ props.setProperty("serverTimezone", newTimezone);
+ Connection tzConn = null;
+
+ try {
+ String escapeToken = "SELECT {ts '2002-11-12 10:00:00'} {t '05:11:02'}";
+ tzConn = getConnectionWithProps(props);
+ assertTrue(!tzConn.nativeSQL(escapeToken).equals(this.conn.nativeSQL(escapeToken)));
+ } finally {
+ if (tzConn != null) {
+ tzConn.close();
+ }
+ }
+
+ }
}
| Thread |
|---|
| • Connector/J commit: r4216 - in branches/branch_5_0/connector-j/src: com/mysql/jdbc testsuite/simple | mmatthews | 7 Sep |