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

ODataException for key-parens segment following OperationSegment with parameters #2754

Open
syprieur opened this issue Oct 2, 2023 · 1 comment · May be fixed by #2757
Open

ODataException for key-parens segment following OperationSegment with parameters #2754

syprieur opened this issue Oct 2, 2023 · 1 comment · May be fixed by #2757
Assignees

Comments

@syprieur
Copy link
Contributor

syprieur commented Oct 2, 2023

Use of ODataUriParser for a Uri containing a key-segment following a composable function returning a collection of entities:

  • Throws if the default key-parens syntax is used.
  • Works properly if the key-as-segment syntax is used.

Assemblies affected

All up to 7.18.0.

Reproduce steps

// Initializes a basic model.
var model = new EdmModel();

// Entity type 'user', with a single string property: its key 'id'.
var user = model.AddEntityType("graph", "user", baseType: null, isAbstract: false, isOpen: false, hasStream: false);
var keyProperty = user.AddStructuralProperty("id", EdmPrimitiveTypeKind.String, isNullable: false);
user.AddKeys(keyProperty);

// Entity container, with entity set 'users'.
var container = model.AddEntityContainer("graph", "service");
container.AddEntitySet("users", user);

// Function 'getConnections' bound to a 'user', with an int parameter and returning a collection of 'user'.
var userReference = new EdmEntityTypeReference(user, isNullable: false);
var userCollectionReference = new EdmCollectionTypeReference(new EdmCollectionType(userReference));
var getConnections = new EdmFunction("graph", "getConnections", userCollectionReference, isBound: true, entitySetPathExpression: null, isComposable: true);
getConnections.AddParameter("boundParameter", userReference);
getConnections.AddParameter("degree", EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int16, isNullable: false));
model.AddElement(getConnections);

// Simple URI: accesses an entity from the collection returned by the function 'getConnections'.

// Works: KeySegment after OperationSegment uses key-as-segment syntax.
var parser = new ODataUriParser(model, new System.Uri("/users('doe')/graph.getConnections(degree=1)/fawn", System.UriKind.Relative));
var path = parser.ParsePath();
Assert.IsNotNull(path);
Assert.AreEqual(4, path.Count); // EntitySetSegment, KeySegment, OperationSegment, KeySegment.

// Throws: KeySegment after OperationSegment uses default key-parens syntax.
parser = new ODataUriParser(model, new System.Uri("/users('doe')/graph.getConnections(degree=1)('fawn')", System.UriKind.Relative));
try
{
    path = parser.ParsePath();
    Assert.Fail("Never reached, as ParsePath throws.");
}
catch (ODataException e)
{
    Assert.AreEqual("Syntax error at position 9 in 'degree=1)('fawn''.", e.Message);
}

Expected result

A valid ODataPath is returned when the key-parens syntax is used (identical to the one returned when the key-as-segment syntax is used). 

Actual result

An ODataException is thrown.

@xuzhg
Copy link
Member

xuzhg commented Oct 3, 2023

ODL has this test case to dis-allow key in parenthesis after composable function with parameters as:

[Fact]
public void KeyLookupCannotAppearAfterFunctionWithParameters()
{
    PathFunctionalTestsUtil.RunParseErrorPath("People(1)/Fully.Qualified.Namespace.AllMyFriendsDogs(inOffice=true)(1)", ODataErrorStrings.ExpressionLexer_SyntaxError(14, "inOffice=true)(1"));
}

https://github.com/OData/odata.net/blob/master/test/FunctionalTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/PathFunctionalTests.cs#L1050-L1053

However, We do think it should be valid to have key in parenthesis after composable function with parameters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants