List:Commits« Previous MessageNext Message »
From:mmatthews Date:January 10 2007 11:49pm
Subject:Connector/J commit: r6291 - branches/branch_5_0/connector-j branches/branch_5_0/connector-j/src/com/mysql/jdbc branches/branch_5_0/connector-j/src/tes...
View as plain text  
Modified:
   branches/branch_5_0/connector-j/CHANGES
   branches/branch_5_0/connector-j/src/com/mysql/jdbc/EscapeProcessor.java
  
branches/branch_5_0/connector-j/src/testsuite/regression/EscapeProcessorRegressionTest.java
   trunk/connector-j/CHANGES
   trunk/connector-j/src/com/mysql/jdbc/EscapeProcessor.java
   trunk/connector-j/src/testsuite/regression/EscapeProcessorRegressionTest.java
Log:
 Fixed BUG#25399 - EscapeProcessor gets confused by multiple backslashes. We now push the
responsibility of syntax errors back on to the server for most escape sequences.
      

Modified: branches/branch_5_0/connector-j/CHANGES
===================================================================
--- branches/branch_5_0/connector-j/CHANGES	2007-01-10 22:22:08 UTC (rev 6290)
+++ branches/branch_5_0/connector-j/CHANGES	2007-01-10 22:49:25 UTC (rev 6291)
@@ -68,7 +68,11 @@
 
 	- Fixed BUG#23303 - DatabaseMetaData.getSchemas() doesn't return a 
 	  TABLE_CATALOG column.
-		  	  
+
+    - Fixed BUG#25399 - EscapeProcessor gets confused by multiple 
+      backslashes. We now push the responsibility of syntax errors back
+      on to the server for most escape sequences.
+            	  	  
 10-20-06 - Version 5.0.4
 
     - Fixed BUG#21379 - column names don't match metadata in cases 

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	2007-01-10
22:22:08 UTC (rev 6290)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/EscapeProcessor.java	2007-01-10
22:49:25 UTC (rev 6291)
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2002-2004 MySQL AB
+ Copyright (C) 2002-2007 MySQL AB
 
  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License as 
