Skip to content

Commit fbf70fe

Browse files
committed
HHH-19052 Using lookahead StringTokenizer when analyzing part of SQL query prefixed by literal prefix
1 parent 8ad3b35 commit fbf70fe

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

Diff for: hibernate-core/src/main/java/org/hibernate/sql/Template.java

+29-6
Original file line numberDiff line numberDiff line change
@@ -194,22 +194,27 @@ else if ( LITERAL_PREFIXES.contains( lcToken ) ) {
194194
continue;
195195
}
196196
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;
197199
final StringBuilder additionalTokens = new StringBuilder();
198200
TimeZoneTokens possibleNextToken = null;
199201
do {
200202
possibleNextToken = possibleNextToken == null
201203
? TimeZoneTokens.getPossibleNextTokens( lcToken )
202204
: possibleNextToken.nextToken();
203205
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 ) ) {
210211
// Don't prefix a literal
211212
result.append( token );
212213
result.append( additionalTokens );
214+
while (tokens.countTokens() > lookahead.countTokens()) {
215+
hasMore = tokens.hasMoreTokens();
216+
nextToken = hasMore ? tokens.nextToken() : null;
217+
}
213218
continue;
214219
}
215220
else {
@@ -401,6 +406,24 @@ else if ( inFromClause && ",".equals(lcToken) ) {
401406
return result.toString();
402407
}
403408

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+
404427
private enum TimeZoneTokens {
405428
NONE,
406429
WITH,

0 commit comments

Comments
 (0)