1
0
Fork 0

normalize AQL filter conditions, so that attribute accesses are normally placed on the left hand side of the condition (#9217)

This commit is contained in:
Jan 2019-06-07 13:36:22 +02:00 committed by GitHub
parent 3f603f024f
commit d1a6d23c36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 45 additions and 2 deletions

View File

@ -819,10 +819,53 @@ AstNode* Ast::createNodeUnaryOperator(AstNodeType type, AstNode const* operand)
/// @brief create an AST binary operator node
AstNode* Ast::createNodeBinaryOperator(AstNodeType type, AstNode const* lhs,
AstNode const* rhs) {
// do a bit of normalization here, so that attribute accesses are normally
// on the left side of a comparison. this may allow future simplifications
// of code that check filter conditions
// note that there will still be cases in which both sides of the comparsion
// contain an attribute access, e.g. doc.value1 == doc.value2
bool swap = false;
if (type == NODE_TYPE_OPERATOR_BINARY_EQ &&
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
// value == doc.value => doc.value == value
swap = true;
} else if (type == NODE_TYPE_OPERATOR_BINARY_NE &&
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
// value != doc.value => doc.value != value
swap = true;
} else if (type == NODE_TYPE_OPERATOR_BINARY_GT &&
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
// value > doc.value => doc.value < value
type = NODE_TYPE_OPERATOR_BINARY_LT;
swap = true;
} else if (type == NODE_TYPE_OPERATOR_BINARY_LT &&
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
// value < doc.value => doc.value > value
type = NODE_TYPE_OPERATOR_BINARY_GT;
swap = true;
} else if (type == NODE_TYPE_OPERATOR_BINARY_GE &&
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
// value >= doc.value => doc.value <= value
type = NODE_TYPE_OPERATOR_BINARY_LE;
swap = true;
} else if (type == NODE_TYPE_OPERATOR_BINARY_LE &&
rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
lhs->type != NODE_TYPE_ATTRIBUTE_ACCESS) {
// value <= doc.value => doc.value >= value
type = NODE_TYPE_OPERATOR_BINARY_GE;
swap = true;
}
AstNode* node = createNode(type);
node->reserve(2);
node->addMember(lhs);
node->addMember(rhs);
node->addMember(swap ? rhs : lhs);
node->addMember(swap ? lhs : rhs);
// initialize sortedness information (currently used for the IN/NOT IN
// operators only) for nodes of type ==, < or <=, the bool means if the range