mirror of https://gitee.com/bigwinds/arangodb
Included a backward transformation AqlValueVPack -> AqlValueJson. This allows to use the new VPack Functions without modification after switch. They return AqlValueVPack.
This commit is contained in:
parent
6eeb686287
commit
f478411bb8
|
@ -37,6 +37,11 @@ using namespace arangodb::aql;
|
|||
using Json = arangodb::basics::Json;
|
||||
using JsonHelper = arangodb::basics::JsonHelper;
|
||||
|
||||
AqlValue::AqlValue(AqlValue$ const& other) : _json(nullptr), _type(JSON) {
|
||||
_json = new Json(TRI_UNKNOWN_MEM_ZONE, arangodb::basics::VelocyPackHelper::velocyPackToJson(other.slice()));
|
||||
TRI_ASSERT(_json != nullptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief a quick method to decide whether a value is true
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -723,19 +728,65 @@ Json AqlValue::toJson(arangodb::AqlTransaction* trx,
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$::AqlValue$(VPackBuilder const& data) {
|
||||
TRI_ASSERT(data.isClosed());
|
||||
VPackValueLength l = data.size();
|
||||
if (l < 16) {
|
||||
// Use internal
|
||||
memcpy(_data.internal, data.data(), l);
|
||||
_data.internal[15] = AqlValueType::INTERNAL;
|
||||
} else {
|
||||
// Use external
|
||||
_data.external = new VPackBuffer<uint8_t>(l);
|
||||
memcpy(_data.external->data(), data.data(), l);
|
||||
_data.internal[15] = AqlValueType::EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$::AqlValue$(VPackBuilder const* data) : AqlValue$(*data){};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$::AqlValue$(VPackSlice const& data) {
|
||||
VPackValueLength l = data.byteSize();
|
||||
if (l < 16) {
|
||||
// Use internal
|
||||
memcpy(_data.internal, data.start(), l);
|
||||
_data.internal[15] = AqlValueType::INTERNAL;
|
||||
} else {
|
||||
// Use external
|
||||
_data.external = new VPackBuffer<uint8_t>(l);
|
||||
memcpy(_data.external->data(), data.start(), l);
|
||||
_data.internal[15] = AqlValueType::EXTERNAL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Copy Constructor.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue$::AqlValue$(AqlValue$ const& other) {
|
||||
VPackSlice s = other.slice();
|
||||
VPackValueLength length = s.length();
|
||||
VPackValueLength length = s.byteSize();
|
||||
if (other.type()) {
|
||||
// Isse external
|
||||
_data.external = new VPackBuffer<uint8_t>(length);
|
||||
memcpy(_data.external->data(), other._data.external->data(), length);
|
||||
_data.internal[15] = AqlValueType::EXTERNAL;
|
||||
} else {
|
||||
memcpy(_data.internal, other._data.internal, length);
|
||||
_data.internal[15] = AqlValueType::INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -785,18 +836,15 @@ AqlValue$::AqlValue$(AqlValue const& other, arangodb::AqlTransaction* trx,
|
|||
}
|
||||
case AqlValue::RANGE: {
|
||||
// TODO Has to be replaced by VPackCustom Type
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
/*
|
||||
TRI_ASSERT(_range != nullptr);
|
||||
TRI_ASSERT(other._range != nullptr);
|
||||
try {
|
||||
VPackArrayBuilder b(&builder);
|
||||
size_t const n = _range->size();
|
||||
size_t const n = other._range->size();
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
builder.add(VPackValue(_range->at(i)));
|
||||
builder.add(VPackValue(other._range->at(i)));
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case AqlValue::EMPTY: {
|
||||
|
@ -813,18 +861,18 @@ AqlValue$::AqlValue$(AqlValue const& other, arangodb::AqlTransaction* trx,
|
|||
// Small enough for local
|
||||
// copy memory from the builder into the internal data.
|
||||
memcpy(_data.internal, builder.data(), length);
|
||||
_data.internal[15] = 1;
|
||||
_data.internal[15] = AqlValueType::INTERNAL;
|
||||
} else {
|
||||
// We need a large external buffer
|
||||
// TODO: Replace by SlimBuffer
|
||||
_data.external = new VPackBuffer<uint8_t>(length);
|
||||
memcpy(_data.external->data(), builder.data(), length);
|
||||
_data.internal[15] = 0;
|
||||
_data.internal[15] = AqlValueType::EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
bool AqlValue$::type() const {
|
||||
return _data.internal[15] == 0;
|
||||
AqlValue$::AqlValueType AqlValue$::type() const {
|
||||
return static_cast<AqlValueType>(_data.internal[15]);
|
||||
}
|
||||
|
||||
VPackSlice AqlValue$::slice() const {
|
||||
|
|
|
@ -46,6 +46,9 @@ namespace aql {
|
|||
|
||||
class AqlItemBlock;
|
||||
|
||||
// Temporary Forward
|
||||
struct AqlValue$;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief a struct to hold a value, registers hole AqlValue* during the
|
||||
/// execution
|
||||
|
@ -89,6 +92,8 @@ struct AqlValue {
|
|||
_range = new Range(low, high);
|
||||
}
|
||||
|
||||
explicit AqlValue(AqlValue$ const& other);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destructor, doing nothing automatically!
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -358,6 +363,13 @@ struct AqlValue {
|
|||
};
|
||||
|
||||
struct AqlValue$ {
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief AqlValueType, indicates what sort of value we have
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum AqlValueType { INTERNAL, EXTERNAL };
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Holds the actual data for this AqlValue it has the following
|
||||
/// semantics:
|
||||
|
@ -378,8 +390,9 @@ struct AqlValue$ {
|
|||
} _data;
|
||||
|
||||
public:
|
||||
AqlValue$(VPackBuilder const& data);
|
||||
AqlValue$(VPackBuilder const* data);
|
||||
AqlValue$(arangodb::velocypack::Builder const&);
|
||||
AqlValue$(arangodb::velocypack::Builder const*);
|
||||
AqlValue$(arangodb::velocypack::Slice const&);
|
||||
|
||||
AqlValue$(AqlValue const&, arangodb::AqlTransaction*,
|
||||
TRI_document_collection_t const*);
|
||||
|
@ -402,7 +415,7 @@ struct AqlValue$ {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Read last bit of the union
|
||||
bool type() const;
|
||||
AqlValueType type() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Returns a slice to read this Value's data
|
||||
|
|
|
@ -912,17 +912,20 @@ AqlValue Functions::IsNull(arangodb::aql::Query* q, arangodb::AqlTransaction* tr
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return IsNullVPack(q, trx, tmp);
|
||||
return AqlValue(IsNullVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
return AqlValue(new Json(value.isNull()));
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue$ Functions::IsNullVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const slice = ExtractFunctionParameter(trx, parameters, 0);
|
||||
return AqlValue(new Json(slice.isNull()));
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
b->add(VPackValue(slice.isNull()));
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -933,18 +936,20 @@ AqlValue Functions::IsBool(arangodb::aql::Query* q, arangodb::AqlTransaction* tr
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return IsBoolVPack(q, trx, tmp);
|
||||
return AqlValue(IsBoolVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
return AqlValue(new Json(value.isBoolean()));
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::IsBoolVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue$ Functions::IsBoolVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const slice = ExtractFunctionParameter(trx, parameters, 0);
|
||||
return AqlValue(new Json(slice.isBoolean()));
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
b->add(VPackValue(slice.isBool()));
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -956,18 +961,20 @@ AqlValue Functions::IsNumber(arangodb::aql::Query* q,
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return IsNumberVPack(q, trx, tmp);
|
||||
return AqlValue(IsNumberVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
return AqlValue(new Json(value.isNumber()));
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::IsNumberVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue$ Functions::IsNumberVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const slice = ExtractFunctionParameter(trx, parameters, 0);
|
||||
return AqlValue(new Json(slice.isNumber()));
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
b->add(VPackValue(slice.isNumber()));
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -980,18 +987,20 @@ AqlValue Functions::IsString(arangodb::aql::Query* q,
|
|||
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return IsStringVPack(q, trx, tmp);
|
||||
return AqlValue(IsStringVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
return AqlValue(new Json(value.isString()));
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::IsStringVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue$ Functions::IsStringVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const slice = ExtractFunctionParameter(trx, parameters, 0);
|
||||
return AqlValue(new Json(slice.isString()));
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
b->add(VPackValue(slice.isString()));
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1003,18 +1012,20 @@ AqlValue Functions::IsArray(arangodb::aql::Query* q,
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return IsArrayVPack(q, trx, tmp);
|
||||
return AqlValue(IsArrayVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
return AqlValue(new Json(value.isArray()));
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::IsArrayVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue$ Functions::IsArrayVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const slice = ExtractFunctionParameter(trx, parameters, 0);
|
||||
return AqlValue(new Json(slice.isArray()));
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
b->add(VPackValue(slice.isArray()));
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1026,18 +1037,20 @@ AqlValue Functions::IsObject(arangodb::aql::Query* q,
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return IsObjectVPack(q, trx, tmp);
|
||||
return AqlValue(IsObjectVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
return AqlValue(new Json(value.isObject()));
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::IsObjectVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue$ Functions::IsObjectVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const slice = ExtractFunctionParameter(trx, parameters, 0);
|
||||
return AqlValue(new Json(slice.isObject()));
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
b->add(VPackValue(slice.isObject()));
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1049,7 +1062,7 @@ AqlValue Functions::ToNumber(arangodb::aql::Query* q,
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return ToNumberVPack(q, trx, tmp);
|
||||
return AqlValue(ToNumberVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
|
||||
|
@ -1063,7 +1076,7 @@ AqlValue Functions::ToNumber(arangodb::aql::Query* q,
|
|||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::ToNumberVPack(arangodb::aql::Query*,
|
||||
AqlValue$ Functions::ToNumberVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const slice = ExtractFunctionParameter(trx, parameters, 0);
|
||||
|
@ -1071,10 +1084,14 @@ AqlValue Functions::ToNumberVPack(arangodb::aql::Query*,
|
|||
bool isValid;
|
||||
double v = ValueToNumber(slice, isValid);
|
||||
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
|
||||
if (!isValid) {
|
||||
return AqlValue(new Json(Json::Null));
|
||||
b->add(VPackValue(VPackValueType::Null));
|
||||
} else {
|
||||
b->add(VPackValue(v));
|
||||
}
|
||||
return AqlValue(new Json(v));
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1086,7 +1103,7 @@ AqlValue Functions::ToString(arangodb::aql::Query* q,
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return ToStringVPack(q, trx, tmp);
|
||||
return AqlValue(ToStringVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
|
||||
|
@ -1107,26 +1124,23 @@ AqlValue Functions::ToString(arangodb::aql::Query* q,
|
|||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::ToStringVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue$ Functions::ToStringVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0);
|
||||
|
||||
arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24);
|
||||
|
||||
arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer());
|
||||
AppendAsString(adapter, value);
|
||||
size_t length = buffer.length();
|
||||
std::unique_ptr<TRI_json_t> j(
|
||||
TRI_CreateStringJson(TRI_UNKNOWN_MEM_ZONE, buffer.steal(), length));
|
||||
|
||||
if (j == nullptr) {
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
try {
|
||||
std::string res(buffer.begin(), buffer.length());
|
||||
b->add(VPackValue(res));
|
||||
} catch (...) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get());
|
||||
j.release();
|
||||
return AqlValue(jr);
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1137,7 +1151,7 @@ AqlValue Functions::ToBool(arangodb::aql::Query* q, arangodb::AqlTransaction* tr
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return ToBoolVPack(q, trx, tmp);
|
||||
return AqlValue(ToBoolVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
|
||||
|
@ -1145,10 +1159,13 @@ AqlValue Functions::ToBool(arangodb::aql::Query* q, arangodb::AqlTransaction* tr
|
|||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::ToBoolVPack(arangodb::aql::Query* q, arangodb::AqlTransaction* trx,
|
||||
AqlValue$ Functions::ToBoolVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0);
|
||||
return AqlValue(new Json(ValueToBoolean(value)));
|
||||
std::shared_ptr<VPackBuilder> b = query->getSharedBuilder();
|
||||
b->add(VPackValue(ValueToBoolean(value)));
|
||||
return AqlValue$(b.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1160,7 +1177,7 @@ AqlValue Functions::ToArray(arangodb::aql::Query* q,
|
|||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return ToArrayVPack(q, trx, tmp);
|
||||
return AqlValue(ToArrayVPack(q, trx, tmp));
|
||||
#else
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0, false);
|
||||
|
||||
|
@ -1195,43 +1212,43 @@ AqlValue Functions::ToArray(arangodb::aql::Query* q,
|
|||
#endif
|
||||
}
|
||||
|
||||
AqlValue Functions::ToArrayVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
AqlValue$ Functions::ToArrayVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0);
|
||||
|
||||
if (value.isArray()) {
|
||||
// return copy of the original array
|
||||
return AqlValue(
|
||||
new Json(TRI_UNKNOWN_MEM_ZONE,
|
||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(value)));
|
||||
return AqlValue$(value);
|
||||
}
|
||||
|
||||
VPackBuilder result;
|
||||
std::shared_ptr<VPackBuilder> result = query->getSharedBuilder();
|
||||
{
|
||||
VPackArrayBuilder b(&result);
|
||||
VPackArrayBuilder b(result.get());
|
||||
if (value.isBoolean() || value.isNumber() || value.isString()) {
|
||||
// return array with single member
|
||||
result.add(value);
|
||||
result->add(value);
|
||||
} else if (value.isObject()) {
|
||||
// return an array with the attribute values
|
||||
for (auto const& it : VPackObjectIterator(value)) {
|
||||
result.add(it.value);
|
||||
result->add(it.value);
|
||||
}
|
||||
}
|
||||
// else return empty array
|
||||
}
|
||||
|
||||
return AqlValue(
|
||||
new Json(TRI_UNKNOWN_MEM_ZONE,
|
||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(result.slice())));
|
||||
return AqlValue$(result.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief function LENGTH
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx,
|
||||
AqlValue Functions::Length(arangodb::aql::Query* q, arangodb::AqlTransaction* trx,
|
||||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return AqlValue(LengthVPack(q, trx, tmp));
|
||||
#else
|
||||
if (!parameters.empty() && parameters[0].first.isArray()) {
|
||||
// shortcut!
|
||||
return AqlValue(
|
||||
|
@ -1292,6 +1309,44 @@ AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx,
|
|||
}
|
||||
|
||||
return AqlValue(new Json(static_cast<double>(length)));
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue$ Functions::LengthVPack(arangodb::aql::Query* q,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
auto const value = ExtractFunctionParameter(trx, parameters, 0);
|
||||
std::shared_ptr<VPackBuilder> builder = q->getSharedBuilder();
|
||||
if (value.isArray()) {
|
||||
// shortcut!
|
||||
builder->add(VPackValue(static_cast<double>(value.length())));
|
||||
return AqlValue$(builder->slice());
|
||||
}
|
||||
size_t length = 0;
|
||||
if (value.isNone() || value.isNull()) {
|
||||
length = 0;
|
||||
} else if (value.isBoolean()) {
|
||||
if (value.getBoolean()) {
|
||||
length = 1;
|
||||
} else {
|
||||
length = 0;
|
||||
}
|
||||
} else if (value.isNumber()) {
|
||||
double tmp = value.getNumericValue<double>();
|
||||
if (std::isnan(tmp) || !std::isfinite(tmp)) {
|
||||
length = strlen("null");
|
||||
} else {
|
||||
char buffer[24];
|
||||
length = static_cast<size_t>(fpconv_dtoa(tmp, buffer));
|
||||
}
|
||||
} else if (value.isString()) {
|
||||
std::string tmp = value.copyString();
|
||||
length = TRI_CharLengthUtf8String(tmp.c_str());
|
||||
} else if (value.isObject()) {
|
||||
length = static_cast<size_t>(value.length());
|
||||
}
|
||||
builder->add(VPackValue(static_cast<double>(length)));
|
||||
return AqlValue$(builder.get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1301,6 +1356,10 @@ AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx,
|
|||
AqlValue Functions::First(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return AqlValue(FirstVPack(query, trx, tmp));
|
||||
#else
|
||||
if (parameters.size() < 1) {
|
||||
THROW_ARANGO_EXCEPTION_PARAMS(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FIRST", (int)1,
|
||||
|
@ -1322,6 +1381,35 @@ AqlValue Functions::First(arangodb::aql::Query* query,
|
|||
auto j = new Json(TRI_UNKNOWN_MEM_ZONE, value.at(0).copy().steal(),
|
||||
Json::AUTOFREE);
|
||||
return AqlValue(j);
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue$ Functions::FirstVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
if (parameters.size() < 1) {
|
||||
THROW_ARANGO_EXCEPTION_PARAMS(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FIRST", (int)1,
|
||||
(int)1);
|
||||
}
|
||||
|
||||
auto value = ExtractFunctionParameter(trx, parameters, 0);
|
||||
|
||||
if (!value.isArray()) {
|
||||
// not an array
|
||||
RegisterWarning(query, "FIRST", TRI_ERROR_QUERY_ARRAY_EXPECTED);
|
||||
std::shared_ptr<VPackBuilder> builder = query->getSharedBuilder();
|
||||
builder->add(VPackValue(VPackValueType::Null));
|
||||
return AqlValue$(builder.get());
|
||||
}
|
||||
|
||||
if (value.length() == 0) {
|
||||
std::shared_ptr<VPackBuilder> builder = query->getSharedBuilder();
|
||||
builder->add(VPackValue(VPackValueType::Null));
|
||||
return AqlValue$(builder.get());
|
||||
}
|
||||
|
||||
return AqlValue$(value.at(0));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1331,6 +1419,10 @@ AqlValue Functions::First(arangodb::aql::Query* query,
|
|||
AqlValue Functions::Last(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
FunctionParameters const& parameters) {
|
||||
#ifdef TMPUSEVPACK
|
||||
auto tmp = transformParameters(parameters, trx);
|
||||
return AqlValue(LastVPack(query, trx, tmp));
|
||||
#else
|
||||
if (parameters.size() < 1) {
|
||||
THROW_ARANGO_EXCEPTION_PARAMS(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)1,
|
||||
|
@ -1354,6 +1446,36 @@ AqlValue Functions::Last(arangodb::aql::Query* query,
|
|||
auto j = new Json(TRI_UNKNOWN_MEM_ZONE, value.at(n - 1).copy().steal(),
|
||||
Json::AUTOFREE);
|
||||
return AqlValue(j);
|
||||
#endif
|
||||
}
|
||||
|
||||
AqlValue$ Functions::LastVPack(arangodb::aql::Query* query,
|
||||
arangodb::AqlTransaction* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
if (parameters.size() < 1) {
|
||||
THROW_ARANGO_EXCEPTION_PARAMS(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)1,
|
||||
(int)1);
|
||||
}
|
||||
|
||||
auto value = ExtractFunctionParameter(trx, parameters, 0);
|
||||
|
||||
if (!value.isArray()) {
|
||||
// not an array
|
||||
RegisterWarning(query, "LAST", TRI_ERROR_QUERY_ARRAY_EXPECTED);
|
||||
std::shared_ptr<VPackBuilder> builder = query->getSharedBuilder();
|
||||
builder->add(VPackValue(VPackValueType::Null));
|
||||
return AqlValue$(builder.get());
|
||||
}
|
||||
|
||||
VPackValueLength const n = value.length();
|
||||
|
||||
if (n == 0) {
|
||||
std::shared_ptr<VPackBuilder> builder = query->getSharedBuilder();
|
||||
builder->add(VPackValue(VPackValueType::Null));
|
||||
return AqlValue$(builder.get());
|
||||
}
|
||||
return AqlValue$(value.at(n-1));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -65,57 +65,63 @@ struct Functions {
|
|||
|
||||
static AqlValue IsNull(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue$ IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue IsBool(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue$ IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue IsNumber(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue IsNumberVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue$ IsNumberVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue IsString(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue IsStringVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue$ IsStringVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue IsArray(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue IsArrayVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue IsObject(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue IsObjectVPack(arangodb::aql::Query*,
|
||||
static AqlValue$ IsArrayVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue IsObject(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue$ IsObjectVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue ToNumber(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
|
||||
static AqlValue ToNumberVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue$ ToNumberVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue ToString(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue ToStringVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue$ ToStringVPack(arangodb::aql::Query*,
|
||||
arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue ToBool(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue ToBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue$ ToBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue ToArray(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue ToArrayVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue$ ToArrayVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue Length(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue$ LengthVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue First(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue$ FirstVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue Last(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue$ LastVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue Nth(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
FunctionParameters const&);
|
||||
static AqlValue Concat(arangodb::aql::Query*, arangodb::AqlTransaction*,
|
||||
|
|
Loading…
Reference in New Issue