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

Query: Adds translation support for single key single value select GROUP BY LINQ queries #4074

Merged
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e1ceebb
preliminary change
Aug 25, 2023
8c2d289
Add some more boiler plate code
Aug 29, 2023
ccba9f2
move all linq test to the same folder; add some groupBy test
Aug 29, 2023
72b315c
fix references error in test refactoring
Aug 30, 2023
d962b02
preliminary for the groupby functions with key and value selector
Sep 7, 2023
36d668e
trying to change collection inputs for group by
Sep 11, 2023
73ea3c6
WIP bookmark
Sep 12, 2023
dc50d78
Successfully ignore "key"
Sep 18, 2023
e42ae59
clean up code
Sep 19, 2023
2244764
Sucessfully bind the case of group by with only key selector and no v…
Sep 19, 2023
df9362e
enable one group by test
Sep 26, 2023
7790ab7
merge with master
Sep 26, 2023
da48bfc
Merge branch 'master' into users/leminh/LINQGroupBySupport
Sep 26, 2023
44d3736
add support for aggregate value selector
Sep 26, 2023
7631e82
added baseline
Sep 27, 2023
b4b1658
working on adding support for multivalue value selector and key selector
Sep 27, 2023
787839d
code clean up
Oct 13, 2023
7da5772
Merge branch 'master' into users/leminh/LINQGroupBySupport
Oct 13, 2023
e8f8f62
more clean up
Oct 13, 2023
f589069
more clean up
Oct 13, 2023
bca5953
update test
Oct 13, 2023
544931a
Move test to separate file
Dec 11, 2023
a7888d8
code clean up
Dec 11, 2023
6b7fb50
remove baseline file that got moved
Dec 11, 2023
d23c29d
merge with master
Dec 11, 2023
5a4470b
fix merge issue
Dec 11, 2023
84e4c2f
merge with master
Jan 25, 2024
1e80e2d
Changes test infrastructure to reflect changes from Master
Jan 25, 2024
0b08efd
address code review part 1
Jan 25, 2024
9a6eacf
Address code review 2 and adds code coverage
Jan 25, 2024
f73baf1
Merge branch 'master' into users/leminh/LINQGroupBySupport
leminh98 Jan 25, 2024
9f77356
Addressed code review and added tests. Still a couple of bugs to iron…
Feb 6, 2024
105a335
Merge branch 'users/leminh/LINQGroupBySupport' of https://github.com/…
Feb 6, 2024
25c7080
resolve merge conflict with master
Feb 6, 2024
430f96a
Fix group by translation issue and add more test
Feb 7, 2024
d1ec2c5
update comments
Mar 6, 2024
fc32e3a
address pr comment
Apr 1, 2024
33a2c9b
Merge branch 'master' into users/leminh/LINQGroupBySupport
leminh98 Apr 1, 2024
2444be7
Merge branch 'master' into users/leminh/LINQGroupBySupport
adityasa Apr 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 128 additions & 17 deletions Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs

Large diffs are not rendered by default.

143 changes: 108 additions & 35 deletions Microsoft.Azure.Cosmos/src/Linq/QueryUnderConstruction.cs

Large diffs are not rendered by default.

35 changes: 28 additions & 7 deletions Microsoft.Azure.Cosmos/src/Linq/TranslationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ internal sealed class TranslationContext
/// </summary>
public IDictionary<object, string> Parameters;

/// <summary>
/// Dictionary for group by key substitution.
/// </summary>
public ParameterSubstitution GroupByKeySubstitution;

/// <summary>
/// Boolean to indicate a GroupBy expression is the last expression to finished processing.
/// </summary>
public bool LastExpressionIsGroupBy;

