[hibernate-dev] SQLServer getLimitString() refactoring
Steve Ebersole
steve at hibernate.org
Wed Jun 13 15:27:18 EDT 2012
So frustrating that we could do this so much cleaner if we were dealing
with syntax trees instead of strings. The dialect could just position
the limit parameter nodes correctly in the tree and that would be that.
Minor, but I'd like to see something other than
bindLimitParametersPreQuery and bindLimitParametersPostQuery. The
parameters are still part of the query so its not really before the
query or after it. bindLimitParametersAtStartOfQuery and
bindLimitParametersAtEndOfQuery?
Also (and the old code did this as well) I notice a lot of calling to
the dialect just to prepare the arguments that you pass in to
bindLimitParametersPreQuery and bindLimitParametersPostQuery. I'd like
to see that cleaned up. Mainly its the interpretation of
org.hibernate.engine.spi.RowSelection. For example, both
interpretFirstRow and getMaxOrLimit are basically calls to the dialect.
Then your new code in Loader can go from
col += dialect.bindLimitParametersPostQuery(
sql,
st,
col,
interpretFirstRow( getFirstRow( selection ) ),
getMaxOrLimit( selection, dialect )
);
to just:
col += dialect.bindLimitParametersPostQuery(
sql,
st,
col,
selection
);
Also, I wonder if it might be better to introduce a delegate for "limit
support" into the Dialect. I have been thinking of this approach for a
few Dialect-related things. Basically right now the Dialect is asked
to do a few things in steps all specific to managing limits on the SQL
query. First it is asked to modify the actual query statement; then
Loader does some other stuff; then it is asked to handle binding
parameters representing to the limit values. Based on the code I see
for SQL Server there is some duplication in that last step to figure
out what it did in the first step.
if ( useLimit ) {
sql = dialect.getLimitString(
sql.trim(), //use of trim() here is ugly?
useLimitOffset ? getFirstRow(selection) : 0,
getMaxOrLimit(selection, dialect)
);
}
What if, instead, we did something like:
final LimitHandler limitHandler = useLimit
? dialect.buildLimitHandler( sql.trim(), selection )
: NoopLimitHandler.INSTANCE;
sql = limitHandler.getProcessedSql();
...
col += limitHandler.bindLimitParametersAtStartOfQuery( st, col );
...
col += limitHandler.bindLimitParametersAtEndOfQuery( st, col );
On Wed 13 Jun 2012 01:58:30 PM CDT, Łukasz Antoniak wrote:
> Hello Guenther,
>
> I totally agree that user could adapt his query to use "AS" keyword, while we focus on keeping getLimitString() most fast and
> simple as possible.
>
> I think that my modifications are more or less ready and you can view them here:
> https://github.com/lukasz-antoniak/hibernate-core/compare/SQLServerLimitString
> TOP(100)PERCENT and ORDER BY issue fixed plus introduced limit parameters binding in Dialect class.
>
> Query "select id, description descr, (select max(id) from Product2) maximum from Product2" fails for me (even without paging):
> 19:50:29,046 ERROR ErrorCounter:54 - line 1:24: unexpected token: descr
> 19:50:29,046 ERROR ErrorCounter:50 - line 1:24: unexpected token: descr
> line 1:24: unexpected token: descr
> at org.hibernate.hql.internal.antlr.HqlBaseParser.identPrimary(HqlBaseParser.java:4016)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.primaryExpression(HqlBaseParser.java:859)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.atom(HqlBaseParser.java:3390)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.unaryExpression(HqlBaseParser.java:3168)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.multiplyExpression(HqlBaseParser.java:3040)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.additiveExpression(HqlBaseParser.java:2750)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.concatenation(HqlBaseParser.java:568)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.relationalExpression(HqlBaseParser.java:2518)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.equalityExpression(HqlBaseParser.java:2379)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.negatedExpression(HqlBaseParser.java:2343)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalAndExpression(HqlBaseParser.java:2259)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalOrExpression(HqlBaseParser.java:2224)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.expression(HqlBaseParser.java:2010)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.aliasedExpression(HqlBaseParser.java:2177)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.selectedPropertiesList(HqlBaseParser.java:1390)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.selectClause(HqlBaseParser.java:1293)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.selectFrom(HqlBaseParser.java:1030)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:700)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:294)
> at org.hibernate.hql.internal.antlr.HqlBaseParser.statement(HqlBaseParser.java:157)
> at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:266)
> at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:180)
> at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
> at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:105)
> at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
> at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168)
> at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:219)
> at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:197)
> at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1736)
> ...
> 19:50:29,062 WARN HqlParser:259 - HHH000203: processEqualityExpression() : No expression to process!
> ...
>
> Best Regards,
> Lukasz Antoniak
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
--
steve at hibernate.org
http://hibernate.org
More information about the hibernate-dev
mailing list