Skip to content

Commit

Permalink
Merge branch 'devel' of https://github.com/arangodb/arangodb into fea…
Browse files Browse the repository at this point in the history
…ture/planning-query-result-cache

* 'devel' of https://github.com/arangodb/arangodb:
  Bug fix/fixes 0409 (#3199)
  give usefull errors in case of rocksdb init aborting with 'IOError' w… (#3178)
  Handle non-existing user config in RestUserHandler (#3200)
  Bug fix/truncate geo (#3173)
  fix deadlocks in cluster traversals (#3198)
  execute DOCUMENT function via CXX on coordinator in cluster mode (#3196)
  Bug fix/fixes 0109 (#3191)
  • Loading branch information
ObiWahn committed Sep 5, 2017
2 parents 94f17bc + eacad99 commit 2bf05bd
Show file tree
Hide file tree
Showing 28 changed files with 696 additions and 267 deletions.
5 changes: 5 additions & 0 deletions LICENSES-OTHER-COMPONENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
* License: gtest [BSD-style 3-Clause License](https://github.com/arangodb/arangodb/blob/devel/3rdParty/V8/v5.7.0.0/testing/gtest/include/gtest/gtest_prod.h)
* License: gyp [BSD-style 3-Clause license](https://github.com/arangodb/arangodb/blob/devel/3rdParty/V8/v5.7.0.0/tools/gyp/LICENSE)

### Googletest

* Project Home: https://github.com/google/googletest
* License: [BSD License](https://github.com/google/googletest/blob/master/googletest/LICENSE)

### ICU 58.1

* Project Home: http://site.icu-project.org/
Expand Down
3 changes: 1 addition & 2 deletions arangod/Aql/AqlFunctionFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,7 @@ void AqlFunctionFeature::addDocumentFunctions() {
&Functions::Merge});
add({"MERGE_RECURSIVE", "AQL_MERGE_RECURSIVE", ".,.|+", true, true, false,
true, true, &Functions::MergeRecursive});
add({"DOCUMENT", "AQL_DOCUMENT", "h.|.", false, false, true, false, true,
&Functions::Document, NotInCluster});
add({"DOCUMENT", "AQL_DOCUMENT", "h.|.", false, false, true, false, true, &Functions::Document});
add({"MATCHES", "AQL_MATCHES", ".,.|.", true, true, false, true, true});
add({"UNSET", "AQL_UNSET", ".,.|+", true, true, false, true, true,
&Functions::Unset});
Expand Down
222 changes: 98 additions & 124 deletions arangod/Aql/AstNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "Aql/Scopes.h"
#include "Aql/V8Executor.h"
#include "Aql/types.h"
#include "Basics/FloatingPoint.h"
#include "Basics/StringBuffer.h"
#include "Basics/Utf8Helper.h"
#include "Basics/VelocyPackHelper.h"
Expand All @@ -48,26 +49,6 @@

using namespace arangodb::aql;

/// @brief quick translation array from an AST node value type to a VPack type
static std::array<VPackValueType, 5> const ValueTypes{{
VPackValueType::Null, // VALUE_TYPE_NULL = 0,
VPackValueType::Bool, // VALUE_TYPE_BOOL = 1,
VPackValueType::Int, // VALUE_TYPE_INT = 2,
VPackValueType::Double, // VALUE_TYPE_DOUBLE = 3,
VPackValueType::String // VALUE_TYPE_STRING = 4
}};

static_assert(AstNodeValueType::VALUE_TYPE_NULL == 0,
"incorrect ast node value types");
static_assert(AstNodeValueType::VALUE_TYPE_BOOL == 1,
"incorrect ast node value types");
static_assert(AstNodeValueType::VALUE_TYPE_INT == 2,
"incorrect ast node value types");
static_assert(AstNodeValueType::VALUE_TYPE_DOUBLE == 3,
"incorrect ast node value types");
static_assert(AstNodeValueType::VALUE_TYPE_STRING == 4,
"incorrect ast node value types");

std::unordered_map<int, std::string const> const AstNode::Operators{
{static_cast<int>(NODE_TYPE_OPERATOR_UNARY_NOT), "!"},
{static_cast<int>(NODE_TYPE_OPERATOR_UNARY_PLUS), "+"},
Expand Down Expand Up @@ -187,12 +168,33 @@ std::unordered_map<int, std::string const> const AstNode::ValueTypeNames{

namespace {

/// @brief quick translation array from an AST node value type to a VPack type
static std::array<VPackValueType, 5> const valueTypes{{
VPackValueType::Null, // VALUE_TYPE_NULL = 0,
VPackValueType::Bool, // VALUE_TYPE_BOOL = 1,
VPackValueType::Int, // VALUE_TYPE_INT = 2,
VPackValueType::Double, // VALUE_TYPE_DOUBLE = 3,
VPackValueType::String // VALUE_TYPE_STRING = 4
}};

static_assert(AstNodeValueType::VALUE_TYPE_NULL == 0,
"incorrect ast node value types");
static_assert(AstNodeValueType::VALUE_TYPE_BOOL == 1,
"incorrect ast node value types");
static_assert(AstNodeValueType::VALUE_TYPE_INT == 2,
"incorrect ast node value types");
static_assert(AstNodeValueType::VALUE_TYPE_DOUBLE == 3,
"incorrect ast node value types");
static_assert(AstNodeValueType::VALUE_TYPE_STRING == 4,
"incorrect ast node value types");


/// @brief get the node type for inter-node comparisons
static VPackValueType GetNodeCompareType(AstNode const* node) {
static VPackValueType getNodeCompareType(AstNode const* node) {
TRI_ASSERT(node != nullptr);

if (node->type == NODE_TYPE_VALUE) {
return ValueTypes[node->value.type];
return valueTypes[node->value.type];
}
if (node->type == NODE_TYPE_ARRAY) {
return VPackValueType::Array;
Expand All @@ -207,6 +209,18 @@ static VPackValueType GetNodeCompareType(AstNode const* node) {
// return null in case assertions are turned off
return VPackValueType::Null;
}

static inline int compareDoubleValues(double lhs, double rhs) {
if (arangodb::almostEquals(lhs, rhs)) {
return 0;
}
double diff = lhs - rhs;
if (diff != 0.0) {
return (diff < 0.0) ? -1 : 1;
}
return 0;
}

}

/// @brief compare two nodes
Expand All @@ -226,18 +240,23 @@ int arangodb::aql::CompareAstNodes(AstNode const* lhs, AstNode const* rhs,
rhs = Ast::resolveConstAttributeAccess(rhs);
}

auto lType = GetNodeCompareType(lhs);
auto rType = GetNodeCompareType(rhs);
auto lType = getNodeCompareType(lhs);
auto rType = getNodeCompareType(rhs);

if (lType != rType) {
if (lType == VPackValueType::Int && rType == VPackValueType::Double) {
// upcast int to double
return compareDoubleValues(static_cast<double>(lhs->getIntValue()), rhs->getDoubleValue());
} else if (lType == VPackValueType::Double && rType == VPackValueType::Int) {
// upcast int to double
return compareDoubleValues(lhs->getDoubleValue(), static_cast<double>(rhs->getIntValue()));
}

int diff = static_cast<int>(lType) - static_cast<int>(rType);

TRI_ASSERT(diff != 0);

if (diff < 0) {
return -1;
}
return 1;
return (diff < 0) ? -1 : 1;
}

switch (lType) {
Expand All @@ -249,23 +268,25 @@ int arangodb::aql::CompareAstNodes(AstNode const* lhs, AstNode const* rhs,
int diff = static_cast<int>(lhs->getIntValue() - rhs->getIntValue());

if (diff != 0) {
if (diff < 0) {
return -1;
}
return 1;
return (diff < 0) ? -1 : 1;
}
return 0;
}

case VPackValueType::Int: {
int64_t l = lhs->getIntValue();
int64_t r = rhs->getIntValue();

if (l != r) {
return (l < r) ? -1 : 1;
}
return 0;
}

case VPackValueType::Int:
case VPackValueType::Double: {
// TODO
double d = lhs->getDoubleValue() - rhs->getDoubleValue();
if (d != 0.0) {
if (d < 0.0) {
return -1;
}
return 1;
double diff = lhs->getDoubleValue() - rhs->getDoubleValue();
if (diff != 0.0) {
return (diff < 0.0) ? -1 : 1;
}
return 0;
}
Expand Down Expand Up @@ -1429,7 +1450,8 @@ bool AstNode::isSimple() const {
}

if (type == NODE_TYPE_REFERENCE || type == NODE_TYPE_VALUE ||
type == NODE_TYPE_VARIABLE || type == NODE_TYPE_NOP) {
type == NODE_TYPE_VARIABLE || type == NODE_TYPE_NOP ||
type == NODE_TYPE_QUANTIFIER) {
setFlag(DETERMINED_SIMPLE, VALUE_SIMPLE);
return true;
}
Expand All @@ -1438,7 +1460,41 @@ bool AstNode::isSimple() const {
type == NODE_TYPE_EXPANSION || type == NODE_TYPE_ITERATOR ||
type == NODE_TYPE_ARRAY_LIMIT ||
type == NODE_TYPE_CALCULATED_OBJECT_ELEMENT ||
type == NODE_TYPE_OPERATOR_TERNARY) {
type == NODE_TYPE_OPERATOR_TERNARY ||
type == NODE_TYPE_OPERATOR_NARY_AND ||
type == NODE_TYPE_OPERATOR_NARY_OR ||
type == NODE_TYPE_OPERATOR_BINARY_PLUS ||
type == NODE_TYPE_OPERATOR_BINARY_MINUS ||
type == NODE_TYPE_OPERATOR_BINARY_TIMES ||
type == NODE_TYPE_OPERATOR_BINARY_DIV ||
type == NODE_TYPE_OPERATOR_BINARY_MOD ||
type == NODE_TYPE_OPERATOR_BINARY_AND ||
type == NODE_TYPE_OPERATOR_BINARY_OR ||
type == NODE_TYPE_OPERATOR_BINARY_EQ ||
type == NODE_TYPE_OPERATOR_BINARY_NE ||
type == NODE_TYPE_OPERATOR_BINARY_LT ||
type == NODE_TYPE_OPERATOR_BINARY_LE ||
type == NODE_TYPE_OPERATOR_BINARY_GT ||
type == NODE_TYPE_OPERATOR_BINARY_GE ||
type == NODE_TYPE_OPERATOR_BINARY_IN ||
type == NODE_TYPE_OPERATOR_BINARY_NIN ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_EQ ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_NE ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_LT ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_LE ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_GT ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_GE ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_IN ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_NIN ||
type == NODE_TYPE_RANGE ||
type == NODE_TYPE_INDEXED_ACCESS ||
type == NODE_TYPE_PASSTHRU ||
type == NODE_TYPE_OBJECT_ELEMENT ||
type == NODE_TYPE_ATTRIBUTE_ACCESS ||
type == NODE_TYPE_BOUND_ATTRIBUTE_ACCESS ||
type == NODE_TYPE_OPERATOR_UNARY_NOT ||
type == NODE_TYPE_OPERATOR_UNARY_PLUS ||
type == NODE_TYPE_OPERATOR_UNARY_MINUS) {
size_t const n = numMembers();

for (size_t i = 0; i < n; ++i) {
Expand All @@ -1454,31 +1510,6 @@ bool AstNode::isSimple() const {
return true;
}

if (type == NODE_TYPE_OBJECT_ELEMENT || type == NODE_TYPE_ATTRIBUTE_ACCESS ||
type == NODE_TYPE_OPERATOR_UNARY_NOT ||
type == NODE_TYPE_OPERATOR_UNARY_PLUS ||
type == NODE_TYPE_OPERATOR_UNARY_MINUS) {
TRI_ASSERT(numMembers() == 1);

if (!getMember(0)->isSimple()) {
setFlag(DETERMINED_SIMPLE);
return false;
}

setFlag(DETERMINED_SIMPLE, VALUE_SIMPLE);
return true;
}

if (type == NODE_TYPE_BOUND_ATTRIBUTE_ACCESS) {
if (!getMember(0)->isSimple()) {
setFlag(DETERMINED_SIMPLE);
return false;
}

setFlag(DETERMINED_SIMPLE, VALUE_SIMPLE);
return true;
}

if (type == NODE_TYPE_FCALL) {
// some functions have C++ handlers
// check if the called function is one of them
Expand Down Expand Up @@ -1528,63 +1559,6 @@ bool AstNode::isSimple() const {
return true;
}

if (type == NODE_TYPE_OPERATOR_BINARY_PLUS ||
type == NODE_TYPE_OPERATOR_BINARY_MINUS ||
type == NODE_TYPE_OPERATOR_BINARY_TIMES ||
type == NODE_TYPE_OPERATOR_BINARY_DIV ||
type == NODE_TYPE_OPERATOR_BINARY_MOD) {
if (!getMember(0)->isSimple() || !getMember(1)->isSimple()) {
setFlag(DETERMINED_SIMPLE);
return false;
}
setFlag(DETERMINED_SIMPLE, VALUE_SIMPLE);
return true;
}

if (type == NODE_TYPE_OPERATOR_BINARY_AND ||
type == NODE_TYPE_OPERATOR_BINARY_OR ||
type == NODE_TYPE_OPERATOR_BINARY_EQ ||
type == NODE_TYPE_OPERATOR_BINARY_NE ||
type == NODE_TYPE_OPERATOR_BINARY_LT ||
type == NODE_TYPE_OPERATOR_BINARY_LE ||
type == NODE_TYPE_OPERATOR_BINARY_GT ||
type == NODE_TYPE_OPERATOR_BINARY_GE ||
type == NODE_TYPE_OPERATOR_BINARY_IN ||
type == NODE_TYPE_OPERATOR_BINARY_NIN ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_EQ ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_NE ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_LT ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_LE ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_GT ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_GE ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_IN ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_NIN || type == NODE_TYPE_RANGE ||
type == NODE_TYPE_INDEXED_ACCESS || type == NODE_TYPE_PASSTHRU) {
// a logical operator is simple if its operands are simple
// a comparison operator is simple if both bounds are simple
// a range is simple if both bounds are simple
if (!getMember(0)->isSimple() || !getMember(1)->isSimple()) {
setFlag(DETERMINED_SIMPLE);
return false;
}

setFlag(DETERMINED_SIMPLE, VALUE_SIMPLE);
return true;
}

if (type == NODE_TYPE_OPERATOR_NARY_AND ||
type == NODE_TYPE_OPERATOR_NARY_OR) {
// a logical operator is simple if all its operands are simple
for (auto const& it : members) {
if (!it->isSimple()) {
setFlag(DETERMINED_SIMPLE);
return false;
}
}
setFlag(DETERMINED_SIMPLE, VALUE_SIMPLE);
return true;
}

setFlag(DETERMINED_SIMPLE);
return false;
}
Expand Down
16 changes: 8 additions & 8 deletions arangod/Cluster/TraverserEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,20 +201,20 @@ void BaseEngine::getVertexData(VPackSlice vertex, VPackBuilder& builder) {
auto shards = _vertexShards.find(shardName);
if (shards == _vertexShards.end()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_COLLECTION_LOCK_FAILED,
"Collection not known to Traversal " +
shardName + " please add 'WITH " + shardName +
"collection not known to traversal: '" +
shardName + "'. please add 'WITH " + shardName +
"' as the first line in your AQL");
// The collection is not known here!
// Maybe handle differently
}

StringRef vertex = id.substr(pos+1);
for (std::string const& shard : shards->second) {
Result res = _trx->documentFastPathLocal(shard, vertex, mmdr);
Result res = _trx->documentFastPathLocal(shard, vertex, mmdr, false);
if (res.ok()) {
// FOUND short circuit.
builder.add(v);
mmdr.addToBuilder(builder, true);
mmdr.addToBuilder(builder, false);
break;
} else if (res.isNot(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND)) {
// We are in a very bad condition here...
Expand Down Expand Up @@ -317,21 +317,21 @@ void BaseTraverserEngine::getVertexData(VPackSlice vertex, size_t depth,
auto shards = _vertexShards.find(shardName);
if (shards == _vertexShards.end()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_COLLECTION_LOCK_FAILED,
"Collection not known to Traversal " +
shardName + " please add 'WITH " + shardName +
"collection not known to traversal: '" +
shardName + "'. please add 'WITH " + shardName +
"' as the first line in your AQL");
// The collection is not known here!
// Maybe handle differently
}

StringRef vertex = id.substr(pos+1);
for (std::string const& shard : shards->second) {
Result res = _trx->documentFastPathLocal(shard, vertex, mmdr);
Result res = _trx->documentFastPathLocal(shard, vertex, mmdr, false);
if (res.ok()) {
// FOUND short circuit.
read++;
builder.add(v);
mmdr.addToBuilder(builder, true);
mmdr.addToBuilder(builder, false);
break;
} else if (res.isNot(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND)) {
// We are in a very bad condition here...
Expand Down
Loading

0 comments on commit 2bf05bd

Please sign in to comment.