diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index 2590b51977..efd9e50260 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -622,6 +622,28 @@ bool AstNode::isConstant () const { return false; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief whether or not a node is a comparison operator +//////////////////////////////////////////////////////////////////////////////// + +bool AstNode::isComparisonOperator () const { + return (type == NODE_TYPE_OPERATOR_BINARY_EQ || + type == NODE_TYPE_OPERATOR_BINARY_NE || + type == NODE_TYPE_OPERATOR_BINARY_LT || + type == NODE_TYPE_OPERATOR_BINARY_LE || + type == NODE_TYPE_OPERATOR_BINARY_GT || + type == NODE_TYPE_OPERATOR_BINARY_GE || + type == NODE_TYPE_OPERATOR_BINARY_IN); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief whether or not a node always produces a boolean value +//////////////////////////////////////////////////////////////////////////////// + +bool AstNode::alwaysProducesBoolValue () const { + return (isBoolValue() || isComparisonOperator()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief whether or not a node (and its subnodes) can throw a runtime /// exception @@ -649,7 +671,12 @@ bool AstNode::canThrow () const { if (type == NODE_TYPE_OPERATOR_BINARY_AND || type == NODE_TYPE_OPERATOR_BINARY_OR) { - // the logical operators can throw + // the logical operators can throw if the operands are not booleans + if (getMember(0)->alwaysProducesBoolValue() && + getMember(1)->alwaysProducesBoolValue()) { + return false; + } + return true; } diff --git a/arangod/Aql/AstNode.h b/arangod/Aql/AstNode.h index 74819a1320..04b9669985 100644 --- a/arangod/Aql/AstNode.h +++ b/arangod/Aql/AstNode.h @@ -272,6 +272,18 @@ namespace triagens { bool isConstant () const; +//////////////////////////////////////////////////////////////////////////////// +/// @brief whether or not a node is a comparison operator +//////////////////////////////////////////////////////////////////////////////// + + bool isComparisonOperator () const; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief whether or not a node always produces a boolean value +//////////////////////////////////////////////////////////////////////////////// + + bool alwaysProducesBoolValue () const; + //////////////////////////////////////////////////////////////////////////////// /// @brief whether or not a node (and its subnodes) may throw a runtime /// exception