1
0
Fork 0

fixed ranges

This commit is contained in:
Jan Steemann 2014-09-16 15:48:33 +02:00
parent 13fbd82e12
commit 992ac23450
4 changed files with 36 additions and 25 deletions

View File

@ -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;
} }
}; };

View File

@ -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));
}; }

View File

@ -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);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -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");