History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: NH-1197
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: David Bachmann
Votes: 2
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
NHibernate

Some tests related to paged subselect are failing under PostgreSQL

Created: 12/Nov/07 08:30 AM   Updated: 10/Nov/08 06:31 AM
Component/s: DataProviders / Dialects
Affects Version/s: 1.2.1
Fix Version/s: 2.1.0.Alpha1

File Attachments: 1. Text File debuglog.txt (189 kb)
2. Text File log-1.2.x-ShouldNotLoadAllChildrenInPagedSubSelect.txt (120 kb)
3. Text File log-1.2.x-SubselectFetchWithLimit.txt (92 kb)
4. Text File NH1197-Workaround-DisablePostgreSQLDialectVariableLimit.patch (2 kb)
5. Text File nh1197.patch (4 kb)

Issue Links:
Related
 


 Description  « Hide
I've encountered some strange behaviour with two tests under PostgreSQL (with current trunk r3096).
The following tests are failing:

NHibernate.Test.SubselectFetchTest.SubselectFetchFixture.SubselectFetchWithLimit()
NHibernate.Test.Criteria.CriteriaQueryTest.NH_1155_ShouldNotLoadAllChildrenInPagedSubSelect()

Apparently the limit parameters are not 'binded' to the command.
Note that all other tests that uses SetMaxResults() and/or SetFirstResult() are working well.

Current implementation of the PostgreSQLDialect uses the following configuration for paged queries:
 SupportsLimit: true
 SupportsLimitOffset: true
 SupportsVariableLimit: true
 BindLimitParametersInReverseOrder: true
 UseMaxForLimit: false
 BindLimitParametersFirst: false
 override SqlString GetLimitString(SqlString querySqlString, bool hasOffset)


I've tried to modify the dialect in order to not use parameters for 'limit' statements and the problem was corrected.
This solution could eventually be used as a workaround for people who are experiencing problem with paged subselect under PostgreSQL.

Full debug log is attached.

This was discovered under PostgreSQL 8.2 using Npgsql1.0, but is not related to a specific version of PostgreSQL or Npgsql.

 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
David Bachmann - 26/Nov/07 08:58 AM
After running the unit tests against 1.2.x branch (r3141) I realize that the same exceptions are thrown.

Could someone with the necessaries privileges change the affected version of this issue to 1.2.1? thanks.

The following new files are attached:
log-1.2.x-ShouldNotLoadAllChildrenInPagedSubSelect.txt
log-1.2.x-SubselectFetchWithLimit.txt

They include an indication of where the test fails and the full debug log executed against branch 1.2.x (r3141) (under PostgreSQL 8.0 using Npgsql2.0beta1)

David Bachmann - 26/Nov/07 09:00 AM
Full debug log for test NHibernate.Test.Criteria.CriteriaQueryTest.NH_1155_ShouldNotLoadAllChildrenInPagedSubSelect()
executed against 1.2.x branch

David Bachmann - 26/Nov/07 09:00 AM
Full debug log for test NHibernate.Test.SubselectFetchTest.SubselectFetchFixture.SubselectFetchWithLimit()
executed against 1.2.x branch

Ayende Rahien - 27/Jun/08 05:32 AM
Wow, that took some finding.
The issue is in SubselectFetch. We are building the query there, including the limit string, but along the way, we lose the parameters for the binding.
This is not an issue generally because most dialect just put the limit inline, without parameters, in this case, it is obviously not the case, and it is causing issues.
Need some thinking...

Ayende Rahien - 27/Jun/08 02:29 PM
This is a partial fix to this issue.
It ensure that we are correctly binding the parameters (and simplifies the SubselectFetch considerably).
However, it also breaks SubselectFetchFixture.SubselectFetchWithLimit testcase, and I am not sure why.

Fabio Maulo - 28/Jun/08 11:47 AM
In practices the patch is a revert of r3020. I'm working on the issue looking a way to fix NH-1155 maintaining the same behavior of H3.2.

Ayende Rahien - 28/Jun/08 12:10 PM
No, it is not a revert, it is moving the functionality.
Note that we are now explicitly setting the row selection, which allows the code to know what the paging is.

Fabio Maulo - 29/Jun/08 01:36 PM
I don't have Postgre but I think that the solution is easy.
Try the override of GetLimitString(SqlString, int, int) in the Postgre dialect and send us a patch when the work is done.

This is the candidate implementation:
public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit)
{
SqlStringBuilder pagingBuilder = new SqlStringBuilder();
pagingBuilder.Add(querySqlString);
pagingBuilder.Add(" limit " + limit);

if (offset > 0)
{
pagingBuilder.Add(" offset " + offset);
}

return pagingBuilder.ToSqlString();
}

Thanks.

David Bachmann - 14/Jul/08 11:41 AM
So, as apparently 1.2.x is closed, I've re-passed every tests on 2.0.x branch (r3636)

The following tests are failing with the symptoms described above:
- NHibernate.Test.SubselectFetchTest.SubselectFetchFixture.SubselectFetchWithLimit()
- NHibernate.Test.Criteria.CriteriaQueryTest.NH_1155_ShouldNotLoadAllChildrenInPagedSubSelect()
- NHibernate.Test.Criteria.CriteriaQueryTest.AllowToSetLimitOnSubqueries()

I've tried to pass those three tests against MySQL 5.1, using MySQLDialect.
This dialect uses parameters for limits (variable limit), as does PostgreSQLDialect.
The three tests are failing in a similar way than with PostgreSQL, even that in this case the error message is much more 'verbose':
> MySql.Data.MySqlClient.MySqlException: Parameter '?p0' must be defined.


In conclusion:
NH does not handle correctly SubSelects and 'Variable Limits', independently of the used database.
(and it's maybe the reason why many dialects do not use 'variable limits', even if they technically could)


Fabio, the solution that you describe in your last comment works, that's what I briefly referred as an eventual workaround in my initial post.
I've attached a patch with this workaround, even if I think that it shouldn't be applied.
The problem is somewhere in NH core and fix this issue that way will not solve the real problem.

Unfortunately I haven't enough NH internals knowledges to provide a better patch, sorry.

Tell me if/how I can help you solve this.
many thanks

Kenneth siewers Møller - 06/Nov/08 06:08 PM
This is a serious bug in the PostgreSQL dialect. I have tried the patch, and it works for version 2.0.1, but I have no real insight in NHibernate to actually determine how this patch affects the rest of the usage.

Is there any news on this issue?

Fabio Maulo - 08/Nov/08 03:27 PM
which patch ?

Fabio Maulo - 10/Nov/08 04:34 AM
Decision taken.
The problem here is the patch of NH-1155. Fixing NH-1155 we had introduce a deviation from H3.2 behavior and a series of bug for all Dialects that are supporting "variable-limits".
The decision is : revert NH-1155 patch.

Kenneth siewers Møller - 10/Nov/08 05:54 AM
Well, I guess it is the patch David Bachmann has attached to this issue. I didn't apply the actual patch however, but rather copied the snippet you provided.
It seems to work as I am using the limit and offset functions in PostgreSQL intensively in a project I'm currently working on.

But as David said, It might have something to do with the inner workings of NHibernate.

I did a compare to Hibernate's PostgreSQLDialect, and it seems to be a bit different...

Fabio Maulo - 10/Nov/08 06:29 AM
Fixed reverting NH-1155 and supporting "Variable-Limit" for Postgre dialect.
Who want work with Postgre in NH2.0 can apply the workaround.
Who are working with trunk have all working as expected.