mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'spdvpk' of github.com:arangodb/arangodb into spdvpk
This commit is contained in:
commit
3f1d090ac7
|
@ -326,10 +326,39 @@ class Slice {
|
|||
|
||||
return last;
|
||||
}
|
||||
|
||||
// look for the specified attribute path inside an Object
|
||||
// returns a Slice(ValueType::None) if not found
|
||||
Slice get(std::vector<char const*> const& attributes) const {
|
||||
size_t const n = attributes.size();
|
||||
if (n == 0) {
|
||||
throw Exception(Exception::InvalidAttributePath);
|
||||
}
|
||||
|
||||
// use ourselves as the starting point
|
||||
Slice last = Slice(start());
|
||||
for (size_t i = 0; i < attributes.size(); ++i) {
|
||||
// fetch subattribute
|
||||
last = last.get(attributes[i]);
|
||||
|
||||
// abort as early as possible
|
||||
if (last.isNone() || (i + 1 < n && !last.isObject())) {
|
||||
return Slice();
|
||||
}
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
// look for the specified attribute inside an Object
|
||||
// returns a Slice(ValueType::None) if not found
|
||||
Slice get(std::string const& attribute) const;
|
||||
|
||||
// look for the specified attribute inside an Object
|
||||
// returns a Slice(ValueType::None) if not found
|
||||
Slice get(char const* attribute) const {
|
||||
return get(std::string(attribute));
|
||||
}
|
||||
|
||||
Slice operator[](std::string const& attribute) const {
|
||||
return get(attribute);
|
||||
|
|
|
@ -731,6 +731,16 @@ Json AqlValue::toJson(arangodb::AqlTransaction* trx,
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$::AqlValue$() {
|
||||
VPackBuilder builder;
|
||||
memcpy(_data.internal, builder.slice().begin(), builder.slice().byteSize());
|
||||
_data.internal[15] = AqlValueType::INTERNAL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -754,7 +764,7 @@ AqlValue$::AqlValue$(VPackBuilder const& data) {
|
|||
/// @brief Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$::AqlValue$(VPackBuilder const* data) : AqlValue$(*data){};
|
||||
AqlValue$::AqlValue$(VPackBuilder const* data) : AqlValue$(*data) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Constructor
|
||||
|
@ -772,8 +782,7 @@ AqlValue$::AqlValue$(VPackSlice const& data) {
|
|||
memcpy(_data.external->data(), data.start(), l);
|
||||
_data.internal[15] = AqlValueType::EXTERNAL;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Copy Constructor.
|
||||
|
@ -877,6 +886,105 @@ AqlValue$::AqlValue$(AqlValue const& other, arangodb::AqlTransaction* trx,
|
|||
AqlValue$::AqlValueType AqlValue$::type() const {
|
||||
return static_cast<AqlValueType>(_data.internal[15]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the numeric value of an AqlValue
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double AqlValue$::toDouble() const {
|
||||
if (slice().isCustom()) {
|
||||
#warning FIX custom
|
||||
// range. TODO
|
||||
//size_t rangeSize = _range->size();
|
||||
//if (rangeSize == 1) {
|
||||
// return _range->at(0);
|
||||
//}
|
||||
return 0.0;
|
||||
}
|
||||
if (slice().isBoolean()) {
|
||||
return slice().getBoolean() ? 1.0 : 0.0;
|
||||
}
|
||||
if (slice().isNumber()) {
|
||||
return slice().getNumber<double>();
|
||||
}
|
||||
if (slice().isString()) {
|
||||
try {
|
||||
return std::stod(slice().copyString());
|
||||
} catch (...) {
|
||||
// conversion failed
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
if (slice().isArray()) {
|
||||
if (slice().length() == 1) {
|
||||
AqlValue$ tmp(slice().at(0));
|
||||
return tmp.toDouble();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the numeric value of an AqlValue
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int64_t AqlValue$::toInt64() const {
|
||||
if (slice().isCustom()) {
|
||||
#warning FIX custom
|
||||
// range. TODO
|
||||
//size_t rangeSize = _range->size();
|
||||
//if (rangeSize == 1) {
|
||||
// return _range->at(0);
|
||||
//}
|
||||
return 0;
|
||||
}
|
||||
if (slice().isBoolean()) {
|
||||
return slice().getBoolean() ? 1 : 0;
|
||||
}
|
||||
if (slice().isNumber()) {
|
||||
return slice().getNumber<int64_t>();
|
||||
}
|
||||
if (slice().isString()) {
|
||||
try {
|
||||
return static_cast<int64_t>(std::stoll(slice().copyString()));
|
||||
} catch (...) {
|
||||
// conversion failed
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (slice().isArray()) {
|
||||
if (slice().length() == 1) {
|
||||
AqlValue$ tmp(slice().at(0));
|
||||
return tmp.toInt64();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AqlValue$::isTrue() const {
|
||||
if (slice().isBoolean() && slice().getBoolean()) {
|
||||
return true;
|
||||
}
|
||||
if (slice().isNumber() && slice().getNumber<double>() != 0.0) {
|
||||
return true;
|
||||
}
|
||||
if (slice().isString() && !slice().copyString().empty()) {
|
||||
return true;
|
||||
}
|
||||
if (slice().isArray() || slice().isObject()) {
|
||||
return true;
|
||||
}
|
||||
if (slice().isCustom()) {
|
||||
// range
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
VPackSlice AqlValue$::slice() const {
|
||||
if (type()) {
|
||||
|
|
|
@ -393,9 +393,11 @@ struct AqlValue$ {
|
|||
} _data;
|
||||
|
||||
public:
|
||||
AqlValue$(arangodb::velocypack::Builder const&);
|
||||
AqlValue$(arangodb::velocypack::Builder const*);
|
||||
AqlValue$(arangodb::velocypack::Slice const&);
|
||||
explicit AqlValue$(arangodb::velocypack::Builder const&);
|
||||
explicit AqlValue$(arangodb::velocypack::Builder const*);
|
||||
explicit AqlValue$(arangodb::velocypack::Slice const&);
|
||||
|
||||
AqlValue$();
|
||||
|
||||
AqlValue$(AqlValue const&, arangodb::AqlTransaction*,
|
||||
TRI_document_collection_t const*);
|
||||
|
@ -407,7 +409,7 @@ struct AqlValue$ {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Copy Constructor.
|
||||
/// @brief Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$(AqlValue$ const& other);
|
||||
|
@ -423,10 +425,34 @@ struct AqlValue$ {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Returns a slice to read this Value's data
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
arangodb::velocypack::Slice slice() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the numeric value of an AqlValue
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double toDouble() const;
|
||||
int64_t toInt64() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not an AqlValue evaluates to true
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool isTrue() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compare function for two values
|
||||
/// TODO: implement
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Compare(arangodb::AqlTransaction*, AqlValue$ const& left, AqlValue$ const& right, bool useUtf8) {
|
||||
// TODO: implement
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(AqlValue$) < 17, "invalid AqlValue size.");
|
||||
static_assert(sizeof(AqlValue$) == 16, "invalid AqlValue$ size");
|
||||
|
||||
} // closes namespace arangodb::aql
|
||||
} // closes namespace arangodb
|
||||
|
|
|
@ -22,16 +22,15 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "AttributeAccessor.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
#include "Aql/AqlItemBlock.h"
|
||||
#include "Aql/Variable.h"
|
||||
#include "Basics/StringBuffer.h"
|
||||
#include "Basics/json.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
#include "VocBase/shaped-json.h"
|
||||
#include "VocBase/VocShaper.h"
|
||||
#include "Utils/AqlTransaction.h"
|
||||
|
||||
#include <velocypack/Slice.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb::aql;
|
||||
using Json = arangodb::basics::Json;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the accessor
|
||||
|
@ -41,38 +40,8 @@ AttributeAccessor::AttributeAccessor(
|
|||
std::vector<char const*> const& attributeParts, Variable const* variable)
|
||||
: _attributeParts(attributeParts),
|
||||
_combinedName(),
|
||||
_variable(variable),
|
||||
_buffer(TRI_UNKNOWN_MEM_ZONE),
|
||||
_shaper(nullptr),
|
||||
_pid(0),
|
||||
_nameCache({"", 0}),
|
||||
_attributeType(ATTRIBUTE_TYPE_REGULAR) {
|
||||
_variable(variable) {
|
||||
TRI_ASSERT(_variable != nullptr);
|
||||
|
||||
if (_attributeParts.size() == 1) {
|
||||
char const* n = _attributeParts[0];
|
||||
|
||||
if (strcmp(n, TRI_VOC_ATTRIBUTE_KEY) == 0) {
|
||||
_attributeType = ATTRIBUTE_TYPE_KEY;
|
||||
} else if (strcmp(n, TRI_VOC_ATTRIBUTE_REV) == 0) {
|
||||
_attributeType = ATTRIBUTE_TYPE_REV;
|
||||
} else if (strcmp(n, TRI_VOC_ATTRIBUTE_ID) == 0) {
|
||||
_attributeType = ATTRIBUTE_TYPE_ID;
|
||||
} else if (strcmp(n, TRI_VOC_ATTRIBUTE_FROM) == 0) {
|
||||
_attributeType = ATTRIBUTE_TYPE_FROM;
|
||||
} else if (strcmp(n, TRI_VOC_ATTRIBUTE_TO) == 0) {
|
||||
_attributeType = ATTRIBUTE_TYPE_TO;
|
||||
}
|
||||
}
|
||||
|
||||
if (_attributeType == ATTRIBUTE_TYPE_REGULAR) {
|
||||
for (auto const& it : _attributeParts) {
|
||||
if (!_combinedName.empty()) {
|
||||
_combinedName.push_back('.');
|
||||
}
|
||||
_combinedName.append(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -96,206 +65,15 @@ AqlValue AttributeAccessor::get(arangodb::AqlTransaction* trx,
|
|||
auto& result = argv->getValueReference(startPos, regs[i]);
|
||||
|
||||
// extract the attribute
|
||||
if (result.isShaped()) {
|
||||
switch (_attributeType) {
|
||||
case ATTRIBUTE_TYPE_KEY: {
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE,
|
||||
TRI_EXTRACT_MARKER_KEY(result._marker)));
|
||||
}
|
||||
|
||||
case ATTRIBUTE_TYPE_REV: {
|
||||
return extractRev(result);
|
||||
}
|
||||
|
||||
case ATTRIBUTE_TYPE_ID: {
|
||||
TRI_document_collection_t const* collection =
|
||||
argv->getDocumentCollection(regs[i]);
|
||||
return extractId(result, trx, collection);
|
||||
}
|
||||
|
||||
case ATTRIBUTE_TYPE_FROM: {
|
||||
return extractFrom(result, trx);
|
||||
}
|
||||
|
||||
case ATTRIBUTE_TYPE_TO: {
|
||||
return extractTo(result, trx);
|
||||
}
|
||||
|
||||
case ATTRIBUTE_TYPE_REGULAR:
|
||||
default: {
|
||||
TRI_document_collection_t const* collection =
|
||||
argv->getDocumentCollection(regs[i]);
|
||||
return extractRegular(result, trx, collection);
|
||||
}
|
||||
}
|
||||
} else if (result.isJson()) {
|
||||
TRI_json_t const* json = result._json->json();
|
||||
size_t const n = _attributeParts.size();
|
||||
size_t i = 0;
|
||||
|
||||
while (TRI_IsObjectJson(json)) {
|
||||
TRI_ASSERT(i < n);
|
||||
|
||||
json = TRI_LookupObjectJson(json, _attributeParts[i]);
|
||||
|
||||
if (json == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
++i;
|
||||
|
||||
if (i == n) {
|
||||
// reached the end
|
||||
std::unique_ptr<TRI_json_t> copy(
|
||||
TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, json));
|
||||
|
||||
if (copy == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
auto result = new Json(TRI_UNKNOWN_MEM_ZONE, copy.get());
|
||||
copy.release();
|
||||
return AqlValue(result);
|
||||
}
|
||||
}
|
||||
|
||||
// fall-through intentional
|
||||
}
|
||||
|
||||
break;
|
||||
VPackSlice const slice;
|
||||
#warning TODO: fill slice from AqlValue (result)
|
||||
VPackSlice extracted = slice.get(_attributeParts);
|
||||
#warning TODO: build result from extracted
|
||||
return AqlValue(new arangodb::basics::Json(arangodb::basics::Json::Null));
|
||||
}
|
||||
// fall-through intentional
|
||||
}
|
||||
|
||||
return AqlValue(new Json(Json::Null));
|
||||
return AqlValue(new arangodb::basics::Json(arangodb::basics::Json::Null));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract the _rev attribute from a ShapedJson marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue AttributeAccessor::extractRev(AqlValue const& src) {
|
||||
_buffer.reset();
|
||||
_buffer.appendInteger(TRI_EXTRACT_MARKER_RID(src._marker));
|
||||
|
||||
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
|
||||
|
||||
return AqlValue(json);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract the _id attribute from a ShapedJson marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue AttributeAccessor::extractId(
|
||||
AqlValue const& src, arangodb::AqlTransaction* trx,
|
||||
TRI_document_collection_t const* document) {
|
||||
if (_nameCache.value.empty()) {
|
||||
_nameCache.value = trx->resolver()->getCollectionName(document->_info.id());
|
||||
}
|
||||
|
||||
_buffer.reset();
|
||||
_buffer.appendText(_nameCache.value);
|
||||
_buffer.appendChar('/');
|
||||
_buffer.appendText(TRI_EXTRACT_MARKER_KEY(src._marker));
|
||||
|
||||
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
|
||||
|
||||
return AqlValue(json);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract the _from attribute from a ShapedJson marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue AttributeAccessor::extractFrom(AqlValue const& src,
|
||||
arangodb::AqlTransaction* trx) {
|
||||
// TODO vpack
|
||||
if (src._marker->getType() != TRI_DOC_MARKER_KEY_EDGE) {
|
||||
return AqlValue(new Json(Json::Null));
|
||||
}
|
||||
|
||||
auto cid = TRI_EXTRACT_MARKER_FROM_CID(src._marker);
|
||||
|
||||
if (_nameCache.value.empty() || _nameCache.cid != cid) {
|
||||
_nameCache.cid = cid;
|
||||
_nameCache.value = trx->resolver()->getCollectionNameCluster(cid);
|
||||
}
|
||||
|
||||
_buffer.reset();
|
||||
_buffer.appendText(_nameCache.value);
|
||||
_buffer.appendChar('/');
|
||||
_buffer.appendText(TRI_EXTRACT_MARKER_FROM_KEY(src._marker));
|
||||
|
||||
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
|
||||
|
||||
return AqlValue(json);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract the _to attribute from a ShapedJson marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue AttributeAccessor::extractTo(AqlValue const& src,
|
||||
arangodb::AqlTransaction* trx) {
|
||||
// TODO vpack
|
||||
if (src._marker->getType() != TRI_DOC_MARKER_KEY_EDGE) {
|
||||
return AqlValue(new Json(Json::Null));
|
||||
}
|
||||
|
||||
auto cid = TRI_EXTRACT_MARKER_TO_CID(src._marker);
|
||||
|
||||
if (_nameCache.value.empty() || _nameCache.cid != cid) {
|
||||
_nameCache.cid = cid;
|
||||
_nameCache.value = trx->resolver()->getCollectionNameCluster(cid);
|
||||
}
|
||||
|
||||
_buffer.reset();
|
||||
_buffer.appendText(_nameCache.value);
|
||||
_buffer.appendChar('/');
|
||||
_buffer.appendText(TRI_EXTRACT_MARKER_TO_KEY(src._marker));
|
||||
|
||||
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
|
||||
|
||||
return AqlValue(json);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract any other attribute from a ShapedJson marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue AttributeAccessor::extractRegular(
|
||||
AqlValue const& src, arangodb::AqlTransaction* trx,
|
||||
TRI_document_collection_t const* document) {
|
||||
if (_shaper == nullptr) {
|
||||
_shaper = document->getShaper();
|
||||
_pid = _shaper->lookupAttributePathByName(_combinedName.c_str());
|
||||
}
|
||||
|
||||
if (_pid != 0) {
|
||||
// attribute exists
|
||||
TRI_ASSERT(_shaper != nullptr);
|
||||
|
||||
TRI_shaped_json_t shapedJson;
|
||||
TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, src._marker);
|
||||
|
||||
TRI_shaped_json_t json;
|
||||
TRI_shape_t const* shape;
|
||||
|
||||
bool ok = _shaper->extractShapedJson(&shapedJson, 0, _pid, &json, &shape);
|
||||
|
||||
if (ok && shape != nullptr) {
|
||||
std::unique_ptr<TRI_json_t> extracted(TRI_JsonShapedJson(_shaper, &json));
|
||||
|
||||
if (extracted == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
auto j = new Json(TRI_UNKNOWN_MEM_ZONE, extracted.get());
|
||||
extracted.release();
|
||||
return AqlValue(j);
|
||||
}
|
||||
}
|
||||
|
||||
return AqlValue(new Json(Json::Null));
|
||||
}
|
||||
|
|
|
@ -27,17 +27,12 @@
|
|||
#include "Basics/Common.h"
|
||||
#include "Aql/AqlValue.h"
|
||||
#include "Aql/types.h"
|
||||
#include "Basics/StringBuffer.h"
|
||||
#include "Utils/AqlTransaction.h"
|
||||
#include "VocBase/shaped-json.h"
|
||||
|
||||
struct TRI_document_collection_t;
|
||||
class VocShaper;
|
||||
|
||||
namespace arangodb {
|
||||
namespace aql {
|
||||
|
||||
class AqlItemBlock;
|
||||
class AqlTransaction;
|
||||
struct Variable;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -45,15 +40,6 @@ struct Variable;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AttributeAccessor {
|
||||
enum AttributeType {
|
||||
ATTRIBUTE_TYPE_KEY,
|
||||
ATTRIBUTE_TYPE_REV,
|
||||
ATTRIBUTE_TYPE_ID,
|
||||
ATTRIBUTE_TYPE_FROM,
|
||||
ATTRIBUTE_TYPE_TO,
|
||||
ATTRIBUTE_TYPE_REGULAR
|
||||
};
|
||||
|
||||
public:
|
||||
AttributeAccessor(std::vector<char const*> const&, Variable const*);
|
||||
|
||||
|
@ -67,39 +53,6 @@ class AttributeAccessor {
|
|||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract the _rev attribute from a ShapedJson marker
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue extractRev(AqlValue const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract the _id attribute from a ShapedJson marker
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue extractId(AqlValue const&, arangodb::AqlTransaction*,
|
||||
struct TRI_document_collection_t const*);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract the _from attribute from a ShapedJson marker
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue extractFrom(AqlValue const&, arangodb::AqlTransaction*);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract the _to attribute from a ShapedJson marker
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue extractTo(AqlValue const&, arangodb::AqlTransaction*);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extract any other attribute from a ShapedJson marker
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue extractRegular(AqlValue const&, arangodb::AqlTransaction*,
|
||||
struct TRI_document_collection_t const*);
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the attribute names vector (e.g. [ "a", "b", "c" ] for a.b.c)
|
||||
|
@ -119,38 +72,6 @@ class AttributeAccessor {
|
|||
|
||||
Variable const* _variable;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief buffer for temporary strings
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
arangodb::basics::StringBuffer _buffer;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief shaper
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VocShaper* _shaper;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief attribute path id cache for shapes
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_shape_pid_t _pid;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collection name lookup cache
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct {
|
||||
std::string value;
|
||||
TRI_voc_cid_t cid;
|
||||
} _nameCache;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief attribute type (to save repeated strcmp calls)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AttributeType _attributeType;
|
||||
};
|
||||
|
||||
} // namespace arangodb::aql
|
||||
|
|
|
@ -128,17 +128,13 @@ void CalculationBlock::executeExpression(AqlItemBlock* result) {
|
|||
TRI_IF_FAILURE("CalculationBlock::executeExpressionWithCondition") {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
result->setValue(i, _outReg, AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE,
|
||||
&Expression::NullJson,
|
||||
Json::NOFREE)));
|
||||
result->setValue(i, _outReg, AqlValue(new Json(Json::Null)));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// execute the expression
|
||||
TRI_document_collection_t const* myCollection = nullptr;
|
||||
AqlValue a =
|
||||
_expression->execute(_trx, result, i, _inVars, _inRegs, &myCollection);
|
||||
AqlValue a = _expression->execute(_trx, result, i, _inVars, _inRegs);
|
||||
|
||||
try {
|
||||
TRI_IF_FAILURE("CalculationBlock::executeExpression") {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,25 +26,29 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
#include "Aql/AstNode.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Aql/Range.h"
|
||||
#include "Aql/Variable.h"
|
||||
#include "Aql/types.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
#include "Basics/StringBuffer.h"
|
||||
#include "Utils/AqlTransaction.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Slice.h>
|
||||
|
||||
struct TRI_json_t;
|
||||
|
||||
namespace arangodb {
|
||||
class AqlTransaction;
|
||||
|
||||
namespace basics {
|
||||
class Json;
|
||||
class StringBuffer;
|
||||
}
|
||||
|
||||
namespace aql {
|
||||
|
||||
class AqlItemBlock;
|
||||
struct AqlValue;
|
||||
struct AqlValue$;
|
||||
class Ast;
|
||||
class AttributeAccessor;
|
||||
class Executor;
|
||||
|
@ -167,8 +171,7 @@ class Expression {
|
|||
|
||||
AqlValue execute(arangodb::AqlTransaction* trx, AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&,
|
||||
TRI_document_collection_t const**);
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief check whether this is a JSON expression
|
||||
|
@ -278,8 +281,7 @@ class Expression {
|
|||
void invalidate();
|
||||
|
||||
private:
|
||||
void setVariable(Variable const* variable, TRI_json_t const* value) {
|
||||
TRI_ASSERT(value != nullptr);
|
||||
void setVariable(Variable const* variable, arangodb::velocypack::Slice value) {
|
||||
_variables.emplace(variable, value);
|
||||
}
|
||||
|
||||
|
@ -289,9 +291,8 @@ class Expression {
|
|||
/// @brief find a value in an array
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool findInArray(AqlValue const&, AqlValue const&,
|
||||
TRI_document_collection_t const*,
|
||||
TRI_document_collection_t const*, arangodb::AqlTransaction*,
|
||||
bool findInArray(AqlValue$ const&, AqlValue$ const&,
|
||||
arangodb::AqlTransaction*,
|
||||
AstNode const*) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -311,18 +312,17 @@ class Expression {
|
|||
/// @brief execute an expression of type SIMPLE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpression(AstNode const*,
|
||||
TRI_document_collection_t const**,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&, bool);
|
||||
AqlValue$ executeSimpleExpression(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&, bool);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with ATTRIBUTE ACCESS
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionAttributeAccess(
|
||||
AqlValue$ executeSimpleExpressionAttributeAccess(
|
||||
AstNode const*, arangodb::AqlTransaction*, AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&, std::vector<RegisterId> const&);
|
||||
|
||||
|
@ -330,7 +330,7 @@ class Expression {
|
|||
/// @brief execute an expression of type SIMPLE with INDEXED ACCESS
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionIndexedAccess(
|
||||
AqlValue$ executeSimpleExpressionIndexedAccess(
|
||||
AstNode const*, arangodb::AqlTransaction*, AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&, std::vector<RegisterId> const&);
|
||||
|
||||
|
@ -338,17 +338,17 @@ class Expression {
|
|||
/// @brief execute an expression of type SIMPLE with ARRAY
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionArray(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
AqlValue$ executeSimpleExpressionArray(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with OBJECT
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionObject(AstNode const*,
|
||||
AqlValue$ executeSimpleExpressionObject(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
|
@ -358,63 +358,63 @@ class Expression {
|
|||
/// @brief execute an expression of type SIMPLE with VALUE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionValue(AstNode const*);
|
||||
AqlValue$ executeSimpleExpressionValue(AstNode const*);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with REFERENCE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionReference(AstNode const*,
|
||||
TRI_document_collection_t const**,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&,
|
||||
bool);
|
||||
AqlValue$ executeSimpleExpressionReference(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&,
|
||||
bool);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with FCALL
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionFCall(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
AqlValue$ executeSimpleExpressionFCall(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with RANGE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionRange(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
AqlValue$ executeSimpleExpressionRange(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with NOT
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionNot(AstNode const*, arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
AqlValue$ executeSimpleExpressionNot(AstNode const*, arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with AND or OR
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionAndOr(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
AqlValue$ executeSimpleExpressionAndOr(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with COMPARISON
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionComparison(
|
||||
AqlValue$ executeSimpleExpressionComparison(
|
||||
AstNode const*, arangodb::AqlTransaction*, AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&, std::vector<RegisterId> const&);
|
||||
|
||||
|
@ -422,7 +422,7 @@ class Expression {
|
|||
/// @brief execute an expression of type SIMPLE with ARRAY COMPARISON
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionArrayComparison(
|
||||
AqlValue$ executeSimpleExpressionArrayComparison(
|
||||
AstNode const*, arangodb::AqlTransaction*, AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&, std::vector<RegisterId> const&);
|
||||
|
||||
|
@ -430,38 +430,37 @@ class Expression {
|
|||
/// @brief execute an expression of type SIMPLE with TERNARY
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionTernary(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with EXPANSION
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionExpansion(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with EXPANSION
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionIterator(AstNode const*,
|
||||
TRI_document_collection_t const**,
|
||||
AqlValue$ executeSimpleExpressionTernary(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with EXPANSION
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$ executeSimpleExpressionExpansion(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with EXPANSION
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$ executeSimpleExpressionIterator(AstNode const*,
|
||||
arangodb::AqlTransaction*,
|
||||
AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an expression of type SIMPLE with BINARY_* (+, -, * , /, %)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue executeSimpleExpressionArithmetic(
|
||||
AqlValue$ executeSimpleExpressionArithmetic(
|
||||
AstNode const*, arangodb::AqlTransaction*, AqlItemBlock const*, size_t,
|
||||
std::vector<Variable const*> const&, std::vector<RegisterId> const&);
|
||||
|
||||
|
@ -552,29 +551,8 @@ class Expression {
|
|||
/// @brief variables only temporarily valid during execution
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unordered_map<Variable const*, TRI_json_t const*> _variables;
|
||||
std::unordered_map<Variable const*, arangodb::velocypack::Slice> _variables;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief "constant" global object for NULL which can be shared by all
|
||||
/// expressions but must never be freed
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_json_t const NullJson;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief "constant" global object for TRUE which can be shared by all
|
||||
/// expressions but must never be freed
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_json_t const TrueJson;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief "constant" global object for FALSE which can be shared by all
|
||||
/// expressions but must never be freed
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_json_t const FalseJson;
|
||||
};
|
||||
|
||||
} // namespace arangodb::aql
|
||||
|
|
|
@ -107,7 +107,7 @@ void IndexBlock::executeExpressions() {
|
|||
auto exp = toReplace->expression;
|
||||
TRI_document_collection_t const* myCollection = nullptr;
|
||||
AqlValue a = exp->execute(_trx, cur, _pos, _inVars[posInExpressions],
|
||||
_inRegs[posInExpressions], &myCollection);
|
||||
_inRegs[posInExpressions]);
|
||||
auto jsonified = a.toJson(_trx, myCollection, true);
|
||||
a.destroy();
|
||||
AstNode* evaluatedNode = ast->nodeFromJson(jsonified.json(), true);
|
||||
|
|
|
@ -184,7 +184,7 @@ void TraversalBlock::executeExpressions() {
|
|||
// inVars and inRegs needs fixx
|
||||
TRI_document_collection_t const* myCollection = nullptr;
|
||||
AqlValue a = it->expression->execute(_trx, cur, _pos, _inVars[i],
|
||||
_inRegs[i], &myCollection);
|
||||
_inRegs[i]);
|
||||
it->compareTo.reset(new Json(a.toJson(_trx, myCollection, true)));
|
||||
a.destroy();
|
||||
}
|
||||
|
|
|
@ -1483,7 +1483,7 @@ static void ModifyVocbaseCol(TRI_voc_document_operation_e operation,
|
|||
auto workOnOneSearchVal = [&](v8::Local<v8::Value> const searchVal) {
|
||||
std::string collName;
|
||||
if (!ExtractDocumentHandle(isolate, searchVal, collName,
|
||||
updateBuilder, false)) {
|
||||
updateBuilder, true)) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3283,6 +3283,18 @@ int TRI_document_collection_t::insert(Transaction* trx, VPackSlice const* slice,
|
|||
TRI_doc_mptr_t* mptr,
|
||||
OperationOptions& options,
|
||||
bool lock) {
|
||||
|
||||
if (_info.type() == TRI_COL_TYPE_EDGE) {
|
||||
VPackSlice s = slice->get(TRI_VOC_ATTRIBUTE_FROM);
|
||||
if (!s.isString()) {
|
||||
return TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE;
|
||||
}
|
||||
s = slice->get(TRI_VOC_ATTRIBUTE_TO);
|
||||
if (!s.isString()) {
|
||||
return TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE;
|
||||
}
|
||||
}
|
||||
|
||||
TRI_ASSERT(mptr != nullptr);
|
||||
mptr->setDataPtr(nullptr);
|
||||
|
||||
|
@ -3475,6 +3487,18 @@ int TRI_document_collection_t::replace(Transaction* trx,
|
|||
OperationOptions& options,
|
||||
bool lock,
|
||||
TRI_voc_rid_t& prevRev) {
|
||||
|
||||
if (_info.type() == TRI_COL_TYPE_EDGE) {
|
||||
VPackSlice s = newSlice.get(TRI_VOC_ATTRIBUTE_FROM);
|
||||
if (!s.isString()) {
|
||||
return TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE;
|
||||
}
|
||||
s = newSlice.get(TRI_VOC_ATTRIBUTE_TO);
|
||||
if (!s.isString()) {
|
||||
return TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the result
|
||||
TRI_ASSERT(mptr != nullptr);
|
||||
mptr->setDataPtr(nullptr);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
/// @author Michael Hackstein
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "VelocyPackHelper.h"
|
||||
#include "Basics/conversions.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Basics/Logger.h"
|
||||
|
@ -43,6 +43,28 @@ using VelocyPackHelper = arangodb::basics::VelocyPackHelper;
|
|||
static std::unique_ptr<VPackAttributeTranslator> Translator;
|
||||
static std::unique_ptr<VPackAttributeExcludeHandler> ExcludeHandler;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief "constant" global object for NULL which can be shared by all
|
||||
/// expressions but must never be freed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static VPackBuilder NullBuilder;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief "constant" global object for TRUE which can be shared by all
|
||||
/// expressions but must never be freed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static VPackBuilder TrueBuilder;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief "constant" global object for FALSE which can be shared by all
|
||||
/// expressions but must never be freed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static VPackBuilder FalseBuilder;
|
||||
|
||||
|
||||
// attribute exclude handler for skipping over system attributes
|
||||
struct SystemAttributeExcludeHandler : public VPackAttributeExcludeHandler {
|
||||
bool shouldExclude(VPackSlice const& key, int nesting) override final {
|
||||
|
@ -92,6 +114,22 @@ void VelocyPackHelper::initialize() {
|
|||
|
||||
// initialize exclude handler for system attributes
|
||||
ExcludeHandler.reset(new SystemAttributeExcludeHandler);
|
||||
|
||||
NullBuilder.add(VPackValue(VPackValueType::Null));
|
||||
TrueBuilder.add(VPackValue(true));
|
||||
FalseBuilder.add(VPackValue(false));
|
||||
}
|
||||
|
||||
arangodb::velocypack::Slice VelocyPackHelper::NullValue() {
|
||||
return NullBuilder.slice();
|
||||
}
|
||||
|
||||
arangodb::velocypack::Slice VelocyPackHelper::TrueValue() {
|
||||
return TrueBuilder.slice();
|
||||
}
|
||||
|
||||
arangodb::velocypack::Slice VelocyPackHelper::FalseValue() {
|
||||
return FalseBuilder.slice();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "Basics/JsonHelper.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Slice.h>
|
||||
#include <velocypack/Options.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
@ -207,6 +208,10 @@ class VelocyPackHelper {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static double toDouble(VPackSlice const&, bool&);
|
||||
|
||||
static arangodb::velocypack::Slice NullValue();
|
||||
static arangodb::velocypack::Slice TrueValue();
|
||||
static arangodb::velocypack::Slice FalseValue();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +219,7 @@ class VelocyPackHelper {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Simple and limited logging of VelocyPack slices
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include "Basics/Logger.h"
|
||||
|
||||
arangodb::LoggerStream& operator<<(arangodb::LoggerStream&,
|
||||
arangodb::velocypack::Slice const&);
|
||||
|
||||
|
|
Loading…
Reference in New Issue