|
21 | 21 | import org.hibernate.sql.ast.tree.from.ValuesTableReference; |
22 | 22 | import org.hibernate.sql.ast.tree.insert.ConflictClause; |
23 | 23 | import org.hibernate.sql.ast.tree.insert.InsertSelectStatement; |
| 24 | +import org.hibernate.sql.ast.tree.select.QueryGroup; |
24 | 25 | import org.hibernate.sql.ast.tree.select.QueryPart; |
25 | 26 | import org.hibernate.sql.ast.tree.select.QuerySpec; |
26 | 27 | import org.hibernate.sql.ast.tree.select.SelectClause; |
@@ -60,11 +61,14 @@ protected void renderSelectExpression(Expression expression) { |
60 | 61 |
|
61 | 62 | @Override |
62 | 63 | protected void visitSqlSelections(SelectClause selectClause) { |
63 | | - if ( supportsSkipFirstClause() ) { |
64 | | - renderSkipFirstClause( (QuerySpec) getQueryPartStack().getCurrent() ); |
65 | | - } |
66 | | - else { |
67 | | - renderFirstClause( (QuerySpec) getQueryPartStack().getCurrent() ); |
| 64 | + final QuerySpec querySpec = (QuerySpec) getQueryPartStack().getCurrent(); |
| 65 | + if ( isRowsOnlyFetchClauseType( querySpec ) ) { |
| 66 | + if ( supportsSkipFirstClause() ) { |
| 67 | + renderSkipFirstClause( querySpec ); |
| 68 | + } |
| 69 | + else { |
| 70 | + renderFirstClause( querySpec ); |
| 71 | + } |
68 | 72 | } |
69 | 73 | if ( selectClause.isDistinct() ) { |
70 | 74 | appendSql( "distinct " ); |
@@ -195,4 +199,30 @@ protected void visitInsertStatementOnly(InsertSelectStatement statement) { |
195 | 199 | public void visitValuesTableReference(ValuesTableReference tableReference) { |
196 | 200 | emulateValuesTableReferenceColumnAliasing( tableReference ); |
197 | 201 | } |
| 202 | + |
| 203 | + protected boolean shouldEmulateFetchClause(QueryPart queryPart) { |
| 204 | + // Check if current query part is already row numbering to avoid infinite recursion |
| 205 | + return useOffsetFetchClause( queryPart ) && getQueryPartForRowNumbering() != queryPart |
| 206 | + && getDialect().supportsWindowFunctions() && !isRowsOnlyFetchClauseType( queryPart ); |
| 207 | + } |
| 208 | + |
| 209 | + @Override |
| 210 | + public void visitQueryGroup(QueryGroup queryGroup) { |
| 211 | + if ( shouldEmulateFetchClause( queryGroup ) ) { |
| 212 | + emulateFetchOffsetWithWindowFunctions( queryGroup, true ); |
| 213 | + } |
| 214 | + else { |
| 215 | + super.visitQueryGroup( queryGroup ); |
| 216 | + } |
| 217 | + } |
| 218 | + |
| 219 | + @Override |
| 220 | + public void visitQuerySpec(QuerySpec querySpec) { |
| 221 | + if ( shouldEmulateFetchClause( querySpec ) ) { |
| 222 | + emulateFetchOffsetWithWindowFunctions( querySpec, true ); |
| 223 | + } |
| 224 | + else { |
| 225 | + super.visitQuerySpec( querySpec ); |
| 226 | + } |
| 227 | + } |
198 | 228 | } |
0 commit comments