8000 issue #7749 (#7794) · HighAvailabilityLab/arangodb@93d624d · GitHub
[go: up one dir, main page]

Skip to content

Commit 93d624d

Browse files
authored
1 parent 259170f commit 93d624d

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ devel
33

44
* fixed issue #7763: Collect after update does not execute updates
55

6+
* fixed issue #7749: AQL query result changed for COLLECT used on empty data/array
7+
68
* fixed a rare thread local dead lock situation in replication:
79
If a follower tries to get in sync in the last steps it requires
810
a lock on the leader. If the follower cancels the lock before the leader

arangod/Aql/CollectBlock.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ void SortedCollectBlock::CollectGroup::addValues(AqlItemBlock const* src,
150150
SortedCollectBlock::SortedCollectBlock(ExecutionEngine* engine,
151151
CollectNode const* en)
152152
: ExecutionBlock(engine, en),
153-
_groupRegisters(),
154-
_aggregateRegisters(),
155153
_currentGroup(en->_count),
156154
_lastBlock(nullptr),
157155
_expressionRegister(ExecutionNode::MaxRegisterId),
@@ -441,9 +439,24 @@ std::pair<ExecutionState, Result> SortedCollectBlock::getOrSkipSome(
441439

442440
// _lastBlock can be null (iff there wasn't a single input row).
443441
// we still need to emit a group (of nulls)
444-
emitGroup(_lastBlock, _result.get(), _skipped, skipping);
445-
++_skipped;
446-
_result->shrink(_skipped);
442+
if (_currentGroup.hasRows || !_aggregateRegisters.empty()) {
443+
// we must produce a result
444+
emitGroup(_lastBlock, _result.get(), _skipped, skipping);
445+
++_skipped;
446+
_result->shrink(_skipped);
447+
} else {
448+
// we don't have anything to return
449+
// don't increase _skipped here
450+
if (_skipped == 0) {
451+
// 0 results
452+
if (_result != nullptr) {
453+
// if the result set is entirely empty, we must free the result,
454+
// as shrinking
455+
auto r = _result.release();
456+
returnBlock(r);
457+
}
458+
}
459+
}
447460
} else {
448461
++_skipped;
449462
}
@@ -469,7 +482,7 @@ std::pair<ExecutionState, Result> SortedCollectBlock::getOrSkipSome(
469482
} else {
470483
return {ExecutionState::HASMORE, TRI_ERROR_NO_ERROR};
471484
}
472-
};
485+
}
473486

474487
/// @brief writes the current group data into the result
475488
void SortedCollectBlock::emitGroup(AqlItemBlock const* cur, AqlItemBlock* res,
@@ -520,7 +533,7 @@ void SortedCollectBlock::emitGroup(AqlItemBlock const* cur, AqlItemBlock* res,
520533
// set the group values
521534
if (_collectRegister != ExecutionNode::MaxRegisterId) {
522535
_currentGroup.addValues(cur, _collectRegister);
523-
536+
524537
if (ExecutionNode::castTo<CollectNode const*>(_exeNode)->_count) {
525538
// only set group count in result register
526539
res->emplaceValue(

tests/js/server/aql/aql-optimizer-collect-into.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,34 @@ function optimizerCollectExpressionTestSuite () {
234234
query = "LET values = [ {time:1}, {time:1}, {time:2}, {time:2}, {time:3}, {time:4}, {time:2}, {time:3}, {time:6} ] FOR p1 IN values COLLECT t = FLOOR(p1.time / 2) AGGREGATE m = MAX(p1.time) FOR p2 IN values FILTER m == p2.time COLLECT q = 0 INTO qs = p2 RETURN {q}";
235235
results = AQL_EXECUTE(query);
236236
assertEqual([ { q: 0 } ], results.json);
237+
},
238+
239+
testCollectWithEmptyInput : function () {
240+
let query = "FOR v IN [] COLLECT w = 1 INTO x RETURN w";
241+
let results = AQL_EXECUTE(query);
242+
assertEqual([ ], results.json);
243+
244+
query = "FOR v IN [] COLLECT w = 1 INTO x RETURN {x}";
245+
results = AQL_EXECUTE(query);
246+
assertEqual([ ], results.json);
247+
248+
query = "FOR v IN [] COLLECT w = 1 INTO x RETURN x";
249+
results = AQL_EXECUTE(query);
250+
assertEqual([ ], results.json);
251+
252+
query = "FOR v IN 1..3 FILTER v > 9 COLLECT w = 1 INTO x RETURN w";
253+
results = AQL_EXECUTE(query);
254+
assertEqual([ ], results.json);
255+
256+
query = "FOR v IN 1..3 FILTER v > 9 COLLECT w = v INTO x RETURN w";
257+
results = AQL_EXECUTE(query);
258+
assertEqual([ ], results.json);
259+
260+
query = "FOR v IN 1..3 COLLECT w = v INTO x RETURN w";
261+
results = AQL_EXECUTE(query);
262+
assertEqual([ 1, 2, 3 ], results.json);
237263
}
238-
264+
239265
};
240266
}
241267

0 commit comments

Comments
 (0)
0