mirror of https://gitee.com/bigwinds/arangodb
Take care of empty lists to loop over.
This commit is contained in:
parent
3b1d938dda
commit
b6564690ee
|
@ -114,6 +114,12 @@ void ExecutionBlock::staticAnalysis (ExecutionBlock* super) {
|
||||||
sq->getSubquery()->staticAnalysis(s);
|
sq->getSubquery()->staticAnalysis(s);
|
||||||
}
|
}
|
||||||
v->reset();
|
v->reset();
|
||||||
|
// Now print the result:
|
||||||
|
for (auto it : _varOverview->varInfo) {
|
||||||
|
std::cout << "Variable ID:" << it.first << " RegisterId:"
|
||||||
|
<< it.second.registerId << " Depth:" << it.second.depth
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|
|
@ -1127,86 +1127,100 @@ namespace triagens {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_buffer.empty()) {
|
AqlItemBlock* res;
|
||||||
if (! ExecutionBlock::getBlock(DefaultBatchSize, DefaultBatchSize)) {
|
|
||||||
_done = true;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
_pos = 0; // this is in the first block
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we make it here, then _buffer.front() exists
|
do {
|
||||||
AqlItemBlock* cur = _buffer.front();
|
// repeatedly try to get more stuff from upstream
|
||||||
|
// note that the value of the variable we have to loop over
|
||||||
// get the thing we are looping over
|
// can contain zero entries, in which case we have to
|
||||||
AqlValue inVarReg = cur->getValue(_pos, _inVarRegId);
|
// try again!
|
||||||
size_t sizeInVar;
|
|
||||||
|
|
||||||
// get the size of the thing we are looping over
|
if (_buffer.empty()) {
|
||||||
collection = nullptr;
|
if (! ExecutionBlock::getBlock(DefaultBatchSize, DefaultBatchSize)) {
|
||||||
switch (inVarReg._type) {
|
_done = true;
|
||||||
case AqlValue::JSON: {
|
return nullptr;
|
||||||
if(!inVarReg._json->isList()){
|
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "EnumerateListBlock: JSON is not a list");
|
|
||||||
}
|
}
|
||||||
sizeInVar = inVarReg._json->size();
|
_pos = 0; // this is in the first block
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case AqlValue::RANGE: {
|
|
||||||
sizeInVar = inVarReg._range->_high - inVarReg._range->_low + 1;
|
// if we make it here, then _buffer.front() exists
|
||||||
break;
|
AqlItemBlock* cur = _buffer.front();
|
||||||
}
|
|
||||||
case AqlValue::DOCVEC: {
|
// get the thing we are looping over
|
||||||
if( _index == 0){// this is a (maybe) new DOCVEC
|
AqlValue inVarReg = cur->getValue(_pos, _inVarRegId);
|
||||||
_DOCVECsize = 0;
|
size_t sizeInVar;
|
||||||
//we require the total number of items
|
|
||||||
for (size_t i = 0; i < inVarReg._vector->size(); i++) {
|
// get the size of the thing we are looping over
|
||||||
_DOCVECsize += inVarReg._vector->at(i)->size();
|
collection = nullptr;
|
||||||
|
switch (inVarReg._type) {
|
||||||
|
case AqlValue::JSON: {
|
||||||
|
if(!inVarReg._json->isList()){
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "EnumerateListBlock: JSON is not a list");
|
||||||
}
|
}
|
||||||
collection = inVarReg._vector->at(0)->getDocumentCollection(0);
|
sizeInVar = inVarReg._json->size();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
sizeInVar = _DOCVECsize;
|
case AqlValue::RANGE: {
|
||||||
break;
|
sizeInVar = inVarReg._range->_high - inVarReg._range->_low + 1;
|
||||||
}
|
break;
|
||||||
default: {
|
}
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "EnumerateListBlock: unexpected type in register");
|
case AqlValue::DOCVEC: {
|
||||||
}
|
if( _index == 0){// this is a (maybe) new DOCVEC
|
||||||
}
|
_DOCVECsize = 0;
|
||||||
|
//we require the total number of items
|
||||||
size_t toSend = std::min(atMost, sizeInVar - _index);
|
for (size_t i = 0; i < inVarReg._vector->size(); i++) {
|
||||||
|
_DOCVECsize += inVarReg._vector->at(i)->size();
|
||||||
//create the result
|
}
|
||||||
auto res = new AqlItemBlock(toSend, _varOverview->nrRegs[_depth]);
|
collection = inVarReg._vector->at(0)->getDocumentCollection(0);
|
||||||
|
}
|
||||||
inheritRegisters(cur, res, _pos);
|
sizeInVar = _DOCVECsize;
|
||||||
|
break;
|
||||||
// we don't have a collection
|
}
|
||||||
res->setDocumentCollection(cur->getNrRegs(), collection);
|
default: {
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "EnumerateListBlock: unexpected type in register");
|
||||||
for (size_t j = 0; j < toSend; j++) {
|
|
||||||
if (j > 0) {
|
|
||||||
// re-use already copied aqlvalues
|
|
||||||
for (RegisterId i = 0; i < cur->getNrRegs(); i++) {
|
|
||||||
res->setValue(j, i, res->getValue(0, i));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add the new register value . . .
|
|
||||||
res->setValue(j, cur->getNrRegs(), getAqlValue(inVarReg));
|
if (sizeInVar == 0) {
|
||||||
// deep copy of the inVariable.at(_pos) with correct memory
|
res = nullptr;
|
||||||
// requirements
|
|
||||||
// Note that _index has been increased by 1 by getAqlValue!
|
|
||||||
}
|
|
||||||
if (_index == sizeInVar) {
|
|
||||||
_index = 0;
|
|
||||||
_thisblock = 0;
|
|
||||||
_seen = 0;
|
|
||||||
// advance read position in the current block . . .
|
|
||||||
if (++_pos == cur->size() ) {
|
|
||||||
delete cur;
|
|
||||||
_buffer.pop_front();
|
|
||||||
_pos = 0;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
size_t toSend = std::min(atMost, sizeInVar - _index);
|
||||||
|
|
||||||
|
//create the result
|
||||||
|
res = new AqlItemBlock(toSend, _varOverview->nrRegs[_depth]);
|
||||||
|
|
||||||
|
inheritRegisters(cur, res, _pos);
|
||||||
|
|
||||||
|
// we don't have a collection
|
||||||
|
res->setDocumentCollection(cur->getNrRegs(), collection);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < toSend; j++) {
|
||||||
|
if (j > 0) {
|
||||||
|
// re-use already copied aqlvalues
|
||||||
|
for (RegisterId i = 0; i < cur->getNrRegs(); i++) {
|
||||||
|
res->setValue(j, i, res->getValue(0, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add the new register value . . .
|
||||||
|
res->setValue(j, cur->getNrRegs(), getAqlValue(inVarReg));
|
||||||
|
// deep copy of the inVariable.at(_pos) with correct memory
|
||||||
|
// requirements
|
||||||
|
// Note that _index has been increased by 1 by getAqlValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_index == sizeInVar) {
|
||||||
|
_index = 0;
|
||||||
|
_thisblock = 0;
|
||||||
|
_seen = 0;
|
||||||
|
// advance read position in the current block . . .
|
||||||
|
if (++_pos == cur->size() ) {
|
||||||
|
delete cur;
|
||||||
|
_buffer.pop_front();
|
||||||
|
_pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (res == nullptr);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue