1
0
Fork 0

Fixed a bug with sort optimization in indexes. Also adapted tests.

This commit is contained in:
Michael Hackstein 2017-01-23 09:45:22 +01:00
parent 54ccffc0ee
commit 36e398f3f4
4 changed files with 34 additions and 6 deletions

View File

@ -458,7 +458,7 @@ bool GatherBlock::OurLessThan::operator()(std::pair<size_t, size_t> const& a,
// Take attributePath into consideration:
AqlValue topA = _gatherBlockBuffer.at(a.first).front()->getValue(a.second,
reg.reg);
AqlValue topB = _gatherBlockBuffer.at(a.first).front()->getValue(b.second,
AqlValue topB = _gatherBlockBuffer.at(b.first).front()->getValue(b.second,
reg.reg);
bool mustDestroyA;
AqlValue aa = topA.get(_trx, reg.attributePath, mustDestroyA, false);

View File

@ -85,6 +85,10 @@ struct SortElement {
SortElement(Variable const* v, bool asc)
: var(v), ascending(asc) {
}
SortElement(Variable const* v, bool asc, std::vector<std::string> const& path)
: var(v), ascending(asc), attributePath(path) {
}
};
typedef std::vector<SortElement> SortElementVector;

View File

@ -2332,12 +2332,33 @@ void arangodb::aql::scatterInClusterRule(Optimizer* opt, ExecutionPlan* plan,
TRI_vocbase_t* vocbase = nullptr;
Collection const* collection = nullptr;
SortElementVector elements;
if (nodeType == ExecutionNode::ENUMERATE_COLLECTION) {
vocbase = static_cast<EnumerateCollectionNode*>(node)->vocbase();
collection = static_cast<EnumerateCollectionNode*>(node)->collection();
} else if (nodeType == ExecutionNode::INDEX) {
vocbase = static_cast<IndexNode*>(node)->vocbase();
collection = static_cast<IndexNode*>(node)->collection();
auto idxNode = static_cast<IndexNode*>(node);
vocbase = idxNode->vocbase();
collection = idxNode->collection();
auto outVars = idxNode->getVariablesSetHere();
TRI_ASSERT(outVars.size() == 1);
Variable const* sortVariable = outVars[0];
bool isSortReverse = idxNode->reverse();
auto allIndexes = idxNode->getIndexes();
TRI_ASSERT(!allIndexes.empty());
// Using Index for sort only works if all indexes are equal.
auto first = allIndexes[0].getIndex();
for (auto const& path : first->fieldNames()) {
elements.emplace_back(sortVariable, !isSortReverse, path);
}
for (auto const& it : allIndexes) {
if (first != it.getIndex()) {
elements.clear();
break;
}
}
} else if (nodeType == ExecutionNode::INSERT ||
nodeType == ExecutionNode::UPDATE ||
nodeType == ExecutionNode::REPLACE ||
@ -2383,11 +2404,14 @@ void arangodb::aql::scatterInClusterRule(Optimizer* opt, ExecutionPlan* plan,
remoteNode->addDependency(node);
// insert a gather node
ExecutionNode* gatherNode =
GatherNode* gatherNode =
new GatherNode(plan, plan->nextId(), vocbase, collection);
plan->registerNode(gatherNode);
TRI_ASSERT(remoteNode);
gatherNode->addDependency(remoteNode);
if (!elements.empty()) {
gatherNode->setElements(elements);
}
// and now link the gather node with the rest of the plan
if (parents.size() == 1) {

View File

@ -112,7 +112,7 @@ function optimizerRuleTestSuite() {
var loopto = 10;
internal.db._drop(colName);
skiplist = internal.db._create(colName);
skiplist = internal.db._create(colName, {numberOfShards: 4});
var i, j;
for (j = 1; j <= loopto; ++j) {
for (i = 1; i <= loopto; ++i) {
@ -127,7 +127,7 @@ function optimizerRuleTestSuite() {
skiplist.ensureIndex({ type: "hash", fields: [ "c" ], unique: false });
internal.db._drop(colNameOther);
skiplist2 = internal.db._create(colNameOther);
skiplist2 = internal.db._create(colNameOther, {numberOfShards: 4});
for (j = 1; j <= loopto; ++j) {
for (i = 1; i <= loopto; ++i) {
skiplist2.save({ "f" : i, "g": j , "h": j, "i": i, "j": i, "joinme" : "aoeu " + j});