/// <summary>
/// If the FROM clause uses a parameter name, it will be substituted for the parameter used in
/// the lambda expressions for the WHERE and SELECT clauses.
Expand Down Expand Up @@ -86,6 +96,7 @@ public TranslationContext(CosmosLinqSerializerOptionsInternal linqSerializerOpti
this.subqueryBindingStack = new Stack<SubqueryBinding>();
this.Parameters = parameters;
this.clientOperation = null;
this.LastExpressionIsGroupBy = false;

if (linqSerializerOptionsInternal?.CustomCosmosLinqSerializer != null)
{
Expand All @@ -104,6 +115,8 @@ public TranslationContext(CosmosLinqSerializerOptionsInternal linqSerializerOpti
this.CosmosLinqSerializer = TranslationContext.DefaultLinqSerializer;
this.MemberNames = TranslationContext.DefaultMemberNames;
}

this.GroupByKeySubstitution = new ParameterSubstitution();
}

public ScalarOperationKind ClientOperation => this.clientOperation ?? ScalarOperationKind.None;
Expand All @@ -120,17 +133,25 @@ public void SetClientOperation(ScalarOperationKind clientOperation)

public Expression LookupSubstitution(ParameterExpression parameter)
{
if (this.CurrentQuery.GroupByParameter != null)
{
Expression groupBySubstitutionExpression = this.GroupByKeySubstitution.Lookup(parameter);
if (groupBySubstitutionExpression != null)
{
return groupBySubstitutionExpression;
}
}
return this.substitutions.Lookup(parameter);
}

public ParameterExpression GenFreshParameter(Type parameterType, string baseParameterName)
public ParameterExpression GenerateFreshParameter(Type parameterType, string baseParameterName, bool includeSuffix = true)
{
return Utilities.NewParameter(baseParameterName, parameterType, this.InScope);
return Utilities.NewParameter(baseParameterName, parameterType, this.InScope, includeSuffix);
}

public Func<string, ParameterExpression> GetGenFreshParameterFunc()
{
return (paramName) => this.GenFreshParameter(typeof(object), paramName);
return (paramName) => this.GenerateFreshParameter(typeof(object), paramName);
}

/// <summary>
Expand Down Expand Up @@ -211,12 +232,12 @@ public void PushCollection(Collection collection)
throw new ArgumentNullException("collection");
}

this.collectionStack.Add(collection);
if (this.CurrentQuery.GroupByParameter == null) this.collectionStack.Add(collection);
}

public void PopCollection()
{
this.collectionStack.RemoveAt(this.collectionStack.Count - 1);
if (this.CurrentQuery.GroupByParameter == null) this.collectionStack.RemoveAt(this.collectionStack.Count - 1);
}

/// <summary>
Expand All @@ -226,7 +247,7 @@ public void PopCollection()
/// <param name="name">Suggested name for the input parameter.</param>
public ParameterExpression SetInputParameter(Type type, string name)
{
return this.CurrentQuery.fromParameters.SetInputParameter(type, name, this.InScope);
return this.CurrentQuery.FromParameters.SetInputParameter(type, name, this.InScope);
}

/// <summary>
Expand All @@ -237,7 +258,7 @@ public ParameterExpression SetInputParameter(Type type, string name)
public void SetFromParameter(ParameterExpression parameter, SqlCollection collection)
{
Binding binding = new Binding(parameter, collection, isInCollection: true);
this.CurrentQuery.fromParameters.Add(binding);
this.CurrentQuery.FromParameters.Add(binding);
}

/// <summary>
Expand Down
7 changes: 4 additions & 3 deletions Microsoft.Azure.Cosmos/src/Linq/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ public static LambdaExpression GetLambda(Expression expr)
/// <param name="prefix">Prefix for the parameter name.</param>
/// <param name="type">Parameter type.</param>
/// <param name="inScope">Names to avoid.</param>
/// <param name="includeSuffix">Enable suffix to parameter name</param>
/// <returns>The new parameter.</returns>
public static ParameterExpression NewParameter(string prefix, Type type, HashSet<ParameterExpression> inScope)
public static ParameterExpression NewParameter(string prefix, Type type, HashSet<ParameterExpression> inScope, bool includeSuffix = true)
{
int suffix = 0;
while (true)
{
string name = prefix + suffix.ToString(CultureInfo.InvariantCulture);
string name = prefix + (includeSuffix ? suffix.ToString(CultureInfo.InvariantCulture) : string.Empty);
ParameterExpression param = Expression.Parameter(type, name);
if (!inScope.Any(p => p.Name.Equals(name)))
if (!inScope.Any(p => p.Name.Equals(name)) || !includeSuffix)
{
inScope.Add(param);
return param;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ public override void Visit(SqlQuery sqlQuery)

if (sqlQuery.GroupByClause != null)
{
this.WriteDelimiter(string.Empty);
sqlQuery.GroupByClause.Accept(this);
this.writer.Write(" ");
}
Expand Down
Loading
Loading