@@ -194,22 +194,27 @@ else if ( LITERAL_PREFIXES.contains( lcToken ) ) {
194
194
continue ;
195
195
}
196
196
else if ( nextToken != null && Character .isWhitespace ( nextToken .charAt ( 0 ) ) ) {
197
+ final StringTokenizer lookahead = lookahead ( sqlWhereString , symbols , tokens );
198
+ String lookaheadToken = lookahead .hasMoreTokens () ? lookahead .nextToken () : null ;
197
199
final StringBuilder additionalTokens = new StringBuilder ();
198
200
TimeZoneTokens possibleNextToken = null ;
199
201
do {
200
202
possibleNextToken = possibleNextToken == null
201
203
? TimeZoneTokens .getPossibleNextTokens ( lcToken )
202
204
: possibleNextToken .nextToken ();
203
205
do {
204
- additionalTokens .append ( nextToken );
205
- hasMore = tokens .hasMoreTokens ();
206
- nextToken = tokens .nextToken ();
207
- } while ( nextToken != null && Character .isWhitespace ( nextToken .charAt ( 0 ) ) );
208
- } while ( nextToken != null && possibleNextToken .isToken ( nextToken ) );
209
- if ( "'" .equals ( nextToken ) ) {
206
+ additionalTokens .append ( lookaheadToken );
207
+ lookaheadToken = lookahead .hasMoreTokens () ? lookahead .nextToken () : null ;
208
+ } while ( lookaheadToken != null && Character .isWhitespace ( lookaheadToken .charAt ( 0 ) ) );
209
+ } while ( lookaheadToken != null && possibleNextToken .isToken ( lookaheadToken ) );
210
+ if ( "'" .equals ( lookaheadToken ) ) {
210
211
// Don't prefix a literal
211
212
result .append ( token );
212
213
result .append ( additionalTokens );
214
+ while (tokens .countTokens () > lookahead .countTokens ()) {
215
+ hasMore = tokens .hasMoreTokens ();
216
+ nextToken = hasMore ? tokens .nextToken () : null ;
217
+ }
213
218
continue ;
214
219
}
215
220
else {
@@ -401,6 +406,24 @@ else if ( inFromClause && ",".equals(lcToken) ) {
401
406
return result .toString ();
402
407
}
403
408
409
+ /**
410
+ * Clone the given token stream, returning a token stream which begins
411
+ * from the next token.
412
+ *
413
+ * @param sql the full SQL we are scanning
414
+ * @param symbols the delimiter symbols
415
+ * @param tokens the current token stream
416
+ * @return a cloned token stream
417
+ */
418
+ private static StringTokenizer lookahead (String sql , String symbols , StringTokenizer tokens ) {
419
+ final StringTokenizer lookahead =
420
+ new StringTokenizer ( sql , symbols , true );
421
+ while ( lookahead .countTokens () > tokens .countTokens () + 1 ) {
422
+ lookahead .nextToken ();
423
+ }
424
+ return lookahead ;
425
+ }
426
+
404
427
private enum TimeZoneTokens {
405
428
NONE ,
406
429
WITH ,
0 commit comments