mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into devel
This commit is contained in:
commit
43f7078ded
|
@ -155,6 +155,35 @@ bool AqlValue::isArray() const noexcept {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::array<std::string const, 8> AqlValue::typeStrings = {
|
||||||
|
"none",
|
||||||
|
"null",
|
||||||
|
"bool",
|
||||||
|
"number",
|
||||||
|
"string",
|
||||||
|
"object",
|
||||||
|
"array",
|
||||||
|
"unknown"};
|
||||||
|
|
||||||
|
std::string const & AqlValue::getTypeString() const noexcept {
|
||||||
|
if(isNone()) {
|
||||||
|
return typeStrings[0];
|
||||||
|
} else if(isNull(true)) {
|
||||||
|
return typeStrings[1];
|
||||||
|
} else if(isBoolean()) {
|
||||||
|
return typeStrings[2];
|
||||||
|
} else if(isNumber()) {
|
||||||
|
return typeStrings[3];
|
||||||
|
} else if(isString()) {
|
||||||
|
return typeStrings[4];
|
||||||
|
} else if(isObject()) {
|
||||||
|
return typeStrings[5];
|
||||||
|
} else if(isArray()){
|
||||||
|
return typeStrings[6];
|
||||||
|
}
|
||||||
|
return typeStrings[7];
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief get the (array) length (note: this treats ranges as arrays, too!)
|
/// @brief get the (array) length (note: this treats ranges as arrays, too!)
|
||||||
size_t AqlValue::length() const {
|
size_t AqlValue::length() const {
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
|
|
|
@ -83,6 +83,7 @@ struct AqlValueFromManagedDocument {};
|
||||||
struct AqlValue final {
|
struct AqlValue final {
|
||||||
friend struct std::hash<arangodb::aql::AqlValue>;
|
friend struct std::hash<arangodb::aql::AqlValue>;
|
||||||
friend struct std::equal_to<arangodb::aql::AqlValue>;
|
friend struct std::equal_to<arangodb::aql::AqlValue>;
|
||||||
|
static std::array<std::string const, 8> typeStrings;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -388,6 +389,10 @@ struct AqlValue final {
|
||||||
/// @brief whether or not the value is an array (note: this treats ranges
|
/// @brief whether or not the value is an array (note: this treats ranges
|
||||||
/// as arrays, too!)
|
/// as arrays, too!)
|
||||||
bool isArray() const noexcept;
|
bool isArray() const noexcept;
|
||||||
|
|
||||||
|
// @brief return a string describing the content of this aqlvalue
|
||||||
|
std::string const & getTypeString() const noexcept;
|
||||||
|
|
||||||
|
|
||||||
/// @brief get the (array) length (note: this treats ranges as arrays, too!)
|
/// @brief get the (array) length (note: this treats ranges as arrays, too!)
|
||||||
size_t length() const;
|
size_t length() const;
|
||||||
|
|
|
@ -2889,8 +2889,13 @@ AstNode* Ast::optimizeFor(AstNode* node) {
|
||||||
// right-hand operand to FOR statement is no array
|
// right-hand operand to FOR statement is no array
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||||
TRI_ERROR_QUERY_ARRAY_EXPECTED,
|
TRI_ERROR_QUERY_ARRAY_EXPECTED,
|
||||||
|
std::string("collection or ") +
|
||||||
TRI_errno_string(TRI_ERROR_QUERY_ARRAY_EXPECTED) +
|
TRI_errno_string(TRI_ERROR_QUERY_ARRAY_EXPECTED) +
|
||||||
std::string(" as operand to FOR loop"));
|
std::string(" as operand to FOR loop; you specified type '") +
|
||||||
|
expression->getValueTypeString() +
|
||||||
|
std::string("' with content '") +
|
||||||
|
expression->toString() +
|
||||||
|
std::string("'"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// no real optimizations will be done here
|
// no real optimizations will be done here
|
||||||
|
|
|
@ -98,7 +98,7 @@ AqlItemBlock* EnumerateListBlock::getSome(size_t, size_t atMost) {
|
||||||
AqlValue const& inVarReg = cur->getValueReference(_pos, _inVarRegId);
|
AqlValue const& inVarReg = cur->getValueReference(_pos, _inVarRegId);
|
||||||
|
|
||||||
if (!inVarReg.isArray()) {
|
if (!inVarReg.isArray()) {
|
||||||
throwArrayExpectedException();
|
throwArrayExpectedException(inVarReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sizeInVar;
|
size_t sizeInVar;
|
||||||
|
@ -195,7 +195,7 @@ size_t EnumerateListBlock::skipSome(size_t atLeast, size_t atMost) {
|
||||||
AqlValue const& inVarReg = cur->getValueReference(_pos, _inVarRegId);
|
AqlValue const& inVarReg = cur->getValueReference(_pos, _inVarRegId);
|
||||||
// get the size of the thing we are looping over
|
// get the size of the thing we are looping over
|
||||||
if (!inVarReg.isArray()) {
|
if (!inVarReg.isArray()) {
|
||||||
throwArrayExpectedException();
|
throwArrayExpectedException(inVarReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sizeInVar;
|
size_t sizeInVar;
|
||||||
|
@ -253,9 +253,12 @@ AqlValue EnumerateListBlock::getAqlValue(AqlValue const& inVarReg, bool& mustDes
|
||||||
DEBUG_END_BLOCK();
|
DEBUG_END_BLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnumerateListBlock::throwArrayExpectedException() {
|
void EnumerateListBlock::throwArrayExpectedException(AqlValue const& value) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||||
TRI_ERROR_QUERY_ARRAY_EXPECTED,
|
TRI_ERROR_QUERY_ARRAY_EXPECTED,
|
||||||
|
std::string("collection or ") +
|
||||||
TRI_errno_string(TRI_ERROR_QUERY_ARRAY_EXPECTED) +
|
TRI_errno_string(TRI_ERROR_QUERY_ARRAY_EXPECTED) +
|
||||||
std::string(" as operand to FOR loop"));
|
std::string(" as operand to FOR loop; you provided a value of type '") +
|
||||||
|
value.getTypeString () +
|
||||||
|
std::string("'"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ class EnumerateListBlock : public ExecutionBlock {
|
||||||
AqlValue getAqlValue(AqlValue const&, bool& mustDestroy);
|
AqlValue getAqlValue(AqlValue const&, bool& mustDestroy);
|
||||||
|
|
||||||
// cppcheck-suppress *
|
// cppcheck-suppress *
|
||||||
void throwArrayExpectedException();
|
void throwArrayExpectedException(AqlValue const& value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// current position in the _inVariable
|
// current position in the _inVariable
|
||||||
|
|
|
@ -80,7 +80,7 @@ SocketTask::~SocketTask() {
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to cancel _keepAliveTimer";
|
LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to cancel _keepAliveTimer";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketTask::start() {
|
void SocketTask::start() {
|
||||||
|
@ -163,28 +163,26 @@ void SocketTask::addWriteBuffer(StringBuffer* buffer,
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
|
|
||||||
boost::system::error_code err;
|
boost::system::error_code err;
|
||||||
do {
|
written = _peer->write(_writeBuffer, err);
|
||||||
err.assign(boost::system::errc::success,
|
|
||||||
boost::system::generic_category());
|
|
||||||
written = _peer->write(_writeBuffer, err);
|
|
||||||
if(_writeBufferStatistics){
|
|
||||||
_writeBufferStatistics->_sentBytes += written;
|
|
||||||
}
|
|
||||||
if (written == total) {
|
|
||||||
locker.unlock();
|
|
||||||
completedWriteBuffer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} while (err == boost::asio::error::would_block);
|
|
||||||
|
|
||||||
if (err != boost::system::errc::success) {
|
if(_writeBufferStatistics){
|
||||||
|
_writeBufferStatistics->_sentBytes += written;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (written == total) {
|
||||||
|
locker.unlock();
|
||||||
|
completedWriteBuffer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err != boost::system::errc::success && err!= boost::asio::error::would_block) {
|
||||||
LOG_TOPIC(DEBUG, Logger::COMMUNICATION)
|
LOG_TOPIC(DEBUG, Logger::COMMUNICATION)
|
||||||
<< "SocketTask::addWriteBuffer (write_some) - write on stream "
|
<< "SocketTask::addWriteBuffer (write_some) - write on stream "
|
||||||
<< " failed with: " << err.message();
|
<< " failed with: " << err.message();
|
||||||
closeStream();
|
closeStream();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
ec.assign(boost::system::errc::success,
|
ec.assign(boost::system::errc::success,
|
||||||
boost::system::generic_category());
|
boost::system::generic_category());
|
||||||
|
|
Loading…
Reference in New Issue