From 2d5816dbb6a60ffad006cbdd0bf997a3a4051716 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Wed, 15 Jun 2016 20:34:06 +0200 Subject: [PATCH] allow switching args for IS_SAME_COLLECTION --- arangod/Aql/FunctionDefinitions.cpp | 2 +- arangod/Aql/Functions.cpp | 79 ++++++++++++++++------------- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/arangod/Aql/FunctionDefinitions.cpp b/arangod/Aql/FunctionDefinitions.cpp index 07d4039fdc..71d04437d5 100644 --- a/arangod/Aql/FunctionDefinitions.cpp +++ b/arangod/Aql/FunctionDefinitions.cpp @@ -438,7 +438,7 @@ struct FunctionDefiner { true, true, &Functions::FirstDocument}); add({"PARSE_IDENTIFIER", "AQL_PARSE_IDENTIFIER", ".", true, true, false, true, true, &Functions::ParseIdentifier}); - add({"IS_SAME_COLLECTION", "AQL_IS_SAME_COLLECTION", "ch,as", true, true, + add({"IS_SAME_COLLECTION", "AQL_IS_SAME_COLLECTION", "chas,chas", true, true, false, true, true, &Functions::IsSameCollection}); add({"CURRENT_USER", "AQL_CURRENT_USER", "", false, false, false, false, true}); diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index c73f7c40c9..257deea9b6 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -222,6 +222,45 @@ static AqlValue ExtractFunctionParameterValue( return parameters.at(position); } +/// @brief extra a collection name from an AqlValue +static std::string ExtractCollectionName(arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters, + size_t position) { + AqlValue value = ExtractFunctionParameterValue(trx, parameters, position); + + std::string identifier; + + if (value.isString()) { + // already a string + identifier = value.slice().copyString(); + } else { + AqlValueMaterializer materializer(trx); + VPackSlice s = materializer.slice(value, true); + VPackSlice id = s; + + if (s.isObject() && s.hasKey(StaticStrings::IdString)) { + id = s.get(StaticStrings::IdString); + } + if (id.isString()) { + identifier = id.copyString(); + } else if (id.isCustom()) { + identifier = trx->extractIdString(s); + } + } + + if (!identifier.empty()) { + size_t pos = identifier.find('/'); + + if (pos != std::string::npos) { + return identifier.substr(0, pos); + } + + return identifier; + } + + return StaticStrings::Empty; +} + /// @brief register warning static void RegisterWarning(arangodb::aql::Query* query, char const* functionName, int code) { @@ -3795,44 +3834,14 @@ AqlValue Functions::IsSameCollection( VPackFunctionParameters const& parameters) { ValidateParameters(parameters, "IS_SAME_COLLECTION", 2, 2); - AqlValue first = ExtractFunctionParameterValue(trx, parameters, 0); - - if (!first.isString()) { - THROW_ARANGO_EXCEPTION_PARAMS( - TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "IS_SAME_COLLECTION"); - } - - std::string const collectionName(first.slice().copyString()); - - AqlValue value = ExtractFunctionParameterValue(trx, parameters, 1); - - AqlValueMaterializer materializer(trx); - VPackSlice s = materializer.slice(value, true); - VPackSlice id = s; - std::string identifier; - - if (s.isObject() && s.hasKey(StaticStrings::IdString)) { - id = s.get(StaticStrings::IdString); - } - if (id.isString()) { - identifier = id.copyString(); - } else if (id.isCustom()) { - identifier = trx->extractIdString(s); - } - - if (!identifier.empty()) { - size_t pos = identifier.find('/'); - - if (pos != std::string::npos) { - bool const isSame = (collectionName == identifier.substr(0, pos)); - return AqlValue(isSame); - } - - // fallthrough intentional + std::string const first = ExtractCollectionName(trx, parameters, 0); + std::string const second = ExtractCollectionName(trx, parameters, 1); + + if (!first.empty() && !second.empty()) { + return AqlValue(first == second); } RegisterWarning(query, "IS_SAME_COLLECTION", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(arangodb::basics::VelocyPackHelper::NullValue()); } -