Skip to content

Commit e99feb8

Browse files
committed
HHH-19695 handle 'fetch first' and 'fetch next' bigrams
1 parent 469ffda commit e99feb8

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

hibernate-core/src/main/java/org/hibernate/sql/Template.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ public final class Template {
8989
= Set.of("date", "time");
9090
private static final Set<String> LITERAL_PREFIXES
9191
= Set.of("n", "x", "varbyte", "bx", "bytea", "date", "time", "timestamp", "zone");
92+
private static final Set<String> FETCH_BIGRAMS
93+
= Set.of("first", "next");
9294

9395
private static final String PUNCTUATION = "=><!+-*/()',|&`";
9496

@@ -166,6 +168,7 @@ public static String renderWhereStringTemplate(
166168
boolean inExtractOrTrim = false;
167169
boolean inCast = false;
168170
boolean afterCastAs = false;
171+
boolean afterFetch = false;
169172

170173
boolean hasMore = tokens.hasMoreTokens();
171174
String nextToken = hasMore ? tokens.nextToken() : null;
@@ -215,10 +218,14 @@ else if ( quotedIdentifier && dialect.closeQuote()==token.charAt(0) ) {
215218
}
216219
}
217220

218-
final boolean quotedOrWhitespace =
219-
quoted || quotedIdentifier || isQuoteCharacter
220-
|| token.isBlank();
221-
if ( quotedOrWhitespace ) {
221+
final boolean isWhitespace = token.isBlank();
222+
223+
final boolean wasAfterFetch = afterFetch;
224+
afterFetch = afterFetch && isWhitespace;
225+
226+
final boolean isQuoted =
227+
quoted || quotedIdentifier || isQuoteCharacter;
228+
if ( isQuoted || isWhitespace ) {
222229
result.append( token );
223230
}
224231
else if ( beforeTable ) {
@@ -247,6 +254,13 @@ else if ( inCast && ("as".equals( lcToken ) || afterCastAs) ) {
247254
result.append( token );
248255
afterCastAs = true;
249256
}
257+
else if ( isFetch( dialect, lcToken ) ) {
258+
result.append( token );
259+
afterFetch = true;
260+
}
261+
else if ( wasAfterFetch && FETCH_BIGRAMS.contains( lcToken ) ) {
262+
result.append( token );
263+
}
250264
else if ( !inFromClause // don't want to append alias to tokens inside the FROM clause
251265
&& isIdentifier( token )
252266
&& !isFunctionOrKeyword( lcToken, nextToken, dialect, typeConfiguration )
@@ -256,7 +270,7 @@ && isIdentifier( token )
256270
.append( dialect.quote(token) );
257271
}
258272
else {
259-
if ( ")".equals( lcToken) ) {
273+
if ( ")".equals(lcToken) ) {
260274
inExtractOrTrim = false;
261275
inCast = false;
262276
afterCastAs = false;
@@ -286,6 +300,11 @@ else if ( inFromClause && ",".equals(lcToken) ) {
286300
return result.toString();
287301
}
288302

303+
private static boolean isFetch(Dialect dialect, String lcToken) {
304+
return "fetch".equals( lcToken )
305+
&& dialect.getKeywords().contains( "fetch" );
306+
}
307+
289308
private static boolean endsWithDot(String token) {
290309
return token != null && token.endsWith( "." );
291310
}

0 commit comments

Comments
 (0)