Skip to content

Obsolete MultiQuery and MultiCriteria #1783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

fredericDelaporte
Copy link
Member

@fredericDelaporte fredericDelaporte commented Jul 5, 2018

The QueryBatch can replace them both, and does not suffer of some of their bugs.

This is a follow-up to #1718 (Combine Future queries for ICriteria and IQuery), which has added the QueryBatch.

At first I was considering adding to it the SetParameter capabilities of MultiQuery, so I was considering better to do that in another PR. But finally, I think we can drop that feature, as it does not make sense for most querying API handled: Criteria, QueryOver and Linq. Only HQL and SQL queries can benefit of it.

Closes #840 by obsoleting the not already fixed part of it.
Closes #1344 by obsoleting the not already fixed part of it.

in a single round trip. A simple use case is executing a paged query while
also getting the total count of results, in a single round-trip. Here is a simple
example:
You can also add queries as future queries to a query batch:

This comment was marked as outdated.

@@ -340,7 +341,7 @@ public void FunctionsOrder()
}
}

[Test]
[Test, Obsolete]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For each obsoleted test, I have added a query batch counterpart.

public class QueryBatchFixture : TestCase
{
// This fixture aggregates most of the tests from MultiCriteriaFixture, MultipleMixedQueriesFixture and
// MultipleQueriesFixture, rewritten for using QueryBatch instead of obsoleted MultiCriteria/MultiQuery.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three obsoleted multi-query/criteria fixtures have their counterparts with query batch here. I have dropped some tests which were a bit redundant.


Sfi.Statistics.Clear();
DoMultiCriteriaAndAssert();
Assert.That(Sfi.Statistics.PrepareStatementCount, Is.EqualTo(0), "Prepared statements");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original test was doing something quite more elaborated, but brittle: it was hacking the cache to directly alter the cached representation in it with fake values, then it was re-executing the queries and checking it was receiving the fakes values.
Sure, that way, we are certain the cache has been hit, but it heavily relies on its current implementation, on the disassemble/assemble implementation, ... So I have replaced that by a statistics check.

var r = s.CreateMultiCriteria().Add(DetachedCriteria.For<Country>()).Add(DetachedCriteria.For<Continent>()).List();
#pragma warning restore 618
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test does test many other things, so I have just disabled the obsolete warning for the multi-part. (And added a query batch counterpart below.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To simplify removing obsoleted things later I think it's better scope this disable warning to the whole block that should be remove.

if (queryParameters.HasAutoDiscoverScalarTypes)
{
loader.AutoDiscoverTypes(reader, queryParameters, null);
loader.AutoDiscoverTypes(reader, queryParameters, forcedResultTransformer);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null value was originating from the MultiQuery implementation, which has a special cache handling, due to caching all queries together as a single entry. But for caching queries independently, this is a bug wrecking the AutoDiscoverTypes feature. Fortunately, one of the many tests added by rewriting multi-criteria/queries tests as query batch tests has allowed to spot this bug.

@fredericDelaporte
Copy link
Member Author

Rebased and amended for accounting TestCase changes.

The QueryBatch can replace them both, and does not suffer of some of
their bugs.
@fredericDelaporte
Copy link
Member Author

Rebased for resolving conflicts with #1789.

{
var driver = Sfi.ConnectionProvider.Driver;
if (!driver.SupportsMultipleQueries)
Assert.Ignore("Driver {0} does not support multi-queries", driver.GetType().FullName);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we want to skip such tests (that are not checking that single query is executed for batch but some data conditions retrieval)? As query batch doesn't throw maybe it's good to test that it also works adequeatly when driver.SupportsMultipleQueries == false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have port existing multi-query/criteria tests without changing their conditions. Many of them would fail with drivers not supporting multiple queries, because they would see more queries executed than expected.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact none of them do check sql queries count, so these conditions were all removable. (Excepted one causing trouble to Firebird by using count as a column alias name, requiring changing the query.)

/// Get the inner Hashtable from the IQueryCache.Cache
/// </summary>
/// <returns></returns>
public static Hashtable GetHashTableUsedAsQueryCache(ISessionFactoryImplementor factory)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please clarify the reasons for this hackish method? It seems all usages are equivalent to factory.QueryCache.Clear()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I cannot. That is just the way it was done for multi-criteria/query.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact reading the code, I can: it is not used only for clearing, but also for checking directly that it gets filled with items.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it something that can be checked with "Sfi.Statistics.QueryCachePutCount"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could, assuming there are no bugs in stats. Here with this test it is really certain things are in the cache.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that's something that you are already using for other tests - CanGetMultiCriteriaFromSecondLevelCache for example.
So the whole usage seems to be analog of clearing statistics and checking put counts. IMHO we should get rid of this method for good.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I know it is done for other tests. About tests I do not think consistency in the way things are tested is good. Instead, testing with different ways help catching more cases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point. But for me it looks like introducing dirty hack for no particular reasons (to me checking count of items in internal cache implementation doesn't add any value to existing tests - you can't say for sure that those items are stored properly and can be retrieved by the same query reexecution).

var queries = s.CreateQueryBatch()
.Add("queryOverList", s.QueryOver<Item>().Where(i => i.Category == "Food"))
.Add<long>("sqlCount",
s.CreateSQLQuery("select count(*) as count from Item i where i.Category = :cat")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this "as count" can cause issues on some dialects maybe we shouldn't use it documentation.

{
using (var s = OpenSession())
{
Console.WriteLine("*** start");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to remove these "*** star*" and "*** end" logging in ported tests.

var r = s.CreateMultiCriteria().Add(DetachedCriteria.For<Country>()).Add(DetachedCriteria.For<Continent>()).List();
#pragma warning restore 618
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To simplify removing obsoleted things later I think it's better scope this disable warning to the whole block that should be remove.

Add some more adjustments according to review
Copy link
Member

@bahusoid bahusoid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@igitur

This comment has been minimized.

@fredericDelaporte

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NH-3864 - Cacheable Multicriteria/Future'd query with aliased join throw exception NH-3835 - Future/MultiCriteria 2nd level caching
3 participants