@@ -186,18 +186,16 @@
 							escapeSequence = st.nextToken();
 
 							if (escapeSequence.length() < 3) {
-								throw SQLError.createSQLException(
-										"Syntax error for escape sequence '"
-												+ token + "'", "42000");
-							}
+								newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
+							} else {
+							
 
-							escapeSequence = escapeSequence.substring(1,
+								escapeSequence = escapeSequence.substring(1,
 									escapeSequence.length() - 1);
-							replaceEscapeSequence = true;
+								replaceEscapeSequence = true;
+							}
 						} catch (java.util.NoSuchElementException e) {
-							throw SQLError.createSQLException(
-									"Syntax error for escape sequence '"
-											+ token + "'", "42000");
+							newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
 						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
 							"{fn")) {
@@ -222,148 +220,146 @@
 						int endPos = token.lastIndexOf('\''); // no }
 
 						if ((startPos == -1) || (endPos == -1)) {
-							throw SQLError.createSQLException(
-									"Syntax error for DATE escape sequence '"
-											+ token + "'", "42000");
+							newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
+						} else {
+	
+							String argument = token.substring(startPos, endPos);
+	
+							try {
+								StringTokenizer st = new StringTokenizer(argument,
+										" -");
+								String year4 = st.nextToken();
+								String month2 = st.nextToken();
+								String day2 = st.nextToken();
+								String dateString = "'" + year4 + "-" + month2
+										+ "-" + day2 + "'";
+								newSql.append(dateString);
+							} catch (java.util.NoSuchElementException e) {
+								throw SQLError.createSQLException(
+										"Syntax error for DATE escape sequence '"
+												+ argument + "'", "42000");
+							}
 						}
-
-						String argument = token.substring(startPos, endPos);
-
-						try {
-							StringTokenizer st = new StringTokenizer(argument,
-									" -");
-							String year4 = st.nextToken();
-							String month2 = st.nextToken();
-							String day2 = st.nextToken();
-							String dateString = "'" + year4 + "-" + month2
-									+ "-" + day2 + "'";
-							newSql.append(dateString);
-						} catch (java.util.NoSuchElementException e) {
-							throw SQLError.createSQLException(
-									"Syntax error for DATE escape sequence '"
-											+ argument + "'", "42000");
-						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
 							"{ts")) {
 						int startPos = token.indexOf('\'') + 1;
 						int endPos = token.lastIndexOf('\''); // no }
 
 						if ((startPos == -1) || (endPos == -1)) {
-							throw SQLError.createSQLException(
-									"Syntax error for TIMESTAMP escape sequence '"
-											+ token + "'", "42000");
-						}
+							newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
+						} else {
 
-						String argument = token.substring(startPos, endPos);
-
-						try {
-							StringTokenizer st = new StringTokenizer(argument,
-									" .-:");
-							String year4 = st.nextToken();
-							String month2 = st.nextToken();
-							String day2 = st.nextToken();
-							String hour = st.nextToken();
-							String minute = st.nextToken();
-							String second = st.nextToken();
-
-							/*
-							 * For now, we get the fractional seconds part, but
-							 * we don't use it, as MySQL doesn't support it in
-							 * it's TIMESTAMP data type
-							 * 
-							 * String fractionalSecond = "";
-							 * 
-							 * if (st.hasMoreTokens()) { fractionalSecond =
-							 * st.nextToken(); }
-							 */
-							/*
-							 * Use the full format because number format will
-							 * not work for "between" clauses.
-							 * 
-							 * Ref. Mysql Docs
-							 * 
-							 * You can specify DATETIME, DATE and TIMESTAMP
-							 * values using any of a common set of formats:
-							 * 
-							 * As a string in either 'YYYY-MM-DD HH:MM:SS' or
-							 * 'YY-MM-DD HH:MM:SS' format.
-							 * 
-							 * Thanks to Craig Longman for pointing out this bug
-							 */
-							if (!conn.getUseTimezone() && !conn.getUseJDBCCompliantTimezoneShift()) {
-								newSql.append("'").append(year4).append("-")
-									.append(month2).append("-").append(day2)
-									.append(" ").append(hour).append(":")
-									.append(minute).append(":").append(second)
-									.append("'");
-							} else {
-								Calendar sessionCalendar;
-								
-								if (conn != null) {
-									sessionCalendar = conn.getCalendarInstanceForSessionOrNew();
+							String argument = token.substring(startPos, endPos);
+	
+							try {
+								StringTokenizer st = new StringTokenizer(argument,
+										" .-:");
+								String year4 = st.nextToken();
+								String month2 = st.nextToken();
+								String day2 = st.nextToken();
+								String hour = st.nextToken();
+								String minute = st.nextToken();
+								String second = st.nextToken();
+	
+								/*
+								 * For now, we get the fractional seconds part, but
+								 * we don't use it, as MySQL doesn't support it in
+								 * it's TIMESTAMP data type
+								 * 
+								 * String fractionalSecond = "";
+								 * 
+								 * if (st.hasMoreTokens()) { fractionalSecond =
+								 * st.nextToken(); }
+								 */
+								/*
+								 * Use the full format because number format will
+								 * not work for "between" clauses.
+								 * 
+								 * Ref. Mysql Docs
+								 * 
+								 * You can specify DATETIME, DATE and TIMESTAMP
+								 * values using any of a common set of formats:
+								 * 
+								 * As a string in either 'YYYY-MM-DD HH:MM:SS' or
+								 * 'YY-MM-DD HH:MM:SS' format.
+								 * 
+								 * Thanks to Craig Longman for pointing out this bug
+								 */
+								if (!conn.getUseTimezone() && !conn.getUseJDBCCompliantTimezoneShift()) {
+									newSql.append("'").append(year4).append("-")
+										.append(month2).append("-").append(day2)
+										.append(" ").append(hour).append(":")
+										.append(minute).append(":").append(second)
+										.append("'");
 								} else {
-									sessionCalendar = new GregorianCalendar();
-									sessionCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
-								}
-								
-								try {
-									int year4Int = Integer.parseInt(year4);
-									int month2Int = Integer.parseInt(month2);
-									int day2Int = Integer.parseInt(day2);
-									int hourInt = Integer.parseInt(hour);
-									int minuteInt = Integer.parseInt(minute);
-									int secondInt = Integer.parseInt(second);
+									Calendar sessionCalendar;
 									
-									synchronized (sessionCalendar) {
-										boolean useGmtMillis = conn.getUseGmtMillisForDatetimes();
-										
-										Timestamp toBeAdjusted = TimeUtil.fastTimestampCreate(useGmtMillis,
-												useGmtMillis ? Calendar.getInstance(TimeZone.getTimeZone("GMT")): null,
-											sessionCalendar,
-											year4Int,
-											month2Int,
-											day2Int,
-											hourInt,
-											minuteInt,
-											secondInt,
-											0);
+									if (conn != null) {
+										sessionCalendar = conn.getCalendarInstanceForSessionOrNew();
+									} else {
+										sessionCalendar = new GregorianCalendar();
+										sessionCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
+									}
 									
-										Timestamp inServerTimezone = TimeUtil.changeTimezone(
-												conn,
+									try {
+										int year4Int = Integer.parseInt(year4);
+										int month2Int = Integer.parseInt(month2);
+										int day2Int = Integer.parseInt(day2);
+										int hourInt = Integer.parseInt(hour);
+										int minuteInt = Integer.parseInt(minute);
+										int secondInt = Integer.parseInt(second);
+										
+										synchronized (sessionCalendar) {
+											boolean useGmtMillis = conn.getUseGmtMillisForDatetimes();
+											
+											Timestamp toBeAdjusted = TimeUtil.fastTimestampCreate(useGmtMillis,
+													useGmtMillis ? Calendar.getInstance(TimeZone.getTimeZone("GMT")): null,
 												sessionCalendar,
-												null,
-												toBeAdjusted,
-												sessionCalendar.getTimeZone(),
-												conn.getServerTimezoneTZ(),
-												false);
+												year4Int,
+												month2Int,
+												day2Int,
+												hourInt,
+												minuteInt,
+												secondInt,
+												0);
 										
-										
-										newSql.append("'");
-										
-										String timezoneLiteral = inServerTimezone.toString();
-										
-										int indexOfDot = timezoneLiteral.indexOf(".");
-										
-										if (indexOfDot != -1) {
-											timezoneLiteral = timezoneLiteral.substring(0, indexOfDot);
+											Timestamp inServerTimezone = TimeUtil.changeTimezone(
+													conn,
+													sessionCalendar,
+													null,
+													toBeAdjusted,
+													sessionCalendar.getTimeZone(),
+													conn.getServerTimezoneTZ(),
+													false);
+											
+											
+											newSql.append("'");
+											
+											String timezoneLiteral = inServerTimezone.toString();
+											
+											int indexOfDot = timezoneLiteral.indexOf(".");
+											
+											if (indexOfDot != -1) {
+												timezoneLiteral = timezoneLiteral.substring(0, indexOfDot);
+											}
+											
+											newSql.append(timezoneLiteral);
 										}
 										
-										newSql.append(timezoneLiteral);
-									}
+										newSql.append("'");	
+										
 									
-									newSql.append("'");	
-									
-								
-								} catch (NumberFormatException nfe) {
-									throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '" 
-										+ token + "'.",
-										SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+									} catch (NumberFormatException nfe) {
+										throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '"

+											+ token + "'.",
+											SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+									}
 								}
+							} catch (java.util.NoSuchElementException e) {
+								throw SQLError.createSQLException(
+										"Syntax error for TIMESTAMP escape sequence '"
+												+ argument + "'", "42000");
 							}
-						} catch (java.util.NoSuchElementException e) {
-							throw SQLError.createSQLException(
-									"Syntax error for TIMESTAMP escape sequence '"
-											+ argument + "'", "42000");
 						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
 							"{t")) {
@@ -371,69 +367,68 @@
 						int endPos = token.lastIndexOf('\''); // no }
 
 						if ((startPos == -1) || (endPos == -1)) {
-							throw SQLError.createSQLException(
-									"Syntax error for TIME escape sequence '"
-											+ token + "'", "42000");
-						}
+							newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
+						} else {
 
-						String argument = token.substring(startPos, endPos);
-
-						try {
-							StringTokenizer st = new StringTokenizer(argument,
-									" :");
-							String hour = st.nextToken();
-							String minute = st.nextToken();
-							String second = st.nextToken();
-							
-							if (!conn.getUseTimezone()) {
-								String timeString = "'" + hour + ":" + minute + ":"
-									+ second + "'";
-								newSql.append(timeString);
-							} else {
-								Calendar sessionCalendar = null;
+							String argument = token.substring(startPos, endPos);
+	
+							try {
+								StringTokenizer st = new StringTokenizer(argument,
+										" :");
+								String hour = st.nextToken();
+								String minute = st.nextToken();
+								String second = st.nextToken();
 								
-								if (conn != null) {
-									sessionCalendar = conn.getCalendarInstanceForSessionOrNew();
+								if (!conn.getUseTimezone()) {
+									String timeString = "'" + hour + ":" + minute + ":"
+										+ second + "'";
+									newSql.append(timeString);
 								} else {
-									sessionCalendar = new GregorianCalendar();
-								}
-
-								try {
-									int hourInt = Integer.parseInt(hour);
-									int minuteInt = Integer.parseInt(minute);
-									int secondInt = Integer.parseInt(second);
+									Calendar sessionCalendar = null;
 									
-									synchronized (sessionCalendar) {
-										Time toBeAdjusted = TimeUtil.fastTimeCreate(
-												sessionCalendar,
-												hourInt,
-												minuteInt,
-												secondInt);
+									if (conn != null) {
+										sessionCalendar = conn.getCalendarInstanceForSessionOrNew();
+									} else {
+										sessionCalendar = new GregorianCalendar();
+									}
+	
+									try {
+										int hourInt = Integer.parseInt(hour);
+										int minuteInt = Integer.parseInt(minute);
+										int secondInt = Integer.parseInt(second);
 										
-										Time inServerTimezone = TimeUtil.changeTimezone(
-												conn,
-												sessionCalendar,
-												null,
-												toBeAdjusted,
-												sessionCalendar.getTimeZone(),
-												conn.getServerTimezoneTZ(),
-												false);
-										
-										newSql.append("'");
-										newSql.append(inServerTimezone.toString());
-										newSql.append("'");		
+										synchronized (sessionCalendar) {
+											Time toBeAdjusted = TimeUtil.fastTimeCreate(
+													sessionCalendar,
+													hourInt,
+													minuteInt,
+													secondInt);
+											
+											Time inServerTimezone = TimeUtil.changeTimezone(
+													conn,
+													sessionCalendar,
+													null,
+													toBeAdjusted,
+													sessionCalendar.getTimeZone(),
+													conn.getServerTimezoneTZ(),
+													false);
+											
+											newSql.append("'");
+											newSql.append(inServerTimezone.toString());
+											newSql.append("'");		
+										}
+									
+									} catch (NumberFormatException nfe) {
+										throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '"

+											+ token + "'.",
+											SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
 									}
-								
-								} catch (NumberFormatException nfe) {
-									throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '" 
-										+ token + "'.",
-										SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
 								}
+							} catch (java.util.NoSuchElementException e) {
+								throw SQLError.createSQLException(
+										"Syntax error for escape sequence '"
+												+ argument + "'", "42000");
 							}
-						} catch (java.util.NoSuchElementException e) {
-							throw SQLError.createSQLException(
-									"Syntax error for escape sequence '"
-											+ argument + "'", "42000");
 						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
 							"{call")

Modified:
branches/branch_5_0/connector-j/src/testsuite/regression/EscapeProcessorRegressionTest.java
===================================================================
---
branches/branch_5_0/connector-j/src/testsuite/regression/EscapeProcessorRegressionTest.java	2007-01-10
22:22:08 UTC (rev 6290)
+++
branches/branch_5_0/connector-j/src/testsuite/regression/EscapeProcessorRegressionTest.java	2007-01-10
22:49:25 UTC (rev 6291)
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2005 MySQL AB
+ Copyright (C) 2005-2007 MySQL AB
 
  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License as 
@@ -84,4 +84,14 @@
 		assertEquals("select '{\"','}'", this.conn
 				.nativeSQL("select '{\"','}'"));
 	}
+	
+	/**
+	 * Tests fix for BUG#25399 - EscapeProcessor gets confused by multiple backslashes
+	 * 
+	 * @throws Exception if the test fails.
+	 */
+	public void testBug25399() throws Exception {
+		assertEquals("\\' {d}",
+				getSingleValueWithQuery("SELECT '\\\\\\' {d}'"));
+	}
 }

Modified: trunk/connector-j/CHANGES
===================================================================
--- trunk/connector-j/CHANGES	2007-01-10 22:22:08 UTC (rev 6290)
+++ trunk/connector-j/CHANGES	2007-01-10 22:49:25 UTC (rev 6291)
@@ -64,7 +64,11 @@
 	  
 	- Fixed BUG#23303 - DatabaseMetaData.getSchemas() doesn't return a 
 	  TABLE_CATALOG column.
-	   	  	    	  	  	  	   	  	   
+
+    - Fixed BUG#25399 - EscapeProcessor gets confused by multiple 
+      backslashes. We now push the responsibility of syntax errors back
+      on to the server for most escape sequences.
+      
 10-20-06 - Version 5.0.4
 
     - Fixed BUG#21379 - column names don't match metadata in cases 

Modified: trunk/connector-j/src/com/mysql/jdbc/EscapeProcessor.java
===================================================================
--- trunk/connector-j/src/com/mysql/jdbc/EscapeProcessor.java	2007-01-10 22:22:08 UTC (rev
6290)
+++ trunk/connector-j/src/com/mysql/jdbc/EscapeProcessor.java	2007-01-10 22:49:25 UTC (rev
6291)
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2002-2004 MySQL AB
+ Copyright (C) 2002-2007 MySQL AB
 
  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License as 
@@ -186,18 +186,16 @@
 							escapeSequence = st.nextToken();
 
 							if (escapeSequence.length() < 3) {
-								throw SQLError.createSQLException(
-										"Syntax error for escape sequence '"
-												+ token + "'", "42000");
-							}
+								newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
+							} else {
+							
 
-							escapeSequence = escapeSequence.substring(1,
+								escapeSequence = escapeSequence.substring(1,
 									escapeSequence.length() - 1);
-							replaceEscapeSequence = true;
+								replaceEscapeSequence = true;
+							}
 						} catch (java.util.NoSuchElementException e) {
-							throw SQLError.createSQLException(
-									"Syntax error for escape sequence '"
-											+ token + "'", "42000");
+							newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
 						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
 							"{fn")) {
@@ -222,148 +220,146 @@
 						int endPos = token.lastIndexOf('\''); // no }
 
 						if ((startPos == -1) || (endPos == -1)) {
-							throw SQLError.createSQLException(
-									"Syntax error for DATE escape sequence '"
-											+ token + "'", "42000");
+							newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
+						} else {
+	
+							String argument = token.substring(startPos, endPos);
+	
+							try {
+								StringTokenizer st = new StringTokenizer(argument,
+										" -");
+								String year4 = st.nextToken();
+								String month2 = st.nextToken();
+								String day2 = st.nextToken();
+								String dateString = "'" + year4 + "-" + month2
+										+ "-" + day2 + "'";
+								newSql.append(dateString);
+							} catch (java.util.NoSuchElementException e) {
+								throw SQLError.createSQLException(
+										"Syntax error for DATE escape sequence '"
+												+ argument + "'", "42000");
+							}
 						}
-
-						String argument = token.substring(startPos, endPos);
-
-						try {
-							StringTokenizer st = new StringTokenizer(argument,
-									" -");
-							String year4 = st.nextToken();
-							String month2 = st.nextToken();
-							String day2 = st.nextToken();
-							String dateString = "'" + year4 + "-" + month2
-									+ "-" + day2 + "'";
-							newSql.append(dateString);
-						} catch (java.util.NoSuchElementException e) {
-							throw SQLError.createSQLException(
-									"Syntax error for DATE escape sequence '"
-											+ argument + "'", "42000");
-						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
 							"{ts")) {
 						int startPos = token.indexOf('\'') + 1;
 						int endPos = token.lastIndexOf('\''); // no }
 
 						if ((startPos == -1) || (endPos == -1)) {
-							throw SQLError.createSQLException(
-									"Syntax error for TIMESTAMP escape sequence '"
-											+ token + "'", "42000");
-						}
+							newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
+						} else {
 
-						String argument = token.substring(startPos, endPos);
-
-						try {
-							StringTokenizer st = new StringTokenizer(argument,
-									" .-:");
-							String year4 = st.nextToken();
-							String month2 = st.nextToken();
-							String day2 = st.nextToken();
-							String hour = st.nextToken();
-							String minute = st.nextToken();
-							String second = st.nextToken();
-
-							/*
-							 * For now, we get the fractional seconds part, but
-							 * we don't use it, as MySQL doesn't support it in
-							 * it's TIMESTAMP data type
-							 * 
-							 * String fractionalSecond = "";
-							 * 
-							 * if (st.hasMoreTokens()) { fractionalSecond =
-							 * st.nextToken(); }
-							 */
-							/*
-							 * Use the full format because number format will
-							 * not work for "between" clauses.
-							 * 
-							 * Ref. Mysql Docs
-							 * 
-							 * You can specify DATETIME, DATE and TIMESTAMP
-							 * values using any of a common set of formats:
-							 * 
-							 * As a string in either 'YYYY-MM-DD HH:MM:SS' or
-							 * 'YY-MM-DD HH:MM:SS' format.
-							 * 
-							 * Thanks to Craig Longman for pointing out this bug
-							 */
-							if (!conn.getUseTimezone() && !conn.getUseJDBCCompliantTimezoneShift()) {
-								newSql.append("'").append(year4).append("-")
-									.append(month2).append("-").append(day2)
-									.append(" ").append(hour).append(":")
-									.append(minute).append(":").append(second)
-									.append("'");
-							} else {
-								Calendar sessionCalendar;
-								
-								if (conn != null) {
-									sessionCalendar = conn.getCalendarInstanceForSessionOrNew();
+							String argument = token.substring(startPos, endPos);
+	
+							try {
+								StringTokenizer st = new StringTokenizer(argument,
+										" .-:");
+								String year4 = st.nextToken();
+								String month2 = st.nextToken();
+								String day2 = st.nextToken();
+								String hour = st.nextToken();
+								String minute = st.nextToken();
+								String second = st.nextToken();
+	
+								/*
+								 * For now, we get the fractional seconds part, but
+								 * we don't use it, as MySQL doesn't support it in
+								 * it's TIMESTAMP data type
+								 * 
+								 * String fractionalSecond = "";
+								 * 
+								 * if (st.hasMoreTokens()) { fractionalSecond =
+								 * st.nextToken(); }
+								 */
+								/*
+								 * Use the full format because number format will
+								 * not work for "between" clauses.
+								 * 
+								 * Ref. Mysql Docs
+								 * 
+								 * You can specify DATETIME, DATE and TIMESTAMP
+								 * values using any of a common set of formats:
+								 * 
+								 * As a string in either 'YYYY-MM-DD HH:MM:SS' or
+								 * 'YY-MM-DD HH:MM:SS' format.
+								 * 
+								 * Thanks to Craig Longman for pointing out this bug
+								 */
+								if (!conn.getUseTimezone() && !conn.getUseJDBCCompliantTimezoneShift()) {
+									newSql.append("'").append(year4).append("-")
+										.append(month2).append("-").append(day2)
+										.append(" ").append(hour).append(":")
+										.append(minute).append(":").append(second)
+										.append("'");
 								} else {
-									sessionCalendar = new GregorianCalendar();
-									sessionCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
-								}
-								
-								try {
-									int year4Int = Integer.parseInt(year4);
-									int month2Int = Integer.parseInt(month2);
-									int day2Int = Integer.parseInt(day2);
-									int hourInt = Integer.parseInt(hour);
-									int minuteInt = Integer.parseInt(minute);
-									int secondInt = Integer.parseInt(second);
+									Calendar sessionCalendar;
 									
-									synchronized (sessionCalendar) {
-										boolean useGmtMillis = conn.getUseGmtMillisForDatetimes();
-										
-										Timestamp toBeAdjusted = TimeUtil.fastTimestampCreate(useGmtMillis,
-												useGmtMillis ? Calendar.getInstance(TimeZone.getTimeZone("GMT")): null,
-											sessionCalendar,
-											year4Int,
-											month2Int,
-											day2Int,
-											hourInt,
-											minuteInt,
-											secondInt,
-											0);
+									if (conn != null) {
+										sessionCalendar = conn.getCalendarInstanceForSessionOrNew();
+									} else {
+										sessionCalendar = new GregorianCalendar();
+										sessionCalendar.setTimeZone(TimeZone.getTimeZone("GMT"));
+									}
 									
-										Timestamp inServerTimezone = TimeUtil.changeTimezone(
-												conn,
+									try {
+										int year4Int = Integer.parseInt(year4);
+										int month2Int = Integer.parseInt(month2);
+										int day2Int = Integer.parseInt(day2);
+										int hourInt = Integer.parseInt(hour);
+										int minuteInt = Integer.parseInt(minute);
+										int secondInt = Integer.parseInt(second);
+										
+										synchronized (sessionCalendar) {
+											boolean useGmtMillis = conn.getUseGmtMillisForDatetimes();
+											
+											Timestamp toBeAdjusted = TimeUtil.fastTimestampCreate(useGmtMillis,
+													useGmtMillis ? Calendar.getInstance(TimeZone.getTimeZone("GMT")): null,
 												sessionCalendar,
-												null,
-												toBeAdjusted,
-												sessionCalendar.getTimeZone(),
-												conn.getServerTimezoneTZ(),
-												false);
+												year4Int,
+												month2Int,
+												day2Int,
+												hourInt,
+												minuteInt,
+												secondInt,
+												0);
 										
-										
-										newSql.append("'");
-										
-										String timezoneLiteral = inServerTimezone.toString();
-										
-										int indexOfDot = timezoneLiteral.indexOf(".");
-										
-										if (indexOfDot != -1) {
-											timezoneLiteral = timezoneLiteral.substring(0, indexOfDot);
+											Timestamp inServerTimezone = TimeUtil.changeTimezone(
+													conn,
+													sessionCalendar,
+													null,
+													toBeAdjusted,
+													sessionCalendar.getTimeZone(),
+													conn.getServerTimezoneTZ(),
+													false);
+											
+											
+											newSql.append("'");
+											
+											String timezoneLiteral = inServerTimezone.toString();
+											
+											int indexOfDot = timezoneLiteral.indexOf(".");
+											
+											if (indexOfDot != -1) {
+												timezoneLiteral = timezoneLiteral.substring(0, indexOfDot);
+											}
+											
+											newSql.append(timezoneLiteral);
 										}
 										
-										newSql.append(timezoneLiteral);
-									}
+										newSql.append("'");	
+										
 									
-									newSql.append("'");	
-									
-								
-								} catch (NumberFormatException nfe) {
-									throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '" 
-										+ token + "'.",
-										SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+									} catch (NumberFormatException nfe) {
+										throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '"

+											+ token + "'.",
+											SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
+									}
 								}
+							} catch (java.util.NoSuchElementException e) {
+								throw SQLError.createSQLException(
+										"Syntax error for TIMESTAMP escape sequence '"
+												+ argument + "'", "42000");
 							}
-						} catch (java.util.NoSuchElementException e) {
-							throw SQLError.createSQLException(
-									"Syntax error for TIMESTAMP escape sequence '"
-											+ argument + "'", "42000");
 						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
 							"{t")) {
@@ -371,81 +367,80 @@
 						int endPos = token.lastIndexOf('\''); // no }
 
 						if ((startPos == -1) || (endPos == -1)) {
-							throw SQLError.createSQLException(
-									"Syntax error for TIME escape sequence '"
-											+ token + "'", "42000");
-						}
+							newSql.append(token); // it's just part of the query, push possible syntax errors
onto server's shoulders
+						} else {
 
-						String argument = token.substring(startPos, endPos);
-
-						try {
-							StringTokenizer st = new StringTokenizer(argument,
-									" :");
-							String hour = st.nextToken();
-							String minute = st.nextToken();
-							String second = st.nextToken();
-							
-							if (!conn.getUseTimezone()) {
-								String timeString = "'" + hour + ":" + minute + ":"
-									+ second + "'";
-								newSql.append(timeString);
-							} else {
-								Calendar sessionCalendar = null;
+							String argument = token.substring(startPos, endPos);
+	
+							try {
+								StringTokenizer st = new StringTokenizer(argument,
+										" :");
+								String hour = st.nextToken();
+								String minute = st.nextToken();
+								String second = st.nextToken();
 								
-								if (conn != null) {
-									sessionCalendar = conn.getCalendarInstanceForSessionOrNew();
+								if (!conn.getUseTimezone()) {
+									String timeString = "'" + hour + ":" + minute + ":"
+										+ second + "'";
+									newSql.append(timeString);
 								} else {
-									sessionCalendar = new GregorianCalendar();
-								}
-
-								try {
-									int hourInt = Integer.parseInt(hour);
-									int minuteInt = Integer.parseInt(minute);
-									int secondInt = Integer.parseInt(second);
+									Calendar sessionCalendar = null;
 									
-									synchronized (sessionCalendar) {
-										Time toBeAdjusted = TimeUtil.fastTimeCreate(
-												sessionCalendar,
-												hourInt,
-												minuteInt,
-												secondInt);
+									if (conn != null) {
+										sessionCalendar = conn.getCalendarInstanceForSessionOrNew();
+									} else {
+										sessionCalendar = new GregorianCalendar();
+									}
+	
+									try {
+										int hourInt = Integer.parseInt(hour);
+										int minuteInt = Integer.parseInt(minute);
+										int secondInt = Integer.parseInt(second);
 										
-										Time inServerTimezone = TimeUtil.changeTimezone(
-												conn,
-												sessionCalendar,
-												null,
-												toBeAdjusted,
-												sessionCalendar.getTimeZone(),
-												conn.getServerTimezoneTZ(),
-												false);
-										
-										newSql.append("'");
-										newSql.append(inServerTimezone.toString());
-										newSql.append("'");		
+										synchronized (sessionCalendar) {
+											Time toBeAdjusted = TimeUtil.fastTimeCreate(
+													sessionCalendar,
+													hourInt,
+													minuteInt,
+													secondInt);
+											
+											Time inServerTimezone = TimeUtil.changeTimezone(
+													conn,
+													sessionCalendar,
+													null,
+													toBeAdjusted,
+													sessionCalendar.getTimeZone(),
+													conn.getServerTimezoneTZ(),
+													false);
+											
+											newSql.append("'");
+											newSql.append(inServerTimezone.toString());
+											newSql.append("'");		
+										}
+									
+									} catch (NumberFormatException nfe) {
+										throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '"

+											+ token + "'.",
+											SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
 									}
-								
-								} catch (NumberFormatException nfe) {
-									throw SQLError.createSQLException("Syntax error in TIMESTAMP escape sequence '" 
-										+ token + "'.",
-										SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
 								}
+							} catch (java.util.NoSuchElementException e) {
+								throw SQLError.createSQLException(
+										"Syntax error for escape sequence '"
+												+ argument + "'", "42000");
 							}
-						} catch (java.util.NoSuchElementException e) {
-							throw SQLError.createSQLException(
-									"Syntax error for escape sequence '"
-											+ argument + "'", "42000");
 						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
-						"{call")
-						|| StringUtils.startsWithIgnoreCase(collapsedToken,
-						"{?=call")) {
+							"{call")
+							|| StringUtils.startsWithIgnoreCase(collapsedToken,
+									"{?=call")) {
 
 						int startPos = StringUtils.indexOfIgnoreCase(token,
-						"CALL") + 5;
+								"CALL") + 5;
 						int endPos = token.length() - 1;
-
+		
 						if (StringUtils.startsWithIgnoreCase(collapsedToken,
-							"{?=call")) {
+								"{?=call")) {
 							callingStoredFunction = true;
 							newSql.append("SELECT ");
 							newSql.append(token.substring(startPos, endPos));
@@ -454,7 +449,7 @@
 							newSql.append("CALL ");
 							newSql.append(token.substring(startPos, endPos));
 						}
-
+						
 						for (int i = endPos - 1; i >= startPos; i--) {
 							char c = token.charAt(i);
 							
@@ -470,7 +465,7 @@
 							break;
 						}
 					} else if (StringUtils.startsWithIgnoreCase(collapsedToken,
-					"{oj")) {
+							"{oj")) {
 						// MySQL already handles this escape sequence
 						// because of ODBC. Cool.
 						newSql.append(token);

Modified: trunk/connector-j/src/testsuite/regression/EscapeProcessorRegressionTest.java
===================================================================
---
trunk/connector-j/src/testsuite/regression/EscapeProcessorRegressionTest.java	2007-01-10
22:22:08 UTC (rev 6290)
+++
trunk/connector-j/src/testsuite/regression/EscapeProcessorRegressionTest.java	2007-01-10
22:49:25 UTC (rev 6291)
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2005 MySQL AB
+ Copyright (C) 2005-2007 MySQL AB
 
  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License as 
@@ -84,4 +84,14 @@
 		assertEquals("select '{\"','}'", this.conn
 				.nativeSQL("select '{\"','}'"));
 	}
+	
+	/**
+	 * Tests fix for BUG#25399 - EscapeProcessor gets confused by multiple backslashes
+	 * 
+	 * @throws Exception if the test fails.
+	 */
+	public void testBug25399() throws Exception {
+		assertEquals("\\' {d}",
+				getSingleValueWithQuery("SELECT '\\\\\\' {d}'"));
+	}
 }

Thread
Connector/J commit: r6291 - branches/branch_5_0/connector-j branches/branch_5_0/connector-j/src/com/mysql/jdbc branches/branch_5_0/connector-j/src/tes...mmatthews10 Jan