Skip to content
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

Reduce cast usage for aggregate functions #2036

Merged
merged 30 commits into from
Feb 20, 2020

Conversation

maca88
Copy link
Contributor

@maca88 maca88 commented Mar 2, 2019

This PR uses the dialect specific SUM function to determine whether cast is needed or not and also takes nullable types into consideration, which fixes #2029.
Note:
The cast usage was not reduced for SQLite as it needs it when sum expression contains a parameter.

Edit: this PR has been extended to other aggregate functions.

hazzik
hazzik previously requested changes Mar 10, 2019
Copy link
Member

@hazzik hazzik left a comment

Choose a reason for hiding this comment

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

Some of the logic is not necessary and/or, probably, needs to be extended to other functions of similar nature.

@maca88
Copy link
Contributor Author

maca88 commented Mar 11, 2019

I've made a more sophisticated logic that can be used also for other aggregates like COUNT and AVG. Instead of checking the ReturnedClass property, the logic is now comparing SqlTypes which should be more correct as the cast is done on the database level. The logic was applied also for AVG but not for COUNT as I found out that the registered function count_big for MsSql2000Dialect is not used for hql queries and would not add a cast for a long type (COUNT in Sql Server returns an int). It seems that NH-865 was never tested. I will try to address the count issue for Sql Server in a separate PR.

: persister.EntityMetamodel.PropertyTypes[index.Value];
}

private string TryGetEntityName(MemberExpression memberExpression)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copied from #1996.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After doing #2079 I found out that this method does not cover all cases. I will update this method and try to add additional tests that cover the edge cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method was improved and exposed for internal usage by #1996. I am thinking to leave this PR as WIP until #1996 get merged in order to replace this method with the new one.

@hazzik hazzik self-requested a review March 13, 2019 01:22
@hazzik hazzik dismissed their stale review March 13, 2019 01:23

PR updated

@maca88 maca88 changed the title Reduce cast usage for SUM aggregate function WIP - Reduce cast usage for SUM aggregate function Mar 14, 2019
@maca88 maca88 changed the title WIP - Reduce cast usage for SUM aggregate function Reduce cast usage for SUM aggregate function Mar 16, 2019
? _hqlTreeBuilder.Cast(VisitExpression(expression.Operand).AsExpression(), expression.Type)
// Make a transparent cast when an IType exists, so that it can be used to retrieve the value from the data reader
: existType
? _hqlTreeBuilder.TransparentCast(VisitExpression(expression.Operand).AsExpression(), expression.Type)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have to recheck this as TransparentCast does support only a few types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added an additional check for calling TransparentCast , as there is an edge case when casting to a custom registered type.

@maca88 maca88 changed the title Reduce cast usage for SUM aggregate function WIP - Reduce cast usage for SUM aggregate function Apr 7, 2019
@maca88
Copy link
Contributor Author

maca88 commented Apr 7, 2019

Set to WIP as I need to revisit this PR, see the comments above.

@maca88
Copy link
Contributor Author

maca88 commented Oct 1, 2019

Rebased and updated TryGetEntityName (from #1996) and SupportsType (from #2079) methods.

@maca88 maca88 changed the title WIP - Reduce cast usage for SUM aggregate function Reduce cast usage for SUM aggregate function Oct 1, 2019
@@ -225,10 +213,24 @@ public static class ExpressionsHelper
out currentComponentType);
break;
case IAbstractComponentType componentType:
// Concatenate the component property path in order to be able to use EntityMetamodel.GetPropertyType to retrieve the type.
// As GetPropertyType supports only components, do not concatenate when dealing with collection composite elements or elements.
if (!currentType.IsAnyType)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for cleaning the code. I've removed this condition as it is no longer needed because AnyType also implements IAssociationType, so it will be handled by the above case.

if (memberPaths.Count == 0)
{
memberPath = currentEntityPersister != null || currentComponentType != null ? member.Path : null;
mappedType = GetType(currentEntityPersister, currentType, member, sessionFactory, out _);
Copy link
Member

@hazzik hazzik Oct 11, 2019

Choose a reason for hiding this comment

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

Are you using this GetType method in other PRs? If no, I think the last argument needs to be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I've removed it.

@maca88
Copy link
Contributor Author

maca88 commented Oct 29, 2019

I've updated the TryGetMappedType method to support polymorphic queries, coalesce and conditional expressions, which will be needed for #2079 in order to detect parameter types.

sqlType = factory.Dialect.GetCastTypeName(sqlTypeCodes[0]);
if (sqlType == null)
{
//TODO: never reached, since GetTypeName() actually throws an exception!
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't make sense using the type name when the dialect doesn't support the cast. If the cast would be supported, GetCastTypeName should return it.

@maca88
Copy link
Contributor Author

maca88 commented Nov 13, 2019

Rebased.

@fredericDelaporte fredericDelaporte changed the title Reduce cast usage for SUM aggregate function Reduce cast usage for aggregate functions Feb 16, 2020
Copy link
Member

@fredericDelaporte fredericDelaporte left a comment

Choose a reason for hiding this comment

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

I have adjusted the TryGetMappedTests.Assert... names for them to be more explicit.
And I have adjusted this PR title.

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.

Incorrect SQL for cast inside an aggregate (MS SQL)
3 participants