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

Add Dollar it in BuildUri response #1991

Merged
merged 11 commits into from
Feb 15, 2021
Merged

Conversation

KenitoInc
Copy link
Contributor

Issues

This pull request fixes issue #1974 .

Description

Briefly describe the changes of this pull request.

Checklist (Uncheck if it is not completed)

  • Test cases added
  • Build and test with one-click build and test script passed

Additional work necessary

If documentation update is needed, please add "Docs Needed" label to the issue and provide details about the required document change in the issue.


if (rightBinaryNode != null && IsDifferentSource(filterClause, rightBinaryNode))
{
rightBinary = "$it/" + rightBinary;
Copy link
Member

Choose a reason for hiding this comment

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

I am worry about the implementation here, does it only work for one level? I mean $it/Product? Do we work: $it/Address/City

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 should support $it/Address/City
I will add tests to validate that.

rightBinary = "$it/" + rightBinary;
}

translatedNode = leftBinary + binaryOperator + rightBinary;
Copy link
Member

Choose a reason for hiding this comment

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

translatedNode = leftBinary + binaryOperator + rightBinary; [](start = 20, length = 59)

If it's not a difference source, we should return the existing string "translateNode".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

#Resolved

Copy link
Member

@xuzhg xuzhg left a comment

Choose a reason for hiding this comment

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

🕐

@KenitoInc KenitoInc requested a review from xuzhg February 2, 2021 08:34
return this.TranslateNode(filterClause.Expression);
string translatedNode = this.TranslateNode(filterClause.Expression);

switch (filterClause.Expression.Kind)
Copy link
Member

Choose a reason for hiding this comment

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

can we refactor the implementation here?

  1. separate the whole into methods
  2. Use the traverse, for example: https://github.com/OData/WebApi/blob/master/src/Microsoft.AspNet.OData.Shared/Query/Expressions/FilterBinder.cs#L184

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@xuzhg Done

@KenitoInc KenitoInc marked this pull request as ready for review February 5, 2021 09:33
@KenitoInc KenitoInc added the Ready for review Use this label if a pull request is ready to be reviewed label Feb 5, 2021
@KenitoInc KenitoInc requested a review from xuzhg February 5, 2021 10:48
Copy link
Member

@marabooy marabooy left a comment

Choose a reason for hiding this comment

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

LGTM

SingleValueFunctionCallNode singleValueFunctionCallNode = node as SingleValueFunctionCallNode;
SingleValueOpenPropertyAccessNode singleValueOpenPropertyAccessNode = node as SingleValueOpenPropertyAccessNode;

if (binaryNode != null)
Copy link
Contributor

Choose a reason for hiding this comment

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

Alternatively,

BinaryOperatorNode binaryNode;
// ... other variable declarations

if ((binaryNode = node as BinaryOperatorNode) != null)
{
   // ...
}
// else if ...

I however don't know if the cost of doing all 5 explicit conversions using the as operator regardless is significant. In this case it might not matter since the most common scenario is handled by the else block and all the explicit conversions will have been done either way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me hear the opinions of others on this.

Copy link
Member

Choose a reason for hiding this comment

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

I had the same thought -- we want to limit the number of casts.

Can we switch on QueryNode.Kind (or QueryNode.InternalKind)?


In reply to: 574336006 [](ancestors = 574336006)

Copy link
Contributor

@gathogojr gathogojr left a comment

Choose a reason for hiding this comment

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

Left a few comments otherwise LGTM

string leftBinary = substrings[0].Trim();
string rightBinary = substrings[1].Trim();

if (leftRangeVariableNode != null && IsDifferentSource(filterClauseRangeVariable, leftRangeVariableNode))
Copy link
Member

Choose a reason for hiding this comment

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

IsDifferentSource(filterClauseRangeVariable, leftRangeVariableNode) [](start = 49, length = 67)

So this logic is assuming that, if the range variable is a different source, the range variable must be $it, right? In which case, $this would work because it's the same type as the filterClauseRangeVariable so it will just fall through? How would this logic change when if we supported $root?

Minimally, we need to document these assumptions and add tests (if they don't already exist) for these different 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.

Good catch!

string[] inSeparator = { inOperator };
string[] substrings = translatedNode.Trim().Split(inSeparator, StringSplitOptions.RemoveEmptyEntries);
string leftIn = substrings[0];
string rightIn = substrings[1];
Copy link
Member

Choose a reason for hiding this comment

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

This logic only needs to execute if the sources are different, so it would be better to move it within your if statement.

char[] parameterSeparators = { ',' };
string[] parameters = withinBrackets.Trim().Split(parameterSeparators, StringSplitOptions.RemoveEmptyEntries);
string leftParameter = parameters[0];
string rightParameter = parameters.Length == 2 ? parameters[1] : String.Empty;
Copy link
Member

Choose a reason for hiding this comment

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

all of this logic should be moved inside the conditional and only executed in the case that we are inserting the $it.

else
{
return false;
}
Copy link
Member

Choose a reason for hiding this comment

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

could simplify to:
return filterClauseRangeVariable.NavigationSource != rangeVariableReferenceNode.NavigationSource;

Uri queryUri = new Uri("People?$expand=MyDog($filter=endswith($it/Name,'abcd'))", UriKind.Relative);
Uri actualUri = UriBuilder(queryUri, ODataUrlKeyDelimiter.Parentheses, settings);
Assert.Equal("http://gobbledygook/People?$expand=" + Uri.EscapeDataString("MyDog($filter=endswith($it/Name,'abcd'))"), actualUri.OriginalString);
}
Copy link
Member

Choose a reason for hiding this comment

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

do we have variants of each of these that don't use $it, and instead assume the range variable of the filter clause?

@mikepizzo
Copy link
Member

A few comments, otherwise looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Ready for review Use this label if a pull request is ready to be reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants