mirror of https://gitee.com/bigwinds/arangodb
fixed ranges
This commit is contained in:
parent
13fbd82e12
commit
992ac23450
|
@ -985,7 +985,9 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildRangeInfo (AstNode const* node, std::string& enumCollVar, std::string& attr) {
|
void buildRangeInfo (AstNode const* node,
|
||||||
|
std::string& enumCollVar,
|
||||||
|
std::string& attr) {
|
||||||
if (node->type == NODE_TYPE_REFERENCE) {
|
if (node->type == NODE_TYPE_REFERENCE) {
|
||||||
auto x = static_cast<Variable*>(node->getData());
|
auto x = static_cast<Variable*>(node->getData());
|
||||||
auto setter = _plan->getVarSetBy(x->id);
|
auto setter = _plan->getVarSetBy(x->id);
|
||||||
|
@ -997,9 +999,10 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
if (node->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
char const* attributeName = node->getStringValue();
|
|
||||||
buildRangeInfo(node->getMember(0), enumCollVar, attr);
|
buildRangeInfo(node->getMember(0), enumCollVar, attr);
|
||||||
|
|
||||||
if (! enumCollVar.empty()) {
|
if (! enumCollVar.empty()) {
|
||||||
|
char const* attributeName = node->getStringValue();
|
||||||
attr.append(attributeName);
|
attr.append(attributeName);
|
||||||
attr.push_back('.');
|
attr.push_back('.');
|
||||||
}
|
}
|
||||||
|
@ -1015,24 +1018,22 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
// Found a multiple attribute access of a variable
|
// Found a multiple attribute access of a variable
|
||||||
_ranges->insert(enumCollVar, attr.substr(0, attr.size() - 1),
|
_ranges->insert(enumCollVar, attr.substr(0, attr.size() - 1),
|
||||||
RangeInfoBound(lhs, true), RangeInfoBound(lhs, true), true);
|
RangeInfoBound(lhs, true), RangeInfoBound(lhs, true), true);
|
||||||
|
|
||||||
|
enumCollVar.clear();
|
||||||
|
attr.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enumCollVar.clear();
|
|
||||||
attr.clear();
|
|
||||||
|
|
||||||
if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
buildRangeInfo(lhs, enumCollVar, attr);
|
buildRangeInfo(lhs, enumCollVar, attr);
|
||||||
if (! enumCollVar.empty()) {
|
if (! enumCollVar.empty()) {
|
||||||
// Found a multiple attribute access of a variable
|
// Found a multiple attribute access of a variable
|
||||||
_ranges->insert(enumCollVar, attr.substr(0, attr.size() - 1),
|
_ranges->insert(enumCollVar, attr.substr(0, attr.size() - 1),
|
||||||
RangeInfoBound(rhs, true), RangeInfoBound(rhs, true), true);
|
RangeInfoBound(rhs, true), RangeInfoBound(rhs, true), true);
|
||||||
|
enumCollVar.clear();
|
||||||
|
attr.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enumCollVar.clear();
|
|
||||||
attr.clear();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1046,8 +1047,6 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
|
|
||||||
auto lhs = node->getMember(0);
|
auto lhs = node->getMember(0);
|
||||||
auto rhs = node->getMember(1);
|
auto rhs = node->getMember(1);
|
||||||
RangeInfoBound low;
|
|
||||||
RangeInfoBound high;
|
|
||||||
|
|
||||||
if (rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
if (rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
// Attribute access on the right:
|
// Attribute access on the right:
|
||||||
|
@ -1055,6 +1054,9 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
// of a variable on the right:
|
// of a variable on the right:
|
||||||
buildRangeInfo(rhs, enumCollVar, attr);
|
buildRangeInfo(rhs, enumCollVar, attr);
|
||||||
if (! enumCollVar.empty()) {
|
if (! enumCollVar.empty()) {
|
||||||
|
RangeInfoBound low;
|
||||||
|
RangeInfoBound high;
|
||||||
|
|
||||||
// Constant value on the left, so insert a constant condition:
|
// Constant value on the left, so insert a constant condition:
|
||||||
if (node->type == NODE_TYPE_OPERATOR_BINARY_GE ||
|
if (node->type == NODE_TYPE_OPERATOR_BINARY_GE ||
|
||||||
node->type == NODE_TYPE_OPERATOR_BINARY_GT) {
|
node->type == NODE_TYPE_OPERATOR_BINARY_GT) {
|
||||||
|
@ -1065,9 +1067,10 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
}
|
}
|
||||||
_ranges->insert(enumCollVar, attr.substr(0, attr.size() - 1),
|
_ranges->insert(enumCollVar, attr.substr(0, attr.size() - 1),
|
||||||
low, high, false);
|
low, high, false);
|
||||||
|
|
||||||
|
enumCollVar.clear();
|
||||||
|
attr.clear();
|
||||||
}
|
}
|
||||||
enumCollVar.clear();
|
|
||||||
attr.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
|
@ -1076,6 +1079,9 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
// of a variable on the left:
|
// of a variable on the left:
|
||||||
buildRangeInfo(lhs, enumCollVar, attr);
|
buildRangeInfo(lhs, enumCollVar, attr);
|
||||||
if (! enumCollVar.empty()) {
|
if (! enumCollVar.empty()) {
|
||||||
|
RangeInfoBound low;
|
||||||
|
RangeInfoBound high;
|
||||||
|
|
||||||
// Constant value on the right, so insert a constant condition:
|
// Constant value on the right, so insert a constant condition:
|
||||||
if (node->type == NODE_TYPE_OPERATOR_BINARY_GE ||
|
if (node->type == NODE_TYPE_OPERATOR_BINARY_GE ||
|
||||||
node->type == NODE_TYPE_OPERATOR_BINARY_GT) {
|
node->type == NODE_TYPE_OPERATOR_BINARY_GT) {
|
||||||
|
@ -1086,6 +1092,9 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
}
|
}
|
||||||
_ranges->insert(enumCollVar, attr.substr(0, attr.size() - 1),
|
_ranges->insert(enumCollVar, attr.substr(0, attr.size() - 1),
|
||||||
low, high, false);
|
low, high, false);
|
||||||
|
|
||||||
|
enumCollVar.clear();
|
||||||
|
attr.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1102,9 +1111,9 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
||||||
buildRangeInfo(node->getMember(1), enumCollVar, attr);
|
buildRangeInfo(node->getMember(1), enumCollVar, attr);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
// default case
|
||||||
attr = "";
|
attr = "";
|
||||||
enumCollVar = "";
|
enumCollVar = "";
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ void RangeInfoBound::andCombineUpperBounds (RangeInfoBound const& that) {
|
||||||
/// (if needed) nodes are registered with the ast
|
/// (if needed) nodes are registered with the ast
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AstNode const* RangeInfoBound::getExpressionAst(Ast* ast) const {
|
AstNode const* RangeInfoBound::getExpressionAst (Ast* ast) const {
|
||||||
if (_expressionAst != nullptr) {
|
if (_expressionAst != nullptr) {
|
||||||
return _expressionAst;
|
return _expressionAst;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,6 @@ triagens::basics::Json RangeInfo::toJson() const {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RangesInfo::insert (RangeInfo newRange) {
|
void RangesInfo::insert (RangeInfo newRange) {
|
||||||
|
|
||||||
TRI_ASSERT(newRange.isDefined());
|
TRI_ASSERT(newRange.isDefined());
|
||||||
|
|
||||||
std::unordered_map<std::string, RangeInfo>* oldMap = find(newRange._var);
|
std::unordered_map<std::string, RangeInfo>* oldMap = find(newRange._var);
|
||||||
|
@ -224,10 +223,9 @@ void RangesInfo::insert (RangeInfo newRange) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RangeInfo::fuse (RangeInfo const& that) {
|
void RangeInfo::fuse (RangeInfo const& that) {
|
||||||
|
|
||||||
TRI_ASSERT(_var == that._var);
|
TRI_ASSERT(_var == that._var);
|
||||||
TRI_ASSERT(_attr == that._attr);
|
TRI_ASSERT(_attr == that._attr);
|
||||||
|
|
||||||
if (! isValid()) {
|
if (! isValid()) {
|
||||||
// intersection of the empty set with any set is empty!
|
// intersection of the empty set with any set is empty!
|
||||||
return;
|
return;
|
||||||
|
@ -281,16 +279,18 @@ void RangeInfo::fuse (RangeInfo const& that) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief insert if there is no range corresponding to variable name <var>,
|
/// @brief insert if there is no range corresponding to variable name <var>,
|
||||||
/// and attribute <name>, and otherwise intersection with existing range
|
/// and attribute <name>, and otherwise intersection with existing range
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RangesInfo::insert (std::string var, std::string name,
|
void RangesInfo::insert (std::string const& var,
|
||||||
RangeInfoBound low, RangeInfoBound high,
|
std::string const& name,
|
||||||
|
RangeInfoBound low,
|
||||||
|
RangeInfoBound high,
|
||||||
bool equality) {
|
bool equality) {
|
||||||
insert(RangeInfo(var, name, low, high, equality));
|
insert(RangeInfo(var, name, low, high, equality));
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
|
@ -575,8 +575,10 @@ namespace triagens {
|
||||||
/// bounds are variable and can only be computed at runtime.
|
/// bounds are variable and can only be computed at runtime.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void insert (std::string var, std::string name,
|
void insert (std::string const& var,
|
||||||
RangeInfoBound low, RangeInfoBound high,
|
std::string const& name,
|
||||||
|
RangeInfoBound low,
|
||||||
|
RangeInfoBound high,
|
||||||
bool equality);
|
bool equality);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -771,7 +771,7 @@ function optimizerRuleTestSuite() {
|
||||||
// The IndexRangeNode created by this rule should be more clever, it knows the ranges.
|
// The IndexRangeNode created by this rule should be more clever, it knows the ranges.
|
||||||
var RAs = getRangeAttributes(XPresult);
|
var RAs = getRangeAttributes(XPresult);
|
||||||
var first = getRangeAttribute(RAs[0], "v", "a", 1);
|
var first = getRangeAttribute(RAs[0], "v", "a", 1);
|
||||||
|
|
||||||
assertEqual(first.highs.length, 0, "no variable high bounds");
|
assertEqual(first.highs.length, 0, "no variable high bounds");
|
||||||
assertEqual(first.lows.length, 0, "no variable low bounds");
|
assertEqual(first.lows.length, 0, "no variable low bounds");
|
||||||
assertEqual(first.lowConst.bound, 4, "proper value was set");
|
assertEqual(first.lowConst.bound, 4, "proper value was set");
|
||||||
|
|
Loading…
Reference in New Issue