diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Template.java b/hibernate-core/src/main/java/org/hibernate/sql/Template.java index 1d97702b483a..c996addf10af 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Template.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Template.java @@ -167,11 +167,12 @@ public static String renderWhereStringTemplate( boolean beforeTable = false; boolean inFromClause = false; boolean afterFromTable = false; - boolean inExtractOrTrim = false; - boolean inCast = false; boolean afterCastAs = false; boolean afterFetch = false; boolean afterCurrent = false; + int inExtractOrTrim = -1; + int inCast = -1; + int nestingLevel = 0; boolean hasMore = tokens.hasMoreTokens(); String nextToken = hasMore ? tokens.nextToken() : null; @@ -245,12 +246,18 @@ else if ( afterFromTable ) { processedToken = token; } else if ( "(".equals(lcToken) ) { + nestingLevel ++; processedToken = token; } else if ( ")".equals(lcToken) ) { - inExtractOrTrim = false; - inCast = false; - afterCastAs = false; + nestingLevel --; + if ( nestingLevel == inExtractOrTrim ) { + inExtractOrTrim = -1; + } + if ( nestingLevel == inCast ) { + inCast = -1; + afterCastAs = false; + } processedToken = token; } else if ( ",".equals(lcToken) ) { @@ -263,7 +270,7 @@ else if ( lcToken.length()==1 && symbols.contains(lcToken) ) { processedToken = token; } else if ( BEFORE_TABLE_KEYWORDS.contains(lcToken) ) { - if ( !inExtractOrTrim ) { + if ( inExtractOrTrim == -1 ) { beforeTable = true; inFromClause = true; } @@ -280,7 +287,7 @@ else if ( isNamedParameter(token) ) { } else if ( "as".equals( lcToken ) ) { processedToken = token; - afterCastAs = inCast; + afterCastAs = inCast>-1; } else if ( isFetch( dialect, lcToken ) ) { processedToken = token; @@ -298,10 +305,10 @@ else if ( isBoolean( lcToken ) ) { } else if ( isFunctionCall( nextToken, sql, symbols, tokens ) ) { if ( FUNCTION_WITH_FROM_KEYWORDS.contains( lcToken ) ) { - inExtractOrTrim = true; + inExtractOrTrim = nestingLevel; } if ( "cast".equals( lcToken ) ) { - inCast = true; + inCast = nestingLevel; } processedToken = token; }