@@ -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