1
0
Fork 0

Merge branch 'spdvpk' of github.com:arangodb/arangodb into spdvpk

This commit is contained in:
Michael Hackstein 2016-03-08 13:08:11 +01:00
commit 3f1d090ac7
14 changed files with 598 additions and 822 deletions

View File

@ -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);

View File

@ -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()) {

View File

@ -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

View File

@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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();
}

View File

@ -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);
}
};

View File

@ -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);

View File

@ -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();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -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&);