Skip to content

Improves filtering by enum #193

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
merged 13 commits into from
Nov 24, 2021
Merged

Improves filtering by enum #193

merged 13 commits into from
Nov 24, 2021

Conversation

alex-kulakov
Copy link
Contributor

Addresses #189

In certain cases Translator changes binary expression to make following operations not add cast of column to real underlying type of the enum constants. Basically, it works around C# compiler feature of using integer constants instead of smaller types constants e.g byte constants.

if (b.Left.StripCasts().Type.StripNullable().IsEnum
&& b.Right.StripCasts().NodeType == ExpressionType.Constant) {

var rawEnum = b.Left.StripCasts();
Copy link
Contributor

Choose a reason for hiding this comment

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

That one is used in the if condition above so it makes sense to move the variable declaration before the if statement.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd even declared two variables

  var rawLeftEnum = b.Left.StripCasts();
  var rawRightEnum = b.Right.StripCasts();

or even four

  var rawLeftEnum = b.Left.StripCasts();
  var rawLeftEnumType = rawLeftEnum.Type;
  var rawRightEnum = b.Right.StripCasts();
  var rawRightEnumType = rawRightEnum.Type;

that way we could avoid multiple excessive method and property getter calls.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, thank you

@@ -207,6 +207,30 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
right = Visit(binaryExpression.Right);
}
}
// Following two checks for enums are here to improve result query
// performance because they let not to cast columns to integer.
else if (EnumRewritableOperations(binaryExpression)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just have a single else if statement for the EnumRewritableOperations case? In that case, you could declare four variables as I suggested for the PartialIndexFilterBuilder inside that else if block. The cost of that is a duplicated block

      else {
        left = Visit(binaryExpression.Left);
        right = Visit(binaryExpression.Right);
      }

but as for me, it is worth it.
Also please pay attention to the EnumRewritableOperations method implementation. We can avoid allocations there.

? rawEnum.Type.StripNullable().GetEnumUnderlyingType().ToNullable()
: rawEnum.Type.GetEnumUnderlyingType();
if (bareLeftType.IsEnum && bareRight.NodeType == ExpressionType.Constant) {
var typeToCast = bareLeft.Type.IsNullable()
Copy link
Contributor

Choose a reason for hiding this comment

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

Still accessing the Type property here.

if (bareLeftType.IsEnum && bareRight.NodeType == ExpressionType.Constant) {
var typeToCast = bareLeft.Type.IsNullable()
? bareLeftType.GetEnumUnderlyingType().ToNullable()
: bareLeft.Type.GetEnumUnderlyingType();
Copy link
Contributor

Choose a reason for hiding this comment

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

and here

? rawEnum.Type.StripNullable().GetEnumUnderlyingType().ToNullable()
: rawEnum.Type.GetEnumUnderlyingType();
else if (bareRightType.IsEnum && bareLeft.NodeType == ExpressionType.Constant) {
var typeToCast = bareRight.Type.IsNullable()
Copy link
Contributor

Choose a reason for hiding this comment

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

and here

else if (bareRightType.IsEnum && bareLeft.NodeType == ExpressionType.Constant) {
var typeToCast = bareRight.Type.IsNullable()
? bareRightType.GetEnumUnderlyingType().ToNullable()
: bareRight.Type.GetEnumUnderlyingType();
Copy link
Contributor

Choose a reason for hiding this comment

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

and here

var bareRightType = bareRight.Type.StripNullable();

if (bareLeftType.IsEnum && bareRight.NodeType == ExpressionType.Constant) {
var typeToCast = bareLeft.Type.IsNullable()
Copy link
Contributor

Choose a reason for hiding this comment

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

same

if (bareLeftType.IsEnum && bareRight.NodeType == ExpressionType.Constant) {
var typeToCast = bareLeft.Type.IsNullable()
? bareLeftType.GetEnumUnderlyingType().ToNullable()
: bareLeft.Type.GetEnumUnderlyingType();
Copy link
Contributor

Choose a reason for hiding this comment

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

one more

right = Visit(Expression.Convert(binaryExpression.Right, typeToCast));
}
else if (bareRightType.IsEnum && bareLeft.NodeType == ExpressionType.Constant) {
var typeToCast = (bareRight.Type.IsNullable())
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 more

else if (bareRightType.IsEnum && bareLeft.NodeType == ExpressionType.Constant) {
var typeToCast = (bareRight.Type.IsNullable())
? bareRightType.GetEnumUnderlyingType().ToNullable()
: bareRight.Type.GetEnumUnderlyingType();
Copy link
Contributor

Choose a reason for hiding this comment

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

and also this one

@alex-kulakov alex-kulakov merged commit e7c82cc into 6.0 Nov 24, 2021
@alex-kulakov alex-kulakov deleted the 6.0-enum-improvements branch November 24, 2021 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants