Skip to content

Do not cache ExpandedQueryExpression query plan if it's based on not cacheable query expression #2300

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 1 commit into from
Jan 14, 2020

Conversation

bahusoid
Copy link
Member

@bahusoid bahusoid commented Jan 3, 2020

Fixes #2298. Do not cache ExpandedQueryExpression query plan if it's based on not cacheable query expression

It fixes regression since 5.1 with possible execution of wrong DML query for queries with parameters list (details here)

In master branch it depends on #2299 (already merged)

And async code should be re-genarated when merging to master (as test for UpdateAsync is not generated in 5.2)

@bahusoid bahusoid changed the title Disable DML LINQ caching Disable DML LINQ query plan caching Jan 3, 2020
@fredericDelaporte

This comment has been minimized.

@fredericDelaporte

This comment has been minimized.

@bahusoid
Copy link
Member Author

bahusoid commented Jan 5, 2020

So the current issue is due to the way DML query is prepared in DmlExpressionRewriter.ConvertAssignmentsToDictionaryExpression. It adds the following Select to query:

selectPartOfUpdateQuery.Select(x => new Dictionary<string, object>()
{
{"propertyPath1", updateValue1},
....
};

The problem here is that property path is stored as string constant and our ExpressionParameterVisitor detects it as query parameter and replaces it with named parameter like p1. So cache key is generated without actual info about modified properties - same key will be generated for all properties.

@bahusoid
Copy link
Member Author

bahusoid commented Jan 5, 2020

I have an idea how to fix it (see bahusoid@4f0dd7a).

Instead of dictionary I generate a block of variable assignments:

var propertyPath1 = propValue1;
var propertyPath2 = propValue2;

So in cache key it's added as (Assign(propertyPath1, p1)propertyPath1) with modified property names in key. Maybe we should make this fix in 5.2 instead?

@@ -257,6 +259,41 @@ public void PlansAreCached()
}
}

//GH-2298 - Different Update queries - same query cache plan
[Test]
public void DmlPlansAreProperlyHandled()
Copy link
Member

Choose a reason for hiding this comment

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

This test would be better put into LinqBulkManipulation namespace I think.

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 prefer to keep it here. IMHO it's very similar to PlansWithNonParameterizedConstantsAreNotCachedForExpandedQuery only for DML query. Also I think it's better to keep tests with a bit hacky reflection logic in one place (part about retrieving query plan cache).

@fredericDelaporte

This comment has been minimized.

@bahusoid

This comment has been minimized.

@bahusoid bahusoid changed the title Disable DML LINQ query plan caching WIP Disable DML LINQ query plan caching Jan 5, 2020
@bahusoid bahusoid changed the title WIP Disable DML LINQ query plan caching WIP Do not cache ExpandedQueryExpression if it's based on not cacheable query expression Jan 5, 2020
@gokhanabatay

This comment has been minimized.

@bahusoid bahusoid changed the base branch from 5.2.x to master January 6, 2020 09:57
@bahusoid bahusoid changed the title WIP Do not cache ExpandedQueryExpression if it's based on not cacheable query expression Do not cache ExpandedQueryExpression query plan if it's based on not cacheable query expression Jan 6, 2020
@bahusoid

This comment has been minimized.

@bahusoid
Copy link
Member Author

bahusoid commented Jan 6, 2020

DML test fails on master due to changes done #2229. After #2299 is merged - it's going to pass.

@bahusoid bahusoid changed the base branch from master to 5.2.x January 10, 2020 07:12
@fredericDelaporte fredericDelaporte added this to the 5.2.7 milestone Jan 12, 2020
@fredericDelaporte

This comment has been minimized.

@bahusoid

This comment has been minimized.

@hazzik

This comment has been minimized.

@hazzik

This comment has been minimized.

@hazzik

This comment has been minimized.

@hazzik

This comment has been minimized.

@fredericDelaporte

This comment has been minimized.

@hazzik

This comment has been minimized.

@fredericDelaporte

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.

4 participants