final SessionImplementor session) throws SQLException, HibernateException {
queryParameters.processFilters( getSQLString(), session );
String sql = queryParameters.getFilteredSQL();
final Dialect dialect = getFactory().getDialect();
final RowSelection selection = queryParameters.getRowSelection();
boolean useLimit = useLimit( selection, dialect );
boolean hasFirstRow = getFirstRow( selection ) > 0;
boolean useLimitOffset = hasFirstRow && useLimit && dialect.supportsLimitOffset();
boolean callable = queryParameters.isCallable();
final boolean canScroll = getFactory().getSettings().isScrollableResultSetsEnabled();
final boolean useScrollableResultSetToSkip = hasFirstRow &&
!useLimitOffset && canScroll;
final ScrollMode scrollMode = getScrollMode( scroll, hasFirstRow, useLimit, queryParameters );
//
// if(canScroll && ( scroll || useScrollableResultSetToSkip )){
// scrollMode = scroll ? queryParameters.getScrollMode() : ScrollMode.SCROLL_INSENSITIVE;
// }else{
// scrollMode = null;
// }
if ( useLimit ) {
sql = dialect.getLimitString(
sql.trim(), //use of trim() here is ugly?
useLimitOffset ? getFirstRow(selection) : 0,
getMaxOrLimit(selection, dialect)
);
}
sql = preprocessSQL( sql, queryParameters, dialect );
PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareQueryStatement(
sql,
callable,
scrollMode
);
try {
int col = 1;
//TODO: can we limit stored procedures ?!
if ( useLimit && dialect.bindLimitParametersFirst() ) {
col += bindLimitParameters( st, col, selection );
}
if (callable) {
col = dialect.registerResultSetOutParameter( (CallableStatement)st, col );
}
col += bindParameterValues( st, queryParameters, col, session );
if ( useLimit && !dialect.bindLimitParametersFirst() ) {
col += bindLimitParameters( st, col, selection );
}
if ( !useLimit ) {
setMaxRows( st, selection );
}
if ( selection != null ) {
if ( selection.getTimeout() != null ) {
st.setQueryTimeout( selection.getTimeout() );
}
if ( selection.getFetchSize() != null ) {
st.setFetchSize( selection.getFetchSize() );
}
}
// handle lock timeout...
LockOptions lockOptions = queryParameters.getLockOptions();