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

[BUG]Excluding And and Or Expressions #1633

Closed
kampilan opened this issue Apr 15, 2020 · 11 comments
Closed

[BUG]Excluding And and Or Expressions #1633

kampilan opened this issue Apr 15, 2020 · 11 comments
Labels

Comments

@kampilan
Copy link

Which LiteDB version/OS/.NET framework version are you using. (REQUIRED)
5.0.7

Describe the bug

The code below is missing And and Or

    private string GetOperator(ExpressionType nodeType)
    {
        switch (nodeType)
        {
            case ExpressionType.Add: return " + ";
            case ExpressionType.Multiply: return " * ";
            case ExpressionType.Subtract: return " - ";
            case ExpressionType.Divide: return " / ";
            case ExpressionType.Equal: return " = ";
            case ExpressionType.NotEqual: return " != ";
            case ExpressionType.GreaterThan: return " > ";
            case ExpressionType.GreaterThanOrEqual: return " >= ";
            case ExpressionType.LessThan: return " < ";
            case ExpressionType.LessThanOrEqual: return " <= ";
            case ExpressionType.AndAlso: return " AND ";
            case ExpressionType.OrElse: return " OR ";
        }

Code to Reproduce
Not needed

Expected behavior

    private string GetOperator(ExpressionType nodeType)
    {
        switch (nodeType)
        {
            case ExpressionType.Add: return " + ";
            case ExpressionType.Multiply: return " * ";
            case ExpressionType.Subtract: return " - ";
            case ExpressionType.Divide: return " / ";
            case ExpressionType.Equal: return " = ";
            case ExpressionType.NotEqual: return " != ";
            case ExpressionType.GreaterThan: return " > ";
            case ExpressionType.GreaterThanOrEqual: return " >= ";
            case ExpressionType.LessThan: return " < ";
            case ExpressionType.LessThanOrEqual: return " <= ";
            case ExpressionType.And: return " AND ";
            case ExpressionType.AndAlso: return " AND ";
            case ExpressionType.Or: return " OR ";
            case ExpressionType.OrElse: return " OR ";
        }

It makes no sense to exclude And and Or as they differ from AndAlso and OrElse only in logical short-cutting which appears to be inconsequential to your use-case.

X == 0 & Y == 1 And Evaluates entire expression even if X != 0
X == 0 && Y == 1 AndAlso. This shortcuts the expression if X != 0

In you use-case this nuance is meaningless so why exclude them?

Thanks
Jim

@lbnascimento
Copy link
Collaborator

@kampilan Done. It will be present in the next incremental release.

@nightroman
Copy link
Contributor

@kampilan I am curious, why is this needed in practice? (Not criticizing in any way, just want to learn)

@nightroman
Copy link
Contributor

@lbnascimento Do we or will we have the same form in LiteDB string expressions?

@lbnascimento
Copy link
Collaborator

@lbnascimento While it could be done, I'm not sure there's any point to it.

@kampilan
Copy link
Author

It's needed because it is in fact a legitimate expression. Like me, most people use Expression.And and Expression.Or. Technically one should use AndAlso and OrElse. I have in fact changed my implementation to use AndAlso and OrElse. It is more correct to do so. But And and Or still need to be supported in this use-case because they are perfectly valid.

@lbnascimento
Copy link
Collaborator

@kampilan I think @nightroman was talking about having actual non-short-circuit operators in BsonExpressions, which I don't think is useful. The solution that you proposed in your first post (and which was implemented, by the way) merely maps & to AND and | to OR, which are then executed as short-circuit operators.

@nightroman
Copy link
Contributor

I am confused by the example X == 0 & Y == 1 and the tests following the change:

TestPredicate<User>(x => x.Salary > 50 && x.Name == "John", "((Salary > @p0) AND (Name = @p1))", 50, "John");
TestPredicate<User>(x => x.Salary > 50 & x.Name == "John", "((Salary > @p0) AND (Name = @p1))", 50, "John");
TestPredicate<User>(x => x.Salary > 50 || x.Name == "John", "((Salary > @p0) OR (Name = @p1))", 50, "John");
TestPredicate<User>(x => x.Salary > 50 | x.Name == "John", "((Salary > @p0) OR (Name = @p1))", 50, "John");

| and & are not Boolean operators at all. What are these tests doing and checking is not clear.

@nightroman
Copy link
Contributor

These are bitwise AND and OR operators. They operate on integers and return integers. Why in the above cases they are treated as Boolean operators is not clear. Technically, translation to string expressions is even wrong. Maybe I miss something simple.

@lbnascimento
Copy link
Collaborator

@nightroman They are overloaded operators: between two integers, they act as bitwise and/or; between two bools, they act as non-short-circuit logic operators. Check the official C# documentation.

@nightroman
Copy link
Contributor

Ah, I see now. Yes, learned something new! TBH, never used & and | as Booleans for many years :)

@kampilan
Copy link
Author

lbnascimento sorry 2 discussions going on at the same time. I agree unneeded,

nightroman I also learned something new. In my opinion poor naming and documentation on MS part.

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

No branches or pull requests

3 participants