mirror of https://gitee.com/bigwinds/arangodb
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:
parent
3f603f024f
commit
d1a6d23c36
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue