Skip to content

Commit

Permalink
Warwn on logical operators
Browse files Browse the repository at this point in the history
Warn on logical operators AND and OR expressions without explicit parenthesization
  • Loading branch information
xtaisafelix authored Nov 30, 2021
1 parent a355478 commit d0f34b1
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions parser/src/main/java/com/facebook/coresql/parser/AstNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
*/
package com.facebook.coresql.parser;

import com.facebook.coresql.linter.warning.WarningCollector;

import java.io.StringReader;

public class AstNode
extends com.facebook.coresql.parser.SimpleNode
{
Expand Down Expand Up @@ -91,4 +95,58 @@ public String toString(String prefix)
return super.toString(prefix) + " (" + getLocation().toString() + ")" +
(NumChildren() == 0 ? " (" + beginToken.image + ")" : "");
}

@Override
public AstNode visitLogicalBinary(com.facebook.coresql.parser.SqlParser context)
{
LogicalBinaryExpression.Operator operator = getLogicalBinaryOperator(context.operator);
boolean warningForMixedAndOr = false;
Expression left = (Expression) visit(context.left);
Expression right = (Expression) visit(context.right);

if (operator.equals(LogicalBinaryExpression.Operator.OR) &&
(mixedAndOrOperatorParenthesisCheck(right, context.right, LogicalBinaryExpression.Operator.AND) ||
mixedAndOrOperatorParenthesisCheck(left, context.left, LogicalBinaryExpression.Operator.AND))) {
warningForMixedAndOr = true;
}

if (operator.equals(LogicalBinaryExpression.Operator.AND) &&
(mixedAndOrOperatorParenthesisCheck(right, context.right, LogicalBinaryExpression.Operator.OR) ||
mixedAndOrOperatorParenthesisCheck(left, context.left, LogicalBinaryExpression.Operator.OR))) {
warningForMixedAndOr = true;
}

if (warningForMixedAndOr) {
warningConsumer.accept(new ParsingWarning(
"The Query contains OR and AND operator without proper parenthesis. "
+ "Make sure the operators are guarded by parenthesis in order "
+ "to fetch logically correct results",
context.getStart().getLine(), context.getStart().getCharPositionInLine()));
}

return new LogicalBinaryExpression(
getLocation(context.operator),
getLogicalBinaryOperator(context.operator),
(Expression) visit(context.left),
(Expression) visit(context.right));
operator,
left,
right);
}

private boolean mixedAndOrOperatorParenthesisCheck(Expression expression, SqlBaseParser.BooleanExpressionContext node, LogicalBinaryExpression.Operator operator)
{
if (expression instanceof LogicalBinaryExpression) {
if (((LogicalBinaryExpression) expression).getOperator().equals(operator)) {
if (node.children.get(0) instanceof SqlBaseParser.ValueExpressionDefaultContext) {
return !(((SqlBaseParser.PredicatedContext) node).valueExpression().getChild(0) instanceof
SqlBaseParser.ParenthesizedExpressionContext);
}
else {
return true;
}
}
}
return false;
}
}

0 comments on commit d0f34b1

Please sign in to comment.