Fix issues with Oracle rownum pagination on Oracle before version 12.2

This commit is contained in:
Christian Beikov 2022-01-04 15:09:09 +01:00
parent 4e29f8d9de
commit de1de9f629
1 changed files with 22 additions and 4 deletions

View File

@ -126,6 +126,25 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
return true; return true;
} }
@Override
protected FetchClauseType getFetchClauseTypeForRowNumbering(QueryPart queryPart) {
final FetchClauseType fetchClauseType = super.getFetchClauseTypeForRowNumbering( queryPart );
final boolean hasOffset;
if ( queryPart.isRoot() && hasLimit() ) {
hasOffset = getLimit().getFirstRow() != null;
}
else {
hasOffset = queryPart.getOffsetClauseExpression() != null;
}
if ( queryPart instanceof QuerySpec && !hasOffset && fetchClauseType == FetchClauseType.ROWS_ONLY ) {
// We return null here, because in this particular case, we render a special rownum query
// which can be seen in #emulateFetchOffsetWithWindowFunctions
// Note that we also build upon this in #visitOrderBy
return null;
}
return fetchClauseType;
}
@Override @Override
protected void emulateFetchOffsetWithWindowFunctions( protected void emulateFetchOffsetWithWindowFunctions(
QueryPart queryPart, QueryPart queryPart,
@ -138,7 +157,7 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
final QuerySpec querySpec = (QuerySpec) queryPart; final QuerySpec querySpec = (QuerySpec) queryPart;
withRowNumbering( withRowNumbering(
querySpec, querySpec,
false, true, // we need select aliases to avoid ORA-00918: column ambiguously defined
() -> { () -> {
final QueryPart currentQueryPart = getQueryPartStack().getCurrent(); final QueryPart currentQueryPart = getQueryPartStack().getCurrent();
final boolean needsParenthesis; final boolean needsParenthesis;
@ -210,10 +229,9 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
renderOrderBy( true, sortSpecifications ); renderOrderBy( true, sortSpecifications );
} }
else { else {
// This logic is tightly coupled to emulateFetchOffsetWithWindowFunctions // This logic is tightly coupled to #emulateFetchOffsetWithWindowFunctions and #getFetchClauseTypeForRowNumbering
// so that this is rendered when we end up in the special case for Oracle that renders a rownum filter // so that this is rendered when we end up in the special case for Oracle that renders a rownum filter
final FetchClauseType fetchClauseType = getFetchClauseTypeForRowNumbering( queryPartForRowNumbering ); if ( getFetchClauseTypeForRowNumbering( queryPartForRowNumbering ) == null ) {
if ( fetchClauseType == FetchClauseType.ROWS_ONLY && queryPartForRowNumbering instanceof QuerySpec ) {
final QuerySpec querySpec = (QuerySpec) queryPartForRowNumbering; final QuerySpec querySpec = (QuerySpec) queryPartForRowNumbering;
if ( querySpec.getOffsetClauseExpression() == null if ( querySpec.getOffsetClauseExpression() == null
&& ( !querySpec.isRoot() || getOffsetParameter() == null ) ) { && ( !querySpec.isRoot() || getOffsetParameter() == null ) ) {