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

MaxNodeCount exceeded #579

Closed
josh-endries opened this issue Jun 28, 2017 · 5 comments
Closed

MaxNodeCount exceeded #579

josh-endries opened this issue Jun 28, 2017 · 5 comments

Comments

@josh-endries
Copy link

josh-endries commented Jun 28, 2017

I'm having basically the same problem as #545 in a .NET BreezeJS app, but that resolution doesn't really make sense to me. I would rather avoid the problem altogether than just raise the limit until it gets hit again. I also don't understand why it's happening in the first place.

There aren't 100 nodes in that query, or mine, so how does the limit get hit, or what does "node" mean? This says it's the number of nodes in the filter tree:

https://msdn.microsoft.com/en-us/library/system.web.http.odata.query.odatavalidationsettings.maxnodecount(v=vs.118).aspx

But, in my query, with only 16 "or Id = x" clauses and a 17th "& OtherId = x" clause, 17 total, I wouldn't expect to hit a 100 node limit. Perhaps worse, I can't predict it, since it doesn't seem to make sense; e.g. I can't do "if I have X IDs to look up, do it differently", since I can't determine what X should be, since it doesn't seem to add up or match the limit as far as I can tell. If I raise it from 100 to 200, does that mean I can actually do 34? o_O

I've got to be missing something...

Edit: Yep! A 200 limit lets me do 34 IDs. I suppose I could raise it to a limit of 1000 to get 100 IDs.

I wonder if it is including expansions in the node list, like if the ID I'm looking up is on a child entity, even though it's a root-level property in my view model, but in EF it's on a child, it's including those "nodes"...

@Spragalas
Copy link

Hi,

I think you could find a little more help in https://github.com/OData/WebApi/ since Restier is depending on that for queries.

Also there is a chance that this is a bug (just a random thought)

@Eddy-Shterenberg
Copy link

Eddy-Shterenberg commented Sep 4, 2017

Hi,

Figures it's not a bug.
I've debugged the flow of System.Web.OData.Query.FilterQueryOption.Validate() ... System.Web.OData.Query.Validators.FilterQueryValidator.ValidateQueryNode

Long story short, for an expression like "(Id eq 1) or (Id eq 2) or (Id eq 3)"
the formula is: number of actual nodes = (Number of ORs * 5) - 1

Thus you touch the limit of 100 nodes by using 20 ORs (20*5-1=99), i.e. by fetching only 20 IDs
this answers why 200 enough for 34 nodes: 34 x 5 - 1 = 169 < 200

TLDR:
Decription of the above formula:

  • PropertyReference counts as 2 nodes
  • Constant value counts as 1 node
  • OR counts as 1 node + left and right values
  • EQ counts as 1 node + left and right values

This way expression "Id eq 1" is:

  • 'eq' is a binary operatory => 1 node + left and right node
  • left node: "Id" is a PropertyReference => 2 nodes
  • right node: "1" is a const => 1 node
    sum them up: 1 + 2 + 1 = 4
    if you compare propery vs property (instead of a const) - add another 1 for the right value,
    and if you using nested properties the number goes higher...

When you add them up with "OR" operator, like "Id eq 1 or Id eq 2", you get:

  • 4 nodes from the left value (Id eq 1)
  • 4 nodes from the right value (Id eq 2)
  • 1 node the OR operator itself
    and it's 9 nodes in total

So the sequences is:

EQ nodes x EQ count + OR Count = Total nodes count
4 x 1 + 0 = 4
4 x 2 + 1 = 9
4 x 3 + 2 = 14
4 x 4 + 3 = 19
...
4 x (n-1) + (n-2) = 4 x (n - 1) + (n - 2)

Resulting formula for n > 0: 4 x (n - 1) + (n - 2) = 5n-1, where n is a number of OR operators
(obviously for n=0 the value is 4)

@SamOrozco
Copy link

@Eddy-Shterenberg Thank you for the explanation.

@Valery-Spiridonov
Copy link

Valery-Spiridonov commented Jan 29, 2019

According to Eddy-Shterenberg's explanation 4 x (n - 1) + (n - 2) = 5n - 6, where a n is number operand sets of filter (number of OR operators is (n - 2)).

If n is a number of filter values then the formula becomes 4 x n + (n - 1) = 5n - 1

But research was very useful! Thanks!

@robertmclaws
Copy link
Collaborator

I'm going to go ahead and close this since it's not a bug, but we'll document the issue for people that run across the error in the future. Thanks! :)

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

No branches or pull requests

6 participants