From 325aa137950443fa5a6e556fa8e9011396419719 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Jun 2016 16:59:36 +0200 Subject: [PATCH 01/19] merge with velocypack --- .../velocypack/include/velocypack/Basics.h | 4 +- .../velocypack/include/velocypack/Builder.h | 8 +- .../velocypack/include/velocypack/Exception.h | 14 +- .../velocypack/include/velocypack/Iterator.h | 44 ++- .../velocypack/include/velocypack/Parser.h | 4 +- .../velocypack/include/velocypack/Slice.h | 16 +- .../velocypack/include/velocypack/Validator.h | 72 ++++ .../include/velocypack/velocypack-common.h | 12 +- 3rdParty/velocypack/src/Dumper.cpp | 2 +- 3rdParty/velocypack/src/Slice.cpp | 2 +- 3rdParty/velocypack/src/Validator.cpp | 318 ++++++++++++++++++ 3rdParty/velocypack/src/fasthash.cpp | 82 ----- 3rdParty/velocypack/src/velocypack-common.cpp | 3 +- CMakeLists.txt | 6 + arangod/Aql/BindParameters.cpp | 2 +- arangod/Aql/EnumerateCollectionBlock.cpp | 2 +- arangod/Aql/Functions.cpp | 70 ++-- arangod/Aql/IndexBlock.cpp | 2 +- arangod/Aql/ModificationBlocks.cpp | 2 +- arangod/Indexes/EdgeIndex.h | 4 +- arangod/Indexes/HashIndex.cpp | 2 +- arangod/Indexes/HashIndex.h | 2 +- arangod/Indexes/PrimaryIndex.h | 2 +- arangod/RestHandler/RestEdgesHandler.cpp | 4 +- .../RestHandler/RestVocbaseBaseHandler.cpp | 13 +- arangod/Utils/Cursor.cpp | 2 +- arangod/Utils/Transaction.cpp | 2 +- lib/Basics/VelocyPackDumper.cpp | 2 +- lib/CMakeLists.txt | 3 +- lib/Rest/GeneralRequest.cpp | 7 +- lib/V8/v8-vpack.cpp | 2 +- 31 files changed, 522 insertions(+), 188 deletions(-) create mode 100644 3rdParty/velocypack/include/velocypack/Validator.h create mode 100644 3rdParty/velocypack/src/Validator.cpp delete mode 100644 3rdParty/velocypack/src/fasthash.cpp diff --git a/3rdParty/velocypack/include/velocypack/Basics.h b/3rdParty/velocypack/include/velocypack/Basics.h index 894922c6c6..2b13c68c8c 100644 --- a/3rdParty/velocypack/include/velocypack/Basics.h +++ b/3rdParty/velocypack/include/velocypack/Basics.h @@ -55,9 +55,9 @@ class NonCopyable { // prevent heap allocation struct NonHeapAllocatable { void* operator new(std::size_t) throw(std::bad_alloc) = delete; - void operator delete(void*) throw() = delete; + void operator delete(void*) noexcept = delete; void* operator new[](std::size_t) throw(std::bad_alloc) = delete; - void operator delete[](void*) throw() = delete; + void operator delete[](void*) noexcept = delete; }; #ifdef _WIN32 diff --git a/3rdParty/velocypack/include/velocypack/Builder.h b/3rdParty/velocypack/include/velocypack/Builder.h index 2e6ebb8349..d6ab7748c7 100644 --- a/3rdParty/velocypack/include/velocypack/Builder.h +++ b/3rdParty/velocypack/include/velocypack/Builder.h @@ -309,11 +309,11 @@ class Builder { return _pos; } - bool isEmpty() const throw() { return _pos == 0; } + bool isEmpty() const noexcept { return _pos == 0; } - bool isClosed() const throw() { return _stack.empty(); } + bool isClosed() const noexcept { return _stack.empty(); } - bool isOpenArray() const throw() { + bool isOpenArray() const noexcept { if (_stack.empty()) { return false; } @@ -321,7 +321,7 @@ class Builder { return _start[tos] == 0x06 || _start[tos] == 0x13; } - bool isOpenObject() const throw() { + bool isOpenObject() const noexcept { if (_stack.empty()) { return false; } diff --git a/3rdParty/velocypack/include/velocypack/Exception.h b/3rdParty/velocypack/include/velocypack/Exception.h index d3f7cf5964..d6fef91894 100644 --- a/3rdParty/velocypack/include/velocypack/Exception.h +++ b/3rdParty/velocypack/include/velocypack/Exception.h @@ -68,6 +68,9 @@ struct Exception : std::exception { BuilderKeyAlreadyWritten = 38, BuilderKeyMustBeString = 39, + ValidatorInvalidLength = 50, + ValidatorInvalidType = 51, + UnknownError = 999 }; @@ -83,11 +86,11 @@ struct Exception : std::exception { explicit Exception(ExceptionType type) : Exception(type, message(type)) {} - char const* what() const throw() { return _msg.c_str(); } + char const* what() const noexcept { return _msg.c_str(); } - ExceptionType errorCode() const throw() { return _type; } + ExceptionType errorCode() const noexcept { return _type; } - static char const* message(ExceptionType type) throw() { + static char const* message(ExceptionType type) noexcept { switch (type) { case InternalError: return "Internal error"; @@ -139,6 +142,11 @@ struct Exception : std::exception { return "The key of the next key/value pair is already written"; case BuilderKeyMustBeString: return "The key of the next key/value pair must be a string"; + + case ValidatorInvalidType: + return "Invalid type found in binary data"; + case ValidatorInvalidLength: + return "Invalid length found in binary data"; case UnknownError: default: diff --git a/3rdParty/velocypack/include/velocypack/Iterator.h b/3rdParty/velocypack/include/velocypack/Iterator.h index ff045bf68d..64437d6ca9 100644 --- a/3rdParty/velocypack/include/velocypack/Iterator.h +++ b/3rdParty/velocypack/include/velocypack/Iterator.h @@ -42,9 +42,8 @@ class ArrayIterator { public: ArrayIterator() = delete; - ArrayIterator(Slice const& slice, bool allowRandomIteration = false) - : _slice(slice), _size(_slice.length()), _position(0), _current(nullptr), - _allowRandomIteration(allowRandomIteration) { + explicit ArrayIterator(Slice const& slice) + : _slice(slice), _size(_slice.length()), _position(0), _current(nullptr) { if (slice.type() != ValueType::Array) { throw Exception(Exception::InvalidValueType, "Expecting Array slice"); } @@ -56,15 +55,13 @@ class ArrayIterator { : _slice(other._slice), _size(other._size), _position(other._position), - _current(other._current), - _allowRandomIteration(other._allowRandomIteration) {} + _current(other._current) {} ArrayIterator& operator=(ArrayIterator const& other) { _slice = other._slice; _size = other._size; _position = other._position; _current = other._current; - _allowRandomIteration = other._allowRandomIteration; return *this; } @@ -97,23 +94,23 @@ class ArrayIterator { return _slice.at(_position); } - ArrayIterator begin() { return ArrayIterator(_slice, _allowRandomIteration); } + ArrayIterator begin() { return ArrayIterator(_slice); } - ArrayIterator begin() const { return ArrayIterator(_slice, _allowRandomIteration); } + ArrayIterator begin() const { return ArrayIterator(_slice); } ArrayIterator end() { - auto it = ArrayIterator(_slice, _allowRandomIteration); + auto it = ArrayIterator(_slice); it._position = it._size; return it; } ArrayIterator end() const { - auto it = ArrayIterator(_slice, _allowRandomIteration); + auto it = ArrayIterator(_slice); it._position = it._size; return it; } - inline bool valid() const throw() { return (_position < _size); } + inline bool valid() const noexcept { return (_position < _size); } inline Slice value() const { if (_position >= _size) { @@ -122,18 +119,18 @@ class ArrayIterator { return operator*(); } - inline bool next() throw() { + inline bool next() noexcept { operator++(); return valid(); } - inline ValueLength index() const throw() { return _position; } + inline ValueLength index() const noexcept { return _position; } - inline ValueLength size() const throw() { return _size; } + inline ValueLength size() const noexcept { return _size; } - inline bool isFirst() const throw() { return (_position == 0); } + inline bool isFirst() const noexcept { return (_position == 0); } - inline bool isLast() const throw() { return (_position + 1 >= _size); } + inline bool isLast() const noexcept { return (_position + 1 >= _size); } inline void forward(ValueLength count) { if (_position + count >= _size) { @@ -161,7 +158,7 @@ class ArrayIterator { auto h = _slice.head(); if (h == 0x13) { _current = _slice.at(0).start(); - } else if (_allowRandomIteration) { + } else { _current = _slice.begin() + _slice.findDataOffset(h); } } @@ -172,7 +169,6 @@ class ArrayIterator { ValueLength _size; ValueLength _position; uint8_t const* _current; - bool _allowRandomIteration; }; class ObjectIterator { @@ -267,7 +263,7 @@ class ObjectIterator { return it; } - inline bool valid() const throw() { return (_position < _size); } + inline bool valid() const noexcept { return (_position < _size); } inline Slice key(bool translate = true) const { if (_position >= _size) { @@ -290,18 +286,18 @@ class ObjectIterator { return _slice.getNthValue(_position); } - inline bool next() throw() { + inline bool next() noexcept { operator++(); return valid(); } - inline ValueLength index() const throw() { return _position; } + inline ValueLength index() const noexcept { return _position; } - inline ValueLength size() const throw() { return _size; } + inline ValueLength size() const noexcept { return _size; } - inline bool isFirst() const throw() { return (_position == 0); } + inline bool isFirst() const noexcept { return (_position == 0); } - inline bool isLast() const throw() { return (_position + 1 >= _size); } + inline bool isLast() const noexcept { return (_position + 1 >= _size); } private: Slice _slice; diff --git a/3rdParty/velocypack/include/velocypack/Parser.h b/3rdParty/velocypack/include/velocypack/Parser.h index 616894f14c..dad363cf5c 100644 --- a/3rdParty/velocypack/include/velocypack/Parser.h +++ b/3rdParty/velocypack/include/velocypack/Parser.h @@ -89,7 +89,7 @@ class Parser { Options const* options; Parser(Parser const&) = delete; - Parser(Parser &&) = delete; + Parser(Parser&&) = delete; Parser& operator=(Parser const&) = delete; Parser& operator=(Parser&&) = delete; ~Parser() = default; @@ -209,7 +209,7 @@ class Parser { ValueLength parseInternal(bool multi); - inline bool isWhiteSpace(uint8_t i) const throw() { + inline bool isWhiteSpace(uint8_t i) const noexcept { return (i == ' ' || i == '\t' || i == '\n' || i == '\r'); } diff --git a/3rdParty/velocypack/include/velocypack/Slice.h b/3rdParty/velocypack/include/velocypack/Slice.h index 6108853c81..e03991a06f 100644 --- a/3rdParty/velocypack/include/velocypack/Slice.h +++ b/3rdParty/velocypack/include/velocypack/Slice.h @@ -42,12 +42,18 @@ #include "velocypack/Value.h" #include "velocypack/ValueType.h" -#ifndef VELOCYPACK_HASH +#ifdef VELOCYPACK_XXHASH // forward for XXH64 function declared elsewhere extern "C" unsigned long long XXH64(void const*, size_t, unsigned long long); #define VELOCYPACK_HASH(mem, size, seed) XXH64(mem, size, seed) +#endif +#ifdef VELOCYPACK_FASTHASH +// forward for fasthash64 function declared elsewhere +uint64_t fasthash64(void const*, size_t, uint64_t); + +#define VELOCYPACK_HASH(mem, size, seed) fasthash64(mem, size, seed) #endif namespace arangodb { @@ -355,7 +361,7 @@ class Slice { } // extract the nth key from an Object - Slice getNthKey(ValueLength index, bool) const; + Slice getNthKey(ValueLength index, bool translate) const; // extract the nth value from an Object Slice getNthValue(ValueLength index) const { @@ -758,6 +764,9 @@ class Slice { } return 9; } + + // get the offset for the nth member from an Array type + ValueLength getNthOffset(ValueLength index) const; Slice makeKey() const; @@ -814,9 +823,6 @@ class Slice { Slice getFromCompactObject(std::string const& attribute) const; - // get the offset for the nth member from an Array type - ValueLength getNthOffset(ValueLength index) const; - // extract the nth member from an Array Slice getNth(ValueLength index) const; diff --git a/3rdParty/velocypack/include/velocypack/Validator.h b/3rdParty/velocypack/include/velocypack/Validator.h new file mode 100644 index 0000000000..bac6b893a3 --- /dev/null +++ b/3rdParty/velocypack/include/velocypack/Validator.h @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief Library to build up VPack documents. +/// +/// DISCLAIMER +/// +/// Copyright 2015 ArangoDB GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Max Neunhoeffer +/// @author Jan Steemann +/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#ifndef VELOCYPACK_VALIDATOR_H +#define VELOCYPACK_VALIDATOR_H 1 + +#include "velocypack/velocypack-common.h" +#include "velocypack/Options.h" + +namespace arangodb { +namespace velocypack { +class Slice; + +class Validator { + // This class can validate a binary VelocyPack value. + + public: + explicit Validator(Options const* options = &Options::Defaults) + : options(options) { + if (options == nullptr) { + throw Exception(Exception::InternalError, "Options cannot be a nullptr"); + } + } + + ~Validator() = default; + + public: + // validates a VelocyPack Slice value starting at ptr, with length bytes length + // throws if the data is invalid + bool validate(char const* ptr, size_t length, bool isSubPart = false) const { + return validate(reinterpret_cast(ptr), length, isSubPart); + } + + // validates a VelocyPack Slice value starting at ptr, with length bytes length + // throws if the data is invalid + bool validate(uint8_t const* ptr, size_t length, bool isSubPart = false) const; + + private: + void validateBufferLength(size_t expected, size_t actual, bool isSubPart) const; + void validateSliceLength(uint8_t const* ptr, size_t length, bool isSubPart) const; + + public: + Options const* options; +}; + +} // namespace arangodb::velocypack +} // namespace arangodb + +#endif diff --git a/3rdParty/velocypack/include/velocypack/velocypack-common.h b/3rdParty/velocypack/include/velocypack/velocypack-common.h index e16292eb1c..70ba87b8dc 100644 --- a/3rdParty/velocypack/include/velocypack/velocypack-common.h +++ b/3rdParty/velocypack/include/velocypack/velocypack-common.h @@ -88,7 +88,7 @@ static constexpr std::size_t checkOverflow(ValueLength length) { #endif // calculate the length of a variable length integer in unsigned LEB128 format -static inline ValueLength getVariableValueLength(ValueLength value) throw() { +static inline ValueLength getVariableValueLength(ValueLength value) noexcept { ValueLength len = 1; while (value >= 0x80) { value >>= 7; @@ -139,7 +139,7 @@ static inline void storeVariableValueLength(uint8_t* dst, ValueLength value) { // returns current value for UTCDate int64_t currentUTCDateValue(); -static inline uint64_t toUInt64(int64_t v) throw() { +static inline uint64_t toUInt64(int64_t v) noexcept { // If v is negative, we need to add 2^63 to make it positive, // before we can cast it to an uint64_t: uint64_t shift2 = 1ULL << 63; @@ -151,7 +151,7 @@ static inline uint64_t toUInt64(int64_t v) throw() { // uint64_t is not guaranteed to work for negative values! } -static inline int64_t toInt64(uint64_t v) throw() { +static inline int64_t toInt64(uint64_t v) noexcept { uint64_t shift2 = 1ULL << 63; int64_t shift = static_cast(shift2 - 1); return v >= shift2 ? (static_cast(v - shift2) - shift) - 1 @@ -161,7 +161,7 @@ static inline int64_t toInt64(uint64_t v) throw() { // read an unsigned little endian integer value of the // specified length, starting at the specified byte offset template -static inline T readInteger(uint8_t const* start, ValueLength length) throw() { +static inline T readInteger(uint8_t const* start, ValueLength length) noexcept { uint64_t value = 0; uint64_t x = 0; uint8_t const* end = start + length; @@ -172,11 +172,11 @@ static inline T readInteger(uint8_t const* start, ValueLength length) throw() { return value; } -static inline uint64_t readUInt64(uint8_t const* start) throw() { +static inline uint64_t readUInt64(uint8_t const* start) noexcept { return readInteger(start, 8); } -static inline void storeUInt64(uint8_t* start, uint64_t value) throw() { +static inline void storeUInt64(uint8_t* start, uint64_t value) noexcept { uint8_t const* end = start + 8; do { *start++ = static_cast(value & 0xff); diff --git a/3rdParty/velocypack/src/Dumper.cpp b/3rdParty/velocypack/src/Dumper.cpp index eb43ecd943..a1babc57d4 100644 --- a/3rdParty/velocypack/src/Dumper.cpp +++ b/3rdParty/velocypack/src/Dumper.cpp @@ -309,7 +309,7 @@ void Dumper::dumpValue(Slice const* slice, Slice const* base) { } case ValueType::Array: { - ArrayIterator it(*slice, true); + ArrayIterator it(*slice); _sink->push_back('['); if (options->prettyPrint) { _sink->push_back('\n'); diff --git a/3rdParty/velocypack/src/Slice.cpp b/3rdParty/velocypack/src/Slice.cpp index 1e994c78e0..9dcfb3485a 100644 --- a/3rdParty/velocypack/src/Slice.cpp +++ b/3rdParty/velocypack/src/Slice.cpp @@ -423,7 +423,7 @@ uint64_t Slice::normalizedHash(uint64_t seed) const { // over all array members uint64_t const n = length() ^ 0xba5bedf00d; value = VELOCYPACK_HASH(&n, sizeof(n), seed); - for (auto const& it : ArrayIterator(*this, true)) { + for (auto const& it : ArrayIterator(*this)) { value ^= it.normalizedHash(value); } } else if (isObject()) { diff --git a/3rdParty/velocypack/src/Validator.cpp b/3rdParty/velocypack/src/Validator.cpp new file mode 100644 index 0000000000..fa2f940773 --- /dev/null +++ b/3rdParty/velocypack/src/Validator.cpp @@ -0,0 +1,318 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief Library to build up VPack documents. +/// +/// DISCLAIMER +/// +/// Copyright 2015 ArangoDB GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Max Neunhoeffer +/// @author Jan Steemann +/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#include "velocypack/velocypack-common.h" +#include "velocypack/Validator.h" +#include "velocypack/Exception.h" +#include "velocypack/Slice.h" +#include "velocypack/ValueType.h" + +using namespace arangodb::velocypack; + +bool Validator::validate(uint8_t const* ptr, size_t length, bool isSubPart) const { + if (length == 0) { + throw Exception(Exception::ValidatorInvalidLength, "length 0 is invalid for any VelocyPack value"); + } + + uint8_t const head = *ptr; + + // type() only reads the first byte, which is safe + ValueType const type = Slice(ptr).type(); + + if (type == ValueType::None && head != 0x00) { + // invalid type + throw Exception(Exception::ValidatorInvalidType); + } + + // special handling for certain types... + switch (type) { + case ValueType::None: + case ValueType::Null: + case ValueType::Bool: + case ValueType::MinKey: + case ValueType::MaxKey: + case ValueType::SmallInt: + case ValueType::Int: + case ValueType::UInt: + case ValueType::Double: + case ValueType::UTCDate: + case ValueType::Binary: + case ValueType::Illegal: { + break; + } + + case ValueType::String: { + if (head == 0xbf) { + // long UTF-8 string. must be at least 9 bytes long so we + // can read the entire string length safely + validateBufferLength(1 + 8, length, true); + } + break; + } + + case ValueType::Array: { + ValueLength byteLength = 0; + bool equalSize = false; + bool hasIndexTable = false; + + if (head >= 0x02 && head <= 0x05) { + // Array without index table, with 1-8 bytes bytelength, all values with same length + byteLength = 1 << (head - 0x02); + equalSize = true; + } else if (head >= 0x06 && head <= 0x09) { + // Array with index table, with 1-8 bytes bytelength + byteLength = 1 << (head - 0x06); + hasIndexTable = true; + } + + if (head == 0x13) { + // compact Array without index table + validateBufferLength(2, length, true); + uint8_t const* p = ptr + 1; + uint8_t const* e = p + length; + ValueLength shifter = 0; + while (true) { + uint8_t c = *p; + byteLength += (c & 0x7f) << shifter; + shifter += 7; + ++p; + if (!(c & 0x80)) { + break; + } + if (p == e) { + throw Exception(Exception::ValidatorInvalidLength, "Array length value is out of bounds"); + } + } + if (byteLength > length || byteLength < 4) { + throw Exception(Exception::ValidatorInvalidLength, "Array length value is out of bounds"); + } + uint8_t const* data = p; + p = ptr + byteLength - 1; + ValueLength nrItems = 0; + shifter = 0; + while (true) { + uint8_t c = *p; + nrItems += (c & 0x7f) << shifter; + shifter += 7; + --p; + if (!(c & 0x80)) { + break; + } + if (p == ptr + byteLength) { + throw Exception(Exception::ValidatorInvalidLength, "Array length value is out of bounds"); + } + } + if (nrItems == 0) { + throw Exception(Exception::ValidatorInvalidLength, "Array length value is out of bounds"); + } + ++p; + + // validate the array members + e = p; + p = data; + while (nrItems-- > 0) { + validate(p, e - p, true); + p += Slice(p).byteSize(); + } + } else if (byteLength > 0) { + ValueLength nrItemsLength = 0; + if (head >= 0x06) { + nrItemsLength = byteLength; + } + validateBufferLength(1 + byteLength + nrItemsLength, length, true); + ValueLength nrItems = Slice(ptr).length(); + uint8_t const* p = ptr + 1 + byteLength; + if (!equalSize) { + p += byteLength; + } + uint8_t const* e = ptr + length; + ValueLength l = 0; + while (nrItems > 0) { + if (p >= e) { + throw Exception(Exception::ValidatorInvalidLength, "Array value is out of bounds"); + } + // validate sub value + validate(p, e - p, true); + ValueLength al = Slice(p).byteSize(); + if (equalSize) { + if (l == 0) { + l = al; + } else if (l != al) { + throw Exception(Exception::ValidatorInvalidLength, "Unexpected Array value length"); + } + } + p += al; + --nrItems; + } + + if (hasIndexTable) { + // now also validate index table + nrItems = Slice(ptr).length(); + for (ValueLength i = 0; i < nrItems; ++i) { + ValueLength offset = Slice(ptr).getNthOffset(i); + if (offset < 1 + byteLength + nrItemsLength || + offset >= Slice(ptr).byteSize() - nrItems * byteLength) { + throw Exception(Exception::ValidatorInvalidLength, "Array value offset is out of bounds"); + } + validate(ptr + offset, length - offset, true); + } + } + } + break; + } + + case ValueType::Object: { + ValueLength byteLength = 0; + if (head >= 0x0b && head <= 0x0e) { + // Object with index table, with 1-8 bytes bytelength, sorted + byteLength = 1 << (head - 0x0b); + } else if (head >= 0x0f && head <= 0x12) { + // Object with index table, with 1-8 bytes bytelength, unsorted + byteLength = 1 << (head - 0x0f); + } else if (head == 0x14) { + // compact Object without index table + // TODO + } + + if (byteLength > 0) { + validateBufferLength(1 + byteLength, length, true); + ValueLength nrItems = Slice(ptr).length(); + uint8_t const* p = ptr + 1 + byteLength; + uint8_t const* e = ptr + length; + while (nrItems > 0) { + if (p >= e) { + throw Exception(Exception::ValidatorInvalidLength, "Object key offset is out of bounds"); + } + // validate key + validate(p, e - p, true); + // skip over key + p += Slice(p).byteSize(); + + if (p >= e) { + throw Exception(Exception::ValidatorInvalidLength, "Object value offset is out of bounds"); + } + // validate value + validate(p, e - p, true); + // skip over value + p += Slice(p).byteSize(); + + --nrItems; + } + + // now also validate index table + for (ValueLength i = 0; i < nrItems; ++i) { + // get offset to key + ValueLength offset = Slice(ptr).getNthOffset(i); + if (offset >= length) { + throw Exception(Exception::ValidatorInvalidLength, "Object key offset is out of bounds"); + } + // validate length of key + validate(ptr + offset, length - offset, true); + // skip over key + offset += Slice(ptr + offset).byteSize(); + if (offset >= length) { + throw Exception(Exception::ValidatorInvalidLength, "Object value offset is out of bounds"); + } + // validate length of value + validate(ptr + offset, length - offset, true); + } + } + break; + } + + case ValueType::BCD: { + throw Exception(Exception::NotImplemented); + } + + case ValueType::External: { + // check if Externals are forbidden + if (options->disallowExternals) { + throw Exception(Exception::BuilderExternalsDisallowed); + } + // validate if Slice length exceeds the given buffer + validateBufferLength(1 + sizeof(void*), length, true); + // do not perform pointer validation + break; + } + + case ValueType::Custom: { + ValueLength byteSize = 0; + + if (head == 0xf0) { + byteSize = 1 + 1; + } else if (head == 0xf1) { + byteSize = 1 + 2; + } else if (head == 0xf2) { + byteSize = 1 + 4; + } else if (head == 0xf3) { + byteSize = 1 + 8; + } else if (head >= 0xf4 && head <= 0xf6) { + validateBufferLength(1 + 1, length, true); + byteSize = 1 + 1 + readInteger(ptr + 1, 1); + if (byteSize == 1 + 1) { + throw Exception(Exception::ValidatorInvalidLength, "Invalid size for Custom type"); + } + } else if (head >= 0xf7 && head <= 0xf9) { + validateBufferLength(1 + 2, length, true); + byteSize = 1 + 2 + readInteger(ptr + 1, 2); + if (byteSize == 1 + 2) { + throw Exception(Exception::ValidatorInvalidLength, "Invalid size for Custom type"); + } + } else if (head >= 0xfa && head <= 0xfc) { + validateBufferLength(1 + 4, length, true); + byteSize = 1 + 4 + readInteger(ptr + 1, 4); + if (byteSize == 1 + 4) { + throw Exception(Exception::ValidatorInvalidLength, "Invalid size for Custom type"); + } + } else if (head >= 0xfd) { + validateBufferLength(1 + 8, length, true); + byteSize = 1 + 8 + readInteger(ptr + 1, 8); + if (byteSize == 1 + 8) { + throw Exception(Exception::ValidatorInvalidLength, "Invalid size for Custom type"); + } + } + + validateSliceLength(ptr, byteSize, isSubPart); + break; + } + } + + // common validation that must happen for all types + validateSliceLength(ptr, length, isSubPart); + return true; +} + +void Validator::validateBufferLength(size_t expected, size_t actual, bool isSubPart) const { + if ((expected > actual) || + (expected != actual && !isSubPart)) { + throw Exception(Exception::ValidatorInvalidLength, "given buffer length is unequal to actual length of Slice in buffer"); + } +} + +void Validator::validateSliceLength(uint8_t const* ptr, size_t length, bool isSubPart) const { + size_t actual = static_cast(Slice(ptr).byteSize()); + validateBufferLength(actual, length, isSubPart); +} diff --git a/3rdParty/velocypack/src/fasthash.cpp b/3rdParty/velocypack/src/fasthash.cpp deleted file mode 100644 index bb0627eba2..0000000000 --- a/3rdParty/velocypack/src/fasthash.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* The MIT License - - Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com) - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#include -#include - -namespace arangodb { -namespace velocypack { - -// Compression function for Merkle-Damgard construction. -// This function is generated using the framework provided. -static inline uint64_t mix(uint64_t h) { - h ^= h >> 23; - h *= 0x2127599bf4325c37ULL; - h ^= h >> 47; - - return h; -} - -uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) { - const uint64_t m = 0x880355f21e6d1965ULL; - const uint64_t *pos = (const uint64_t *)buf; - const uint64_t *end = pos + (len / 8); - const unsigned char *pos2; - uint64_t h = seed ^ (len * m); - uint64_t v; - - while (pos != end) { - v = *pos++; - h ^= mix(v); - h *= m; - } - - pos2 = (const unsigned char *)pos; - v = 0; - - switch (len & 7) { - case 7: - v ^= (uint64_t)pos2[6] << 48; - case 6: - v ^= (uint64_t)pos2[5] << 40; - case 5: - v ^= (uint64_t)pos2[4] << 32; - case 4: - v ^= (uint64_t)pos2[3] << 24; - case 3: - v ^= (uint64_t)pos2[2] << 16; - case 2: - v ^= (uint64_t)pos2[1] << 8; - case 1: - v ^= (uint64_t)pos2[0]; - h ^= mix(v); - h *= m; - } - - return mix(h); -} - -} // namespace arangodb::velocypack -} // namespace arangodb diff --git a/3rdParty/velocypack/src/velocypack-common.cpp b/3rdParty/velocypack/src/velocypack-common.cpp index 295d81e8e8..6f5e5885ba 100644 --- a/3rdParty/velocypack/src/velocypack-common.cpp +++ b/3rdParty/velocypack/src/velocypack-common.cpp @@ -59,8 +59,7 @@ static_assert(sizeof(std::size_t) == sizeof(uint64_t), int64_t arangodb::velocypack::currentUTCDateValue() { return static_cast( - std::chrono::system_clock::now().time_since_epoch().count() / - std::chrono::milliseconds(1).count()); + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); } static_assert(sizeof(arangodb::velocypack::ValueLength) >= sizeof(SIZE_MAX), diff --git a/CMakeLists.txt b/CMakeLists.txt index 001a44e9dd..943fa7ab37 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -625,6 +625,12 @@ endif () add_subdirectory(3rdParty) +################################################################################ +## VELOCYPACK +################################################################################ + +add_definitions("-DVELOCYPACK_XXHASH=1") + set(BOOST_VERSION 1.61.0b1) foreach (LINK_DIR ${LINK_DIRECTORIES}) diff --git a/arangod/Aql/BindParameters.cpp b/arangod/Aql/BindParameters.cpp index 9fbf00c311..dfe481549c 100644 --- a/arangod/Aql/BindParameters.cpp +++ b/arangod/Aql/BindParameters.cpp @@ -85,7 +85,7 @@ VPackBuilder BindParameters::StripCollectionNames(VPackSlice const& keys, TRI_ASSERT(keys.isArray()); VPackBuilder result; result.openArray(); - for (auto const& element : VPackArrayIterator(keys, false)) { + for (auto const& element : VPackArrayIterator(keys)) { if (element.isString()) { VPackValueLength l; char const* s = element.getString(l); diff --git a/arangod/Aql/EnumerateCollectionBlock.cpp b/arangod/Aql/EnumerateCollectionBlock.cpp index 0079d5dd60..69906c8a98 100644 --- a/arangod/Aql/EnumerateCollectionBlock.cpp +++ b/arangod/Aql/EnumerateCollectionBlock.cpp @@ -90,7 +90,7 @@ bool EnumerateCollectionBlock::moreDocuments(size_t hint) { _documents = _scanner.scan(hint); TRI_ASSERT(_documents.isArray()); - _iterator = VPackArrayIterator(_documents, true); + _iterator = VPackArrayIterator(_documents); VPackValueLength count = _iterator.size(); diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index fea4910d3f..13244f22f3 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -351,7 +351,7 @@ static void ExtractKeys(std::unordered_set& names, AqlValueMaterializer materializer(trx); VPackSlice s = materializer.slice(param, false); - for (auto const& v : VPackArrayIterator(s, true)) { + for (auto const& v : VPackArrayIterator(s)) { if (v.isString()) { names.emplace(v.copyString()); } else { @@ -418,7 +418,7 @@ static bool ListContainsElement(arangodb::AqlTransaction* trx, AqlValueMaterializer testeeMaterializer(trx); VPackSlice testeeSlice = testeeMaterializer.slice(testee, false); - VPackArrayIterator it(slice, true); + VPackArrayIterator it(slice); while (it.valid()) { if (arangodb::basics::VelocyPackHelper::compare(testeeSlice, it.value(), false, options) == 0) { index = static_cast(it.index()); @@ -467,7 +467,7 @@ static bool Variance(arangodb::AqlTransaction* trx, AqlValueMaterializer materializer(trx); VPackSlice slice = materializer.slice(values, false); - for (auto const& element : VPackArrayIterator(slice, true)) { + for (auto const& element : VPackArrayIterator(slice)) { if (!element.isNull()) { if (!element.isNumber()) { return false; @@ -494,7 +494,7 @@ static bool SortNumberList(arangodb::AqlTransaction* trx, AqlValueMaterializer materializer(trx); VPackSlice slice = materializer.slice(values, false); - for (auto const& element : VPackArrayIterator(slice, true)) { + for (auto const& element : VPackArrayIterator(slice)) { if (!element.isNull()) { if (!element.isNumber()) { return false; @@ -547,7 +547,7 @@ static void RequestEdges(VPackSlice vertexSlice, VPackSlice edges = opRes->slice(); TRI_ASSERT(edges.isArray()); if (includeVertices) { - for (auto const& edge : VPackArrayIterator(edges, true)) { + for (auto const& edge : VPackArrayIterator(edges)) { VPackObjectBuilder guard(&result); if (matcher == nullptr || matcher->matches(edge)) { result.add("edge", edge); @@ -597,7 +597,7 @@ static void RequestEdges(VPackSlice vertexSlice, } } } else { - for (auto const& edge : VPackArrayIterator(edges, true)) { + for (auto const& edge : VPackArrayIterator(edges)) { if (matcher == nullptr || matcher->matches(edge)) { result.add(edge); } @@ -724,7 +724,7 @@ static AqlValue MergeParameters(arangodb::aql::Query* query, THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } // merge in all other arguments - for (auto const& it : VPackArrayIterator(initialSlice, true)) { + for (auto const& it : VPackArrayIterator(initialSlice)) { if (!it.isObject()) { RegisterInvalidArgumentWarning(query, funcName); builder.clear(); @@ -905,7 +905,7 @@ static AqlValue buildGeoResult(arangodb::AqlTransaction* trx, static void FlattenList(VPackSlice const& array, size_t maxDepth, size_t curDepth, VPackBuilder& result) { TRI_ASSERT(result.isOpenArray()); - for (auto const& tmp : VPackArrayIterator(array, true)) { + for (auto const& tmp : VPackArrayIterator(array)) { if (tmp.isArray() && curDepth < maxDepth) { FlattenList(tmp, maxDepth, curDepth + 1, result); } else { @@ -1258,7 +1258,7 @@ AqlValue Functions::Concat(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice slice = materializer.slice(member, false); - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { if (it.isNull()) { continue; } @@ -1313,7 +1313,7 @@ AqlValue Functions::ConcatSeparator(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice slice = materializer.slice(member, false); - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { if (it.isNull()) { continue; } @@ -1752,7 +1752,7 @@ AqlValue Functions::Min(arangodb::aql::Query* query, VPackSlice slice = materializer.slice(value, false); VPackSlice minValue; - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { if (it.isNull()) { continue; } @@ -1781,7 +1781,7 @@ AqlValue Functions::Max(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice slice = materializer.slice(value, false); VPackSlice maxValue; - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { if (maxValue.isNone() || arangodb::basics::VelocyPackHelper::compare(it, maxValue, true) > 0) { maxValue = it; } @@ -1807,7 +1807,7 @@ AqlValue Functions::Sum(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice slice = materializer.slice(value, false); double sum = 0.0; - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { if (it.isNull()) { continue; } @@ -1841,7 +1841,7 @@ AqlValue Functions::Average(arangodb::aql::Query* query, double sum = 0.0; size_t count = 0; - for (auto const& v : VPackArrayIterator(slice, true)) { + for (auto const& v : VPackArrayIterator(slice)) { if (v.isNull()) { continue; } @@ -1976,7 +1976,7 @@ AqlValue Functions::Unique(arangodb::aql::Query* query, values(512, arangodb::basics::VelocyPackHelper::VPackHash(), arangodb::basics::VelocyPackHelper::VPackEqual(&options)); - for (auto const& s : VPackArrayIterator(slice, true)) { + for (auto const& s : VPackArrayIterator(slice)) { if (!s.isNone()) { values.emplace(s); } @@ -2013,7 +2013,7 @@ AqlValue Functions::SortedUnique(arangodb::aql::Query* query, arangodb::basics::VelocyPackHelper::VPackLess less(trx->transactionContext()->getVPackOptions(), &slice, &slice); std::set> values(less); - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { if (!it.isNone()) { values.insert(it); } @@ -2059,7 +2059,7 @@ AqlValue Functions::Union(arangodb::aql::Query* query, VPackSlice slice = materializer.slice(value, false); // this passes ownership for the JSON contens into result - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { builder->add(it); TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); @@ -2110,7 +2110,7 @@ AqlValue Functions::UnionDistinct(arangodb::aql::Query* query, materializers.emplace_back(trx); VPackSlice slice = materializers.back().slice(value, false); - for (auto const& v : VPackArrayIterator(slice, true)) { + for (auto const& v : VPackArrayIterator(slice)) { if (values.find(v) == values.end()) { TRI_IF_FAILURE("AqlFunctions::OutOfMemory1") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); @@ -2176,7 +2176,7 @@ AqlValue Functions::Intersection(arangodb::aql::Query* query, materializers.emplace_back(trx); VPackSlice slice = materializers.back().slice(value, false); - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { if (i == 0) { // round one @@ -2678,7 +2678,7 @@ AqlValue Functions::Slice(arangodb::aql::Query* query, builder->openArray(); int64_t pos = 0; - VPackArrayIterator it(arraySlice, true); + VPackArrayIterator it(arraySlice); while (it.valid()) { if (pos >= from && pos < to) { builder->add(it.value()); @@ -2722,7 +2722,7 @@ AqlValue Functions::Minus(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice arraySlice = materializer.slice(baseArray, false); - VPackArrayIterator it(arraySlice, true); + VPackArrayIterator it(arraySlice); while (it.valid()) { contains.emplace(it.value(), it.index()); it.next(); @@ -2741,7 +2741,7 @@ AqlValue Functions::Minus(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice arraySlice = materializer.slice(next, false); - for (auto const& search : VPackArrayIterator(arraySlice, true)) { + for (auto const& search : VPackArrayIterator(arraySlice)) { auto find = contains.find(search); if (find != contains.end()) { @@ -2787,7 +2787,7 @@ AqlValue Functions::Document(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice idSlice = materializer.slice(id, false); builder->openArray(); - for (auto const& next : VPackArrayIterator(idSlice, true)) { + for (auto const& next : VPackArrayIterator(idSlice)) { if (next.isString()) { std::string identifier = next.copyString(); std::string colName; @@ -2829,7 +2829,7 @@ AqlValue Functions::Document(arangodb::aql::Query* query, if (!notFound) { AqlValueMaterializer materializer(trx); VPackSlice idSlice = materializer.slice(id, false); - for (auto const& next : VPackArrayIterator(idSlice, true)) { + for (auto const& next : VPackArrayIterator(idSlice)) { if (next.isString()) { std::string identifier(next.copyString()); GetDocumentByIdentifier(trx, collectionName, identifier, true, *builder.get()); @@ -2943,7 +2943,7 @@ AqlValue Functions::Edges(arangodb::aql::Query* query, builder->openArray(); if (vertexSlice.isArray()) { - for (auto const& v : VPackArrayIterator(vertexSlice, true)) { + for (auto const& v : VPackArrayIterator(vertexSlice)) { RequestEdges(v, trx, collectionName, indexId, direction, matcher.get(), includeVertices, *builder.get()); } @@ -3323,7 +3323,7 @@ AqlValue Functions::Push(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice l = materializer.slice(list, false); - for (auto const& it : VPackArrayIterator(l, true)) { + for (auto const& it : VPackArrayIterator(l)) { builder->add(it); } VPackOptions options; @@ -3364,7 +3364,7 @@ AqlValue Functions::Pop(arangodb::aql::Query* query, TransactionBuilderLeaser builder(trx); builder->openArray(); - auto iterator = VPackArrayIterator(slice, true); + auto iterator = VPackArrayIterator(slice); while (iterator.valid() && !iterator.isLast()) { builder->add(iterator.value()); iterator.next(); @@ -3412,7 +3412,7 @@ AqlValue Functions::Append(arangodb::aql::Query* query, trx->transactionContext()->orderCustomTypeHandler().get(); if (!list.isNull(true)) { if (list.isArray()) { - for (auto const& it : VPackArrayIterator(l, true)) { + for (auto const& it : VPackArrayIterator(l)) { builder->add(it); } } @@ -3427,7 +3427,7 @@ AqlValue Functions::Append(arangodb::aql::Query* query, if (unique) { std::unordered_set added; added.reserve(static_cast(slice.length())); - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { if (added.find(it) == added.end() && !ListContainsElement(&options, l, it)) { builder->add(it); @@ -3435,7 +3435,7 @@ AqlValue Functions::Append(arangodb::aql::Query* query, } } } else { - for (auto const& it : VPackArrayIterator(slice, true)) { + for (auto const& it : VPackArrayIterator(slice)) { builder->add(it); } } @@ -3483,7 +3483,7 @@ AqlValue Functions::Unshift(arangodb::aql::Query* query, if (list.isArray()) { AqlValueMaterializer materializer(trx); VPackSlice v = materializer.slice(list, false); - for (auto const& it : VPackArrayIterator(v, true)) { + for (auto const& it : VPackArrayIterator(v)) { builder->add(it); } } @@ -3514,7 +3514,7 @@ AqlValue Functions::Shift(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice l = materializer.slice(list, false); - auto iterator = VPackArrayIterator(l, true); + auto iterator = VPackArrayIterator(l); // This jumps over the first element while (iterator.next()) { builder->add(iterator.value()); @@ -3563,7 +3563,7 @@ AqlValue Functions::RemoveValue(arangodb::aql::Query* query, AqlValueMaterializer materializer(trx); VPackSlice v = materializer.slice(list, false); - for (auto const& it : VPackArrayIterator(v, true)) { + for (auto const& it : VPackArrayIterator(v)) { if (useLimit && limit == 0) { // Just copy builder->add(it); @@ -3616,7 +3616,7 @@ AqlValue Functions::RemoveValues(arangodb::aql::Query* query, TransactionBuilderLeaser builder(trx); builder->openArray(); - for (auto const& it : VPackArrayIterator(l, true)) { + for (auto const& it : VPackArrayIterator(l)) { if (!ListContainsElement(&options, v, it)) { builder->add(it); } @@ -3665,7 +3665,7 @@ AqlValue Functions::RemoveNth(arangodb::aql::Query* query, size_t target = static_cast(p); size_t cur = 0; builder->openArray(); - for (auto const& it : VPackArrayIterator(v, true)) { + for (auto const& it : VPackArrayIterator(v)) { if (cur != target) { builder->add(it); } diff --git a/arangod/Aql/IndexBlock.cpp b/arangod/Aql/IndexBlock.cpp index e234dd2373..0bfdf8e58f 100644 --- a/arangod/Aql/IndexBlock.cpp +++ b/arangod/Aql/IndexBlock.cpp @@ -410,7 +410,7 @@ bool IndexBlock::readIndex(size_t atMost) { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } - for (auto const& doc : VPackArrayIterator(slice, true)) { + for (auto const& doc : VPackArrayIterator(slice)) { if (!hasMultipleIndexes) { _documents.emplace_back(doc); } else { diff --git a/arangod/Aql/ModificationBlocks.cpp b/arangod/Aql/ModificationBlocks.cpp index c1e972a9c1..1a47c6c4e5 100644 --- a/arangod/Aql/ModificationBlocks.cpp +++ b/arangod/Aql/ModificationBlocks.cpp @@ -453,7 +453,7 @@ AqlItemBlock* InsertBlock::work(std::vector& blocks) { dstRow -= n; VPackSlice resultList = opRes.slice(); TRI_ASSERT(resultList.isArray()); - for (auto const& elm: VPackArrayIterator(resultList, false)) { + for (auto const& elm: VPackArrayIterator(resultList)) { bool wasError = arangodb::basics::VelocyPackHelper::getBooleanValue( elm, "error", false); if (!wasError) { diff --git a/arangod/Indexes/EdgeIndex.h b/arangod/Indexes/EdgeIndex.h index 8cc8ff6e82..50981e23aa 100644 --- a/arangod/Indexes/EdgeIndex.h +++ b/arangod/Indexes/EdgeIndex.h @@ -55,7 +55,7 @@ class EdgeIndexIterator final : public IndexIterator { _index(index), _searchValues(searchValues), _keys(_searchValues.slice()), - _iterator(_keys, true), + _iterator(_keys), _posInBuffer(0), _batchSize(1000) {} @@ -66,7 +66,7 @@ class EdgeIndexIterator final : public IndexIterator { _index(index), _searchValues(arangodb::velocypack::Builder::clone(searchValues)), _keys(_searchValues.slice()), - _iterator(_keys, true), + _iterator(_keys), _posInBuffer(0), _batchSize(1000) {} diff --git a/arangod/Indexes/HashIndex.cpp b/arangod/Indexes/HashIndex.cpp index 155c66e57e..e5294e858a 100644 --- a/arangod/Indexes/HashIndex.cpp +++ b/arangod/Indexes/HashIndex.cpp @@ -599,7 +599,7 @@ void HashIndex::transformSearchValues(VPackSlice const values, } VPackArrayBuilder guard(&result); - for (auto const& v : VPackArrayIterator(values, true)) { + for (auto const& v : VPackArrayIterator(values)) { if (!v.isObject() || !v.hasKey(TRI_SLICE_KEY_EQUAL)) { THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, "Hash index only allows == comparison."); } diff --git a/arangod/Indexes/HashIndex.h b/arangod/Indexes/HashIndex.h index 3d6027d7b7..2a282b5dec 100644 --- a/arangod/Indexes/HashIndex.h +++ b/arangod/Indexes/HashIndex.h @@ -123,7 +123,7 @@ class HashIndexIteratorVPack final : public IndexIterator { : _trx(trx), _index(index), _searchValues(searchValues.get()), - _iterator(_searchValues->slice(), true), + _iterator(_searchValues->slice()), _buffer(), _posInBuffer(0) { searchValues.release(); // now we have ownership for searchValues diff --git a/arangod/Indexes/PrimaryIndex.h b/arangod/Indexes/PrimaryIndex.h index e9bc969843..f75ac0a894 100644 --- a/arangod/Indexes/PrimaryIndex.h +++ b/arangod/Indexes/PrimaryIndex.h @@ -47,7 +47,7 @@ class PrimaryIndexIterator final : public IndexIterator { : _trx(trx), _index(index), _keys(keys.get()), - _iterator(_keys->slice(), true) { + _iterator(_keys->slice()) { keys.release(); // now we have ownership for _keys TRI_ASSERT(_keys->slice().isArray()); diff --git a/arangod/RestHandler/RestEdgesHandler.cpp b/arangod/RestHandler/RestEdgesHandler.cpp index bffb591e42..eb75cf9b70 100644 --- a/arangod/RestHandler/RestEdgesHandler.cpp +++ b/arangod/RestHandler/RestEdgesHandler.cpp @@ -108,7 +108,7 @@ bool RestEdgesHandler::getEdgesForVertexList( // generate result scannedIndex += static_cast(edges.length()); - for (auto const& edge : VPackArrayIterator(edges, true)) { + for (auto const& edge : VPackArrayIterator(edges)) { bool add = true; if (!expressions.empty()) { for (auto& exp : expressions) { @@ -164,7 +164,7 @@ bool RestEdgesHandler::getEdgesForVertex( // generate result scannedIndex += static_cast(edges.length()); - for (auto const& edge : VPackArrayIterator(edges, true)) { + for (auto const& edge : VPackArrayIterator(edges)) { bool add = true; if (!expressions.empty()) { for (auto& exp : expressions) { diff --git a/arangod/RestHandler/RestVocbaseBaseHandler.cpp b/arangod/RestHandler/RestVocbaseBaseHandler.cpp index 04b27930e0..48c352273c 100644 --- a/arangod/RestHandler/RestVocbaseBaseHandler.cpp +++ b/arangod/RestHandler/RestVocbaseBaseHandler.cpp @@ -637,13 +637,15 @@ bool RestVocbaseBaseHandler::extractBooleanParameter(char const* name, std::shared_ptr RestVocbaseBaseHandler::parseVelocyPackBody( VPackOptions const* options, bool& success) { - bool found; - std::string const& contentType = - _request->header(StaticStrings::ContentTypeHeader, found); - try { success = true; +#if 0 + // currently deactivated... + bool found; + std::string const& contentType = + _request->header(StaticStrings::ContentTypeHeader, found); + if (found && contentType.size() == StaticStrings::MimeTypeVPack.size() && contentType == StaticStrings::MimeTypeVPack) { VPackSlice slice{_request->body().c_str()}; @@ -653,6 +655,9 @@ std::shared_ptr RestVocbaseBaseHandler::parseVelocyPackBody( } else { return _request->toVelocyPack(options); } +#else + return _request->toVelocyPack(options); +#endif } catch (std::bad_alloc const&) { generateOOMError(); } catch (VPackException const& e) { diff --git a/arangod/Utils/Cursor.cpp b/arangod/Utils/Cursor.cpp index fc224ebb26..b80de5506f 100644 --- a/arangod/Utils/Cursor.cpp +++ b/arangod/Utils/Cursor.cpp @@ -70,7 +70,7 @@ VelocyPackCursor::VelocyPackCursor(TRI_vocbase_t* vocbase, CursorId id, : Cursor(id, batchSize, extra, ttl, hasCount), _vocbase(vocbase), _result(std::move(result)), - _iterator(_result.result->slice(), true), + _iterator(_result.result->slice()), _cached(_result.cached) { TRI_ASSERT(_result.result->slice().isArray()); TRI_UseVocBase(vocbase); diff --git a/arangod/Utils/Transaction.cpp b/arangod/Utils/Transaction.cpp index 080084fad2..38a66496e8 100644 --- a/arangod/Utils/Transaction.cpp +++ b/arangod/Utils/Transaction.cpp @@ -1146,7 +1146,7 @@ OperationResult Transaction::anyLocal(std::string const& collectionName, } VPackSlice docs = result->slice(); - VPackArrayIterator it(docs, true); + VPackArrayIterator it(docs); while (it.valid()) { resultBuilder.add(it.value()); it.next(); diff --git a/lib/Basics/VelocyPackDumper.cpp b/lib/Basics/VelocyPackDumper.cpp index 537b4ec60a..449a7b0a75 100644 --- a/lib/Basics/VelocyPackDumper.cpp +++ b/lib/Basics/VelocyPackDumper.cpp @@ -366,7 +366,7 @@ void VelocyPackDumper::dumpValue(VPackSlice const* slice, VPackSlice const* base } case VPackValueType::Array: { - VPackArrayIterator it(*slice, true); + VPackArrayIterator it(*slice); TRI_AppendCharUnsafeStringBuffer(buffer, '['); while (it.valid()) { if (!it.isFirst()) { diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 906aa136bb..152633a910 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -87,11 +87,12 @@ set(LIB_ARANGO_VPACK ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Parser.cpp ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Slice.cpp ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/ValueType.cpp + ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Validator.cpp ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Version.cpp ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/asm-functions.cpp - ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/fasthash.cpp ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/fpconv.cpp ${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/velocypack-common.cpp + ${PROJECT_SOURCE_DIR}/lib/Basics/xxhash.cpp ) if (ASM_OPTIMIZATIONS AND CMAKE_TARGET_ARCHITECTURE_CODE MATCHES "x86_64") diff --git a/lib/Rest/GeneralRequest.cpp b/lib/Rest/GeneralRequest.cpp index 06e91bb8ae..d693cf30ea 100644 --- a/lib/Rest/GeneralRequest.cpp +++ b/lib/Rest/GeneralRequest.cpp @@ -258,7 +258,12 @@ void GeneralRequest::setArrayValue(char* key, size_t length, char const* value) _arrayValues[std::string(key, length)].emplace_back(value); } -bool GeneralRequest::velocyPackResponse () const { +bool GeneralRequest::velocyPackResponse() const { +#if 0 + // currently deactivated std::string const& result = header(StaticStrings::Accept); return (std::string::npos != result.find(StaticStrings::MimeTypeVPack)); +#else + return false; +#endif } diff --git a/lib/V8/v8-vpack.cpp b/lib/V8/v8-vpack.cpp index 131c5fe81c..9db9b33360 100644 --- a/lib/V8/v8-vpack.cpp +++ b/lib/V8/v8-vpack.cpp @@ -138,7 +138,7 @@ static v8::Handle ObjectVPackArray(v8::Isolate* isolate, } uint32_t j = 0; - VPackArrayIterator it(slice, true); + VPackArrayIterator it(slice); while (it.valid()) { v8::Handle val = From eca908359ad68a669a921dd54d2738b073004527 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Jun 2016 17:16:55 +0200 Subject: [PATCH 02/19] make some system collections smaller --- js/common/modules/@arangodb/foxx/manager-utils.js | 2 +- js/server/modules/@arangodb/statistics.js | 4 ++-- js/server/upgrade-database.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/common/modules/@arangodb/foxx/manager-utils.js b/js/common/modules/@arangodb/foxx/manager-utils.js index ffcda165d5..a0ecec5ebb 100644 --- a/js/common/modules/@arangodb/foxx/manager-utils.js +++ b/js/common/modules/@arangodb/foxx/manager-utils.js @@ -54,7 +54,7 @@ var getStorage = function() { var c = db._collection("_apps"); if (c === null) { c = db._create("_apps", {isSystem: true, replicationFactor: 1, - distributeShardsLike: "_graphs"}); + distributeShardsLike: "_graphs", journalSize: 4 * 1024 * 1024}); c.ensureIndex({ type: "hash", fields: [ "mount" ], unique: true }); } return c; diff --git a/js/server/modules/@arangodb/statistics.js b/js/server/modules/@arangodb/statistics.js index 4544b5b053..dd87ce57d9 100644 --- a/js/server/modules/@arangodb/statistics.js +++ b/js/server/modules/@arangodb/statistics.js @@ -49,10 +49,11 @@ function createStatisticsCollection (name) { if (collection === null) { var r = null; - + try { r = db._create(name, { isSystem: true, waitForSync: false, replicationFactor: 1, + journalSize: 8 * 1024 * 1024, distributeShardsLike: "_graphs" }); } catch (err) { @@ -424,7 +425,6 @@ exports.STATISTICS_INTERVAL = 10; exports.STATISTICS_HISTORY_INTERVAL = 15 * 60; - //////////////////////////////////////////////////////////////////////////////// /// @brief createCollections /// diff --git a/js/server/upgrade-database.js b/js/server/upgrade-database.js index a23c6d2967..2a433c89c5 100644 --- a/js/server/upgrade-database.js +++ b/js/server/upgrade-database.js @@ -625,7 +625,7 @@ task: function() { // needs to be big enough for assets return createSystemCollection("_routing", { - journalSize: 8 * 1024 * 1024, + journalSize: 4 * 1024 * 1024, replicationFactor: DEFAULT_REPLICATION_FACTOR_SYSTEM, distributeShardsLike: "_graphs" }); @@ -692,7 +692,7 @@ task: function() { return createSystemCollection("_aqlfunctions", { - journalSize: 2 * 1024 * 1024, + journalSize: 1 * 1024 * 1024, replicationFactor: DEFAULT_REPLICATION_FACTOR_SYSTEM, distributeShardsLike: "_graphs" }); @@ -763,7 +763,7 @@ task: function() { return createSystemCollection("_jobs", { - journalSize: 4 * 1024 * 1024, + journalSize: 2 * 1024 * 1024, replicationFactor: DEFAULT_REPLICATION_FACTOR_SYSTEM, distributeShardsLike: "_graphs" }); From 1cda48bfc24396943a0dd7509cdbb889e1aa435d Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Mon, 6 Jun 2016 17:58:16 +0200 Subject: [PATCH 03/19] renamed REGEX to REGEX_MATCH --- Documentation/Books/AQL/Functions/String.mdpp | 10 +++---- arangod/Aql/FunctionDefinitions.cpp | 4 +-- arangod/Aql/Functions.cpp | 14 +++++----- arangod/Aql/Functions.h | 2 +- js/server/modules/@arangodb/aql.js | 4 +-- js/server/tests/aql/aql-functions-string.js | 28 +++++++++---------- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Documentation/Books/AQL/Functions/String.mdpp b/Documentation/Books/AQL/Functions/String.mdpp index 044a664699..cb6c316373 100644 --- a/Documentation/Books/AQL/Functions/String.mdpp +++ b/Documentation/Books/AQL/Functions/String.mdpp @@ -267,9 +267,9 @@ RANDOM_TOKEN(8) // "zGl09z42" RANDOM_TOKEN(8) // "m9w50Ft9" ``` -!SUBSECTION REGEX() +!SUBSECTION REGEX_MATCH() -`REGEX(text, search, caseInsensitive) → bool` +`REGEX_MATCH(text, search, caseInsensitive) → bool` Check whether the pattern *search* is contained in the string *text*, using regular expression matching. @@ -327,9 +327,9 @@ If the regular expression in *search* is invalid, a warning will be raised and the function will return *false*. ```js -REGEX("the quick brown fox", "the.*fox") // true -REGEX("the quick brown fox", "^(a|the)\s+(quick|slow).*f.x$") // true -REGEX("the\nquick\nbrown\nfox", "^the(\n[a-w]+)+\nfox$") // true +REGEX_MATCH("the quick brown fox", "the.*fox") // true +REGEX_MATCH("the quick brown fox", "^(a|the)\s+(quick|slow).*f.x$") // true +REGEX_MATCH("the\nquick\nbrown\nfox", "^the(\n[a-w]+)+\nfox$") // true ``` !SUBSECTION REVERSE() diff --git a/arangod/Aql/FunctionDefinitions.cpp b/arangod/Aql/FunctionDefinitions.cpp index 72940723df..d63fb5d2dc 100644 --- a/arangod/Aql/FunctionDefinitions.cpp +++ b/arangod/Aql/FunctionDefinitions.cpp @@ -177,8 +177,8 @@ struct FunctionDefiner { false, true, true, &Functions::Contains}); add({"LIKE", "AQL_LIKE", "s,r|b", true, true, false, true, true, &Functions::Like}); - add({"REGEX", "AQL_REGEX", "s,r|b", true, true, false, true, - true, &Functions::Regex}); + add({"REGEX_MATCH", "AQL_REGEX_MATCH", "s,r|b", true, true, false, true, + true, &Functions::RegexMatch}); add({"LEFT", "AQL_LEFT", "s,n", true, true, false, true, true}); add({"RIGHT", "AQL_RIGHT", "s,n", true, true, false, true, true}); add({"TRIM", "AQL_TRIM", "s|ns", true, true, false, true, true}); diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index fea4910d3f..038d7cae7d 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -1419,11 +1419,11 @@ AqlValue Functions::Like(arangodb::aql::Query* query, return AqlValue(result); } -/// @brief function REGEX -AqlValue Functions::Regex(arangodb::aql::Query* query, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { - ValidateParameters(parameters, "REGEX", 2, 3); +/// @brief function REGEX_MATCH +AqlValue Functions::RegexMatch(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + ValidateParameters(parameters, "REGEX_MATCH", 2, 3); bool const caseInsensitive = GetBooleanParameter(trx, parameters, 2, false); StringBufferLeaser buffer(trx); arangodb::basics::VPackStringBufferAdapter adapter(buffer->stringBuffer()); @@ -1464,7 +1464,7 @@ AqlValue Functions::Regex(arangodb::aql::Query* query, if (matcher == nullptr) { // compiling regular expression failed - RegisterWarning(query, "REGEX", TRI_ERROR_QUERY_INVALID_REGEX); + RegisterWarning(query, "REGEX_MATCH", TRI_ERROR_QUERY_INVALID_REGEX); return AqlValue(arangodb::basics::VelocyPackHelper::NullValue()); } @@ -1479,7 +1479,7 @@ AqlValue Functions::Regex(arangodb::aql::Query* query, if (error) { // compiling regular expression failed - RegisterWarning(query, "REGEX", TRI_ERROR_QUERY_INVALID_REGEX); + RegisterWarning(query, "REGEX_MATCH", TRI_ERROR_QUERY_INVALID_REGEX); return AqlValue(arangodb::basics::VelocyPackHelper::NullValue()); } diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index cec9b63f95..63ae304902 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -97,7 +97,7 @@ struct Functions { VPackFunctionParameters const&); static AqlValue Like(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); - static AqlValue Regex(arangodb::aql::Query*, arangodb::AqlTransaction*, + static AqlValue RegexMatch(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); static AqlValue Passthru(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); diff --git a/js/server/modules/@arangodb/aql.js b/js/server/modules/@arangodb/aql.js index c374f7f485..0dfe22d2a6 100644 --- a/js/server/modules/@arangodb/aql.js +++ b/js/server/modules/@arangodb/aql.js @@ -2301,7 +2301,7 @@ function AQL_LIKE (value, regex, caseInsensitive) { /// @brief searches a substring in a string, using a regex //////////////////////////////////////////////////////////////////////////////// -function AQL_REGEX (value, regex, caseInsensitive) { +function AQL_REGEX_MATCH (value, regex, caseInsensitive) { 'use strict'; var modifiers = ''; @@ -8358,7 +8358,7 @@ exports.AQL_UPPER = AQL_UPPER; exports.AQL_SUBSTRING = AQL_SUBSTRING; exports.AQL_CONTAINS = AQL_CONTAINS; exports.AQL_LIKE = AQL_LIKE; -exports.AQL_REGEX = AQL_REGEX; +exports.AQL_REGEX_MATCH = AQL_REGEX_MATCH; exports.AQL_LEFT = AQL_LEFT; exports.AQL_RIGHT = AQL_RIGHT; exports.AQL_TRIM = AQL_TRIM; diff --git a/js/server/tests/aql/aql-functions-string.js b/js/server/tests/aql/aql-functions-string.js index 95a9c91c01..f529bb16e0 100644 --- a/js/server/tests/aql/aql-functions-string.js +++ b/js/server/tests/aql/aql-functions-string.js @@ -62,18 +62,18 @@ function ahuacatlStringFunctionsTestSuite () { //////////////////////////////////////////////////////////////////////////////// testRegexInvalid : function () { - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX()"); - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX(\"test\")"); - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX(\"test\", \"meow\", \"foo\", \"bar\")"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH()"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH(\"test\")"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH(\"test\", \"meow\", \"foo\", \"bar\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"[\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"[^\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"a.(\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"(a\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"(a]\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"**\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"?\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX(\"test\", \"*\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"[\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"[^\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"a.(\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"(a\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"(a]\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"**\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"?\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"*\")"); }, testRegex : function () { @@ -217,13 +217,13 @@ function ahuacatlStringFunctionsTestSuite () { ]; values.forEach(function(v) { - var query = "RETURN REGEX(@what, @re)"; + var query = "RETURN REGEX_MATCH(@what, @re)"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); - query = "RETURN NOOPT(REGEX(@what, @re))"; + query = "RETURN NOOPT(REGEX_MATCH(@what, @re))"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); - query = "RETURN NOOPT(V8(REGEX(@what, @re)))"; + query = "RETURN NOOPT(V8(REGEX_MATCH(@what, @re)))"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); }); From 16c6c2087d5173407bebc4ef569173851b365060 Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Mon, 6 Jun 2016 17:00:10 +0200 Subject: [PATCH 04/19] added unprepare --- arangod/Actions/ActionFeature.cpp | 2 +- arangod/Actions/ActionFeature.h | 2 +- arangod/Dispatcher/DispatcherFeature.cpp | 2 ++ arangod/Dispatcher/DispatcherFeature.h | 1 + arangod/Indexes/RocksDBFeature.cpp | 2 +- arangod/Indexes/RocksDBFeature.h | 2 +- arangod/RestServer/BootstrapFeature.h | 1 + arangod/RestServer/ConsoleFeature.cpp | 2 ++ arangod/RestServer/ConsoleFeature.h | 1 + arangod/RestServer/DatabaseFeature.cpp | 2 +- arangod/RestServer/DatabaseFeature.h | 2 +- arangod/RestServer/DatabaseServerFeature.cpp | 2 +- arangod/RestServer/DatabaseServerFeature.h | 2 +- arangod/RestServer/QueryRegistryFeature.cpp | 2 +- arangod/RestServer/QueryRegistryFeature.h | 2 +- arangod/RestServer/RestServerFeature.cpp | 3 ++- arangod/RestServer/RestServerFeature.h | 1 + arangod/Scheduler/SchedulerFeature.cpp | 5 ++++- arangod/Scheduler/SchedulerFeature.h | 1 + arangod/V8Server/V8DealerFeature.cpp | 2 +- arangod/V8Server/V8DealerFeature.h | 2 +- arangosh/Benchmark/BenchFeature.cpp | 2 +- arangosh/Benchmark/BenchFeature.h | 4 ++-- arangosh/Shell/ConsoleFeature.cpp | 2 +- arangosh/Shell/ConsoleFeature.h | 2 +- arangosh/Shell/V8ShellFeature.cpp | 2 +- arangosh/Shell/V8ShellFeature.h | 4 ++-- .../ApplicationFeature.cpp | 5 ++++- lib/ApplicationFeatures/ApplicationFeature.h | 5 ++++- lib/ApplicationFeatures/ApplicationServer.cpp | 20 ++++++++++++++++++- lib/ApplicationFeatures/ApplicationServer.h | 12 ++++++++++- lib/ApplicationFeatures/DaemonFeature.cpp | 2 +- lib/ApplicationFeatures/DaemonFeature.h | 2 +- lib/ApplicationFeatures/NonceFeature.cpp | 6 +----- lib/ApplicationFeatures/NonceFeature.h | 3 +-- lib/ApplicationFeatures/SupervisorFeature.cpp | 3 +++ lib/ApplicationFeatures/V8PlatformFeature.cpp | 2 +- lib/ApplicationFeatures/V8PlatformFeature.h | 2 +- .../WorkMonitorFeature.cpp | 2 +- lib/ApplicationFeatures/WorkMonitorFeature.h | 2 +- lib/Logger/LoggerFeature.cpp | 2 +- lib/Logger/LoggerFeature.h | 2 +- lib/Ssl/SslFeature.cpp | 2 +- lib/Ssl/SslFeature.h | 2 +- lib/Ssl/SslServerFeature.cpp | 4 +--- lib/Ssl/SslServerFeature.h | 3 +-- 46 files changed, 90 insertions(+), 48 deletions(-) diff --git a/arangod/Actions/ActionFeature.cpp b/arangod/Actions/ActionFeature.cpp index 9a8ce1ed26..4f2a2db811 100644 --- a/arangod/Actions/ActionFeature.cpp +++ b/arangod/Actions/ActionFeature.cpp @@ -65,7 +65,7 @@ void ActionFeature::start() { nullptr); } -void ActionFeature::stop() { +void ActionFeature::unprepare() { TRI_CleanupActions(); ACTION = nullptr; diff --git a/arangod/Actions/ActionFeature.h b/arangod/Actions/ActionFeature.h index fbae1518b0..724b0e555a 100644 --- a/arangod/Actions/ActionFeature.h +++ b/arangod/Actions/ActionFeature.h @@ -36,7 +36,7 @@ class ActionFeature final : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; public: bool allowUseDatabase() { return _allowUseDatabase; } diff --git a/arangod/Dispatcher/DispatcherFeature.cpp b/arangod/Dispatcher/DispatcherFeature.cpp index 2c8e84bbf8..56fca43588 100644 --- a/arangod/Dispatcher/DispatcherFeature.cpp +++ b/arangod/Dispatcher/DispatcherFeature.cpp @@ -157,7 +157,9 @@ void DispatcherFeature::stop() { } _dispatcher->shutdown(); +} +void DispatcherFeature::unprepare() { DISPATCHER = nullptr; } diff --git a/arangod/Dispatcher/DispatcherFeature.h b/arangod/Dispatcher/DispatcherFeature.h index 11bd697a18..df9172d5a7 100644 --- a/arangod/Dispatcher/DispatcherFeature.h +++ b/arangod/Dispatcher/DispatcherFeature.h @@ -49,6 +49,7 @@ class DispatcherFeature final void start() override final; void beginShutdown() override final; void stop() override final; + void unprepare() override final; private: uint64_t _nrStandardThreads; diff --git a/arangod/Indexes/RocksDBFeature.cpp b/arangod/Indexes/RocksDBFeature.cpp index 8126d8d3ea..c877ce89ab 100644 --- a/arangod/Indexes/RocksDBFeature.cpp +++ b/arangod/Indexes/RocksDBFeature.cpp @@ -257,7 +257,7 @@ void RocksDBFeature::start() { } } -void RocksDBFeature::stop() { +void RocksDBFeature::unprepare() { if (!isEnabled()) { return; } diff --git a/arangod/Indexes/RocksDBFeature.h b/arangod/Indexes/RocksDBFeature.h index 2e75f5884a..b77c78110a 100644 --- a/arangod/Indexes/RocksDBFeature.h +++ b/arangod/Indexes/RocksDBFeature.h @@ -45,7 +45,7 @@ class RocksDBFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; inline rocksdb::OptimisticTransactionDB* db() const { return _db; } inline RocksDBKeyComparator* comparator() const { return _comparator; } diff --git a/arangod/RestServer/BootstrapFeature.h b/arangod/RestServer/BootstrapFeature.h index ce41ea4db0..21f9ddbb99 100644 --- a/arangod/RestServer/BootstrapFeature.h +++ b/arangod/RestServer/BootstrapFeature.h @@ -34,6 +34,7 @@ class BootstrapFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void start() override final; void stop() override final; + bool isReady() const { return _isReady; } diff --git a/arangod/RestServer/ConsoleFeature.cpp b/arangod/RestServer/ConsoleFeature.cpp index 0ce35fcc35..13e6f61381 100644 --- a/arangod/RestServer/ConsoleFeature.cpp +++ b/arangod/RestServer/ConsoleFeature.cpp @@ -73,6 +73,8 @@ void ConsoleFeature::stop() { while (_consoleThread->isRunning() && ++iterations < 30) { usleep(100 * 1000); // spin while console is still needed } +} +void ConsoleFeature::unprepare() { std::cout << std::endl << TRI_BYE_MESSAGE << std::endl; } diff --git a/arangod/RestServer/ConsoleFeature.h b/arangod/RestServer/ConsoleFeature.h index 997c1aa40b..63e9f56609 100644 --- a/arangod/RestServer/ConsoleFeature.h +++ b/arangod/RestServer/ConsoleFeature.h @@ -37,6 +37,7 @@ class ConsoleFeature final : public application_features::ApplicationFeature { public: void start() override final; void stop() override final; + void unprepare() override final; private: OperationMode _operationMode; diff --git a/arangod/RestServer/DatabaseFeature.cpp b/arangod/RestServer/DatabaseFeature.cpp index b87380929f..859a7e6f7d 100644 --- a/arangod/RestServer/DatabaseFeature.cpp +++ b/arangod/RestServer/DatabaseFeature.cpp @@ -171,7 +171,7 @@ void DatabaseFeature::start() { } } -void DatabaseFeature::stop() { +void DatabaseFeature::unprepare() { // close all databases closeDatabases(); diff --git a/arangod/RestServer/DatabaseFeature.h b/arangod/RestServer/DatabaseFeature.h index 017968a0a4..36cf9c610f 100644 --- a/arangod/RestServer/DatabaseFeature.h +++ b/arangod/RestServer/DatabaseFeature.h @@ -39,7 +39,7 @@ class DatabaseFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; public: TRI_vocbase_t* vocbase() const { return _vocbase; } diff --git a/arangod/RestServer/DatabaseServerFeature.cpp b/arangod/RestServer/DatabaseServerFeature.cpp index a96c1e0925..072b101166 100644 --- a/arangod/RestServer/DatabaseServerFeature.cpp +++ b/arangod/RestServer/DatabaseServerFeature.cpp @@ -82,7 +82,7 @@ void DatabaseServerFeature::start() { } } -void DatabaseServerFeature::stop() { +void DatabaseServerFeature::unprepare() { // turn off index threads INDEX_POOL = nullptr; _indexPool.reset(); diff --git a/arangod/RestServer/DatabaseServerFeature.h b/arangod/RestServer/DatabaseServerFeature.h index dd5f0960fb..51dfa2ce55 100644 --- a/arangod/RestServer/DatabaseServerFeature.h +++ b/arangod/RestServer/DatabaseServerFeature.h @@ -47,7 +47,7 @@ class DatabaseServerFeature final void validateOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; private: uint64_t _indexThreads = 2; diff --git a/arangod/RestServer/QueryRegistryFeature.cpp b/arangod/RestServer/QueryRegistryFeature.cpp index ffd0cf1a3b..ef6efd92c2 100644 --- a/arangod/RestServer/QueryRegistryFeature.cpp +++ b/arangod/RestServer/QueryRegistryFeature.cpp @@ -85,7 +85,7 @@ void QueryRegistryFeature::start() { DatabaseServerFeature::SERVER->_queryRegistry = _queryRegistry.get(); } -void QueryRegistryFeature::stop() { +void QueryRegistryFeature::unprepare() { // clear the query registery DatabaseServerFeature::SERVER->_queryRegistry = nullptr; // TODO: reset QUERY_REGISTRY as well? diff --git a/arangod/RestServer/QueryRegistryFeature.h b/arangod/RestServer/QueryRegistryFeature.h index 25086f0f9e..c6337534c3 100644 --- a/arangod/RestServer/QueryRegistryFeature.h +++ b/arangod/RestServer/QueryRegistryFeature.h @@ -42,7 +42,7 @@ class QueryRegistryFeature final : public application_features::ApplicationFeatu void validateOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; private: bool _queryTracking = true; diff --git a/arangod/RestServer/RestServerFeature.cpp b/arangod/RestServer/RestServerFeature.cpp index 997dc0f88f..b05d7c4b9c 100644 --- a/arangod/RestServer/RestServerFeature.cpp +++ b/arangod/RestServer/RestServerFeature.cpp @@ -315,13 +315,14 @@ void RestServerFeature::stop() { for (auto& server : _servers) { server->stop(); } +} +void RestServerFeature::unprepare() { for (auto& server : _servers) { delete server; } _httpOptions._vocbase = nullptr; - RESTSERVER = nullptr; } diff --git a/arangod/RestServer/RestServerFeature.h b/arangod/RestServer/RestServerFeature.h index 07001fa9b5..e53bca5324 100644 --- a/arangod/RestServer/RestServerFeature.h +++ b/arangod/RestServer/RestServerFeature.h @@ -78,6 +78,7 @@ class RestServerFeature final void prepare() override final; void start() override final; void stop() override final; + void unprepare() override final; private: double _keepAliveTimeout; diff --git a/arangod/Scheduler/SchedulerFeature.cpp b/arangod/Scheduler/SchedulerFeature.cpp index 6dd0aa50f1..43dc75634f 100644 --- a/arangod/Scheduler/SchedulerFeature.cpp +++ b/arangod/Scheduler/SchedulerFeature.cpp @@ -141,8 +141,11 @@ void SchedulerFeature::stop() { } _scheduler->shutdown(); + } +} - // delete the scheduler +void SchedulerFeature::unprepare() { + if (_scheduler != nullptr) { delete _scheduler; _scheduler = nullptr; SCHEDULER = nullptr; diff --git a/arangod/Scheduler/SchedulerFeature.h b/arangod/Scheduler/SchedulerFeature.h index 445b241abf..755fd19445 100644 --- a/arangod/Scheduler/SchedulerFeature.h +++ b/arangod/Scheduler/SchedulerFeature.h @@ -46,6 +46,7 @@ class SchedulerFeature final : public application_features::ApplicationFeature { void validateOptions(std::shared_ptr) override final; void start() override final; void stop() override final; + void unprepare() override final; private: uint64_t _nrSchedulerThreads; diff --git a/arangod/V8Server/V8DealerFeature.cpp b/arangod/V8Server/V8DealerFeature.cpp index 05dbb2e7ec..e186904459 100644 --- a/arangod/V8Server/V8DealerFeature.cpp +++ b/arangod/V8Server/V8DealerFeature.cpp @@ -224,7 +224,7 @@ void V8DealerFeature::start() { startGarbageCollection(); } -void V8DealerFeature::stop() { +void V8DealerFeature::unprepare() { shutdownContexts(); // delete GC thread after all action threads have been stopped diff --git a/arangod/V8Server/V8DealerFeature.h b/arangod/V8Server/V8DealerFeature.h index c467d379d5..ec742a1014 100644 --- a/arangod/V8Server/V8DealerFeature.h +++ b/arangod/V8Server/V8DealerFeature.h @@ -45,7 +45,7 @@ class V8DealerFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; private: double _gcFrequency; diff --git a/arangosh/Benchmark/BenchFeature.cpp b/arangosh/Benchmark/BenchFeature.cpp index 84891e10bf..0faedde84e 100644 --- a/arangosh/Benchmark/BenchFeature.cpp +++ b/arangosh/Benchmark/BenchFeature.cpp @@ -314,6 +314,6 @@ void BenchFeature::start() { *_result = ret; } -void BenchFeature::stop() { +void BenchFeature::unprepare() { ARANGOBENCH = nullptr; } diff --git a/arangosh/Benchmark/BenchFeature.h b/arangosh/Benchmark/BenchFeature.h index 0e0fadeed2..ebd937ce83 100644 --- a/arangosh/Benchmark/BenchFeature.h +++ b/arangosh/Benchmark/BenchFeature.h @@ -32,8 +32,8 @@ class BenchFeature final : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override; - void start() override; - void stop() override; + void start() override final; + void unprepare() override final; public: bool async() const { return _async; } diff --git a/arangosh/Shell/ConsoleFeature.cpp b/arangosh/Shell/ConsoleFeature.cpp index aac58c7392..5172c1acc2 100644 --- a/arangosh/Shell/ConsoleFeature.cpp +++ b/arangosh/Shell/ConsoleFeature.cpp @@ -136,7 +136,7 @@ void ConsoleFeature::start() { #endif } -void ConsoleFeature::stop() { +void ConsoleFeature::unprepare() { closeLog(); } diff --git a/arangosh/Shell/ConsoleFeature.h b/arangosh/Shell/ConsoleFeature.h index f7bdb2f979..9b60bfcf9c 100644 --- a/arangosh/Shell/ConsoleFeature.h +++ b/arangosh/Shell/ConsoleFeature.h @@ -36,7 +36,7 @@ class ConsoleFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; public: bool quiet() const { return _quiet; } diff --git a/arangosh/Shell/V8ShellFeature.cpp b/arangosh/Shell/V8ShellFeature.cpp index edc33e8a66..6a00d561be 100644 --- a/arangosh/Shell/V8ShellFeature.cpp +++ b/arangosh/Shell/V8ShellFeature.cpp @@ -130,7 +130,7 @@ void V8ShellFeature::start() { initGlobals(); } -void V8ShellFeature::stop() { +void V8ShellFeature::unprepare() { { v8::Locker locker{_isolate}; diff --git a/arangosh/Shell/V8ShellFeature.h b/arangosh/Shell/V8ShellFeature.h index 06822d2d41..5be29b574e 100644 --- a/arangosh/Shell/V8ShellFeature.h +++ b/arangosh/Shell/V8ShellFeature.h @@ -44,8 +44,8 @@ class V8ShellFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override; void validateOptions( std::shared_ptr options) override; - void start() override; - void stop() override; + void start() override final; + void unprepare() override final; private: std::string _startupDirectory; diff --git a/lib/ApplicationFeatures/ApplicationFeature.cpp b/lib/ApplicationFeatures/ApplicationFeature.cpp index f516cfc427..65773baed5 100644 --- a/lib/ApplicationFeatures/ApplicationFeature.cpp +++ b/lib/ApplicationFeatures/ApplicationFeature.cpp @@ -72,9 +72,12 @@ void ApplicationFeature::start() {} // notify the feature about a shutdown request void ApplicationFeature::beginShutdown() {} -// stop and shut down the feature +// stop the feature void ApplicationFeature::stop() {} +// shut down the feature +void ApplicationFeature::unprepare() {} + // determine all direct and indirect ancestors of a feature std::unordered_set ApplicationFeature::ancestors() const { TRI_ASSERT(_ancestorsDetermined); diff --git a/lib/ApplicationFeatures/ApplicationFeature.h b/lib/ApplicationFeatures/ApplicationFeature.h index 86119b39d9..b590f8a23a 100644 --- a/lib/ApplicationFeatures/ApplicationFeature.h +++ b/lib/ApplicationFeatures/ApplicationFeature.h @@ -126,9 +126,12 @@ class ApplicationFeature { // notify the feature about a shutdown request virtual void beginShutdown(); - // stop and shut down the feature + // stop the feature virtual void stop(); + // shut down the feature + virtual void unprepare(); + protected: // return the ApplicationServer instance ApplicationServer* server() const { return _server; } diff --git a/lib/ApplicationFeatures/ApplicationServer.cpp b/lib/ApplicationFeatures/ApplicationServer.cpp index caf005f932..3eb5ce3b84 100644 --- a/lib/ApplicationFeatures/ApplicationServer.cpp +++ b/lib/ApplicationFeatures/ApplicationServer.cpp @@ -205,6 +205,11 @@ void ApplicationServer::run(int argc, char* argv[]) { reportServerProgress(_state); stop(); + // unprepare all features + _state = ServerState::IN_UNPREPARE; + reportServerProgress(_state); + unprepare(); + // stopped _state = ServerState::STOPPED; reportServerProgress(_state); @@ -540,12 +545,25 @@ void ApplicationServer::stop() { auto feature = *it; LOG_TOPIC(TRACE, Logger::STARTUP) << feature->name() << "::stop"; - feature->stop(); + // feature->stop(); feature->state(FeatureState::STOPPED); reportFeatureProgress(_state, feature->name()); } } +void ApplicationServer::unprepare() { + LOG_TOPIC(TRACE, Logger::STARTUP) << "ApplicationServer::unprepare"; + + for (auto it = _orderedFeatures.rbegin(); it != _orderedFeatures.rend(); ++it) { + auto feature = *it; + + LOG_TOPIC(TRACE, Logger::STARTUP) << feature->name() << "::unprepare"; + feature->unprepare(); + feature->state(FeatureState::UNPREPARED); + reportFeatureProgress(_state, feature->name()); + } +} + void ApplicationServer::wait() { LOG_TOPIC(TRACE, Logger::STARTUP) << "ApplicationServer::wait"; diff --git a/lib/ApplicationFeatures/ApplicationServer.h b/lib/ApplicationFeatures/ApplicationServer.h index aa51f37b3b..65bbe79ce2 100644 --- a/lib/ApplicationFeatures/ApplicationServer.h +++ b/lib/ApplicationFeatures/ApplicationServer.h @@ -44,6 +44,7 @@ enum class ServerState { IN_START, IN_WAIT, IN_STOP, + IN_UNPREPARE, STOPPED, ABORT }; @@ -103,6 +104,11 @@ class ProgressHandler { // `stop` // // Stops the features. The `stop` methods are called in reversed `start` order. +// This must stop all threads, but not destroy the features. +// +// `unprepare` +// +// This destroys the features. class ApplicationServer { ApplicationServer(ApplicationServer const&) = delete; @@ -115,7 +121,8 @@ class ApplicationServer { VALIDATED, PREPARED, STARTED, - STOPPED + STOPPED, + UNPREPARED }; static ApplicationServer* server; @@ -252,6 +259,9 @@ class ApplicationServer { // stops features void stop(); + // destroys features + void unprepare(); + // after start, the server will wait in this method until // beginShutdown is called void wait(); diff --git a/lib/ApplicationFeatures/DaemonFeature.cpp b/lib/ApplicationFeatures/DaemonFeature.cpp index 3114dfc4ef..597539d3f8 100644 --- a/lib/ApplicationFeatures/DaemonFeature.cpp +++ b/lib/ApplicationFeatures/DaemonFeature.cpp @@ -118,7 +118,7 @@ void DaemonFeature::daemonize() { } } -void DaemonFeature::stop() { +void DaemonFeature::unprepare() { if (!_daemon) { return; } diff --git a/lib/ApplicationFeatures/DaemonFeature.h b/lib/ApplicationFeatures/DaemonFeature.h index 0efb0ba1c2..2e300498ad 100644 --- a/lib/ApplicationFeatures/DaemonFeature.h +++ b/lib/ApplicationFeatures/DaemonFeature.h @@ -36,7 +36,7 @@ class DaemonFeature final : public application_features::ApplicationFeature { void collectOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void daemonize() override final; - void stop() override final; + void unprepare() override final; public: void setDaemon(bool value) { _daemon = value; } diff --git a/lib/ApplicationFeatures/NonceFeature.cpp b/lib/ApplicationFeatures/NonceFeature.cpp index 8a4cac5fb5..291ca106d4 100644 --- a/lib/ApplicationFeatures/NonceFeature.cpp +++ b/lib/ApplicationFeatures/NonceFeature.cpp @@ -51,10 +51,6 @@ void NonceFeature::prepare() { } } -void NonceFeature::start() { - LOG(DEBUG) << "setting nonce hash size to " << _size; -} - -void NonceFeature::stop() { +void NonceFeature::unprepare() { Nonce::destroy(); } diff --git a/lib/ApplicationFeatures/NonceFeature.h b/lib/ApplicationFeatures/NonceFeature.h index 3ebeed5033..f00763fbda 100644 --- a/lib/ApplicationFeatures/NonceFeature.h +++ b/lib/ApplicationFeatures/NonceFeature.h @@ -36,8 +36,7 @@ class NonceFeature : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override final; void prepare() override final; - void start() override final; - void stop() override final; + void unprepare() override final; private: uint64_t _size; diff --git a/lib/ApplicationFeatures/SupervisorFeature.cpp b/lib/ApplicationFeatures/SupervisorFeature.cpp index 9642d3ab5e..5dfd1eace3 100644 --- a/lib/ApplicationFeatures/SupervisorFeature.cpp +++ b/lib/ApplicationFeatures/SupervisorFeature.cpp @@ -223,5 +223,8 @@ void SupervisorFeature::daemonize() { std::for_each(supervisorFeatures.rbegin(), supervisorFeatures.rend(), [](ApplicationFeature* feature) { feature->stop(); }); + std::for_each(supervisorFeatures.rbegin(), supervisorFeatures.rend(), + [](ApplicationFeature* feature) { feature->unprepare(); }); + exit(result); } diff --git a/lib/ApplicationFeatures/V8PlatformFeature.cpp b/lib/ApplicationFeatures/V8PlatformFeature.cpp index 33e717be55..619135659e 100644 --- a/lib/ApplicationFeatures/V8PlatformFeature.cpp +++ b/lib/ApplicationFeatures/V8PlatformFeature.cpp @@ -80,7 +80,7 @@ void V8PlatformFeature::start() { _allocator.reset(new ArrayBufferAllocator); } -void V8PlatformFeature::stop() { +void V8PlatformFeature::unprepare() { v8::V8::Dispose(); v8::V8::ShutdownPlatform(); _platform.reset(); diff --git a/lib/ApplicationFeatures/V8PlatformFeature.h b/lib/ApplicationFeatures/V8PlatformFeature.h index f7da36e46f..c8c2cbb3c0 100644 --- a/lib/ApplicationFeatures/V8PlatformFeature.h +++ b/lib/ApplicationFeatures/V8PlatformFeature.h @@ -37,7 +37,7 @@ class V8PlatformFeature final public: void collectOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; v8::ArrayBuffer::Allocator* arrayBufferAllocator() const { return _allocator.get(); diff --git a/lib/ApplicationFeatures/WorkMonitorFeature.cpp b/lib/ApplicationFeatures/WorkMonitorFeature.cpp index 2af903af94..13c929935c 100644 --- a/lib/ApplicationFeatures/WorkMonitorFeature.cpp +++ b/lib/ApplicationFeatures/WorkMonitorFeature.cpp @@ -35,4 +35,4 @@ WorkMonitorFeature::WorkMonitorFeature( void WorkMonitorFeature::start() { InitializeWorkMonitor(); } -void WorkMonitorFeature::stop() { ShutdownWorkMonitor(); } +void WorkMonitorFeature::unprepare() { ShutdownWorkMonitor(); } diff --git a/lib/ApplicationFeatures/WorkMonitorFeature.h b/lib/ApplicationFeatures/WorkMonitorFeature.h index 2e4266b2f0..d92378c8af 100644 --- a/lib/ApplicationFeatures/WorkMonitorFeature.h +++ b/lib/ApplicationFeatures/WorkMonitorFeature.h @@ -33,7 +33,7 @@ class WorkMonitorFeature final public: void start() override final; - void stop() override final; + void unprepare() override final; }; } diff --git a/lib/Logger/LoggerFeature.cpp b/lib/Logger/LoggerFeature.cpp index 2feb29d9a3..b498b371f5 100644 --- a/lib/Logger/LoggerFeature.cpp +++ b/lib/Logger/LoggerFeature.cpp @@ -177,7 +177,7 @@ void LoggerFeature::prepare() { } } -void LoggerFeature::stop() { +void LoggerFeature::unprepare() { Logger::flush(); Logger::shutdown(true); } diff --git a/lib/Logger/LoggerFeature.h b/lib/Logger/LoggerFeature.h index 5cbc13bbad..ce1e9fe08e 100644 --- a/lib/Logger/LoggerFeature.h +++ b/lib/Logger/LoggerFeature.h @@ -35,7 +35,7 @@ class LoggerFeature final : public application_features::ApplicationFeature { void loadOptions(std::shared_ptr) override final; void validateOptions(std::shared_ptr) override final; void prepare() override final; - void stop() override final; + void unprepare() override final; public: void setBackgrounded(bool backgrounded) { _backgrounded = backgrounded; } diff --git a/lib/Ssl/SslFeature.cpp b/lib/Ssl/SslFeature.cpp index a9821594c3..e2fae73a62 100644 --- a/lib/Ssl/SslFeature.cpp +++ b/lib/Ssl/SslFeature.cpp @@ -145,7 +145,7 @@ void SslFeature::prepare() { opensslSetup(); } -void SslFeature::stop() { +void SslFeature::unprepare() { opensslCleanup(); ERR_free_strings(); diff --git a/lib/Ssl/SslFeature.h b/lib/Ssl/SslFeature.h index 7721ecf60b..1a6acc1d11 100644 --- a/lib/Ssl/SslFeature.h +++ b/lib/Ssl/SslFeature.h @@ -34,7 +34,7 @@ class SslFeature final : public application_features::ApplicationFeature { public: void prepare() override final; - void stop() override final; + void unprepare() override final; }; } diff --git a/lib/Ssl/SslServerFeature.cpp b/lib/Ssl/SslServerFeature.cpp index 89d939c500..27f5fc69a1 100644 --- a/lib/Ssl/SslServerFeature.cpp +++ b/lib/Ssl/SslServerFeature.cpp @@ -94,9 +94,7 @@ void SslServerFeature::collectOptions(std::shared_ptr options) { void SslServerFeature::prepare() { createSslContext(); -} -void SslServerFeature::start() { LOG(INFO) << "using SSL options: " << stringifySslOptions(_options); if (!_cipherList.empty()) { @@ -104,7 +102,7 @@ void SslServerFeature::start() { } } -void SslServerFeature::stop() { +void SslServerFeature::unprepare() { if (_sslContext != nullptr) { SSL_CTX_free(_sslContext); _sslContext = nullptr; diff --git a/lib/Ssl/SslServerFeature.h b/lib/Ssl/SslServerFeature.h index 03cc5ba577..7c35c196ea 100644 --- a/lib/Ssl/SslServerFeature.h +++ b/lib/Ssl/SslServerFeature.h @@ -35,8 +35,7 @@ class SslServerFeature final : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override final; void prepare() override final; - void start() override final; - void stop() override final; + void unprepare() override final; public: SSL_CTX* sslContext() const { return _sslContext; } From 54be4668522c244dd8e1ebf577da5c8cf3e262f8 Mon Sep 17 00:00:00 2001 From: Andreas Streichardt Date: Mon, 6 Jun 2016 18:56:08 +0200 Subject: [PATCH 05/19] Add mesos documentation --- .../Books/Manual/Deployment/Mesos.mdpp | 158 ++++++++++++++---- 1 file changed, 130 insertions(+), 28 deletions(-) diff --git a/Documentation/Books/Manual/Deployment/Mesos.mdpp b/Documentation/Books/Manual/Deployment/Mesos.mdpp index e651f2d86c..de3d4c71fb 100644 --- a/Documentation/Books/Manual/Deployment/Mesos.mdpp +++ b/Documentation/Books/Manual/Deployment/Mesos.mdpp @@ -1,52 +1,154 @@ !SECTION Distributed deployment using Apache Mesos -Philosophie: Es muss extrem einfach aussehen, trotzdem sollte die Section -hinreichend viel Detailinformation liefern. Ich weiß, dass das ein -Widerspruch ist. +TODO: Intro (vom Rechner) !SUBSECTION DC/OS -Explain that ArangoDB is in "the universe" and can be launched under -"Services" in the UI. +DC/OS is the recommended way to install a cluster as it eases much of the process to install a Mesos cluster. You can deploy it very quickly on a variety of cloud hosters or setup your own DC/OS locally. DC/OS is a set of tools built on top of Apache Mesos. Apache Mesos is a so called "Distributed Cluster Operation System" and the core of DC/OS. Apache Mesos has the concept of so called [persistent volumes](http://mesos.apache.org/documentation/latest/persistent-volume/) which make it perfectly suitable for a database. -Show how one reaches the coordinator UI via the DC/OS UI after deployment. +!SUBSUBSECTION Installing -Explain about scaling up and down via the UI. +DC/OS comes with its own package management. Packages can be installed from the so called "Universe". As an official DC/OS partner ArangoDB can be installed from there straight away. -Explain configuration options or link to some place where they are -explained. +1. Installing via DC/OS UI + 1. Go to https://dcos.io and prepare a cluster + 2. Open your browser and go to the DC/OS admin interface + 3. Open the "Universe" tab + 4. Locate arangodb and hit "Install Package" + 5. Optionally review the settings (Advanced Installation) + 6. Press "Install Package" -Explain about the `dcos` CLI and the ArangoDB `dcos`-subcommand. +2. Installing via DC/OS Commandline -Explain how to shut down an ArangoDB cluster cleanly. + 1. Install the [dcos cli](https://docs.mesosphere.com/usage/cli/) + 2. Open a terminal and issue `dcos install arangodb` + +Both options are essentially doing the same in the background. Both are starting ArangoDB with its default options set. To review the default options click "Advanced Installation" in the webinterface or type `dcos package describe --config arangodb`. -Say that ArangoDB uses persistent volumes, explain advantage. +To get an explanation of the various command line options please check the latest options here (choose the most recent number and have a look at config.json): -Say that this makes it impossible to deploy ArangoDB to "public Mesos Agents". -Explain how to setup a marathon-lb load balancer to reach the coordinators -either from within the DC/OS cluster or from the outside (via public slaves). +https://github.com/mesosphere/universe/tree/version-3.x/repo/packages/A/arangodb -Explain authentication setup (once we have it). +Alternatively check the DC/OS webinterface. Hit installing ArangoDB on the "Services" tab and examine "Advanced Installation". -Staubsauger? +After installing DC/OS will start deploying the ArangoDB cluster on the DC/OS cluster. You can watch ArangoDB starting on the "Services" tab in the webinterface. Once it is listed as healthy click the link next to it and you should see the ArangoDB webinterface. + +!SUBSUBSECTION While running + +!SUBSUBSUBSECTION ArangoDB Mesos framework +While ArangoDB is deployed Mesos will keep your cluster running. The web interface has many monitoring facilities so be sure to make yourself familiar with the DC/OS webinterface. As a fault tolerant system Mesos will take care of most failure scenarios automatically. Mesos does that by running ArangoDB as a so called "framework". This framework has been specifically built to keep ArangoDB running in a healthy condition on the Mesos cluster. From time to time a task might fail. The ArangoDB framework will then take care of rescheduling the failed task. As it knows about the very specifics of each cluster task and its role it will automatically take care of most failure scenarios. + +To inspect what the framework is doing go to `WEBINTERFACEURL`/mesos in your browser. Locate the task "arangodb" and inspect stderr in the "Sandbox". This can be of interest for example when a slave got lost and the framework is rescheduling the task. + +!SUBSUBSUBSECTION Using ArangoDB + +To use ArangoDB as a datastore in your DC/OS cluster you can facilitate the service discovery of DC/OS. Assuming you deployed a standard ArangoDB cluster the [mesos dns](https://github.com/mesosphere/mesos-dns) will know about `arangodb.mesos`. By doing a SRV DNS request (check the documentation of mesos dns) you can find out the port where the internal HAProxy of ArangoDB is running. This will offer a round robin load balancer to access all ArangoDB coordinators. + +!SUBSUBSUBSECTION Scaling ArangoDB + +To change the settings of your ArangoDB Cluster access the ArangoDB UI and hit "Nodes". On the scale tab you will have the ability to scale your cluster up and down. + +After changing the settings the ArangoDB framework will take care of the rest. Scaling your cluster up is generally a straightforward operation as Mesos will simply launch another task and be done with it. Scaling down is a bit more complicated as the data first has to be moved to some other place so that will naturally take somewhat longer. + +Please note that scaling operations might not always work. For example if the underlying Mesos cluster is completely saturated with tasks scaling up will not be possible. Scaling down might also fail due to not being able to move all shards of a DBServer to a new destination because of size limitations. Be sure to check the output of the ArangoDB framework. + +!SUBSUBSECTION Deinstallation + +Deinstalling ArangoDB is a bit more difficult as there is much state being kept in the Mesos cluster which is not automatically cleaned up. To deinstall from the command line use the following one liner: + +`dcos arangodb uninstall ; dcos package uninstall arangodb` + +This will first cleanup the state in the cluster and then uninstall arangodb. + +!SUBSUBSUBSECTION arangodb-cleanup-framework + +Should you forget to cleanup the state you can do so later by using the [arangodb-cleanup-framework](https://github.com/arangodb/arangodb-cleanup-framework/) container. Otherwise you might not be able to deploy a new arangodb installation. + +The cleanup framework will announce itself as a normal ArangoDB. Mesos will recognize this and offer all persistent volumes it still has for ArangoDB to this framework. The cleanup framework will then properly free the persistent volumes. Finally it will clean up any state left in zookeeper (the central configuration manager in a Mesos cluster). + +To deploy follow the instructions in the github repository. After deploying watch the output in the sandbox of the Mesos webinterface. After a while there shouldn't be any persistent resource offers anymore as everything was cleaned up. After that you can delete the cleanup framework again via marathon. !SUBSECTION Apache Mesos and Marathon -Explain how to launch an ArangoDB cluster via Marathon in an Apache -Mesos cluster. +You can also install ArangoDB on a bare Apache Mesos cluster provided that marathon is running on it. -Explain configuration options or link to some place where they are -explained. +Doing so has the following downsides: -Show how one reaches the coordinator UI, HOW DOES THIS ACTUALLY WORK? -DO WE NEED EXPLAIN ABOUT sshuttle? +1. Manual Mesos cluster setup +1. You need to implement your own service discovery +1. You are missing the dcos cli +1. Install and Deinstall are tedious +1. You need to setup some kind of proxy tunnel to access arangodb from the outside +1. Sparse monitoring capabilities -Mention scaling up and down as in DC/OS case. +However these are things which do not influence ArangoDB itself and operating your cluster like this is fully supported. -Explain how to shut down an ArangoDB cluster cleanly. +!SUBSUBSECTION Installing via Marathon -Explain authentication setup (once we have it) or say it is exactly as -in the DC/OS case. +To install ArangoDB via marathon you need a proper config file: -Staubsauger? Deployment via Marathon. +``` +{ + "id": "arangodb", + "cpus": 0.25, + "mem": 256.0, + "ports": [0, 0, 0], + "instances": 1, + "args": [ + "framework", + "--framework_name=arangodb", + "--master=zk://172.17.0.2:2181/mesos", + "--zk=zk://172.17.0.2:2181/arangodb", + "--user=", + "--principal=pri", + "--role=arangodb", + "--mode=cluster", + "--async_replication=true", + "--minimal_resources_agent=mem(*):512;cpus(*):0.25;disk(*):512", + "--minimal_resources_dbserver=mem(*):512;cpus(*):0.25;disk(*):1024", + "--minimal_resources_secondary=mem(*):512;cpus(*):0.25;disk(*):1024", + "--minimal_resources_coordinator=mem(*):512;cpus(*):0.25;disk(*):1024", + "--nr_agents=1", + "--nr_dbservers=2", + "--nr_coordinators=2", + "--failover_timeout=86400", + "--arangodb_image=arangodb/arangodb-mesos:3.0", + "--secondaries_with_dbservers=false", + "--coordinators_with_dbservers=false" + ], + "container": { + "type": "DOCKER", + "docker": { + "image": "arangodb/arangodb-mesos-framework:3.0", + "network": "HOST" + } + }, + "healthChecks": [ + { + "protocol": "HTTP", + "path": "/framework/v1/health.json", + "gracePeriodSeconds": 3, + "intervalSeconds": 10, + "portIndex": 0, + "timeoutSeconds": 10, + "maxConsecutiveFailures": 0 + } + ] +} +``` +Carefully review the settings (especially the IPs and the resources). Then you can deploy to marathon: + +`curl -X POST -H "Content-Type: application/json" http://url-of-marathon/v2/apps -d @arangodb3.json` + +Alternatively use the webinterface of marathon to deploy ArangoDB. + +!SUBSUBSECTION Deinstallation via Marathon + +As with DC/OS you first need to properly cleanup any state leftovers. + +The easiest is to simply delete arangodb and then deploy the cleanup-framework (see section arangodb-cleanup-framework). + +!SUBSECTION Configuration options + +The Arangodb Mesos framework has a ton of different options which are listed and described here: https://github.com/arangodb/arangodb-mesos-framework/tree/3.0 \ No newline at end of file From 3798221f7cb38d3ae60674a3e9d6d582f6466ae7 Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Mon, 6 Jun 2016 17:07:33 +0000 Subject: [PATCH 06/19] fixed progation of kill --- lib/ApplicationFeatures/SupervisorFeature.cpp | 151 ++++++++++-------- 1 file changed, 87 insertions(+), 64 deletions(-) diff --git a/lib/ApplicationFeatures/SupervisorFeature.cpp b/lib/ApplicationFeatures/SupervisorFeature.cpp index 5dfd1eace3..d671ef01bf 100644 --- a/lib/ApplicationFeatures/SupervisorFeature.cpp +++ b/lib/ApplicationFeatures/SupervisorFeature.cpp @@ -33,6 +33,15 @@ using namespace arangodb::application_features; using namespace arangodb::basics; using namespace arangodb::options; +static bool DONE = false; +static int CLIENT_PID = false; + +static void StopHandler(int) { + LOG_TOPIC(INFO, Logger::STARTUP) << "received SIGINT for supervisor"; + kill(CLIENT_PID, SIGTERM); + DONE = true; +} + SupervisorFeature::SupervisorFeature( application_features::ApplicationServer* server) : ApplicationFeature(server, "Supervisor"), _supervisor(false) { @@ -104,11 +113,8 @@ void SupervisorFeature::daemonize() { // parent (supervisor) if (0 < _clientPid) { - LOG_TOPIC(DEBUG, Logger::STARTUP) << "supervisor mode: within parent"; TRI_SetProcessTitle("arangodb [supervisor]"); - ArangoGlobalContext::CONTEXT->unmaskStandardSignals(); - std::for_each(supervisorFeatures.begin(), supervisorFeatures.end(), [](ApplicationFeature* feature) { LoggerFeature* logger = @@ -126,81 +132,98 @@ void SupervisorFeature::daemonize() { std::for_each(supervisorFeatures.begin(), supervisorFeatures.end(), [](ApplicationFeature* feature) { feature->start(); }); + LOG_TOPIC(DEBUG, Logger::STARTUP) << "supervisor mode: within parent"; + + ArangoGlobalContext::CONTEXT->unmaskStandardSignals(); + signal(SIGINT, StopHandler); + signal(SIGTERM, StopHandler); + + CLIENT_PID = _clientPid; + DONE = false; + int status; - waitpid(_clientPid, &status, 0); + int res = waitpid(_clientPid, &status, 0); bool horrible = true; - if (WIFEXITED(status)) { - // give information about cause of death - if (WEXITSTATUS(status) == 0) { - LOG_TOPIC(INFO, Logger::STARTUP) << "child " << _clientPid - << " died of natural causes"; - done = true; - horrible = false; - } else { - t = time(0) - startTime; + if (!DONE) { + done = true; + horrible = false; + } + else { + LOG_TOPIC(DEBUG, Logger::STARTUP) << "waitpid woke up with return value " + << res << " and status " << status; - LOG_TOPIC(ERR, Logger::STARTUP) - << "child " << _clientPid - << " died a horrible death, exit status " << WEXITSTATUS(status); + if (WIFEXITED(status)) { + // give information about cause of death + if (WEXITSTATUS(status) == 0) { + LOG_TOPIC(INFO, Logger::STARTUP) << "child " << _clientPid + << " died of natural causes"; + done = true; + horrible = false; + } else { + t = time(0) - startTime; - if (t < MIN_TIME_ALIVE_IN_SEC) { - LOG_TOPIC(ERR, Logger::STARTUP) - << "child only survived for " << t - << " seconds, this will not work - please fix the error " - "first"; - done = true; - } else { - done = false; - } - } - } else if (WIFSIGNALED(status)) { - switch (WTERMSIG(status)) { - case 2: - case 9: - case 15: - LOG_TOPIC(INFO, Logger::STARTUP) - << "child " << _clientPid - << " died of natural causes, exit status " << WTERMSIG(status); - done = true; - horrible = false; - break; + LOG_TOPIC(ERR, Logger::STARTUP) + << "child " << _clientPid + << " died a horrible death, exit status " << WEXITSTATUS(status); - default: - t = time(0) - startTime; + if (t < MIN_TIME_ALIVE_IN_SEC) { + LOG_TOPIC(ERR, Logger::STARTUP) + << "child only survived for " << t + << " seconds, this will not work - please fix the error " + "first"; + done = true; + } else { + done = false; + } + } + } else if (WIFSIGNALED(status)) { + switch (WTERMSIG(status)) { + case 2: + case 9: + case 15: + LOG_TOPIC(INFO, Logger::STARTUP) + << "child " << _clientPid + << " died of natural causes, exit status " << WTERMSIG(status); + done = true; + horrible = false; + break; - LOG_TOPIC(ERR, Logger::STARTUP) << "child " << _clientPid - << " died a horrible death, signal " - << WTERMSIG(status); + default: + t = time(0) - startTime; - if (t < MIN_TIME_ALIVE_IN_SEC) { - LOG_TOPIC(ERR, Logger::STARTUP) - << "child only survived for " << t - << " seconds, this will not work - please fix the " - "error first"; - done = true; + LOG_TOPIC(ERR, Logger::STARTUP) << "child " << _clientPid + << " died a horrible death, signal " + << WTERMSIG(status); + + if (t < MIN_TIME_ALIVE_IN_SEC) { + LOG_TOPIC(ERR, Logger::STARTUP) + << "child only survived for " << t + << " seconds, this will not work - please fix the " + "error first"; + done = true; #ifdef WCOREDUMP - if (WCOREDUMP(status)) { - LOG_TOPIC(WARN, Logger::STARTUP) << "child process " - << _clientPid - << " produced a core dump"; - } + if (WCOREDUMP(status)) { + LOG_TOPIC(WARN, Logger::STARTUP) << "child process " + << _clientPid + << " produced a core dump"; + } #endif - } else { - done = false; - } + } else { + done = false; + } - break; - } - } else { - LOG_TOPIC(ERR, Logger::STARTUP) - << "child " << _clientPid - << " died a horrible death, unknown cause"; - done = false; + break; + } + } else { + LOG_TOPIC(ERR, Logger::STARTUP) + << "child " << _clientPid + << " died a horrible death, unknown cause"; + done = false; + } } - // remove pid file if (horrible) { result = EXIT_FAILURE; } From d72d9a7a2c9d19e5a5681db04c4a83dabc095b72 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Mon, 6 Jun 2016 22:40:40 +0200 Subject: [PATCH 07/19] Use performRequests for countOnCluster. --- arangod/Cluster/ClusterMethods.cpp | 40 ++++++++++++++---------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/arangod/Cluster/ClusterMethods.cpp b/arangod/Cluster/ClusterMethods.cpp index ed20d5a2ec..758b4a7b48 100644 --- a/arangod/Cluster/ClusterMethods.cpp +++ b/arangod/Cluster/ClusterMethods.cpp @@ -649,21 +649,19 @@ int countOnCoordinator(std::string const& dbname, std::string const& collname, } auto shards = collinfo->shardIds(); - CoordTransactionID coordTransactionID = TRI_NewTickServer(); + std::vector requests; + auto body = std::make_shared(); for (auto const& p : *shards) { - auto headers = std::make_unique>(); - cc->asyncRequest( - "", coordTransactionID, "shard:" + p.first, - arangodb::GeneralRequest::RequestType::GET, - "/_db/" + StringUtils::urlEncode(dbname) + "/_api/collection/" + - StringUtils::urlEncode(p.first) + "/count", - std::shared_ptr(), headers, nullptr, 300.0); + requests.emplace_back("shard:" + p.first, + arangodb::GeneralRequest::RequestType::GET, + "/_db/" + StringUtils::urlEncode(dbname) + + "/_api/collection/" + + StringUtils::urlEncode(p.first) + "/count", body); } - // Now listen to the results: - int count; - int nrok = 0; - for (count = (int)shards->size(); count > 0; count--) { - auto res = cc->wait("", coordTransactionID, 0, "", 0.0); + size_t nrDone = 0; + cc->performRequests(requests, CL_DEFAULT_TIMEOUT, nrDone, Logger::QUERIES); + for (auto& req : requests) { + auto& res = req.result; if (res.status == CL_COMM_RECEIVED) { if (res.answer_code == arangodb::GeneralResponse::ResponseCode::OK) { std::shared_ptr answerBuilder = ExtractAnswer(res); @@ -674,18 +672,18 @@ int countOnCoordinator(std::string const& dbname, std::string const& collname, result += arangodb::basics::VelocyPackHelper::getNumericValue( answer, "count", 0); - nrok++; + } else { + return TRI_ERROR_INTERNAL; } + } else { + return static_cast(res.answer_code); } + } else { + return TRI_ERROR_CLUSTER_BACKEND_UNAVAILABLE; } } - - if (nrok != (int)shards->size()) { - return TRI_ERROR_INTERNAL; - } - - return TRI_ERROR_NO_ERROR; // the cluster operation was OK, however, - // the DBserver could have reported an error. + + return TRI_ERROR_NO_ERROR; } //////////////////////////////////////////////////////////////////////////////// From 2b74afbb407a957ceedd2d243909f106e760858d Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Mon, 6 Jun 2016 22:40:55 +0200 Subject: [PATCH 08/19] Add more tests for resilience of count. --- .../resilience-synchronous-repl-cluster.js | 102 +++++++++++------- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/js/server/tests/resilience/resilience-synchronous-repl-cluster.js b/js/server/tests/resilience/resilience-synchronous-repl-cluster.js index 6aae90b9f2..a93936814f 100644 --- a/js/server/tests/resilience/resilience-synchronous-repl-cluster.js +++ b/js/server/tests/resilience/resilience-synchronous-repl-cluster.js @@ -283,22 +283,26 @@ function SynchronousReplicationSuite () { catch (e1) { assertEqual(ERRORS.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code, e1.errorNum); } - assertEqual(2, c.count()); if (healing.place === 15) { healFailure(healing); } if (failure.place === 16) { makeFailure(failure); } - c.remove([ids[0]._key, ids[1]._key]); + assertEqual(2, c.count()); if (healing.place === 16) { healFailure(healing); } if (failure.place === 17) { makeFailure(failure); } + c.remove([ids[0]._key, ids[1]._key]); + + if (healing.place === 17) { healFailure(healing); } + if (failure.place === 18) { makeFailure(failure); } + docs = c.document([ids[0]._key, ids[1]._key]); assertEqual(2, docs.length); assertTrue(docs[0].error); assertTrue(docs[1].error); - if (healing.place === 17) { healFailure(healing); } + if (healing.place === 18) { healFailure(healing); } } //////////////////////////////////////////////////////////////////////////////// @@ -336,7 +340,6 @@ function SynchronousReplicationSuite () { /// @brief check whether we have access to global.instanceInfo //////////////////////////////////////////////////////////////////////////////// -/* testCheckInstanceInfo : function () { assertTrue(global.instanceInfo !== undefined); }, @@ -376,7 +379,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail1 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:1, follower:true}, {place:17, follower:true}); + runBasicOperations({place:1, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -386,7 +389,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail2 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:2, follower:true}, {place:17, follower:true}); + runBasicOperations({place:2, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -396,7 +399,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail3 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:3, follower:true}, {place:17, follower:true}); + runBasicOperations({place:3, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -406,7 +409,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail4 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:4, follower:true}, {place:17, follower:true}); + runBasicOperations({place:4, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -416,7 +419,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail5 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:5, follower:true}, {place:17, follower:true}); + runBasicOperations({place:5, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -426,7 +429,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail6 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:6, follower:true}, {place:17, follower:true}); + runBasicOperations({place:6, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -436,7 +439,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail7 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:7, follower:true}, {place:17, follower:true}); + runBasicOperations({place:7, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -446,7 +449,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail8 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:8, follower:true}, {place:17, follower:true}); + runBasicOperations({place:8, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -456,7 +459,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail9 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:9, follower:true}, {place:17, follower:true}); + runBasicOperations({place:9, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -466,7 +469,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail10 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:10, follower:true}, {place:17, follower:true}); + runBasicOperations({place:10, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -476,7 +479,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail11 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:11, follower:true}, {place:17, follower:true}); + runBasicOperations({place:11, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -486,7 +489,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail12 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:12, follower:true}, {place:17, follower:true}); + runBasicOperations({place:12, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -496,7 +499,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail13 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:13, follower:true}, {place:17, follower:true}); + runBasicOperations({place:13, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -506,7 +509,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail14 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:14, follower:true}, {place:17, follower:true}); + runBasicOperations({place:14, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -516,7 +519,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail15 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:15, follower:true}, {place:17, follower:true}); + runBasicOperations({place:15, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -526,7 +529,7 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail16 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:16, follower:true}, {place:17, follower:true}); + runBasicOperations({place:16, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -536,10 +539,20 @@ function SynchronousReplicationSuite () { testBasicOperationsFollowerFail17 : function () { assertTrue(waitForSynchronousReplication("_system")); - runBasicOperations({place:17, follower:true}, {place:17, follower:true}); + runBasicOperations({place:17, follower:true}, {place:18, follower:true}); assertTrue(waitForSynchronousReplication("_system")); }, -*/ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief fail in place 18 +//////////////////////////////////////////////////////////////////////////////// + + testBasicOperationsFollowerFail18 : function () { + assertTrue(waitForSynchronousReplication("_system")); + runBasicOperations({place:18, follower:true}, {place:18, follower:true}); + assertTrue(waitForSynchronousReplication("_system")); + }, + //////////////////////////////////////////////////////////////////////////////// /// @brief run a standard check with failures: //////////////////////////////////////////////////////////////////////////////// @@ -559,7 +572,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail1 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:1, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -570,7 +583,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail2 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:2, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -581,7 +594,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail3 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:3, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -592,7 +605,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail4 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:4, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -603,7 +616,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail5 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:5, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -614,7 +627,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail6 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:6, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -625,7 +638,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail7 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:7, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -636,7 +649,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail8 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:8, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -647,7 +660,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail9 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:9, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -658,7 +671,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail10 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:10, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -669,7 +682,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail11 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:11, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -680,7 +693,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail12 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:12, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -691,7 +704,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail13 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:13, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -702,7 +715,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail14 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:14, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -713,7 +726,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail15 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:15, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -724,7 +737,7 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail16 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:16, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, @@ -735,7 +748,18 @@ function SynchronousReplicationSuite () { testBasicOperationsLeaderFail17 : function () { assertTrue(waitForSynchronousReplication("_system")); runBasicOperations({place:17, follower: false}, - {place:17, follower: false}); + {place:18, follower: false}); + assertTrue(waitForSynchronousReplication("_system")); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief fail leader in place 18 +//////////////////////////////////////////////////////////////////////////////// + + testBasicOperationsLeaderFail18 : function () { + assertTrue(waitForSynchronousReplication("_system")); + runBasicOperations({place:18, follower: false}, + {place:18, follower: false}); assertTrue(waitForSynchronousReplication("_system")); }, From 031094763b1d7ebe64f3938f629c5e390f0c2b9e Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Jun 2016 23:37:29 +0200 Subject: [PATCH 09/19] renamed REGEX_MATCH to REGEX_TEST --- Documentation/Books/AQL/Functions/String.mdpp | 10 +++---- arangod/Aql/FunctionDefinitions.cpp | 4 +-- arangod/Aql/Functions.cpp | 16 +++++------ arangod/Aql/Functions.h | 2 +- .../aardvark/APP/frontend/src/mode-aql.js | 6 ++-- js/server/modules/@arangodb/aql.js | 4 +-- js/server/tests/aql/aql-functions-string.js | 28 +++++++++---------- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Documentation/Books/AQL/Functions/String.mdpp b/Documentation/Books/AQL/Functions/String.mdpp index cb6c316373..261390675d 100644 --- a/Documentation/Books/AQL/Functions/String.mdpp +++ b/Documentation/Books/AQL/Functions/String.mdpp @@ -267,9 +267,9 @@ RANDOM_TOKEN(8) // "zGl09z42" RANDOM_TOKEN(8) // "m9w50Ft9" ``` -!SUBSECTION REGEX_MATCH() +!SUBSECTION REGEX_TEST() -`REGEX_MATCH(text, search, caseInsensitive) → bool` +`REGEX_TEST(text, search, caseInsensitive) → bool` Check whether the pattern *search* is contained in the string *text*, using regular expression matching. @@ -327,9 +327,9 @@ If the regular expression in *search* is invalid, a warning will be raised and the function will return *false*. ```js -REGEX_MATCH("the quick brown fox", "the.*fox") // true -REGEX_MATCH("the quick brown fox", "^(a|the)\s+(quick|slow).*f.x$") // true -REGEX_MATCH("the\nquick\nbrown\nfox", "^the(\n[a-w]+)+\nfox$") // true +REGEX_TEST("the quick brown fox", "the.*fox") // true +REGEX_TEST("the quick brown fox", "^(a|the)\s+(quick|slow).*f.x$") // true +REGEX_TEST("the\nquick\nbrown\nfox", "^the(\n[a-w]+)+\nfox$") // true ``` !SUBSECTION REVERSE() diff --git a/arangod/Aql/FunctionDefinitions.cpp b/arangod/Aql/FunctionDefinitions.cpp index d63fb5d2dc..93c5ded434 100644 --- a/arangod/Aql/FunctionDefinitions.cpp +++ b/arangod/Aql/FunctionDefinitions.cpp @@ -177,8 +177,8 @@ struct FunctionDefiner { false, true, true, &Functions::Contains}); add({"LIKE", "AQL_LIKE", "s,r|b", true, true, false, true, true, &Functions::Like}); - add({"REGEX_MATCH", "AQL_REGEX_MATCH", "s,r|b", true, true, false, true, - true, &Functions::RegexMatch}); + add({"REGEX_TEST", "AQL_REGEX_TEST", "s,r|b", true, true, false, true, + true, &Functions::RegexTest}); add({"LEFT", "AQL_LEFT", "s,n", true, true, false, true, true}); add({"RIGHT", "AQL_RIGHT", "s,n", true, true, false, true, true}); add({"TRIM", "AQL_TRIM", "s|ns", true, true, false, true, true}); diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 61de94d90c..cf4791f167 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -1419,11 +1419,11 @@ AqlValue Functions::Like(arangodb::aql::Query* query, return AqlValue(result); } -/// @brief function REGEX_MATCH -AqlValue Functions::RegexMatch(arangodb::aql::Query* query, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { - ValidateParameters(parameters, "REGEX_MATCH", 2, 3); +/// @brief function REGEX_TEST +AqlValue Functions::RegexTest(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + ValidateParameters(parameters, "REGEX_TEST", 2, 3); bool const caseInsensitive = GetBooleanParameter(trx, parameters, 2, false); StringBufferLeaser buffer(trx); arangodb::basics::VPackStringBufferAdapter adapter(buffer->stringBuffer()); @@ -1464,7 +1464,7 @@ AqlValue Functions::RegexMatch(arangodb::aql::Query* query, if (matcher == nullptr) { // compiling regular expression failed - RegisterWarning(query, "REGEX_MATCH", TRI_ERROR_QUERY_INVALID_REGEX); + RegisterWarning(query, "REGEX_TEST", TRI_ERROR_QUERY_INVALID_REGEX); return AqlValue(arangodb::basics::VelocyPackHelper::NullValue()); } @@ -1479,7 +1479,7 @@ AqlValue Functions::RegexMatch(arangodb::aql::Query* query, if (error) { // compiling regular expression failed - RegisterWarning(query, "REGEX_MATCH", TRI_ERROR_QUERY_INVALID_REGEX); + RegisterWarning(query, "REGEX_TEST", TRI_ERROR_QUERY_INVALID_REGEX); return AqlValue(arangodb::basics::VelocyPackHelper::NullValue()); } @@ -3996,7 +3996,7 @@ AqlValue Functions::Range(arangodb::aql::Query* query, AqlValue stepValue = ExtractFunctionParameterValue(trx, parameters, 2); if (stepValue.isNull(true)) { - // no step specified + // no step specified. return a real range object return AqlValue(left.toInt64(), right.toInt64()); } diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 63ae304902..fcee83d9cc 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -97,7 +97,7 @@ struct Functions { VPackFunctionParameters const&); static AqlValue Like(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); - static AqlValue RegexMatch(arangodb::aql::Query*, arangodb::AqlTransaction*, + static AqlValue RegexTest(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); static AqlValue Passthru(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); diff --git a/js/apps/system/_admin/aardvark/APP/frontend/src/mode-aql.js b/js/apps/system/_admin/aardvark/APP/frontend/src/mode-aql.js index 3878552615..f41c208ee3 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/src/mode-aql.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/src/mode-aql.js @@ -88,14 +88,14 @@ var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var AqlHighlightRules = function() { var keywords = ( - "for|return|filter|sort|limit|let|collect|asc|desc|in|into|insert|update|remove|replace|upsert|options|with|and|or|not|distinct|graph|outbound|inbound|any|all|none|aggregate|like|count" + "for|return|filter|sort|limit|let|collect|asc|desc|in|into|insert|update|remove|replace|upsert|options|with|and|or|not|distinct|graph|shortest_path|outbound|inbound|any|all|none|aggregate|like" ); var builtinFunctions = ( "(to_bool|to_number|to_string|to_list|is_null|is_bool|is_number|is_string|is_list|is_document|typename|" + "concat|concat_separator|char_length|lower|upper|substring|left|right|trim|reverse|contains|" + - "log|log2|log10|exp|exp2|sin|cos|tan|asin|acos|atan|atan2|radians|degrees|pi|regex|" + - "like|floor|ceil|round|abs|rand|sqrt|pow|length|min|max|average|sum|median|variance_population|" + + "log|log2|log10|exp|exp2|sin|cos|tan|asin|acos|atan|atan2|radians|degrees|pi|regex_test|" + + "like|floor|ceil|round|abs|rand|sqrt|pow|length|count|min|max|average|sum|median|variance_population|" + "variance_sample|first|last|unique|matches|merge|merge_recursive|has|attributes|values|unset|unset_recursive|keep|" + "near|within|within_rectangle|is_in_polygon|fulltext|paths|traversal|traversal_tree|edges|stddev_sample|stddev_population|" + "slice|nth|position|translate|zip|call|apply|push|append|pop|shift|unshift|remove_value|remove_values|" + diff --git a/js/server/modules/@arangodb/aql.js b/js/server/modules/@arangodb/aql.js index 0dfe22d2a6..545cf575cc 100644 --- a/js/server/modules/@arangodb/aql.js +++ b/js/server/modules/@arangodb/aql.js @@ -2301,7 +2301,7 @@ function AQL_LIKE (value, regex, caseInsensitive) { /// @brief searches a substring in a string, using a regex //////////////////////////////////////////////////////////////////////////////// -function AQL_REGEX_MATCH (value, regex, caseInsensitive) { +function AQL_REGEX_TEST (value, regex, caseInsensitive) { 'use strict'; var modifiers = ''; @@ -8358,7 +8358,7 @@ exports.AQL_UPPER = AQL_UPPER; exports.AQL_SUBSTRING = AQL_SUBSTRING; exports.AQL_CONTAINS = AQL_CONTAINS; exports.AQL_LIKE = AQL_LIKE; -exports.AQL_REGEX_MATCH = AQL_REGEX_MATCH; +exports.AQL_REGEX_TEST = AQL_REGEX_TEST; exports.AQL_LEFT = AQL_LEFT; exports.AQL_RIGHT = AQL_RIGHT; exports.AQL_TRIM = AQL_TRIM; diff --git a/js/server/tests/aql/aql-functions-string.js b/js/server/tests/aql/aql-functions-string.js index f529bb16e0..c806d901aa 100644 --- a/js/server/tests/aql/aql-functions-string.js +++ b/js/server/tests/aql/aql-functions-string.js @@ -62,18 +62,18 @@ function ahuacatlStringFunctionsTestSuite () { //////////////////////////////////////////////////////////////////////////////// testRegexInvalid : function () { - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH()"); - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH(\"test\")"); - assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_MATCH(\"test\", \"meow\", \"foo\", \"bar\")"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_TEST()"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_TEST(\"test\")"); + assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN REGEX_TEST(\"test\", \"meow\", \"foo\", \"bar\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"[\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"[^\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"a.(\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"(a\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"(a]\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"**\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"?\")"); - assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_MATCH(\"test\", \"*\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_TEST(\"test\", \"[\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_TEST(\"test\", \"[^\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_TEST(\"test\", \"a.(\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_TEST(\"test\", \"(a\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_TEST(\"test\", \"(a]\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_TEST(\"test\", \"**\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_TEST(\"test\", \"?\")"); + assertQueryWarningAndFalse(errors.ERROR_QUERY_INVALID_REGEX.code, "RETURN REGEX_TEST(\"test\", \"*\")"); }, testRegex : function () { @@ -217,13 +217,13 @@ function ahuacatlStringFunctionsTestSuite () { ]; values.forEach(function(v) { - var query = "RETURN REGEX_MATCH(@what, @re)"; + var query = "RETURN REGEX_TEST(@what, @re)"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); - query = "RETURN NOOPT(REGEX_MATCH(@what, @re))"; + query = "RETURN NOOPT(REGEX_TEST(@what, @re))"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); - query = "RETURN NOOPT(V8(REGEX_MATCH(@what, @re)))"; + query = "RETURN NOOPT(V8(REGEX_TEST(@what, @re)))"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); }); From fad6de811031d1e960b3fb51c90a6de95b224f91 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Jun 2016 23:51:57 +0200 Subject: [PATCH 10/19] updated new features --- .../Manual/ReleaseNotes/NewFeatures30.mdpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Documentation/Books/Manual/ReleaseNotes/NewFeatures30.mdpp b/Documentation/Books/Manual/ReleaseNotes/NewFeatures30.mdpp index d29ecd0dc0..f20a9f7aca 100644 --- a/Documentation/Books/Manual/ReleaseNotes/NewFeatures30.mdpp +++ b/Documentation/Books/Manual/ReleaseNotes/NewFeatures30.mdpp @@ -89,6 +89,49 @@ var q = `FOR doc IN ´collection´ RETURN doc.´name´`; The following AQL functions have been added in 3.0: +- *REGEX_TEST(value, regex)*: tests whether the string *value* matches the regular expression + specified in *regex*. Returns *true* if it matches, and *false* otherwise. + + The regular expression may consist of literal characters and the following + characters and sequences: + + - `.` – the dot matches any single character except line terminators. + To include line terminators, use `[\s\S]` instead to simulate `.` with *DOTALL* flag. + - `\d` – matches a single digit, equivalent to `[0-9]` + - `\s` – matches a single whitespace character + - `\S` – matches a single non-whitespace character + - `\t` – matches a tab character + - `\r` – matches a carriage return + - `\n` – matches a line-feed character + - `[xyz]` – set of characters. matches any of the enclosed characters (i.e. + *x*, *y* or *z* in this case + - `[^xyz]` – negated set of characters. matches any other character than the + enclosed ones (i.e. anything but *x*, *y* or *z* in this case) + - `[x-z]` – range of characters. Matches any of the characters in the + specified range, e.g. `[0-9A-F]` to match any character in + *0123456789ABCDEF* + - `[^x-z]` – negated range of characters. Matches any other character than the + ones specified in the range + - `(xyz)` – defines and matches a pattern group + - `(x|y)` – matches either *x* or *y* + - `^` – matches the beginning of the string (e.g. `^xyz`) + - `$` – matches the end of the string (e.g. `xyz$`) + + Note that the characters `.`, `*`, `?`, `[`, `]`, `(`, `)`, `{`, `}`, `^`, + and `$` have a special meaning in regular expressions and may need to be + escaped using a backslash (`\\`). A literal backslash should also be escaped + using another backslash, i.e. `\\\\`. + + Characters and sequences may optionally be repeated using the following + quantifiers: + + - `x*` – matches zero or more occurrences of *x* + - `x+` – matches one or more occurrences of *x* + - `x?` – matches one or zero occurrences of *x* + - `x{y}` – matches exactly *y* occurrences of *x* + - `x{y,z}` – matches between *y* and *z* occurrences of *x* + - `x{y,}` – matches at least *y* occurences of *x* + - *HASH(value)*: Calculates a hash value for *value*. *value* is not required to be a string, but can have any data type. The calculated hash value will take the data type of *value* into account, so for example the number *1* and the string *"1"* will have From f9fc22d0b49d2cb9524d9ef6956b8200ff322f99 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Mon, 6 Jun 2016 23:51:58 +0200 Subject: [PATCH 11/19] Minor tweak to error handling in performRequests. --- arangod/Cluster/ClusterComm.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arangod/Cluster/ClusterComm.cpp b/arangod/Cluster/ClusterComm.cpp index ef60721420..cbc27cea0d 100644 --- a/arangod/Cluster/ClusterComm.cpp +++ b/arangod/Cluster/ClusterComm.cpp @@ -1153,11 +1153,15 @@ size_t ClusterComm::performRequests(std::vector& requests, } else if (res.status == CL_COMM_BACKEND_UNAVAILABLE || (res.status == CL_COMM_TIMEOUT && !res.sendWasComplete)) { requests[index].result = res; + // In this case we will retry at the dueTime, if it is before endTime: + if (dueTime[index] >= endTime) { + requests[index].done = true; + nrDone++; + } LOG_TOPIC(TRACE, logTopic) << "ClusterComm::performRequests: " << "got BACKEND_UNAVAILABLE or TIMEOUT from " << requests[index].destination << ":" << requests[index].path; - // In this case we will retry at the dueTime } else { // a "proper error" requests[index].result = res; requests[index].done = true; From 69e254d28a94b39bf45cc6d5e87209fa0e052edf Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Mon, 6 Jun 2016 23:49:36 +0200 Subject: [PATCH 12/19] trying to fix cleanup --- arangod/Agency/AgencyFeature.cpp | 2 +- arangod/Agency/AgencyFeature.h | 2 +- arangod/Cluster/ClusterFeature.cpp | 2 +- arangod/Cluster/ClusterFeature.h | 2 +- arangod/Dispatcher/Dispatcher.cpp | 26 +++++++++++-------- arangod/Dispatcher/DispatcherFeature.cpp | 4 ++- arangod/RestServer/BootstrapFeature.cpp | 2 +- arangod/RestServer/BootstrapFeature.h | 2 +- arangod/RestServer/ConsoleFeature.cpp | 4 +-- arangod/RestServer/ConsoleFeature.h | 1 - arangod/Scheduler/SchedulerFeature.cpp | 12 +++++---- arangod/Scheduler/SchedulerFeature.h | 1 + arangod/Statistics/StatisticsFeature.cpp | 2 +- arangod/Statistics/StatisticsFeature.h | 2 +- arangod/Wal/LogfileManager.cpp | 2 +- arangod/Wal/LogfileManager.h | 2 +- lib/ApplicationFeatures/ApplicationServer.cpp | 2 +- 17 files changed, 38 insertions(+), 32 deletions(-) diff --git a/arangod/Agency/AgencyFeature.cpp b/arangod/Agency/AgencyFeature.cpp index 4c54c29f15..872e788f63 100644 --- a/arangod/Agency/AgencyFeature.cpp +++ b/arangod/Agency/AgencyFeature.cpp @@ -189,7 +189,7 @@ void AgencyFeature::start() { _agent->load(); } -void AgencyFeature::stop() { +void AgencyFeature::unprepare() { if (!isEnabled()) { return; diff --git a/arangod/Agency/AgencyFeature.h b/arangod/Agency/AgencyFeature.h index c810ef0203..f5379d5653 100644 --- a/arangod/Agency/AgencyFeature.h +++ b/arangod/Agency/AgencyFeature.h @@ -40,7 +40,7 @@ class AgencyFeature : virtual public application_features::ApplicationFeature { void validateOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; private: uint64_t _size; // agency size (default: 5) diff --git a/arangod/Cluster/ClusterFeature.cpp b/arangod/Cluster/ClusterFeature.cpp index b6d66318f1..82a9be79f0 100644 --- a/arangod/Cluster/ClusterFeature.cpp +++ b/arangod/Cluster/ClusterFeature.cpp @@ -461,7 +461,7 @@ void ClusterFeature::start() { dispatcher->buildAqlQueue(); } -void ClusterFeature::stop() { +void ClusterFeature::unprepare() { if (_enableCluster) { if (_heartbeatThread != nullptr) { _heartbeatThread->beginShutdown(); diff --git a/arangod/Cluster/ClusterFeature.h b/arangod/Cluster/ClusterFeature.h index 1b76ecf956..cbb0abe161 100644 --- a/arangod/Cluster/ClusterFeature.h +++ b/arangod/Cluster/ClusterFeature.h @@ -42,7 +42,7 @@ class ClusterFeature : public application_features::ApplicationFeature { void validateOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; private: std::vector _agencyEndpoints; diff --git a/arangod/Dispatcher/Dispatcher.cpp b/arangod/Dispatcher/Dispatcher.cpp index 3c45027784..d55594c1ba 100644 --- a/arangod/Dispatcher/Dispatcher.cpp +++ b/arangod/Dispatcher/Dispatcher.cpp @@ -24,10 +24,10 @@ #include "Dispatcher.h" -#include "Logger/Logger.h" #include "Dispatcher/DispatcherQueue.h" #include "Dispatcher/DispatcherThread.h" #include "Dispatcher/Job.h" +#include "Logger/Logger.h" using namespace arangodb::basics; using namespace arangodb::rest; @@ -59,21 +59,22 @@ void Dispatcher::addStandardQueue(size_t nrThreads, size_t nrExtraThreads, size_t maxSize) { TRI_ASSERT(_queues[STANDARD_QUEUE] == nullptr); - _queues[STANDARD_QUEUE] = - new DispatcherQueue(_scheduler, this, STANDARD_QUEUE, - CreateDispatcherThread, nrThreads, nrExtraThreads, maxSize); + _queues[STANDARD_QUEUE] = new DispatcherQueue( + _scheduler, this, STANDARD_QUEUE, CreateDispatcherThread, nrThreads, + nrExtraThreads, maxSize); } //////////////////////////////////////////////////////////////////////////////// /// @brief adds the AQL queue (used for the cluster) //////////////////////////////////////////////////////////////////////////////// -void Dispatcher::addAQLQueue(size_t nrThreads, size_t nrExtraThreads, +void Dispatcher::addAQLQueue(size_t nrThreads, size_t nrExtraThreads, size_t maxSize) { TRI_ASSERT(_queues[AQL_QUEUE] == nullptr); - _queues[AQL_QUEUE] = new DispatcherQueue( - _scheduler, this, AQL_QUEUE, CreateDispatcherThread, nrThreads, nrExtraThreads, maxSize); + _queues[AQL_QUEUE] = + new DispatcherQueue(_scheduler, this, AQL_QUEUE, CreateDispatcherThread, + nrThreads, nrExtraThreads, maxSize); } //////////////////////////////////////////////////////////////////////////////// @@ -100,7 +101,8 @@ int Dispatcher::addJob(std::unique_ptr& job, bool startThread) { // log success, but do this BEFORE the real add, because the addJob might // execute // and delete the job before we have a chance to log something - LOG(TRACE) << "added job " << (void*)(job.get()) << " to queue '" << qnr << "'"; + LOG(TRACE) << "added job " << (void*)(job.get()) << " to queue '" << qnr + << "'"; // add the job to the list of ready jobs return queue->addJob(job, startThread); @@ -152,8 +154,6 @@ void Dispatcher::shutdown() { LOG(DEBUG) << "shutting down the dispatcher"; for (auto queue : _queues) { - - if (queue != nullptr) { queue->shutdown(); } @@ -169,7 +169,11 @@ void Dispatcher::reportStatus() { DispatcherQueue* queue = _queues[i]; if (queue != nullptr) { - LOG(INFO) << "dispatcher queue '" << i << "': initial = " << queue->_nrThreads << ", running = " << queue->_nrRunning.load() << ", waiting = " << queue->_nrWaiting.load() << ", blocked = " << queue->_nrBlocked.load(); + LOG(INFO) << "dispatcher queue '" << i + << "': initial = " << queue->_nrThreads + << ", running = " << queue->_nrRunning.load() + << ", waiting = " << queue->_nrWaiting.load() + << ", blocked = " << queue->_nrBlocked.load(); } } } diff --git a/arangod/Dispatcher/DispatcherFeature.cpp b/arangod/Dispatcher/DispatcherFeature.cpp index 56fca43588..565f316c2d 100644 --- a/arangod/Dispatcher/DispatcherFeature.cpp +++ b/arangod/Dispatcher/DispatcherFeature.cpp @@ -57,7 +57,9 @@ DispatcherFeature::DispatcherFeature( } DispatcherFeature::~DispatcherFeature() { - delete _dispatcher; + if (_dispatcher != nullptr) { + delete _dispatcher; + } } void DispatcherFeature::collectOptions( diff --git a/arangod/RestServer/BootstrapFeature.cpp b/arangod/RestServer/BootstrapFeature.cpp index 0095d9ceb5..2fb139c153 100644 --- a/arangod/RestServer/BootstrapFeature.cpp +++ b/arangod/RestServer/BootstrapFeature.cpp @@ -162,7 +162,7 @@ void BootstrapFeature::start() { _isReady = true; } -void BootstrapFeature::stop() { +void BootstrapFeature::unprepare() { auto server = ApplicationServer::getFeature("DatabaseServer"); TRI_server_t* s = server->SERVER; diff --git a/arangod/RestServer/BootstrapFeature.h b/arangod/RestServer/BootstrapFeature.h index 21f9ddbb99..5813102671 100644 --- a/arangod/RestServer/BootstrapFeature.h +++ b/arangod/RestServer/BootstrapFeature.h @@ -33,7 +33,7 @@ class BootstrapFeature final : public application_features::ApplicationFeature { public: void collectOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; bool isReady() const { return _isReady; diff --git a/arangod/RestServer/ConsoleFeature.cpp b/arangod/RestServer/ConsoleFeature.cpp index 13e6f61381..184aa07bdb 100644 --- a/arangod/RestServer/ConsoleFeature.cpp +++ b/arangod/RestServer/ConsoleFeature.cpp @@ -60,7 +60,7 @@ void ConsoleFeature::start() { _consoleThread->start(); } -void ConsoleFeature::stop() { +void ConsoleFeature::unprepare() { if (_operationMode != OperationMode::MODE_CONSOLE) { return; } @@ -73,8 +73,6 @@ void ConsoleFeature::stop() { while (_consoleThread->isRunning() && ++iterations < 30) { usleep(100 * 1000); // spin while console is still needed } -} -void ConsoleFeature::unprepare() { std::cout << std::endl << TRI_BYE_MESSAGE << std::endl; } diff --git a/arangod/RestServer/ConsoleFeature.h b/arangod/RestServer/ConsoleFeature.h index 63e9f56609..961d6d1803 100644 --- a/arangod/RestServer/ConsoleFeature.h +++ b/arangod/RestServer/ConsoleFeature.h @@ -36,7 +36,6 @@ class ConsoleFeature final : public application_features::ApplicationFeature { public: void start() override final; - void stop() override final; void unprepare() override final; private: diff --git a/arangod/Scheduler/SchedulerFeature.cpp b/arangod/Scheduler/SchedulerFeature.cpp index 43dc75634f..5218e53053 100644 --- a/arangod/Scheduler/SchedulerFeature.cpp +++ b/arangod/Scheduler/SchedulerFeature.cpp @@ -58,6 +58,12 @@ SchedulerFeature::SchedulerFeature( startsAfter("WorkMonitor"); } +SchedulerFeature::~SchedulerFeature() { + if (_scheduler != nullptr) { + delete _scheduler; + } +} + void SchedulerFeature::collectOptions( std::shared_ptr options) { options->addSection("scheduler", "Configure the I/O scheduler"); @@ -145,11 +151,7 @@ void SchedulerFeature::stop() { } void SchedulerFeature::unprepare() { - if (_scheduler != nullptr) { - delete _scheduler; - _scheduler = nullptr; - SCHEDULER = nullptr; - } + SCHEDULER = nullptr; } #ifdef _WIN32 diff --git a/arangod/Scheduler/SchedulerFeature.h b/arangod/Scheduler/SchedulerFeature.h index 755fd19445..c739db6969 100644 --- a/arangod/Scheduler/SchedulerFeature.h +++ b/arangod/Scheduler/SchedulerFeature.h @@ -40,6 +40,7 @@ class SchedulerFeature final : public application_features::ApplicationFeature { public: explicit SchedulerFeature(application_features::ApplicationServer* server); + ~SchedulerFeature(); public: void collectOptions(std::shared_ptr) override final; diff --git a/arangod/Statistics/StatisticsFeature.cpp b/arangod/Statistics/StatisticsFeature.cpp index 959cc795cb..8879f91e36 100644 --- a/arangod/Statistics/StatisticsFeature.cpp +++ b/arangod/Statistics/StatisticsFeature.cpp @@ -54,7 +54,7 @@ void StatisticsFeature::start() { TRI_InitializeStatistics(); } -void StatisticsFeature::stop() { +void StatisticsFeature::unprepare() { TRI_ShutdownStatistics(); STATISTICS = nullptr; } diff --git a/arangod/Statistics/StatisticsFeature.h b/arangod/Statistics/StatisticsFeature.h index 854eb3b06c..9054da2803 100644 --- a/arangod/Statistics/StatisticsFeature.h +++ b/arangod/Statistics/StatisticsFeature.h @@ -42,7 +42,7 @@ class StatisticsFeature final public: void collectOptions(std::shared_ptr) override final; void start() override final; - void stop() override final; + void unprepare() override final; public: void disableStatistics() { _statistics = false; } diff --git a/arangod/Wal/LogfileManager.cpp b/arangod/Wal/LogfileManager.cpp index 49464e9ae4..2c34287e1e 100644 --- a/arangod/Wal/LogfileManager.cpp +++ b/arangod/Wal/LogfileManager.cpp @@ -454,7 +454,7 @@ bool LogfileManager::open() { return true; } -void LogfileManager::stop() { +void LogfileManager::unprepare() { _shutdown = 1; LOG(TRACE) << "shutting down WAL"; diff --git a/arangod/Wal/LogfileManager.h b/arangod/Wal/LogfileManager.h index c2b2fa9b60..91ab218124 100644 --- a/arangod/Wal/LogfileManager.h +++ b/arangod/Wal/LogfileManager.h @@ -116,7 +116,7 @@ class LogfileManager final : public application_features::ApplicationFeature { void validateOptions(std::shared_ptr) override final; void prepare() override final; void start() override final; - void stop() override final; + void unprepare() override final; public: // run the recovery procedure diff --git a/lib/ApplicationFeatures/ApplicationServer.cpp b/lib/ApplicationFeatures/ApplicationServer.cpp index 3eb5ce3b84..c91caaa758 100644 --- a/lib/ApplicationFeatures/ApplicationServer.cpp +++ b/lib/ApplicationFeatures/ApplicationServer.cpp @@ -545,7 +545,7 @@ void ApplicationServer::stop() { auto feature = *it; LOG_TOPIC(TRACE, Logger::STARTUP) << feature->name() << "::stop"; - // feature->stop(); + feature->stop(); feature->state(FeatureState::STOPPED); reportFeatureProgress(_state, feature->name()); } From 823e4224bdeabb2ab8066faa4e53c61b717f3663 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Jun 2016 23:54:43 +0200 Subject: [PATCH 13/19] added SHORTEST_PATH to keywords list --- Documentation/Books/AQL/Fundamentals/Syntax.mdpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/Books/AQL/Fundamentals/Syntax.mdpp b/Documentation/Books/AQL/Fundamentals/Syntax.mdpp index 0ad6210053..034aada9d3 100644 --- a/Documentation/Books/AQL/Fundamentals/Syntax.mdpp +++ b/Documentation/Books/AQL/Fundamentals/Syntax.mdpp @@ -118,6 +118,7 @@ The complete list of keywords is currently:
  • REMOVE
  • REPLACE
  • RETURN
  • +
  • SHORTEST_PATH
  • SORT
  • TRUE
  • UPDATE
  • From d87aa2b4203fa5c8bb2f612a98d309b006f80662 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Tue, 7 Jun 2016 00:11:10 +0200 Subject: [PATCH 14/19] added ctor for AuthResult to prevent UB --- arangod/VocBase/AuthInfo.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arangod/VocBase/AuthInfo.h b/arangod/VocBase/AuthInfo.h index eb5cfca1c3..77c0d195e2 100644 --- a/arangod/VocBase/AuthInfo.h +++ b/arangod/VocBase/AuthInfo.h @@ -84,6 +84,7 @@ class AuthEntry { class AuthResult { public: + AuthResult() : _authorized(false), _mustChange(false) {} std::string _username; bool _authorized; bool _mustChange; From 2f1993d0a4194678b8b85b588c28cbc11bf007e3 Mon Sep 17 00:00:00 2001 From: Andreas Streichardt Date: Tue, 7 Jun 2016 09:11:36 +0200 Subject: [PATCH 15/19] Merge with local version --- Documentation/Books/Manual/Deployment/Mesos.mdpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/Books/Manual/Deployment/Mesos.mdpp b/Documentation/Books/Manual/Deployment/Mesos.mdpp index de3d4c71fb..48d0e8c3a5 100644 --- a/Documentation/Books/Manual/Deployment/Mesos.mdpp +++ b/Documentation/Books/Manual/Deployment/Mesos.mdpp @@ -1,6 +1,6 @@ !SECTION Distributed deployment using Apache Mesos -TODO: Intro (vom Rechner) +ArangoDB has a sophisticated yet easy to use cluster mode. To leverage the full cluster feature set (monitoring, scaling and failover) you have to run ArangoDB on some kind of cluster management system. Currently ArangoDB relies on Apache Mesos in that matter. Mesos is a cluster operating system which is powers some of the worlds biggest datacenters running several thousands of nodes. Running Arango !SUBSECTION DC/OS @@ -151,4 +151,4 @@ The easiest is to simply delete arangodb and then deploy the cleanup-framework ( !SUBSECTION Configuration options -The Arangodb Mesos framework has a ton of different options which are listed and described here: https://github.com/arangodb/arangodb-mesos-framework/tree/3.0 \ No newline at end of file +The Arangodb Mesos framework has a ton of different options which are listed and described here: https://github.com/arangodb/arangodb-mesos-framework/tree/3.0 From 50ea64a5fba93bacfac4ab9efc7f2603193f530b Mon Sep 17 00:00:00 2001 From: Andreas Streichardt Date: Tue, 7 Jun 2016 10:19:57 +0200 Subject: [PATCH 16/19] Change agency id to be 0 by default in --help --- arangod/Agency/AgencyFeature.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arangod/Agency/AgencyFeature.cpp b/arangod/Agency/AgencyFeature.cpp index 872e788f63..b968c28e0d 100644 --- a/arangod/Agency/AgencyFeature.cpp +++ b/arangod/Agency/AgencyFeature.cpp @@ -38,7 +38,7 @@ using namespace arangodb::rest; AgencyFeature::AgencyFeature(application_features::ApplicationServer* server) : ApplicationFeature(server, "Agency"), _size(1), - _agentId((std::numeric_limits::max)()), + _agentId(0), _minElectionTimeout(0.15), _maxElectionTimeout(2.0), _notify(false), @@ -104,7 +104,8 @@ void AgencyFeature::collectOptions(std::shared_ptr options) { } void AgencyFeature::validateOptions(std::shared_ptr options) { - if (_agentId == (std::numeric_limits::max)()) { + ProgramOptions::ProcessingResult const& result = options->processingResult(); + if (!result.touched("agency.id")) { disable(); return; } From 7bceb5cd31f00fbcf17846f70f7f6d600c588d15 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Tue, 7 Jun 2016 10:44:01 +0200 Subject: [PATCH 17/19] micro optimizations --- arangod/Aql/AqlItemBlock.h | 30 ++++++------------------ arangod/Aql/AqlValue.h | 12 +++++----- arangod/Aql/EnumerateCollectionBlock.cpp | 2 +- 3 files changed, 14 insertions(+), 30 deletions(-) diff --git a/arangod/Aql/AqlItemBlock.h b/arangod/Aql/AqlItemBlock.h index 45b3e195b7..f70f2008f0 100644 --- a/arangod/Aql/AqlItemBlock.h +++ b/arangod/Aql/AqlItemBlock.h @@ -85,17 +85,7 @@ class AqlItemBlock { // First update the reference count, if this fails, the value is empty if (value.requiresDestruction()) { - auto it = _valueCount.find(value); - - if (it == _valueCount.end()) { - TRI_IF_FAILURE("AqlItemBlock::setValue") { - THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); - } - _valueCount.emplace(value, 1); - } else { - TRI_ASSERT(it->second > 0); - ++(it->second); - } + ++_valueCount[value]; } _data[index * _nrRegs + varNr] = value; @@ -106,8 +96,7 @@ class AqlItemBlock { /// use with caution only in special situations when it can be ensured that /// no one else will be pointing to the same value void destroyValue(size_t index, RegisterId varNr) { - size_t const pos = index * _nrRegs + varNr; - auto& element = _data[pos]; + auto& element = _data[index * _nrRegs + varNr]; if (element.requiresDestruction()) { auto it = _valueCount.find(element); @@ -130,8 +119,7 @@ class AqlItemBlock { /// @brief eraseValue, erase the current value of a register not freeing it /// this is used if the value is stolen and later released from elsewhere void eraseValue(size_t index, RegisterId varNr) { - size_t const pos = index * _nrRegs + varNr; - auto& element = _data[pos]; + auto& element = _data[index * _nrRegs + varNr]; if (element.requiresDestruction()) { auto it = _valueCount.find(element); @@ -149,7 +137,7 @@ class AqlItemBlock { element.erase(); } - /// @brief eraseValue, erase the current value of a register not freeing it + /// @brief eraseValue, erase the current value of all values, not freeing them. /// this is used if the value is stolen and later released from elsewhere void eraseAll() { for (auto& it : _data) { @@ -176,13 +164,9 @@ class AqlItemBlock { /// the same value again. Note that once you do this for a single AqlValue /// you should delete the AqlItemBlock soon, because the stolen AqlValues /// might be deleted at any time! - void steal(AqlValue const& v) { - if (v.requiresDestruction()) { - auto it = _valueCount.find(v); - - if (it != _valueCount.end()) { - _valueCount.erase(it); - } + void steal(AqlValue const& value) { + if (value.requiresDestruction()) { + _valueCount.erase(value); } } diff --git a/arangod/Aql/AqlValue.h b/arangod/Aql/AqlValue.h index c9e5332bb7..54815891a9 100644 --- a/arangod/Aql/AqlValue.h +++ b/arangod/Aql/AqlValue.h @@ -226,13 +226,13 @@ struct AqlValue final { ~AqlValue() = default; /// @brief whether or not the value must be destroyed - inline bool requiresDestruction() const { + inline bool requiresDestruction() const noexcept { AqlValueType t = type(); return (t == VPACK_MANAGED || t == DOCVEC || t == RANGE); } /// @brief whether or not the value is empty / none - inline bool isEmpty() const { + inline bool isEmpty() const noexcept { if (type() != VPACK_INLINE) { return false; } @@ -240,12 +240,12 @@ struct AqlValue final { } /// @brief whether or not the value is a range - inline bool isRange() const { + inline bool isRange() const noexcept { return type() == RANGE; } /// @brief whether or not the value is a docvec - inline bool isDocvec() const { + inline bool isDocvec() const noexcept { return type() == DOCVEC; } @@ -352,7 +352,7 @@ struct AqlValue final { AqlValue clone() const; /// @brief invalidates/resets a value to None, not freeing any memory - void erase() { + void erase() noexcept { _data.internal[0] = '\x00'; setType(AqlValueType::VPACK_INLINE); } @@ -378,7 +378,7 @@ struct AqlValue final { /// @brief Returns the type of this value. If true it uses an external pointer /// if false it uses the internal data structure - inline AqlValueType type() const { + inline AqlValueType type() const noexcept { return static_cast(_data.internal[sizeof(_data.internal) - 1]); } diff --git a/arangod/Aql/EnumerateCollectionBlock.cpp b/arangod/Aql/EnumerateCollectionBlock.cpp index 69906c8a98..8f65355a3f 100644 --- a/arangod/Aql/EnumerateCollectionBlock.cpp +++ b/arangod/Aql/EnumerateCollectionBlock.cpp @@ -199,7 +199,7 @@ AqlItemBlock* EnumerateCollectionBlock::getSome(size_t, // atLeast, for (size_t j = 0; j < toSend; j++) { if (j > 0) { - // re-use already copied aqlvalues + // re-use already copied AQLValues for (RegisterId i = 0; i < curRegs; i++) { res->setValue(j, i, res->getValueReference(0, i)); // Note: if this throws, then all values will be deleted From 80d31646222a5a504d1fb33aab5c6439c06c9ef1 Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Tue, 7 Jun 2016 09:32:47 +0000 Subject: [PATCH 18/19] state after compaction reload with no logs --- README | 95 ---------------------------------------- arangod/Agency/State.cpp | 8 +++- 2 files changed, 7 insertions(+), 96 deletions(-) diff --git a/README b/README index 47e3b03efc..e69de29bb2 100644 --- a/README +++ b/README @@ -1,95 +0,0 @@ -****** ArangoDB ****** -ArangoDB is a multi-model, open-source database with flexible data models for -documents, graphs, and key-values. Build high performance applications using a -convenient SQL-like query language or JavaScript extensions. Use ACID -transactions if you require them. Scale horizontally with a few mouse clicks. -The supported data models can be mixed in queries and allow ArangoDB to be the -aggregation point for your data. -To get started, try one of our 10 minutes tutorials in your favorite -programming language or try one of our ArangoDB_Cookbook_recipes. -For the impatient: download and install ArangoDB. Start the server arangod and -point your browser to http://127.0.0.1:8529/. -***** Key Features in ArangoDB ***** - * Multi-Model: Documents, graphs and key-value pairs — model your data as - you see fit for your application. - * Joins: Conveniently join what belongs together for flexible ad-hoc - querying, less data redundancy. - * Transactions: Easy application development keeping your data consistent - and safe. No hassle in your client. -Here is an AQL query that makes use of all those features: -[AQL Query Example] -Joins and transactions are key features for flexible, secure data designs, -widely used in relational databases but lacking in many NoSQL products. -However, there is no need to forego them in ArangoDB. You decide how and when -to use joins and strong consistency guarantees, without sacrificing performance -and scalability. -Furthermore, ArangoDB offers a JavaScript framework called Foxx that is -executed in the database server with direct access to the data. Build your own -data-centric microservices with a few lines of code: -Microservice Example -[Microservice Example] -By extending the HTTP API with user code written in JavaScript, ArangoDB can be -turned into a strict schema-enforcing persistence engine. -Next step, bundle your Foxx application as a docker_container and get it -running in the cloud. -Other features of ArangoDB include: - * Schema-free schemata let you combine the space efficiency of MySQL with - the performance power of NoSQL - * Use a data-centric microservices approach with ArangoDB Foxx and fuse - your application-logic and database together for maximal throughput - * JavaScript for all: no language zoo, you can use one language from your - browser to your back-end - * ArangoDB is multi-threaded - exploit the power of all your cores - * Flexible data modeling: model your data as combination of key-value - pairs, documents or graphs - perfect for social relations - * Free index choice: use the correct index for your problem, be it a skip - list or a fulltext search - * Configurable durability: let the application decide if it needs more - durability or more performance - * Powerful query language (AQL) to retrieve and modify data - * Transactions: run queries on multiple documents or collections with - optional transactional consistency and isolation - * Replication and Sharding: set up the database in a master-slave - configuration or spread bigger datasets across multiple servers - * It is open source (Apache License 2.0) -For more in-depth information read the design_goals_of_ArangoDB -***** Latest Release - ArangoDB 2.8 ***** -The What's_new_in_ArangoDB_2.8 can be found in the documentation. -AQL Graph Traversals / Pattern Matching: AQL offers a new feature to traverse -over a graph without writing JavaScript functions but with all the other -features you know from AQL. For this purpose, a special version of FOR -variable-name IN expression has been introduced. -The added Array Indexes are a major improvement to ArangoDB that you will love -and never want to miss again. Hash indexes and skiplist indexes can now be -defined for array values as well, so it’s freaking fast to access documents -by individual array values. -Additional, there is a cool new aggregation feature that was added after the -beta releases. AQL introduces the keyword AGGREGATE for use in AQL COLLECT -statements. Using AGGREGATE allows more efficient aggregation (incrementally -while building the groups) than previous versions of AQL, which built group -aggregates afterwards from the total of all group values -Optimizer improvements: The AQL query optimizer can now use indexes if multiple -filter conditions on attributes of the same collection are combined with -logical ORs, and if the usage of indexes would completely cover these -conditions. -ArangoDB 2.8 now has an automatic deadlock detection for transactions. A -deadlock is a situation in which two or more concurrent operations (user -transactions or AQL queries) try to access the same resources (collections, -documents) and need to wait for the others to finish, but none of them can make -any progress. -Foxx Improvements -The module resolution used by require now behaves more like in node.js. The -org/arangodb/request module now returns response bodies for error responses by -default. The old behavior of not returning bodies for error responses can be -re-enabled by explicitly setting the option returnBodyOnError to false. -***** More Information ***** -Please check the Installation_Manual for installation and compilation -instructions. -The User_Manual has an introductory chapter showing the basic operations of -ArangoDB. -***** Stay in Contact ***** -We really appreciate feature requests and bug reports. Please use our Github -issue tracker for reporting them: -https://github.com/arangodb/arangodb/issues -You can use the Google group for improvements, feature requests, comments -http://www.arangodb.com/community diff --git a/arangod/Agency/State.cpp b/arangod/Agency/State.cpp index 91dc2afa08..44f805d3c4 100644 --- a/arangod/Agency/State.cpp +++ b/arangod/Agency/State.cpp @@ -193,7 +193,13 @@ std::vector State::slices(arangodb::consensus::index_t start, } for (size_t i = start - _cur; i <= end - _cur; ++i) { // TODO:: Check bounds - slices.push_back(VPackSlice(_log[i].entry->data())); + try { + slices.push_back(VPackSlice(_log.at(i).entry->data())); + } catch (std::exception const& e) { + break; + LOG_TOPIC(ERR, Logger::AGENCY) << start-_cur << " " << end-_cur << " " << i << " " << _log.size(); + } + } return slices; From 274cfeb5c2bc253dc8e6d26bdd134284c3cbdf11 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Tue, 7 Jun 2016 12:20:03 +0200 Subject: [PATCH 19/19] added regex operators ~= and !~ --- arangod/Aql/grammar.cpp | 2234 ++++++++++--------- arangod/Aql/grammar.h | 80 +- arangod/Aql/grammar.y | 18 +- arangod/Aql/tokens.cpp | 576 ++--- arangod/Aql/tokens.ll | 8 + js/server/tests/aql/aql-functions-string.js | 7 +- js/server/tests/aql/aql-regex.js | 113 + 7 files changed, 1619 insertions(+), 1417 deletions(-) create mode 100644 js/server/tests/aql/aql-regex.js diff --git a/arangod/Aql/grammar.cpp b/arangod/Aql/grammar.cpp index 24219e707a..7664d49c2e 100644 --- a/arangod/Aql/grammar.cpp +++ b/arangod/Aql/grammar.cpp @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.2. */ +/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.2" +#define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -147,46 +147,48 @@ extern int Aqldebug; T_AND = 288, T_OR = 289, T_NIN = 290, - T_EQ = 291, - T_NE = 292, - T_LT = 293, - T_GT = 294, - T_LE = 295, - T_GE = 296, - T_LIKE = 297, - T_PLUS = 298, - T_MINUS = 299, - T_TIMES = 300, - T_DIV = 301, - T_MOD = 302, - T_QUESTION = 303, - T_COLON = 304, - T_SCOPE = 305, - T_RANGE = 306, - T_COMMA = 307, - T_OPEN = 308, - T_CLOSE = 309, - T_OBJECT_OPEN = 310, - T_OBJECT_CLOSE = 311, - T_ARRAY_OPEN = 312, - T_ARRAY_CLOSE = 313, - T_OUTBOUND = 314, - T_INBOUND = 315, - T_ANY = 316, - T_ALL = 317, - T_NONE = 318, - UMINUS = 319, - UPLUS = 320, - FUNCCALL = 321, - REFERENCE = 322, - INDEXED = 323, - EXPANSION = 324 + T_REGEX_MATCH = 291, + T_REGEX_NON_MATCH = 292, + T_EQ = 293, + T_NE = 294, + T_LT = 295, + T_GT = 296, + T_LE = 297, + T_GE = 298, + T_LIKE = 299, + T_PLUS = 300, + T_MINUS = 301, + T_TIMES = 302, + T_DIV = 303, + T_MOD = 304, + T_QUESTION = 305, + T_COLON = 306, + T_SCOPE = 307, + T_RANGE = 308, + T_COMMA = 309, + T_OPEN = 310, + T_CLOSE = 311, + T_OBJECT_OPEN = 312, + T_OBJECT_CLOSE = 313, + T_ARRAY_OPEN = 314, + T_ARRAY_CLOSE = 315, + T_OUTBOUND = 316, + T_INBOUND = 317, + T_ANY = 318, + T_ALL = 319, + T_NONE = 320, + UMINUS = 321, + UPLUS = 322, + FUNCCALL = 323, + REFERENCE = 324, + INDEXED = 325, + EXPANSION = 326 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; + union YYSTYPE { #line 19 "Aql/grammar.y" /* yacc.c:355 */ @@ -199,8 +201,10 @@ union YYSTYPE bool boolval; int64_t intval; -#line 203 "Aql/grammar.cpp" /* yacc.c:355 */ +#line 205 "Aql/grammar.cpp" /* yacc.c:355 */ }; + +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif @@ -397,7 +401,7 @@ static AstNode const* GetIntoExpression(AstNode const* node) { } -#line 401 "Aql/grammar.cpp" /* yacc.c:358 */ +#line 405 "Aql/grammar.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -641,21 +645,21 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 7 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1176 +#define YYLAST 1247 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 71 +#define YYNTOKENS 73 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 90 /* YYNRULES -- Number of rules. */ -#define YYNRULES 212 +#define YYNRULES 214 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 353 +#define YYNSTATES 357 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 324 +#define YYMAXUTOK 326 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -668,7 +672,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 72, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -696,35 +700,35 @@ static const yytype_uint8 yytranslate[] = 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69 + 65, 66, 67, 68, 69, 70, 71 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 364, 364, 367, 378, 382, 386, 393, 395, 395, - 406, 411, 416, 418, 421, 424, 427, 430, 436, 438, - 443, 445, 447, 449, 451, 453, 455, 457, 459, 461, - 463, 468, 474, 479, 484, 492, 500, 505, 507, 512, - 519, 529, 529, 543, 552, 563, 593, 660, 685, 718, - 720, 725, 732, 735, 738, 747, 761, 778, 778, 792, - 792, 802, 802, 813, 816, 822, 828, 831, 834, 837, - 843, 848, 855, 863, 866, 872, 882, 892, 900, 911, - 916, 924, 935, 940, 943, 949, 949, 1000, 1003, 1006, - 1012, 1012, 1022, 1028, 1031, 1034, 1037, 1040, 1043, 1049, - 1052, 1068, 1068, 1077, 1077, 1087, 1090, 1093, 1099, 1102, - 1105, 1108, 1111, 1114, 1117, 1120, 1123, 1126, 1129, 1132, - 1135, 1138, 1141, 1144, 1150, 1153, 1156, 1159, 1162, 1165, - 1168, 1171, 1177, 1183, 1185, 1190, 1193, 1193, 1209, 1212, - 1218, 1221, 1227, 1227, 1236, 1238, 1243, 1246, 1252, 1255, - 1269, 1269, 1278, 1280, 1285, 1287, 1292, 1306, 1310, 1319, - 1326, 1329, 1335, 1338, 1344, 1347, 1350, 1356, 1359, 1365, - 1368, 1376, 1380, 1391, 1395, 1402, 1407, 1407, 1415, 1424, - 1433, 1436, 1439, 1445, 1448, 1454, 1486, 1489, 1492, 1499, - 1509, 1509, 1522, 1537, 1551, 1565, 1565, 1608, 1611, 1617, - 1624, 1634, 1637, 1640, 1643, 1646, 1652, 1655, 1658, 1668, - 1674, 1677, 1682 + 0, 367, 367, 370, 381, 385, 389, 396, 398, 398, + 409, 414, 419, 421, 424, 427, 430, 433, 439, 441, + 446, 448, 450, 452, 454, 456, 458, 460, 462, 464, + 466, 471, 477, 482, 487, 495, 503, 508, 510, 515, + 522, 532, 532, 546, 555, 566, 596, 663, 688, 721, + 723, 728, 735, 738, 741, 750, 764, 781, 781, 795, + 795, 805, 805, 816, 819, 825, 831, 834, 837, 840, + 846, 851, 858, 866, 869, 875, 885, 895, 903, 914, + 919, 927, 938, 943, 946, 952, 952, 1003, 1006, 1009, + 1015, 1015, 1025, 1031, 1034, 1037, 1040, 1043, 1046, 1052, + 1055, 1071, 1071, 1080, 1080, 1090, 1093, 1096, 1102, 1105, + 1108, 1111, 1114, 1117, 1120, 1123, 1126, 1129, 1132, 1135, + 1138, 1141, 1144, 1147, 1153, 1159, 1166, 1169, 1172, 1175, + 1178, 1181, 1184, 1187, 1193, 1199, 1201, 1206, 1209, 1209, + 1225, 1228, 1234, 1237, 1243, 1243, 1252, 1254, 1259, 1262, + 1268, 1271, 1285, 1285, 1294, 1296, 1301, 1303, 1308, 1322, + 1326, 1335, 1342, 1345, 1351, 1354, 1360, 1363, 1366, 1372, + 1375, 1381, 1384, 1392, 1396, 1407, 1411, 1418, 1423, 1423, + 1431, 1440, 1449, 1452, 1455, 1461, 1464, 1470, 1502, 1505, + 1508, 1515, 1525, 1525, 1538, 1553, 1567, 1581, 1581, 1624, + 1627, 1633, 1640, 1650, 1653, 1656, 1659, 1662, 1668, 1671, + 1674, 1684, 1690, 1693, 1698 }; #endif @@ -745,11 +749,12 @@ static const char *const yytname[] = "\"quoted string\"", "\"integer number\"", "\"number\"", "\"bind parameter\"", "\"assignment\"", "\"not operator\"", "\"and operator\"", "\"or operator\"", "\"not in operator\"", - "\"== operator\"", "\"!= operator\"", "\"< operator\"", "\"> operator\"", - "\"<= operator\"", "\">= operator\"", "\"like operator\"", - "\"+ operator\"", "\"- operator\"", "\"* operator\"", "\"/ operator\"", - "\"% operator\"", "\"?\"", "\":\"", "\"::\"", "\"..\"", "\",\"", "\"(\"", - "\")\"", "\"{\"", "\"}\"", "\"[\"", "\"]\"", "\"outbound modifier\"", + "\"~= operator\"", "\"~! operator\"", "\"== operator\"", + "\"!= operator\"", "\"< operator\"", "\"> operator\"", "\"<= operator\"", + "\">= operator\"", "\"like operator\"", "\"+ operator\"", + "\"- operator\"", "\"* operator\"", "\"/ operator\"", "\"% operator\"", + "\"?\"", "\":\"", "\"::\"", "\"..\"", "\",\"", "\"(\"", "\")\"", "\"{\"", + "\"}\"", "\"[\"", "\"]\"", "\"outbound modifier\"", "\"inbound modifier\"", "\"any modifier\"", "\"all modifier\"", "\"none modifier\"", "UMINUS", "UPLUS", "FUNCCALL", "REFERENCE", "INDEXED", "EXPANSION", "'.'", "$accept", "with_collection", @@ -792,16 +797,16 @@ static const yytype_uint16 yytoknum[] = 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 46 + 325, 326, 46 }; # endif -#define YYPACT_NINF -303 +#define YYPACT_NINF -305 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-303))) + (!!((Yystate) == (-305))) -#define YYTABLE_NINF -211 +#define YYTABLE_NINF -213 #define yytable_value_is_error(Yytable_value) \ 0 @@ -810,42 +815,42 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - -10, -303, -303, 53, 5, -303, 396, -303, -303, -303, - -303, -14, -303, 52, 52, 1083, 132, 24, -303, 290, - 1083, 1083, 1083, 1083, -303, -303, -303, -303, -303, -303, - 185, -303, -303, -303, -303, 17, 22, 27, 30, 34, - 5, -303, -303, -1, 42, -303, 26, -303, -303, -303, - 50, -303, -303, -303, 1083, 73, 1083, 1083, 1083, -303, - -303, 853, 113, -303, -303, -303, -303, -303, -303, -303, - 70, -303, -303, -303, -303, -303, 853, 79, -303, 102, - 52, 134, 1083, 94, -303, -303, 593, 593, -303, 441, - -303, 481, 1083, 52, 102, 124, 134, -303, 991, 52, - 52, 1083, -303, -303, -303, -303, 630, -303, 115, 1083, - 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, - 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, -303, -303, - -303, 156, 126, -303, 1013, 57, 1083, 151, 52, 114, - -303, 119, -303, 150, 102, 131, -303, 401, 290, 1105, - 103, 102, 102, 1083, 102, 1083, 102, 667, 153, -303, - 114, 102, -303, 102, -303, -303, -303, 518, -303, 1083, - 20, -303, 853, 1048, -303, 136, 139, -303, 163, 1083, - 168, 175, -303, 177, 853, 170, 179, 1125, 926, 890, - 1125, 962, 962, 171, 171, 171, 171, 962, 174, 174, - -303, -303, -303, 704, 261, 1083, 1083, 1083, 1083, 1083, - 1083, 1083, 1083, -303, 1048, -303, 742, 184, -303, -303, - 853, 52, 119, -303, 52, 1083, -303, 1083, -303, -303, - -303, -303, -303, 344, 41, 369, -303, -303, -303, -303, - -303, -303, -303, 593, -303, 593, -303, 1083, 1083, 52, - -303, -303, 199, -303, 240, 991, 52, 853, 178, -303, - -303, 181, -303, 1083, 779, -303, 115, 1083, -303, 1083, - 1083, 1125, 1125, 962, 962, 171, 171, 171, 171, 188, - -303, -303, 238, -303, -303, 853, -303, 102, 102, 555, - 853, 192, -303, 143, -303, 195, -303, 71, -303, 518, - 1083, 237, -303, -303, 1083, 853, 202, -303, 853, 853, - 853, -303, 1083, 245, -303, -303, -303, -303, 1083, 52, - -303, -303, -303, -303, -303, 240, 991, -303, 1083, 853, - 1083, 252, 593, -303, 76, -303, 1083, 853, 816, 1083, - 201, 102, -303, 208, 240, 1083, 853, -303, -303, 76, - -303, 853, -303 + 38, -305, -305, 66, 14, -305, 215, -305, -305, -305, + -305, 17, -305, 43, 43, 1164, 1042, 213, -305, 174, + 1164, 1164, 1164, 1164, -305, -305, -305, -305, -305, -305, + 137, -305, -305, -305, -305, 3, 22, 30, 33, 39, + 14, -305, -305, -1, 34, -305, 69, -305, -305, -305, + -20, -305, -305, -305, 1164, 75, 1164, 1164, 1164, -305, + -305, 922, 42, -305, -305, -305, -305, -305, -305, -305, + -22, -305, -305, -305, -305, -305, 922, 109, -305, 130, + 43, 143, 1164, 127, -305, -305, 648, 648, -305, 527, + -305, 569, 1164, 43, 130, 156, 143, -305, 1066, 43, + 43, 1164, -305, -305, -305, -305, 687, -305, 15, 1164, + 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, + 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1164, + -305, -305, -305, 63, 159, -305, 1090, 35, 1164, 149, + 43, 134, -305, 162, -305, 194, 130, 184, -305, 445, + 174, 1188, 102, 130, 130, 1164, 130, 1164, 130, 726, + 208, -305, 134, 130, -305, 130, -305, -305, -305, 608, + -305, 1164, 4, -305, 922, 1127, -305, 185, 189, -305, + 192, 1164, 186, 193, -305, 195, 922, 188, 197, 147, + 999, 961, 147, 119, 119, 119, 119, 263, 263, 263, + 263, 119, 183, 183, -305, -305, -305, 765, 92, 1164, + 1164, 1164, 1164, 1164, 1164, 1164, 1164, -305, 1127, -305, + 805, 209, -305, -305, 922, 43, 162, -305, 43, 1164, + -305, 1164, -305, -305, -305, -305, -305, 348, 372, 411, + -305, -305, -305, -305, -305, -305, -305, 648, -305, 648, + -305, 1164, 1164, 43, -305, -305, 135, -305, 485, 1066, + 43, 922, 199, -305, -305, 204, -305, 1164, 844, -305, + 15, 1164, -305, 1164, 1164, 147, 147, 119, 119, 263, + 263, 263, 263, 207, -305, -305, 255, -305, -305, 922, + -305, 130, 130, 241, 922, 210, -305, 153, -305, 212, + -305, 118, -305, 608, 1164, 256, -305, -305, 1164, 922, + 216, -305, 922, 922, 922, -305, 1164, 261, -305, -305, + -305, -305, 1164, 43, -305, -305, -305, -305, -305, 485, + 1066, -305, 1164, 922, 1164, 286, 648, -305, 1, -305, + 1164, 922, 883, 1164, 235, 130, -305, 242, 485, 1164, + 922, -305, -305, 1, -305, 922, -305 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -853,70 +858,70 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 7, 8, 18, 0, 0, 10, 0, 1, 2, 209, + 7, 8, 18, 0, 0, 10, 0, 1, 2, 211, 4, 9, 3, 0, 0, 0, 0, 41, 61, 0, 0, 0, 0, 0, 85, 11, 19, 20, 22, 21, 52, 23, 24, 25, 12, 26, 27, 28, 29, 30, - 0, 6, 212, 0, 36, 37, 0, 203, 204, 205, - 185, 201, 199, 200, 0, 0, 0, 0, 190, 150, - 142, 35, 0, 188, 93, 94, 95, 186, 140, 141, - 97, 202, 96, 187, 90, 72, 92, 0, 59, 148, - 0, 52, 0, 70, 197, 198, 0, 0, 79, 0, - 82, 0, 0, 0, 148, 148, 52, 5, 0, 0, - 0, 0, 107, 103, 105, 106, 0, 18, 152, 144, + 0, 6, 214, 0, 36, 37, 0, 205, 206, 207, + 187, 203, 201, 202, 0, 0, 0, 0, 192, 152, + 144, 35, 0, 190, 93, 94, 95, 188, 142, 143, + 97, 204, 96, 189, 90, 72, 92, 0, 59, 150, + 0, 52, 0, 70, 199, 200, 0, 0, 79, 0, + 82, 0, 0, 0, 150, 150, 52, 5, 0, 0, + 0, 0, 107, 103, 105, 106, 0, 18, 154, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 88, 87, - 89, 0, 0, 101, 0, 0, 0, 0, 0, 0, - 43, 42, 49, 0, 148, 62, 63, 66, 0, 0, - 0, 148, 148, 0, 148, 0, 148, 0, 53, 44, - 57, 148, 47, 148, 180, 181, 182, 31, 183, 0, - 0, 38, 39, 136, 189, 0, 156, 211, 0, 0, - 0, 153, 154, 0, 146, 0, 145, 121, 109, 108, - 122, 115, 116, 117, 118, 119, 120, 123, 110, 111, - 112, 113, 114, 0, 98, 0, 0, 0, 0, 0, - 0, 0, 0, 100, 136, 160, 0, 195, 192, 193, - 91, 0, 60, 149, 0, 0, 45, 0, 67, 68, - 65, 69, 71, 185, 201, 209, 73, 206, 207, 208, - 74, 75, 76, 0, 77, 0, 80, 0, 0, 0, - 48, 46, 182, 184, 0, 0, 0, 135, 0, 138, - 18, 134, 191, 0, 0, 151, 0, 0, 143, 0, - 0, 130, 131, 124, 125, 126, 127, 128, 129, 0, - 194, 161, 162, 40, 50, 51, 64, 148, 148, 0, - 54, 58, 55, 0, 169, 175, 32, 0, 170, 0, - 0, 0, 104, 137, 136, 158, 0, 155, 157, 147, - 132, 102, 0, 164, 78, 81, 83, 84, 0, 0, - 179, 178, 176, 171, 172, 0, 0, 139, 0, 163, - 0, 167, 0, 56, 0, 33, 0, 159, 165, 0, - 0, 148, 173, 177, 0, 0, 168, 196, 86, 0, - 34, 166, 174 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 88, 87, 89, 0, 0, 101, 0, 0, 0, 0, + 0, 0, 43, 42, 49, 0, 150, 62, 63, 66, + 0, 0, 0, 150, 150, 0, 150, 0, 150, 0, + 53, 44, 57, 150, 47, 150, 182, 183, 184, 31, + 185, 0, 0, 38, 39, 138, 191, 0, 158, 213, + 0, 0, 0, 155, 156, 0, 148, 0, 147, 121, + 109, 108, 122, 124, 125, 115, 116, 117, 118, 119, + 120, 123, 110, 111, 112, 113, 114, 0, 98, 0, + 0, 0, 0, 0, 0, 0, 0, 100, 138, 162, + 0, 197, 194, 195, 91, 0, 60, 151, 0, 0, + 45, 0, 67, 68, 65, 69, 71, 187, 203, 211, + 73, 208, 209, 210, 74, 75, 76, 0, 77, 0, + 80, 0, 0, 0, 48, 46, 184, 186, 0, 0, + 0, 137, 0, 140, 18, 136, 193, 0, 0, 153, + 0, 0, 145, 0, 0, 132, 133, 126, 127, 128, + 129, 130, 131, 0, 196, 163, 164, 40, 50, 51, + 64, 150, 150, 0, 54, 58, 55, 0, 171, 177, + 32, 0, 172, 0, 0, 0, 104, 139, 138, 160, + 0, 157, 159, 149, 134, 102, 0, 166, 78, 81, + 83, 84, 0, 0, 181, 180, 178, 173, 174, 0, + 0, 141, 0, 165, 0, 169, 0, 56, 0, 33, + 0, 161, 167, 0, 0, 150, 175, 179, 0, 0, + 170, 198, 86, 0, 34, 168, 176 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -303, -7, -303, -303, -303, -303, -106, -303, -303, -303, - -303, -303, -303, -303, 162, 233, -303, -303, -303, 133, - 40, -56, -303, -303, -303, 242, -303, -303, -303, -303, - 63, -303, -303, -303, -63, -303, -303, -303, -303, -303, - -303, -303, -303, -303, -303, -303, -303, -2, -303, -303, - -303, -303, -303, -303, -303, 78, 8, -303, -303, -303, - -303, -303, -303, -303, -86, -96, -303, -303, -303, 28, - -303, -303, -303, -303, -245, -303, -302, -303, -69, -253, - -303, -303, -303, 31, -303, -9, 145, -4, -303, -8 + -305, 6, -305, -305, -305, -305, -106, -305, -305, -305, + -305, -305, -305, -305, 198, 269, -305, -305, -305, 160, + 73, -58, -305, -305, -305, 273, -305, -305, -305, -305, + 76, -305, -305, -305, -63, -305, -305, -305, -305, -305, + -305, -305, -305, -305, -305, -305, -305, -2, -305, -305, + -305, -305, -305, -305, -305, 95, 9, -305, -305, -305, + -305, -305, -305, -305, -86, -137, -305, -305, -305, 48, + -305, -305, -305, -305, -304, -305, -300, -305, -88, -257, + -305, -305, -305, -67, -305, -7, 167, -4, -305, -8 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 10, 11, 2, 4, 3, 5, 25, 6, 26, - 27, 28, 29, 44, 45, 79, 30, 80, 31, 141, - 142, 95, 291, 161, 249, 81, 138, 32, 82, 145, - 146, 230, 33, 34, 151, 35, 36, 88, 37, 90, - 38, 318, 39, 92, 131, 75, 136, 257, 62, 63, - 214, 173, 64, 65, 66, 258, 259, 260, 261, 67, - 68, 109, 185, 186, 140, 69, 108, 180, 181, 182, - 217, 313, 331, 340, 295, 343, 296, 334, 297, 169, - 70, 107, 282, 83, 71, 72, 236, 73, 183, 143 + 27, 28, 29, 44, 45, 79, 30, 80, 31, 143, + 144, 95, 295, 163, 253, 81, 140, 32, 82, 147, + 148, 234, 33, 34, 153, 35, 36, 88, 37, 90, + 38, 322, 39, 92, 133, 75, 138, 261, 62, 63, + 218, 175, 64, 65, 66, 262, 263, 264, 265, 67, + 68, 109, 187, 188, 142, 69, 108, 182, 183, 184, + 221, 317, 335, 344, 299, 347, 300, 338, 301, 171, + 70, 107, 286, 83, 71, 72, 240, 73, 185, 145 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -924,315 +929,329 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 12, 175, 300, 1, 41, 43, 46, 12, 159, 162, - 84, 98, 8, 61, 76, 85, 9, -13, 86, 87, - 89, 91, -14, 335, 152, 144, 154, -15, 156, 168, - -16, 8, 255, 97, -17, 9, 12, 77, 40, 78, - 163, -207, 350, 223, -207, -207, -207, -207, -207, -207, - -207, 99, 102, 7, 104, 105, 106, 101, 226, -207, - -207, -207, -207, -207, 223, 241, 242, -207, 244, -13, - 246, -13, 256, 336, -14, 250, -14, 251, 42, -15, - 147, -15, -16, 218, -16, 158, -17, 9, -17, 342, - 157, 170, 46, -207, 100, -207, 167, 323, 253, 172, - -99, 9, 294, -99, 352, 137, 9, 184, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 103, 134, 139, 237, - 238, 219, 216, 239, 220, 164, 165, 166, 84, 84, - 135, 176, 177, 85, 85, 178, 148, 187, 93, 74, - 160, 243, 213, 245, 303, 47, 48, 49, 50, 51, - 52, 53, 9, 132, 54, 221, 133, 254, 205, 59, - 320, 224, 179, 9, 55, 56, 57, 264, 231, 232, - 287, 225, 288, 227, 248, 58, 168, 59, -210, 60, - 262, 206, 207, 208, 209, 210, 211, 212, 77, 93, - 78, 314, 315, 271, 272, 273, 274, 275, 276, 277, - 278, -88, 263, 283, 121, 122, 123, 124, 125, 123, - 124, 125, 127, 285, 265, 147, 267, 266, 268, 281, - 253, 269, 302, 304, -88, -88, -88, -88, -88, -88, - -88, 292, 311, 312, 319, 289, 290, 322, 301, 326, - 298, 328, 110, 299, 330, 348, 293, 168, 339, 347, - 349, 305, 171, 94, 284, 308, 294, 309, 310, 341, - 9, 222, 96, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 321, - 286, 127, 279, 324, 307, 240, 0, 0, 325, 164, - 165, 252, 129, 130, 121, 122, 123, 124, 125, 0, - 329, 333, 327, 47, 48, 49, 332, 51, 52, 53, - 9, 298, 0, 0, 299, 0, 337, 0, 338, 0, - 298, 0, 0, 0, 344, 0, 0, 346, 0, 0, - 298, 0, 0, 351, -206, 298, 0, -206, -206, -206, - -206, -206, -206, -206, 0, 0, 0, 0, 0, 0, - 0, 0, -206, -206, -206, -206, -206, 0, 0, -208, - -206, 0, -208, -208, -208, -208, -208, -208, -208, 0, - 0, 0, 0, 0, 0, 0, 0, -208, -208, -208, - -208, -208, 0, 0, -99, -208, -206, -99, -206, 13, - 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, - 0, 228, 229, 110, 20, 21, 22, 23, 24, 0, - 0, -208, 0, -208, 47, 48, 49, 0, 51, 52, - 53, 9, 0, 0, 111, 112, 113, 114, 115, 116, + 12, 177, 304, -13, 227, 43, 46, 12, 161, 164, + 170, 98, 84, 61, 76, 85, 259, 41, 86, 87, + 89, 91, -14, 146, 154, 227, 156, 298, 158, 339, + -15, 9, -99, -16, 346, -99, 12, 136, 165, -17, + 8, 178, 179, 8, 9, 180, 97, 9, 354, 356, + 137, 1, 102, 99, 104, 105, 106, -13, 260, -13, + 230, 222, 166, 167, 168, 9, 7, 245, 246, 42, + 248, 40, 250, 340, 181, 209, -14, 254, -14, 255, + 149, 257, 235, 236, -15, 160, -15, -16, 100, -16, + 159, 172, 46, -17, 134, -17, 169, 135, 210, 174, + 101, 211, 212, 213, 214, 215, 216, 186, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 241, 242, + 103, 110, 243, 223, 220, 139, 224, 123, 124, 125, + 126, 127, 84, 84, 327, 85, 85, -88, 9, 189, + 77, 93, 78, 247, 113, 249, 141, 93, 307, 118, + 119, 120, 121, 225, 123, 124, 125, 126, 127, 258, + -88, 170, 129, -88, -88, -88, -88, -88, -88, 268, + 324, 150, 162, 9, 291, 217, 292, 118, 119, 120, + 121, 59, 123, 124, 125, 126, 127, 47, 48, 49, + 129, 51, 52, 53, 9, 318, 319, 275, 276, 277, + 278, 279, 280, 281, 282, 257, 228, 287, 13, 14, + 15, 16, 17, 18, 19, 229, 77, 289, 78, 149, + 125, 126, 127, 20, 21, 22, 23, 24, 231, 252, + -212, 266, 170, 267, 269, 296, 271, 270, 272, 293, + 294, 273, 305, 110, 302, 306, 285, 303, 308, 352, + 316, 320, 321, 315, 323, 309, 326, 332, 330, 312, + 334, 313, 314, 345, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 0, 0, 127, 149, 153, 150, 0, 0, 0, 0, - 0, 0, 128, 129, 130, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 0, 0, 127, 149, 155, 150, 0, 0, 0, 0, - 0, 0, 128, 129, 130, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 110, 0, 127, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 128, 129, 130, 0, 0, 0, 0, 0, - 0, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 110, 0, 127, - 0, 0, 0, 0, 0, 316, 317, 164, 165, 252, - 129, 130, 0, 0, 0, 0, 0, 0, 111, 112, + 127, 128, 343, 325, 129, 351, 353, 328, 173, 94, + 226, 288, 329, 96, 130, 131, 132, 290, 123, 124, + 125, 126, 127, 283, 333, 337, 129, 331, 311, 244, + 336, 0, 0, 0, 0, 302, 0, 0, 303, 0, + 341, 0, 342, 0, 302, 0, 0, 0, 348, 0, + 0, 350, 0, 0, 302, 0, 0, 355, -208, 302, + 0, -208, -208, -208, -208, -208, -208, -208, 0, 0, + 0, 0, 0, 0, 0, 0, -208, -208, -208, -208, + -208, 0, -209, 0, -208, -209, -209, -209, -209, -209, + -209, -209, 0, 0, 0, 0, 0, 0, 0, 0, + -209, -209, -209, -209, -209, 0, 0, 0, -209, 0, + -99, 0, -208, -99, -208, 0, 0, 0, 0, 0, + 0, -210, 0, 0, -210, -210, -210, -210, -210, -210, + -210, 0, 0, 0, 0, 0, -209, 0, -209, -210, + -210, -210, -210, -210, 0, 0, 0, -210, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 232, 233, 110, 0, 0, + 0, 0, 0, 0, 0, -210, 0, -210, 47, 48, + 49, 0, 51, 52, 53, 9, 0, 0, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 0, 149, 127, 150, 0, 0, - 0, 0, 0, 0, 0, 0, 128, 129, 130, 0, + 123, 124, 125, 126, 127, 128, 0, 110, 129, 0, + 0, 297, 0, 0, 0, 0, 0, 0, 130, 131, + 132, 298, 0, 0, 0, 9, 0, 0, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 0, 0, 129, 151, + 155, 152, 0, 0, 0, 0, 166, 167, 256, 131, + 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 0, 0, + 129, 151, 157, 152, 0, 0, 0, 0, 0, 0, + 130, 131, 132, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 110, 0, 129, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 130, 131, 132, 0, 0, 0, 0, 0, + 0, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 0, + 151, 129, 152, 0, 0, 0, 0, 0, 0, 166, + 167, 256, 131, 132, 0, 0, 0, 0, 0, 0, + 0, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 110, + 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 130, 131, 132, 0, 0, 0, 0, 0, 0, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 110, 0, + 129, 0, 0, 176, 0, 251, 0, 0, 0, 0, + 130, 131, 132, 0, 0, 0, 0, 0, 0, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 110, 0, 129, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, + 131, 132, 0, 0, 0, 0, 0, 0, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 274, 110, 129, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 130, 131, + 132, 0, 0, 0, 0, 0, 0, 0, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 110, 0, 129, 0, + 0, 0, 0, 0, 0, 284, 0, 0, 130, 131, + 132, 0, 0, 0, 0, 0, 0, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 110, 0, 129, 0, 0, + 0, 0, 0, 0, 310, 0, 0, 130, 131, 132, 0, 0, 0, 0, 0, 0, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 110, 0, 127, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 128, 129, 130, 0, 0, 0, - 0, 0, 0, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 110, - 0, 127, 0, 0, 174, 0, 247, 0, 0, 0, - 0, 128, 129, 130, 0, 0, 0, 0, 0, 0, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 110, 0, 127, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 128, 129, - 130, 0, 0, 0, 0, 0, 0, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 270, 110, 127, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 128, 129, 130, 0, 0, + 125, 126, 127, 128, 110, 0, 129, 349, 0, 0, + 0, 0, 0, 0, 0, 0, 130, 131, 132, 0, 0, 0, 0, 0, 0, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 110, 0, 127, 0, 0, 0, 0, 0, 0, - 280, 0, 0, 128, 129, 130, 0, 0, 0, 0, - 0, 0, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 110, 0, - 127, 0, 0, 0, 0, 0, 0, 306, 0, 0, - 128, 129, 130, 0, 0, 0, 0, 0, 0, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 110, 0, 127, 345, 0, - 0, 0, 0, 0, 0, 0, 0, 128, 129, 130, - 0, 0, 0, 0, 0, 0, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 110, 0, 127, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 128, 129, 130, 0, 0, 0, - 0, 0, 0, 111, 0, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 110, 0, - 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 128, 129, 130, 0, 0, 0, 0, 0, 0, - 0, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 110, 0, 0, 127, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 128, 129, 130, - 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, - 116, 117, 118, 119, 0, 121, 122, 123, 124, 125, - 0, 0, 0, 127, 47, 48, 49, 50, 51, 52, - 53, 9, 0, 54, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 55, 56, 57, 47, 48, 49, 50, - 51, 52, 53, 9, 58, 54, 59, 0, 60, 0, - 164, 165, 166, 0, 0, 55, 56, 57, 215, 0, - 0, 0, 0, 0, 0, 0, 58, 0, 59, 0, - 60, 47, 48, 49, 50, 51, 52, 53, 9, 0, - 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 56, 57, 0, 0, 0, 0, 0, 0, 0, - 0, 58, -133, 59, 0, 60, 47, 48, 49, 50, - 51, 52, 53, 9, 0, 54, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 56, 57, 47, 48, - 49, 233, 234, 52, 53, 235, 58, 54, 59, 0, - 60, 0, 0, 0, 0, 0, 0, 55, 56, 57, - 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, - 59, 0, 60, 116, 117, 118, 119, 0, 121, 122, - 123, 124, 125, 0, 0, 0, 127 + 126, 127, 128, 110, 0, 129, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 130, 131, 132, 0, 0, + 0, 0, 0, 0, 111, 0, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 110, 0, 0, 129, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 130, 131, 132, 0, 0, 0, + 0, 0, 0, 0, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 0, + 0, 0, 129, 0, 0, 0, 0, 0, 0, 74, + 0, 0, 130, 131, 132, 47, 48, 49, 50, 51, + 52, 53, 9, 0, 54, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 55, 56, 57, 47, + 48, 49, 50, 51, 52, 53, 9, 58, 54, 59, + 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 56, 57, 47, 48, 49, 50, 51, 52, 53, + 9, 58, 54, 59, 0, 60, 0, 166, 167, 168, + 0, 0, 0, 0, 55, 56, 57, 219, 0, 0, + 0, 0, 0, 0, 0, 58, 0, 59, 0, 60, + 47, 48, 49, 50, 51, 52, 53, 9, 0, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 56, 57, 0, 0, 0, 0, 0, 0, + 0, 0, 58, -135, 59, 0, 60, 47, 48, 49, + 50, 51, 52, 53, 9, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, + 57, 47, 48, 49, 237, 238, 52, 53, 239, 58, + 54, 59, 0, 60, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 56, 57, 0, 0, 0, 0, 0, + 0, 0, 0, 58, 0, 59, 0, 60 }; static const yytype_int16 yycheck[] = { - 4, 107, 255, 13, 11, 13, 14, 11, 94, 95, - 19, 12, 26, 15, 16, 19, 30, 0, 20, 21, - 22, 23, 0, 325, 87, 81, 89, 0, 91, 98, - 0, 26, 12, 40, 0, 30, 40, 13, 52, 15, - 96, 0, 344, 139, 3, 4, 5, 6, 7, 8, - 9, 52, 54, 0, 56, 57, 58, 31, 144, 18, - 19, 20, 21, 22, 160, 151, 152, 26, 154, 52, - 156, 54, 52, 326, 52, 161, 54, 163, 26, 52, - 82, 54, 52, 26, 54, 93, 52, 30, 54, 334, - 92, 99, 100, 52, 52, 54, 98, 26, 167, 101, - 50, 30, 26, 53, 349, 26, 30, 109, 110, 111, + 4, 107, 259, 0, 141, 13, 14, 11, 94, 95, + 98, 12, 19, 15, 16, 19, 12, 11, 20, 21, + 22, 23, 0, 81, 87, 162, 89, 26, 91, 329, + 0, 30, 52, 0, 338, 55, 40, 59, 96, 0, + 26, 26, 27, 26, 30, 30, 40, 30, 348, 353, + 72, 13, 54, 54, 56, 57, 58, 54, 54, 56, + 146, 26, 61, 62, 63, 30, 0, 153, 154, 26, + 156, 54, 158, 330, 59, 12, 54, 163, 56, 165, + 82, 169, 149, 150, 54, 93, 56, 54, 54, 56, + 92, 99, 100, 54, 52, 56, 98, 55, 35, 101, + 31, 38, 39, 40, 41, 42, 43, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 53, 57, 26, 26, - 27, 135, 134, 30, 136, 59, 60, 61, 147, 148, - 70, 26, 27, 147, 148, 30, 52, 149, 14, 17, - 26, 153, 26, 155, 260, 23, 24, 25, 26, 27, - 28, 29, 30, 50, 32, 14, 53, 169, 12, 55, - 27, 52, 57, 30, 42, 43, 44, 179, 147, 148, - 243, 31, 245, 52, 31, 53, 255, 55, 49, 57, - 54, 35, 36, 37, 38, 39, 40, 41, 13, 14, - 15, 287, 288, 205, 206, 207, 208, 209, 210, 211, - 212, 12, 49, 221, 43, 44, 45, 46, 47, 45, - 46, 47, 51, 225, 56, 227, 49, 52, 58, 45, - 299, 52, 54, 52, 35, 36, 37, 38, 39, 40, - 41, 249, 54, 5, 52, 247, 248, 52, 256, 12, - 254, 49, 12, 255, 9, 341, 16, 326, 6, 58, - 52, 263, 100, 30, 224, 267, 26, 269, 270, 332, - 30, 138, 30, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 293, - 227, 51, 214, 297, 266, 150, -1, -1, 300, 59, - 60, 61, 62, 63, 43, 44, 45, 46, 47, -1, - 312, 319, 304, 23, 24, 25, 318, 27, 28, 29, - 30, 325, -1, -1, 326, -1, 328, -1, 330, -1, - 334, -1, -1, -1, 336, -1, -1, 339, -1, -1, - 344, -1, -1, 345, 0, 349, -1, 3, 4, 5, - 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, -1, 18, 19, 20, 21, 22, -1, -1, 0, - 26, -1, 3, 4, 5, 6, 7, 8, 9, -1, - -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, - 21, 22, -1, -1, 50, 26, 52, 53, 54, 3, - 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, - -1, 10, 11, 12, 18, 19, 20, 21, 22, -1, - -1, 52, -1, 54, 23, 24, 25, -1, 27, 28, - 29, 30, -1, -1, 33, 34, 35, 36, 37, 38, + 122, 123, 124, 125, 126, 127, 128, 129, 26, 27, + 55, 12, 30, 137, 136, 26, 138, 45, 46, 47, + 48, 49, 149, 150, 26, 149, 150, 12, 30, 151, + 13, 14, 15, 155, 35, 157, 26, 14, 264, 40, + 41, 42, 43, 14, 45, 46, 47, 48, 49, 171, + 35, 259, 53, 38, 39, 40, 41, 42, 43, 181, + 27, 54, 26, 30, 247, 26, 249, 40, 41, 42, + 43, 57, 45, 46, 47, 48, 49, 23, 24, 25, + 53, 27, 28, 29, 30, 291, 292, 209, 210, 211, + 212, 213, 214, 215, 216, 303, 54, 225, 3, 4, + 5, 6, 7, 8, 9, 31, 13, 229, 15, 231, + 47, 48, 49, 18, 19, 20, 21, 22, 54, 31, + 51, 56, 330, 51, 58, 253, 51, 54, 60, 251, + 252, 54, 260, 12, 258, 56, 47, 259, 54, 345, + 5, 20, 21, 56, 54, 267, 54, 51, 12, 271, + 9, 273, 274, 336, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - -1, -1, 51, 12, 13, 14, -1, -1, -1, -1, - -1, -1, 61, 62, 63, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - -1, -1, 51, 12, 13, 14, -1, -1, -1, -1, - -1, -1, 61, 62, 63, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 12, -1, 51, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 61, 62, 63, -1, -1, -1, -1, -1, - -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 12, -1, 51, - -1, -1, -1, -1, -1, 20, 21, 59, 60, 61, - 62, 63, -1, -1, -1, -1, -1, -1, 33, 34, + 49, 50, 6, 297, 53, 60, 54, 301, 100, 30, + 140, 228, 304, 30, 63, 64, 65, 231, 45, 46, + 47, 48, 49, 218, 316, 323, 53, 308, 270, 152, + 322, -1, -1, -1, -1, 329, -1, -1, 330, -1, + 332, -1, 334, -1, 338, -1, -1, -1, 340, -1, + -1, 343, -1, -1, 348, -1, -1, 349, 0, 353, + -1, 3, 4, 5, 6, 7, 8, 9, -1, -1, + -1, -1, -1, -1, -1, -1, 18, 19, 20, 21, + 22, -1, 0, -1, 26, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, + 18, 19, 20, 21, 22, -1, -1, -1, 26, -1, + 52, -1, 54, 55, 56, -1, -1, -1, -1, -1, + -1, 0, -1, -1, 3, 4, 5, 6, 7, 8, + 9, -1, -1, -1, -1, -1, 54, -1, 56, 18, + 19, 20, 21, 22, -1, -1, -1, 26, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 10, 11, 12, -1, -1, + -1, -1, -1, -1, -1, 54, -1, 56, 23, 24, + 25, -1, 27, 28, 29, 30, -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, -1, 12, 51, 14, -1, -1, - -1, -1, -1, -1, -1, -1, 61, 62, 63, -1, + 45, 46, 47, 48, 49, 50, -1, 12, 53, -1, + -1, 16, -1, -1, -1, -1, -1, -1, 63, 64, + 65, 26, -1, -1, -1, 30, -1, -1, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, -1, -1, 53, 12, + 13, 14, -1, -1, -1, -1, 61, 62, 63, 64, + 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, -1, -1, + 53, 12, 13, 14, -1, -1, -1, -1, -1, -1, + 63, 64, 65, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 12, -1, 53, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 63, 64, 65, -1, -1, -1, -1, -1, + -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, -1, + 12, 53, 14, -1, -1, -1, -1, -1, -1, 61, + 62, 63, 64, 65, -1, -1, -1, -1, -1, -1, + -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 12, + -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 63, 64, 65, -1, -1, -1, -1, -1, -1, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 12, -1, + 53, -1, -1, 56, -1, 19, -1, -1, -1, -1, + 63, 64, 65, -1, -1, -1, -1, -1, -1, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 12, -1, 53, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 63, + 64, 65, -1, -1, -1, -1, -1, -1, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 12, 53, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 63, 64, + 65, -1, -1, -1, -1, -1, -1, -1, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 12, -1, 53, -1, + -1, -1, -1, -1, -1, 60, -1, -1, 63, 64, + 65, -1, -1, -1, -1, -1, -1, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 12, -1, 53, -1, -1, + -1, -1, -1, -1, 60, -1, -1, 63, 64, 65, -1, -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 12, -1, 51, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 61, 62, 63, -1, -1, -1, - -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, - -1, 51, -1, -1, 54, -1, 19, -1, -1, -1, - -1, 61, 62, 63, -1, -1, -1, -1, -1, -1, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 12, -1, 51, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 61, 62, - 63, -1, -1, -1, -1, -1, -1, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 12, 51, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 61, 62, 63, -1, -1, + 47, 48, 49, 50, 12, -1, 53, 54, -1, -1, + -1, -1, -1, -1, -1, -1, 63, 64, 65, -1, -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 12, -1, 51, -1, -1, -1, -1, -1, -1, - 58, -1, -1, 61, 62, 63, -1, -1, -1, -1, - -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 12, -1, - 51, -1, -1, -1, -1, -1, -1, 58, -1, -1, - 61, 62, 63, -1, -1, -1, -1, -1, -1, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 12, -1, 51, 52, -1, - -1, -1, -1, -1, -1, -1, -1, 61, 62, 63, - -1, -1, -1, -1, -1, -1, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 12, -1, 51, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 61, 62, 63, -1, -1, -1, - -1, -1, -1, 33, -1, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 12, -1, - -1, 51, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 61, 62, 63, -1, -1, -1, -1, -1, -1, - -1, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 12, -1, -1, 51, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 61, 62, 63, - -1, -1, -1, -1, -1, -1, -1, 35, -1, -1, - 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, - -1, -1, -1, 51, 23, 24, 25, 26, 27, 28, - 29, 30, -1, 32, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 42, 43, 44, 23, 24, 25, 26, - 27, 28, 29, 30, 53, 32, 55, -1, 57, -1, - 59, 60, 61, -1, -1, 42, 43, 44, 45, -1, - -1, -1, -1, -1, -1, -1, 53, -1, 55, -1, - 57, 23, 24, 25, 26, 27, 28, 29, 30, -1, - 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, - -1, 53, 54, 55, -1, 57, 23, 24, 25, 26, - 27, 28, 29, 30, -1, 32, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 42, 43, 44, 23, 24, - 25, 26, 27, 28, 29, 30, 53, 32, 55, -1, - 57, -1, -1, -1, -1, -1, -1, 42, 43, 44, - -1, -1, -1, -1, -1, -1, -1, -1, 53, -1, - 55, -1, 57, 38, 39, 40, 41, -1, 43, 44, - 45, 46, 47, -1, -1, -1, 51 + 48, 49, 50, 12, -1, 53, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 63, 64, 65, -1, -1, + -1, -1, -1, -1, 33, -1, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 12, -1, -1, 53, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 63, 64, 65, -1, -1, -1, + -1, -1, -1, -1, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, -1, + -1, -1, 53, -1, -1, -1, -1, -1, -1, 17, + -1, -1, 63, 64, 65, 23, 24, 25, 26, 27, + 28, 29, 30, -1, 32, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 44, 45, 46, 23, + 24, 25, 26, 27, 28, 29, 30, 55, 32, 57, + -1, 59, -1, -1, -1, -1, -1, -1, -1, -1, + 44, 45, 46, 23, 24, 25, 26, 27, 28, 29, + 30, 55, 32, 57, -1, 59, -1, 61, 62, 63, + -1, -1, -1, -1, 44, 45, 46, 47, -1, -1, + -1, -1, -1, -1, -1, 55, -1, 57, -1, 59, + 23, 24, 25, 26, 27, 28, 29, 30, -1, 32, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 44, 45, 46, -1, -1, -1, -1, -1, -1, + -1, -1, 55, 56, 57, -1, 59, 23, 24, 25, + 26, 27, 28, 29, 30, -1, 32, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 44, 45, + 46, 23, 24, 25, 26, 27, 28, 29, 30, 55, + 32, 57, -1, 59, -1, -1, -1, -1, -1, -1, + -1, -1, 44, 45, 46, -1, -1, -1, -1, -1, + -1, -1, -1, 55, -1, 57, -1, 59 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 13, 74, 76, 75, 77, 79, 0, 26, 30, - 72, 73, 158, 3, 4, 5, 6, 7, 8, 9, - 18, 19, 20, 21, 22, 78, 80, 81, 82, 83, - 87, 89, 98, 103, 104, 106, 107, 109, 111, 113, - 52, 72, 26, 160, 84, 85, 160, 23, 24, 25, - 26, 27, 28, 29, 32, 42, 43, 44, 53, 55, - 57, 118, 119, 120, 123, 124, 125, 130, 131, 136, - 151, 155, 156, 158, 17, 116, 118, 13, 15, 86, - 88, 96, 99, 154, 156, 158, 118, 118, 108, 118, - 110, 118, 114, 14, 86, 92, 96, 72, 12, 52, - 52, 31, 118, 53, 118, 118, 118, 152, 137, 132, + 0, 13, 76, 78, 77, 79, 81, 0, 26, 30, + 74, 75, 160, 3, 4, 5, 6, 7, 8, 9, + 18, 19, 20, 21, 22, 80, 82, 83, 84, 85, + 89, 91, 100, 105, 106, 108, 109, 111, 113, 115, + 54, 74, 26, 162, 86, 87, 162, 23, 24, 25, + 26, 27, 28, 29, 32, 44, 45, 46, 55, 57, + 59, 120, 121, 122, 125, 126, 127, 132, 133, 138, + 153, 157, 158, 160, 17, 118, 120, 13, 15, 88, + 90, 98, 101, 156, 158, 160, 120, 120, 110, 120, + 112, 120, 116, 14, 88, 94, 98, 74, 12, 54, + 54, 31, 120, 55, 120, 120, 120, 154, 139, 134, 12, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 51, 61, 62, - 63, 115, 50, 53, 57, 70, 117, 26, 97, 26, - 135, 90, 91, 160, 92, 100, 101, 118, 52, 12, - 14, 105, 105, 13, 105, 13, 105, 118, 160, 135, - 26, 94, 135, 92, 59, 60, 61, 118, 149, 150, - 160, 85, 118, 122, 54, 77, 26, 27, 30, 57, - 138, 139, 140, 159, 118, 133, 134, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 12, 35, 36, 37, 38, - 39, 40, 41, 26, 121, 45, 118, 141, 26, 158, - 118, 14, 90, 136, 52, 31, 135, 52, 10, 11, - 102, 154, 154, 26, 27, 30, 157, 26, 27, 30, - 157, 135, 135, 118, 135, 118, 135, 19, 31, 95, - 135, 135, 61, 149, 118, 12, 52, 118, 126, 127, - 128, 129, 54, 49, 118, 56, 52, 49, 58, 52, - 49, 118, 118, 118, 118, 118, 118, 118, 118, 126, - 58, 45, 153, 160, 91, 118, 101, 105, 105, 118, - 118, 93, 160, 16, 26, 145, 147, 149, 158, 118, - 150, 160, 54, 77, 52, 118, 58, 140, 118, 118, - 118, 54, 5, 142, 135, 135, 20, 21, 112, 52, - 27, 158, 52, 26, 158, 118, 12, 127, 49, 118, - 9, 143, 118, 160, 148, 147, 150, 118, 118, 6, - 144, 105, 145, 146, 118, 52, 118, 58, 135, 52, - 147, 118, 145 + 42, 43, 44, 45, 46, 47, 48, 49, 50, 53, + 63, 64, 65, 117, 52, 55, 59, 72, 119, 26, + 99, 26, 137, 92, 93, 162, 94, 102, 103, 120, + 54, 12, 14, 107, 107, 13, 107, 13, 107, 120, + 162, 137, 26, 96, 137, 94, 61, 62, 63, 120, + 151, 152, 162, 87, 120, 124, 56, 79, 26, 27, + 30, 59, 140, 141, 142, 161, 120, 135, 136, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 12, + 35, 38, 39, 40, 41, 42, 43, 26, 123, 47, + 120, 143, 26, 160, 120, 14, 92, 138, 54, 31, + 137, 54, 10, 11, 104, 156, 156, 26, 27, 30, + 159, 26, 27, 30, 159, 137, 137, 120, 137, 120, + 137, 19, 31, 97, 137, 137, 63, 151, 120, 12, + 54, 120, 128, 129, 130, 131, 56, 51, 120, 58, + 54, 51, 60, 54, 51, 120, 120, 120, 120, 120, + 120, 120, 120, 128, 60, 47, 155, 162, 93, 120, + 103, 107, 107, 120, 120, 95, 162, 16, 26, 147, + 149, 151, 160, 120, 152, 162, 56, 79, 54, 120, + 60, 142, 120, 120, 120, 56, 5, 144, 137, 137, + 20, 21, 114, 54, 27, 160, 54, 26, 160, 120, + 12, 129, 51, 120, 9, 145, 120, 162, 150, 149, + 152, 120, 120, 6, 146, 107, 147, 148, 120, 54, + 120, 60, 137, 54, 149, 120, 147 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 71, 72, 72, 73, 73, 73, 74, 75, 74, - 76, 77, 78, 78, 78, 78, 78, 78, 79, 79, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 81, 81, 81, 81, 82, 83, 84, 84, 85, - 86, 88, 87, 89, 89, 89, 89, 89, 89, 90, - 90, 91, 92, 92, 92, 93, 93, 95, 94, 97, - 96, 99, 98, 100, 100, 101, 102, 102, 102, 102, - 103, 103, 104, 105, 105, 106, 107, 108, 108, 109, - 110, 110, 111, 112, 112, 114, 113, 115, 115, 115, - 117, 116, 116, 118, 118, 118, 118, 118, 118, 119, - 119, 121, 120, 122, 120, 123, 123, 123, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 125, 126, 126, 127, 128, 127, 129, 129, - 130, 130, 132, 131, 133, 133, 134, 134, 135, 135, - 137, 136, 138, 138, 139, 139, 140, 140, 140, 140, - 141, 141, 142, 142, 143, 143, 143, 144, 144, 145, - 145, 145, 145, 146, 146, 147, 148, 147, 147, 147, - 149, 149, 149, 150, 150, 151, 151, 151, 151, 151, - 152, 151, 151, 151, 151, 153, 151, 154, 154, 155, - 155, 156, 156, 156, 156, 156, 157, 157, 157, 158, - 159, 159, 160 + 0, 73, 74, 74, 75, 75, 75, 76, 77, 76, + 78, 79, 80, 80, 80, 80, 80, 80, 81, 81, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 83, 83, 83, 83, 84, 85, 86, 86, 87, + 88, 90, 89, 91, 91, 91, 91, 91, 91, 92, + 92, 93, 94, 94, 94, 95, 95, 97, 96, 99, + 98, 101, 100, 102, 102, 103, 104, 104, 104, 104, + 105, 105, 106, 107, 107, 108, 109, 110, 110, 111, + 112, 112, 113, 114, 114, 116, 115, 117, 117, 117, + 119, 118, 118, 120, 120, 120, 120, 120, 120, 121, + 121, 123, 122, 124, 122, 125, 125, 125, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 127, 128, 128, 129, 130, 129, + 131, 131, 132, 132, 134, 133, 135, 135, 136, 136, + 137, 137, 139, 138, 140, 140, 141, 141, 142, 142, + 142, 142, 143, 143, 144, 144, 145, 145, 145, 146, + 146, 147, 147, 147, 147, 148, 148, 149, 150, 149, + 149, 149, 151, 151, 151, 152, 152, 153, 153, 153, + 153, 153, 154, 153, 153, 153, 153, 155, 153, 156, + 156, 157, 157, 158, 158, 158, 158, 158, 159, 159, + 159, 160, 161, 161, 162 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -1250,16 +1269,16 @@ static const yytype_uint8 yyr2[] = 0, 3, 1, 1, 1, 1, 1, 1, 3, 1, 3, 0, 5, 0, 5, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, - 4, 4, 5, 0, 1, 1, 0, 2, 1, 3, - 1, 1, 0, 4, 0, 1, 1, 3, 0, 2, - 0, 4, 0, 1, 1, 3, 1, 3, 3, 5, - 1, 2, 0, 2, 0, 2, 4, 0, 2, 1, - 1, 2, 2, 1, 3, 1, 0, 4, 2, 2, - 1, 1, 1, 1, 2, 1, 1, 1, 1, 3, - 0, 4, 3, 3, 4, 0, 8, 1, 1, 1, + 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, + 4, 4, 4, 4, 5, 0, 1, 1, 0, 2, + 1, 3, 1, 1, 0, 4, 0, 1, 1, 3, + 0, 2, 0, 4, 0, 1, 1, 3, 1, 3, + 3, 5, 1, 2, 0, 2, 0, 2, 4, 0, + 2, 1, 1, 2, 2, 1, 3, 1, 0, 4, + 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 3, 0, 4, 3, 3, 4, 0, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 + 1, 1, 1, 1, 1 }; @@ -2037,15 +2056,15 @@ yyreduce: switch (yyn) { case 2: -#line 364 "Aql/grammar.y" /* yacc.c:1646 */ +#line 367 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 2045 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2064 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 3: -#line 367 "Aql/grammar.y" /* yacc.c:1646 */ +#line 370 "Aql/grammar.y" /* yacc.c:1646 */ { char const* p = (yyvsp[0].node)->getStringValue(); size_t const len = (yyvsp[0].node)->getStringLength(); @@ -2054,297 +2073,297 @@ yyreduce: } (yyval.node) = (yyvsp[0].node); } -#line 2058 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2077 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 4: -#line 378 "Aql/grammar.y" /* yacc.c:1646 */ +#line 381 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = static_cast(parser->peekStack()); node->addMember((yyvsp[0].node)); } -#line 2067 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2086 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 5: -#line 382 "Aql/grammar.y" /* yacc.c:1646 */ +#line 385 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = static_cast(parser->peekStack()); node->addMember((yyvsp[0].node)); } -#line 2076 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2095 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 6: -#line 386 "Aql/grammar.y" /* yacc.c:1646 */ +#line 389 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = static_cast(parser->peekStack()); node->addMember((yyvsp[0].node)); } -#line 2085 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2104 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 7: -#line 393 "Aql/grammar.y" /* yacc.c:1646 */ +#line 396 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2092 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2111 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 8: -#line 395 "Aql/grammar.y" /* yacc.c:1646 */ +#line 398 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2101 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2120 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 9: -#line 398 "Aql/grammar.y" /* yacc.c:1646 */ +#line 401 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = static_cast(parser->popStack()); auto withNode = parser->ast()->createNodeWithCollections(node); parser->ast()->addOperation(withNode); } -#line 2111 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2130 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 10: -#line 406 "Aql/grammar.y" /* yacc.c:1646 */ +#line 409 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2118 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2137 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 11: -#line 411 "Aql/grammar.y" /* yacc.c:1646 */ +#line 414 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2125 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2144 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 12: -#line 416 "Aql/grammar.y" /* yacc.c:1646 */ +#line 419 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2132 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2151 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 13: -#line 418 "Aql/grammar.y" /* yacc.c:1646 */ - { - parser->ast()->scopes()->endNested(); - } -#line 2140 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 14: #line 421 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 2148 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2159 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 15: + case 14: #line 424 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 2156 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2167 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 16: + case 15: #line 427 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 2164 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2175 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 17: + case 16: #line 430 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 2172 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2183 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 17: +#line 433 "Aql/grammar.y" /* yacc.c:1646 */ + { + parser->ast()->scopes()->endNested(); + } +#line 2191 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 18: -#line 436 "Aql/grammar.y" /* yacc.c:1646 */ +#line 439 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2179 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2198 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 19: -#line 438 "Aql/grammar.y" /* yacc.c:1646 */ +#line 441 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2186 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2205 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 20: -#line 443 "Aql/grammar.y" /* yacc.c:1646 */ +#line 446 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2193 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2212 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 21: -#line 445 "Aql/grammar.y" /* yacc.c:1646 */ +#line 448 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2200 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2219 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 22: -#line 447 "Aql/grammar.y" /* yacc.c:1646 */ +#line 450 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2207 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2226 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 23: -#line 449 "Aql/grammar.y" /* yacc.c:1646 */ +#line 452 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2214 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2233 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 24: -#line 451 "Aql/grammar.y" /* yacc.c:1646 */ +#line 454 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2221 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2240 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 25: -#line 453 "Aql/grammar.y" /* yacc.c:1646 */ +#line 456 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2228 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2247 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 26: -#line 455 "Aql/grammar.y" /* yacc.c:1646 */ +#line 458 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2235 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2254 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 27: -#line 457 "Aql/grammar.y" /* yacc.c:1646 */ +#line 460 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2242 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2261 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 28: -#line 459 "Aql/grammar.y" /* yacc.c:1646 */ +#line 462 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2249 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2268 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 29: -#line 461 "Aql/grammar.y" /* yacc.c:1646 */ +#line 464 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2256 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2275 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 30: -#line 463 "Aql/grammar.y" /* yacc.c:1646 */ +#line 466 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2263 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2282 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 31: -#line 468 "Aql/grammar.y" /* yacc.c:1646 */ +#line 471 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(arangodb::aql::AQL_SCOPE_FOR); auto node = parser->ast()->createNodeFor((yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[0].node), true); parser->ast()->addOperation(node); } -#line 2274 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2293 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 32: -#line 474 "Aql/grammar.y" /* yacc.c:1646 */ +#line 477 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(arangodb::aql::AQL_SCOPE_FOR); auto node = parser->ast()->createNodeTraversal((yyvsp[-4].strval).value, (yyvsp[-4].strval).length, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2284 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2303 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 33: -#line 479 "Aql/grammar.y" /* yacc.c:1646 */ +#line 482 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(arangodb::aql::AQL_SCOPE_FOR); auto node = parser->ast()->createNodeTraversal((yyvsp[-6].strval).value, (yyvsp[-6].strval).length, (yyvsp[-4].strval).value, (yyvsp[-4].strval).length, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2294 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2313 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 34: -#line 484 "Aql/grammar.y" /* yacc.c:1646 */ +#line 487 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(arangodb::aql::AQL_SCOPE_FOR); auto node = parser->ast()->createNodeTraversal((yyvsp[-8].strval).value, (yyvsp[-8].strval).length, (yyvsp[-6].strval).value, (yyvsp[-6].strval).length, (yyvsp[-4].strval).value, (yyvsp[-4].strval).length, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2304 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2323 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 35: -#line 492 "Aql/grammar.y" /* yacc.c:1646 */ +#line 495 "Aql/grammar.y" /* yacc.c:1646 */ { // operand is a reference. can use it directly auto node = parser->ast()->createNodeFilter((yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2314 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2333 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 36: -#line 500 "Aql/grammar.y" /* yacc.c:1646 */ +#line 503 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2321 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2340 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 37: -#line 505 "Aql/grammar.y" /* yacc.c:1646 */ +#line 508 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2328 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2347 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 38: -#line 507 "Aql/grammar.y" /* yacc.c:1646 */ +#line 510 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2335 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2354 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 39: -#line 512 "Aql/grammar.y" /* yacc.c:1646 */ +#line 515 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeLet((yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[0].node), true); parser->ast()->addOperation(node); } -#line 2344 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2363 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 40: -#line 519 "Aql/grammar.y" /* yacc.c:1646 */ +#line 522 "Aql/grammar.y" /* yacc.c:1646 */ { if (! TRI_CaseEqualString((yyvsp[-2].strval).value, "COUNT")) { parser->registerParseError(TRI_ERROR_QUERY_PARSE, "unexpected qualifier '%s', expecting 'COUNT'", (yyvsp[-2].strval).value, yylloc.first_line, yylloc.first_column); @@ -2352,20 +2371,20 @@ yyreduce: (yyval.strval) = (yyvsp[0].strval); } -#line 2356 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2375 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 41: -#line 529 "Aql/grammar.y" /* yacc.c:1646 */ +#line 532 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2365 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2384 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 42: -#line 532 "Aql/grammar.y" /* yacc.c:1646 */ +#line 535 "Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); @@ -2374,11 +2393,11 @@ yyreduce: } (yyval.node) = list; } -#line 2378 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2397 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 43: -#line 543 "Aql/grammar.y" /* yacc.c:1646 */ +#line 546 "Aql/grammar.y" /* yacc.c:1646 */ { /* COLLECT WITH COUNT INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); @@ -2388,11 +2407,11 @@ yyreduce: auto node = parser->ast()->createNodeCollectCount(parser->ast()->createNodeArray(), (yyvsp[-1].strval).value, (yyvsp[-1].strval).length, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2392 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2411 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 44: -#line 552 "Aql/grammar.y" /* yacc.c:1646 */ +#line 555 "Aql/grammar.y" /* yacc.c:1646 */ { /* COLLECT var = expr WITH COUNT INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); @@ -2404,11 +2423,11 @@ yyreduce: auto node = parser->ast()->createNodeCollectCount((yyvsp[-2].node), (yyvsp[-1].strval).value, (yyvsp[-1].strval).length, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2408 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2427 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 45: -#line 563 "Aql/grammar.y" /* yacc.c:1646 */ +#line 566 "Aql/grammar.y" /* yacc.c:1646 */ { /* AGGREGATE var = expr OPTIONS ... */ auto scopes = parser->ast()->scopes(); @@ -2439,11 +2458,11 @@ yyreduce: auto node = parser->ast()->createNodeCollect(parser->ast()->createNodeArray(), (yyvsp[-2].node), into, intoExpression, nullptr, (yyvsp[-1].node)); parser->ast()->addOperation(node); } -#line 2443 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2462 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 46: -#line 593 "Aql/grammar.y" /* yacc.c:1646 */ +#line 596 "Aql/grammar.y" /* yacc.c:1646 */ { /* COLLECT var = expr AGGREGATE var = expr OPTIONS ... */ auto scopes = parser->ast()->scopes(); @@ -2511,11 +2530,11 @@ yyreduce: auto node = parser->ast()->createNodeCollect((yyvsp[-3].node), (yyvsp[-2].node), into, intoExpression, nullptr, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2515 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2534 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 47: -#line 660 "Aql/grammar.y" /* yacc.c:1646 */ +#line 663 "Aql/grammar.y" /* yacc.c:1646 */ { /* COLLECT var = expr INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); @@ -2541,11 +2560,11 @@ yyreduce: auto node = parser->ast()->createNodeCollect((yyvsp[-2].node), parser->ast()->createNodeArray(), into, intoExpression, nullptr, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2545 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2564 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 48: -#line 685 "Aql/grammar.y" /* yacc.c:1646 */ +#line 688 "Aql/grammar.y" /* yacc.c:1646 */ { /* COLLECT var = expr INTO var KEEP ... OPTIONS ... */ auto scopes = parser->ast()->scopes(); @@ -2576,80 +2595,61 @@ yyreduce: auto node = parser->ast()->createNodeCollect((yyvsp[-3].node), parser->ast()->createNodeArray(), into, intoExpression, (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2580 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2599 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 49: -#line 718 "Aql/grammar.y" /* yacc.c:1646 */ +#line 721 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2587 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2606 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 50: -#line 720 "Aql/grammar.y" /* yacc.c:1646 */ +#line 723 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2594 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2613 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 51: -#line 725 "Aql/grammar.y" /* yacc.c:1646 */ +#line 728 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeAssign((yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[0].node)); parser->pushArrayElement(node); } -#line 2603 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2622 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 52: -#line 732 "Aql/grammar.y" /* yacc.c:1646 */ +#line 735 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = nullptr; } -#line 2611 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2630 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 53: -#line 735 "Aql/grammar.y" /* yacc.c:1646 */ +#line 738 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 2619 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2638 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 54: -#line 738 "Aql/grammar.y" /* yacc.c:1646 */ +#line 741 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); node->addMember(parser->ast()->createNodeValueString((yyvsp[-2].strval).value, (yyvsp[-2].strval).length)); node->addMember((yyvsp[0].node)); (yyval.node) = node; } -#line 2630 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 55: -#line 747 "Aql/grammar.y" /* yacc.c:1646 */ - { - if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval).value, (yyvsp[0].strval).length)) { - parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); - } - - auto node = parser->ast()->createNodeReference((yyvsp[0].strval).value, (yyvsp[0].strval).length); - if (node == nullptr) { - ABORT_OOM - } - - // indicate the this node is a reference to the variable name, not the variable value - node->setFlag(FLAG_KEEP_VARIABLENAME); - parser->pushArrayElement(node); - } #line 2649 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 56: -#line 761 "Aql/grammar.y" /* yacc.c:1646 */ + case 55: +#line 750 "Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval).value, (yyvsp[0].strval).length)) { parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); @@ -2667,8 +2667,27 @@ yyreduce: #line 2668 "Aql/grammar.cpp" /* yacc.c:1646 */ break; + case 56: +#line 764 "Aql/grammar.y" /* yacc.c:1646 */ + { + if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval).value, (yyvsp[0].strval).length)) { + parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); + } + + auto node = parser->ast()->createNodeReference((yyvsp[0].strval).value, (yyvsp[0].strval).length); + if (node == nullptr) { + ABORT_OOM + } + + // indicate the this node is a reference to the variable name, not the variable value + node->setFlag(FLAG_KEEP_VARIABLENAME); + parser->pushArrayElement(node); + } +#line 2687 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + case 57: -#line 778 "Aql/grammar.y" /* yacc.c:1646 */ +#line 781 "Aql/grammar.y" /* yacc.c:1646 */ { if (! TRI_CaseEqualString((yyvsp[0].strval).value, "KEEP")) { parser->registerParseError(TRI_ERROR_QUERY_PARSE, "unexpected qualifier '%s', expecting 'KEEP'", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); @@ -2677,158 +2696,158 @@ yyreduce: auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2681 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2700 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 58: -#line 785 "Aql/grammar.y" /* yacc.c:1646 */ +#line 788 "Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); (yyval.node) = list; } -#line 2690 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2709 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 59: -#line 792 "Aql/grammar.y" /* yacc.c:1646 */ +#line 795 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2699 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2718 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 60: -#line 795 "Aql/grammar.y" /* yacc.c:1646 */ +#line 798 "Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); (yyval.node) = list; } -#line 2708 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2727 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 61: -#line 802 "Aql/grammar.y" /* yacc.c:1646 */ +#line 805 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2717 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2736 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 62: -#line 805 "Aql/grammar.y" /* yacc.c:1646 */ +#line 808 "Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); auto node = parser->ast()->createNodeSort(list); parser->ast()->addOperation(node); } -#line 2727 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2746 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 63: -#line 813 "Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushArrayElement((yyvsp[0].node)); - } -#line 2735 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 64: #line 816 "Aql/grammar.y" /* yacc.c:1646 */ { parser->pushArrayElement((yyvsp[0].node)); } -#line 2743 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2754 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 64: +#line 819 "Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushArrayElement((yyvsp[0].node)); + } +#line 2762 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 65: -#line 822 "Aql/grammar.y" /* yacc.c:1646 */ +#line 825 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeSortElement((yyvsp[-1].node), (yyvsp[0].node)); } -#line 2751 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2770 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 66: -#line 828 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeValueBool(true); - } -#line 2759 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 67: #line 831 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeValueBool(true); } -#line 2767 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2778 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 67: +#line 834 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeValueBool(true); + } +#line 2786 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 68: -#line 834 "Aql/grammar.y" /* yacc.c:1646 */ +#line 837 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeValueBool(false); } -#line 2775 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2794 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 69: -#line 837 "Aql/grammar.y" /* yacc.c:1646 */ +#line 840 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2783 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2802 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 70: -#line 843 "Aql/grammar.y" /* yacc.c:1646 */ +#line 846 "Aql/grammar.y" /* yacc.c:1646 */ { auto offset = parser->ast()->createNodeValueInt(0); auto node = parser->ast()->createNodeLimit(offset, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2793 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2812 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 71: -#line 848 "Aql/grammar.y" /* yacc.c:1646 */ +#line 851 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeLimit((yyvsp[-2].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2802 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2821 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 72: -#line 855 "Aql/grammar.y" /* yacc.c:1646 */ +#line 858 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeReturn((yyvsp[0].node)); parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2812 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2831 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 73: -#line 863 "Aql/grammar.y" /* yacc.c:1646 */ +#line 866 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2820 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2839 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 74: -#line 866 "Aql/grammar.y" /* yacc.c:1646 */ +#line 869 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2828 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2847 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 75: -#line 872 "Aql/grammar.y" /* yacc.c:1646 */ +#line 875 "Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2836,11 +2855,11 @@ yyreduce: auto node = parser->ast()->createNodeRemove((yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2840 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2859 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 76: -#line 882 "Aql/grammar.y" /* yacc.c:1646 */ +#line 885 "Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2848,11 +2867,11 @@ yyreduce: auto node = parser->ast()->createNodeInsert((yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2852 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2871 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 77: -#line 892 "Aql/grammar.y" /* yacc.c:1646 */ +#line 895 "Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2861,11 +2880,11 @@ yyreduce: AstNode* node = parser->ast()->createNodeUpdate(nullptr, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2865 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2884 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 78: -#line 900 "Aql/grammar.y" /* yacc.c:1646 */ +#line 903 "Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2874,18 +2893,18 @@ yyreduce: AstNode* node = parser->ast()->createNodeUpdate((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2878 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2897 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 79: -#line 911 "Aql/grammar.y" /* yacc.c:1646 */ +#line 914 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2885 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2904 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 80: -#line 916 "Aql/grammar.y" /* yacc.c:1646 */ +#line 919 "Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2894,11 +2913,11 @@ yyreduce: AstNode* node = parser->ast()->createNodeReplace(nullptr, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2898 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2917 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 81: -#line 924 "Aql/grammar.y" /* yacc.c:1646 */ +#line 927 "Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2907,44 +2926,44 @@ yyreduce: AstNode* node = parser->ast()->createNodeReplace((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2911 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2930 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 82: -#line 935 "Aql/grammar.y" /* yacc.c:1646 */ +#line 938 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2918 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2937 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 83: -#line 940 "Aql/grammar.y" /* yacc.c:1646 */ +#line 943 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.intval) = static_cast(NODE_TYPE_UPDATE); } -#line 2926 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2945 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 84: -#line 943 "Aql/grammar.y" /* yacc.c:1646 */ +#line 946 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.intval) = static_cast(NODE_TYPE_REPLACE); } -#line 2934 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2953 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 85: -#line 949 "Aql/grammar.y" /* yacc.c:1646 */ +#line 952 "Aql/grammar.y" /* yacc.c:1646 */ { // reserve a variable named "$OLD", we might need it in the update expression // and in a later return thing parser->pushStack(parser->ast()->createNodeVariable(TRI_CHAR_LENGTH_PAIR(Variable::NAME_OLD), true)); } -#line 2944 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2963 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 86: -#line 953 "Aql/grammar.y" /* yacc.c:1646 */ +#line 956 "Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2989,35 +3008,35 @@ yyreduce: auto node = parser->ast()->createNodeUpsert(static_cast((yyvsp[-3].intval)), parser->ast()->createNodeReference(TRI_CHAR_LENGTH_PAIR(Variable::NAME_OLD)), (yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2993 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3012 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 87: -#line 1000 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1003 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeQuantifier(Quantifier::ALL); } -#line 3001 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3020 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 88: -#line 1003 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1006 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeQuantifier(Quantifier::ANY); } -#line 3009 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3028 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 89: -#line 1006 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1009 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeQuantifier(Quantifier::NONE); } -#line 3017 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3036 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 90: -#line 1012 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1015 "Aql/grammar.y" /* yacc.c:1646 */ { auto const scopeType = parser->ast()->scopes()->type(); @@ -3026,83 +3045,83 @@ yyreduce: parser->registerParseError(TRI_ERROR_QUERY_PARSE, "cannot use DISTINCT modifier on top-level query element", yylloc.first_line, yylloc.first_column); } } -#line 3030 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3049 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 91: -#line 1019 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1022 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeDistinct((yyvsp[0].node)); } -#line 3038 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3057 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 92: -#line 1022 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1025 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3046 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3065 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 93: -#line 1028 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 3054 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 94: #line 1031 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3062 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3073 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 95: + case 94: #line 1034 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3070 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3081 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 96: + case 95: #line 1037 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3078 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3089 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 97: + case 96: #line 1040 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3086 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3097 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 97: +#line 1043 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3105 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 98: -#line 1043 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1046 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeRange((yyvsp[-2].node), (yyvsp[0].node)); } -#line 3094 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3113 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 99: -#line 1049 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1052 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.strval) = (yyvsp[0].strval); } -#line 3102 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3121 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 100: -#line 1052 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1055 "Aql/grammar.y" /* yacc.c:1646 */ { std::string temp((yyvsp[-2].strval).value, (yyvsp[-2].strval).length); temp.append("::"); @@ -3116,307 +3135,330 @@ yyreduce: (yyval.strval).value = p; (yyval.strval).length = temp.size(); } -#line 3120 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3139 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 101: -#line 1068 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1071 "Aql/grammar.y" /* yacc.c:1646 */ { parser->pushStack((yyvsp[-1].strval).value); auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 3131 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3150 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 102: -#line 1073 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1076 "Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeFunctionCall(static_cast(parser->popStack()), list); } -#line 3140 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3159 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 103: -#line 1077 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1080 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 3149 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3168 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 104: -#line 1080 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1083 "Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeFunctionCall("LIKE", list); } -#line 3158 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3177 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 105: -#line 1087 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1090 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_PLUS, (yyvsp[0].node)); } -#line 3166 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3185 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 106: -#line 1090 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1093 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_MINUS, (yyvsp[0].node)); } -#line 3174 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3193 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 107: -#line 1093 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1096 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_NOT, (yyvsp[0].node)); } -#line 3182 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3201 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 108: -#line 1099 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1102 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_OR, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3190 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3209 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 109: -#line 1102 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1105 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_AND, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3198 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3217 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 110: -#line 1105 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1108 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_PLUS, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3206 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3225 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 111: -#line 1108 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1111 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_MINUS, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3214 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3233 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 112: -#line 1111 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1114 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_TIMES, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3222 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3241 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 113: -#line 1114 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1117 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_DIV, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3230 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3249 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 114: -#line 1117 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1120 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_MOD, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3238 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3257 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 115: -#line 1120 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1123 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_EQ, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3246 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3265 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 116: -#line 1123 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1126 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_NE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3254 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3273 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 117: -#line 1126 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1129 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_LT, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3262 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3281 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 118: -#line 1129 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1132 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_GT, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3270 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3289 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 119: -#line 1132 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1135 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_LE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3278 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3297 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 120: -#line 1135 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1138 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_GE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3286 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3305 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 121: -#line 1138 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1141 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_IN, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3294 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3313 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 122: -#line 1141 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1144 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_NIN, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3302 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3321 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 123: -#line 1144 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1147 "Aql/grammar.y" /* yacc.c:1646 */ { AstNode* arguments = parser->ast()->createNodeArray(2); arguments->addMember((yyvsp[-2].node)); arguments->addMember((yyvsp[0].node)); (yyval.node) = parser->ast()->createNodeFunctionCall("LIKE", arguments); } -#line 3313 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3332 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 124: -#line 1150 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1153 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_EQ, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); + AstNode* arguments = parser->ast()->createNodeArray(2); + arguments->addMember((yyvsp[-2].node)); + arguments->addMember((yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeFunctionCall("REGEX_TEST", arguments); } -#line 3321 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3343 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 125: -#line 1153 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1159 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_NE, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); + AstNode* arguments = parser->ast()->createNodeArray(2); + arguments->addMember((yyvsp[-2].node)); + arguments->addMember((yyvsp[0].node)); + AstNode* node = parser->ast()->createNodeFunctionCall("REGEX_TEST", arguments); + (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_NOT, node); } -#line 3329 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3355 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 126: -#line 1156 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1166 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_LT, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); + (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_EQ, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); } -#line 3337 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3363 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 127: -#line 1159 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1169 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_GT, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); + (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_NE, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); } -#line 3345 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3371 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 128: -#line 1162 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1172 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_LE, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); + (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_LT, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); } -#line 3353 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3379 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 129: -#line 1165 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1175 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_GE, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); + (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_GT, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); } -#line 3361 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3387 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 130: -#line 1168 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1178 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_IN, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); + (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_LE, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); } -#line 3369 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3395 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 131: -#line 1171 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1181 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_NIN, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); + (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_GE, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); } -#line 3377 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3403 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 132: -#line 1177 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1184 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeTernaryOperator((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_IN, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); } -#line 3385 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3411 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 133: -#line 1183 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1187 "Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_NIN, (yyvsp[-3].node), (yyvsp[0].node), (yyvsp[-2].node)); } -#line 3392 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3419 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 134: -#line 1185 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1193 "Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = parser->ast()->createNodeTernaryOperator((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); } -#line 3399 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3427 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 135: -#line 1190 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1199 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); } -#line 3407 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3434 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 136: -#line 1193 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1201 "Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3441 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 137: +#line 1206 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3449 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 138: +#line 1209 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(arangodb::aql::AQL_SCOPE_SUBQUERY); parser->ast()->startSubQuery(); } -#line 3416 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3458 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 137: -#line 1196 "Aql/grammar.y" /* yacc.c:1646 */ + case 139: +#line 1212 "Aql/grammar.y" /* yacc.c:1646 */ { AstNode* node = parser->ast()->endSubQuery(); parser->ast()->scopes()->endCurrent(); @@ -3427,98 +3469,98 @@ yyreduce: (yyval.node) = parser->ast()->createNodeReference(variableName); } -#line 3431 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 138: -#line 1209 "Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushArrayElement((yyvsp[0].node)); - } -#line 3439 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 139: -#line 1212 "Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushArrayElement((yyvsp[0].node)); - } -#line 3447 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3473 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 140: -#line 1218 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1225 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + parser->pushArrayElement((yyvsp[0].node)); } -#line 3455 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3481 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 141: -#line 1221 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1228 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + parser->pushArrayElement((yyvsp[0].node)); } -#line 3463 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3489 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 142: -#line 1227 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1234 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3497 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 143: +#line 1237 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3505 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 144: +#line 1243 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 3472 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 143: -#line 1230 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = static_cast(parser->popStack()); - } -#line 3480 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 144: -#line 1236 "Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 3487 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3514 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 145: -#line 1238 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1246 "Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = static_cast(parser->popStack()); } -#line 3494 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3522 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 146: -#line 1243 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1252 "Aql/grammar.y" /* yacc.c:1646 */ { - parser->pushArrayElement((yyvsp[0].node)); } -#line 3502 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3529 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 147: -#line 1246 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1254 "Aql/grammar.y" /* yacc.c:1646 */ { - parser->pushArrayElement((yyvsp[0].node)); } -#line 3510 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3536 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 148: -#line 1252 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1259 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = nullptr; + parser->pushArrayElement((yyvsp[0].node)); } -#line 3518 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3544 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 149: -#line 1255 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1262 "Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushArrayElement((yyvsp[0].node)); + } +#line 3552 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 150: +#line 1268 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = nullptr; + } +#line 3560 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 151: +#line 1271 "Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].node) == nullptr) { ABORT_OOM @@ -3530,56 +3572,56 @@ yyreduce: (yyval.node) = (yyvsp[0].node); } -#line 3534 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3576 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 150: -#line 1269 "Aql/grammar.y" /* yacc.c:1646 */ + case 152: +#line 1285 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeObject(); parser->pushStack(node); } -#line 3543 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 151: -#line 1272 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = static_cast(parser->popStack()); - } -#line 3551 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 152: -#line 1278 "Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 3558 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3585 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 153: -#line 1280 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1288 "Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = static_cast(parser->popStack()); } -#line 3565 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3593 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 154: -#line 1285 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1294 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 3572 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3600 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 155: -#line 1287 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1296 "Aql/grammar.y" /* yacc.c:1646 */ { } -#line 3579 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3607 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 156: -#line 1292 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1301 "Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3614 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 157: +#line 1303 "Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3621 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 158: +#line 1308 "Aql/grammar.y" /* yacc.c:1646 */ { // attribute-name-only (comparable to JS enhanced object literals, e.g. { foo, bar }) auto ast = parser->ast(); @@ -3594,20 +3636,20 @@ yyreduce: auto node = ast->createNodeReference(variable); parser->pushObjectElement((yyvsp[0].strval).value, (yyvsp[0].strval).length, node); } -#line 3598 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3640 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 157: -#line 1306 "Aql/grammar.y" /* yacc.c:1646 */ + case 159: +#line 1322 "Aql/grammar.y" /* yacc.c:1646 */ { // attribute-name : attribute-value parser->pushObjectElement((yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[0].node)); } -#line 3607 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3649 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 158: -#line 1310 "Aql/grammar.y" /* yacc.c:1646 */ + case 160: +#line 1326 "Aql/grammar.y" /* yacc.c:1646 */ { // bind-parameter : attribute-value if ((yyvsp[-2].strval).length < 1 || (yyvsp[-2].strval).value[0] == '@') { @@ -3617,100 +3659,100 @@ yyreduce: auto param = parser->ast()->createNodeParameter((yyvsp[-2].strval).value, (yyvsp[-2].strval).length); parser->pushObjectElement(param, (yyvsp[0].node)); } -#line 3621 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3663 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 159: -#line 1319 "Aql/grammar.y" /* yacc.c:1646 */ + case 161: +#line 1335 "Aql/grammar.y" /* yacc.c:1646 */ { // [ attribute-name-expression ] : attribute-value parser->pushObjectElement((yyvsp[-3].node), (yyvsp[0].node)); } -#line 3630 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 160: -#line 1326 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = 1; - } -#line 3638 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 161: -#line 1329 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = (yyvsp[-1].intval) + 1; - } -#line 3646 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3672 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 162: -#line 1335 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1342 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = nullptr; + (yyval.intval) = 1; } -#line 3654 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3680 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 163: -#line 1338 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1345 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + (yyval.intval) = (yyvsp[-1].intval) + 1; } -#line 3662 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3688 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 164: -#line 1344 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1351 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = nullptr; } -#line 3670 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3696 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 165: -#line 1347 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeArrayLimit(nullptr, (yyvsp[0].node)); - } -#line 3678 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 166: -#line 1350 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeArrayLimit((yyvsp[-2].node), (yyvsp[0].node)); - } -#line 3686 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 167: -#line 1356 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = nullptr; - } -#line 3694 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 168: -#line 1359 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1354 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3702 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3704 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 166: +#line 1360 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = nullptr; + } +#line 3712 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 167: +#line 1363 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeArrayLimit(nullptr, (yyvsp[0].node)); + } +#line 3720 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 168: +#line 1366 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeArrayLimit((yyvsp[-2].node), (yyvsp[0].node)); + } +#line 3728 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 169: -#line 1365 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1372 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); + (yyval.node) = nullptr; } -#line 3710 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3736 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 170: -#line 1368 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1375 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3744 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 171: +#line 1381 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); + } +#line 3752 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 172: +#line 1384 "Aql/grammar.y" /* yacc.c:1646 */ { char const* p = (yyvsp[0].node)->getStringValue(); size_t const len = (yyvsp[0].node)->getStringLength(); @@ -3719,20 +3761,20 @@ yyreduce: } (yyval.node) = (yyvsp[0].node); } -#line 3723 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3765 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 171: -#line 1376 "Aql/grammar.y" /* yacc.c:1646 */ + case 173: +#line 1392 "Aql/grammar.y" /* yacc.c:1646 */ { auto tmp = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); (yyval.node) = parser->ast()->createNodeCollectionDirection((yyvsp[-1].intval), tmp); } -#line 3732 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3774 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 172: -#line 1380 "Aql/grammar.y" /* yacc.c:1646 */ + case 174: +#line 1396 "Aql/grammar.y" /* yacc.c:1646 */ { char const* p = (yyvsp[0].node)->getStringValue(); size_t const len = (yyvsp[0].node)->getStringLength(); @@ -3741,58 +3783,58 @@ yyreduce: } (yyval.node) = parser->ast()->createNodeCollectionDirection((yyvsp[-1].intval), (yyvsp[0].node)); } -#line 3745 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 173: -#line 1391 "Aql/grammar.y" /* yacc.c:1646 */ - { - auto node = static_cast(parser->peekStack()); - node->addMember((yyvsp[0].node)); - } -#line 3754 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 174: -#line 1395 "Aql/grammar.y" /* yacc.c:1646 */ - { - auto node = static_cast(parser->peekStack()); - node->addMember((yyvsp[0].node)); - } -#line 3763 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3787 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 175: -#line 1402 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1407 "Aql/grammar.y" /* yacc.c:1646 */ + { + auto node = static_cast(parser->peekStack()); + node->addMember((yyvsp[0].node)); + } +#line 3796 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 176: +#line 1411 "Aql/grammar.y" /* yacc.c:1646 */ + { + auto node = static_cast(parser->peekStack()); + node->addMember((yyvsp[0].node)); + } +#line 3805 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 177: +#line 1418 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); node->addMember((yyvsp[0].node)); (yyval.node) = parser->ast()->createNodeCollectionList(node); } -#line 3773 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3815 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 176: -#line 1407 "Aql/grammar.y" /* yacc.c:1646 */ + case 178: +#line 1423 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); node->addMember((yyvsp[-1].node)); } -#line 3783 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3825 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 177: -#line 1411 "Aql/grammar.y" /* yacc.c:1646 */ + case 179: +#line 1427 "Aql/grammar.y" /* yacc.c:1646 */ { auto node = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeCollectionList(node); } -#line 3792 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3834 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 178: -#line 1415 "Aql/grammar.y" /* yacc.c:1646 */ + case 180: +#line 1431 "Aql/grammar.y" /* yacc.c:1646 */ { // graph name char const* p = (yyvsp[0].node)->getStringValue(); @@ -3802,60 +3844,60 @@ yyreduce: } (yyval.node) = (yyvsp[0].node); } -#line 3806 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3848 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 179: -#line 1424 "Aql/grammar.y" /* yacc.c:1646 */ + case 181: +#line 1440 "Aql/grammar.y" /* yacc.c:1646 */ { // graph name (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 3815 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 180: -#line 1433 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = 2; - } -#line 3823 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 181: -#line 1436 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = 1; - } -#line 3831 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3857 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 182: -#line 1439 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1449 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.intval) = 0; + (yyval.intval) = 2; } -#line 3839 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3865 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 183: -#line 1445 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1452 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeDirection((yyvsp[0].intval), 1); + (yyval.intval) = 1; } -#line 3847 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3873 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 184: -#line 1448 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1455 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeDirection((yyvsp[0].intval), (yyvsp[-1].node)); + (yyval.intval) = 0; } -#line 3855 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3881 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 185: -#line 1454 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1461 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeDirection((yyvsp[0].intval), 1); + } +#line 3889 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 186: +#line 1464 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeDirection((yyvsp[0].intval), (yyvsp[-1].node)); + } +#line 3897 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 187: +#line 1470 "Aql/grammar.y" /* yacc.c:1646 */ { // variable or collection auto ast = parser->ast(); @@ -3888,27 +3930,27 @@ yyreduce: (yyval.node) = node; } -#line 3892 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 186: -#line 1486 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 3900 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 187: -#line 1489 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 3908 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3934 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 188: -#line 1492 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1502 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3942 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 189: +#line 1505 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3950 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 190: +#line 1508 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); @@ -3916,11 +3958,11 @@ yyreduce: ABORT_OOM } } -#line 3920 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3962 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 189: -#line 1499 "Aql/grammar.y" /* yacc.c:1646 */ + case 191: +#line 1515 "Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[-1].node)->type == NODE_TYPE_EXPANSION) { // create a dummy passthru node that reduces and evaluates the expansion first @@ -3931,20 +3973,20 @@ yyreduce: (yyval.node) = (yyvsp[-1].node); } } -#line 3935 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3977 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 190: -#line 1509 "Aql/grammar.y" /* yacc.c:1646 */ + case 192: +#line 1525 "Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(arangodb::aql::AQL_SCOPE_SUBQUERY); parser->ast()->startSubQuery(); } -#line 3944 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3986 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 191: -#line 1512 "Aql/grammar.y" /* yacc.c:1646 */ + case 193: +#line 1528 "Aql/grammar.y" /* yacc.c:1646 */ { AstNode* node = parser->ast()->endSubQuery(); parser->ast()->scopes()->endCurrent(); @@ -3955,11 +3997,11 @@ yyreduce: (yyval.node) = parser->ast()->createNodeReference(variableName); } -#line 3959 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4001 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 192: -#line 1522 "Aql/grammar.y" /* yacc.c:1646 */ + case 194: +#line 1538 "Aql/grammar.y" /* yacc.c:1646 */ { // named variable access, e.g. variable.reference if ((yyvsp[-2].node)->type == NODE_TYPE_EXPANSION) { @@ -3975,11 +4017,11 @@ yyreduce: (yyval.node) = parser->ast()->createNodeAttributeAccess((yyvsp[-2].node), (yyvsp[0].strval).value, (yyvsp[0].strval).length); } } -#line 3979 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4021 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 193: -#line 1537 "Aql/grammar.y" /* yacc.c:1646 */ + case 195: +#line 1553 "Aql/grammar.y" /* yacc.c:1646 */ { // named variable access, e.g. variable.@reference if ((yyvsp[-2].node)->type == NODE_TYPE_EXPANSION) { @@ -3994,11 +4036,11 @@ yyreduce: (yyval.node) = parser->ast()->createNodeBoundAttributeAccess((yyvsp[-2].node), (yyvsp[0].node)); } } -#line 3998 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4040 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 194: -#line 1551 "Aql/grammar.y" /* yacc.c:1646 */ + case 196: +#line 1567 "Aql/grammar.y" /* yacc.c:1646 */ { // indexed variable access, e.g. variable[index] if ((yyvsp[-3].node)->type == NODE_TYPE_EXPANSION) { @@ -4013,11 +4055,11 @@ yyreduce: (yyval.node) = parser->ast()->createNodeIndexedAccess((yyvsp[-3].node), (yyvsp[-1].node)); } } -#line 4017 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4059 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 195: -#line 1565 "Aql/grammar.y" /* yacc.c:1646 */ + case 197: +#line 1581 "Aql/grammar.y" /* yacc.c:1646 */ { // variable expansion, e.g. variable[*], with optional FILTER, LIMIT and RETURN clauses if ((yyvsp[0].intval) > 1 && (yyvsp[-2].node)->type == NODE_TYPE_EXPANSION) { @@ -4041,11 +4083,11 @@ yyreduce: auto scopes = parser->ast()->scopes(); scopes->stackCurrentVariable(scopes->getVariable(nextName)); } -#line 4045 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4087 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 196: -#line 1587 "Aql/grammar.y" /* yacc.c:1646 */ + case 198: +#line 1603 "Aql/grammar.y" /* yacc.c:1646 */ { auto scopes = parser->ast()->scopes(); scopes->unstackCurrentVariable(); @@ -4064,27 +4106,27 @@ yyreduce: (yyval.node) = parser->ast()->createNodeExpansion((yyvsp[-5].intval), iterator, parser->ast()->createNodeReference(variable->name), (yyvsp[-3].node), (yyvsp[-2].node), (yyvsp[-1].node)); } } -#line 4068 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 197: -#line 1608 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 4076 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 198: -#line 1611 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 4084 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4110 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 199: -#line 1617 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1624 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 4118 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 200: +#line 1627 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 4126 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 201: +#line 1633 "Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].node) == nullptr) { ABORT_OOM @@ -4092,11 +4134,11 @@ yyreduce: (yyval.node) = (yyvsp[0].node); } -#line 4096 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4138 "Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 200: -#line 1624 "Aql/grammar.y" /* yacc.c:1646 */ + case 202: +#line 1640 "Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].node) == nullptr) { ABORT_OOM @@ -4104,67 +4146,67 @@ yyreduce: (yyval.node) = (yyvsp[0].node); } -#line 4108 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 201: -#line 1634 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); - } -#line 4116 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 202: -#line 1637 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 4124 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4150 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 203: -#line 1640 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1650 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueNull(); + (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 4132 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4158 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 204: -#line 1643 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1653 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(true); + (yyval.node) = (yyvsp[0].node); } -#line 4140 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4166 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 205: -#line 1646 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1656 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(false); + (yyval.node) = parser->ast()->createNodeValueNull(); } -#line 4148 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4174 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 206: -#line 1652 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1659 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval).value, TRI_TRANSACTION_WRITE); + (yyval.node) = parser->ast()->createNodeValueBool(true); } -#line 4156 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4182 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 207: -#line 1655 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1662 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval).value, TRI_TRANSACTION_WRITE); + (yyval.node) = parser->ast()->createNodeValueBool(false); } -#line 4164 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4190 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 208: -#line 1658 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1668 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval).value, TRI_TRANSACTION_WRITE); + } +#line 4198 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 209: +#line 1671 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval).value, TRI_TRANSACTION_WRITE); + } +#line 4206 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 210: +#line 1674 "Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].strval).length < 2 || (yyvsp[0].strval).value[0] != '@') { parser->registerParseError(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE, TRI_errno_string(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE), (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); @@ -4172,43 +4214,43 @@ yyreduce: (yyval.node) = parser->ast()->createNodeParameter((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 4176 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 209: -#line 1668 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeParameter((yyvsp[0].strval).value, (yyvsp[0].strval).length); - } -#line 4184 "Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 210: -#line 1674 "Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.strval) = (yyvsp[0].strval); - } -#line 4192 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4218 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 211: -#line 1677 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1684 "Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.strval) = (yyvsp[0].strval); + (yyval.node) = parser->ast()->createNodeParameter((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 4200 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4226 "Aql/grammar.cpp" /* yacc.c:1646 */ break; case 212: -#line 1682 "Aql/grammar.y" /* yacc.c:1646 */ +#line 1690 "Aql/grammar.y" /* yacc.c:1646 */ { (yyval.strval) = (yyvsp[0].strval); } -#line 4208 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4234 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 213: +#line 1693 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.strval) = (yyvsp[0].strval); + } +#line 4242 "Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 214: +#line 1698 "Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.strval) = (yyvsp[0].strval); + } +#line 4250 "Aql/grammar.cpp" /* yacc.c:1646 */ break; -#line 4212 "Aql/grammar.cpp" /* yacc.c:1646 */ +#line 4254 "Aql/grammar.cpp" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires diff --git a/arangod/Aql/grammar.h b/arangod/Aql/grammar.h index 99ca3863f0..f9b7276162 100644 --- a/arangod/Aql/grammar.h +++ b/arangod/Aql/grammar.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.2. */ +/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -79,46 +79,48 @@ extern int Aqldebug; T_AND = 288, T_OR = 289, T_NIN = 290, - T_EQ = 291, - T_NE = 292, - T_LT = 293, - T_GT = 294, - T_LE = 295, - T_GE = 296, - T_LIKE = 297, - T_PLUS = 298, - T_MINUS = 299, - T_TIMES = 300, - T_DIV = 301, - T_MOD = 302, - T_QUESTION = 303, - T_COLON = 304, - T_SCOPE = 305, - T_RANGE = 306, - T_COMMA = 307, - T_OPEN = 308, - T_CLOSE = 309, - T_OBJECT_OPEN = 310, - T_OBJECT_CLOSE = 311, - T_ARRAY_OPEN = 312, - T_ARRAY_CLOSE = 313, - T_OUTBOUND = 314, - T_INBOUND = 315, - T_ANY = 316, - T_ALL = 317, - T_NONE = 318, - UMINUS = 319, - UPLUS = 320, - FUNCCALL = 321, - REFERENCE = 322, - INDEXED = 323, - EXPANSION = 324 + T_REGEX_MATCH = 291, + T_REGEX_NON_MATCH = 292, + T_EQ = 293, + T_NE = 294, + T_LT = 295, + T_GT = 296, + T_LE = 297, + T_GE = 298, + T_LIKE = 299, + T_PLUS = 300, + T_MINUS = 301, + T_TIMES = 302, + T_DIV = 303, + T_MOD = 304, + T_QUESTION = 305, + T_COLON = 306, + T_SCOPE = 307, + T_RANGE = 308, + T_COMMA = 309, + T_OPEN = 310, + T_CLOSE = 311, + T_OBJECT_OPEN = 312, + T_OBJECT_CLOSE = 313, + T_ARRAY_OPEN = 314, + T_ARRAY_CLOSE = 315, + T_OUTBOUND = 316, + T_INBOUND = 317, + T_ANY = 318, + T_ALL = 319, + T_NONE = 320, + UMINUS = 321, + UPLUS = 322, + FUNCCALL = 323, + REFERENCE = 324, + INDEXED = 325, + EXPANSION = 326 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; + union YYSTYPE { #line 19 "Aql/grammar.y" /* yacc.c:1909 */ @@ -131,8 +133,10 @@ union YYSTYPE bool boolval; int64_t intval; -#line 135 "Aql/grammar.hpp" /* yacc.c:1909 */ +#line 137 "Aql/grammar.hpp" /* yacc.c:1909 */ }; + +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif diff --git a/arangod/Aql/grammar.y b/arangod/Aql/grammar.y index 235556e504..e8a6706b60 100644 --- a/arangod/Aql/grammar.y +++ b/arangod/Aql/grammar.y @@ -238,6 +238,9 @@ static AstNode const* GetIntoExpression(AstNode const* node) { %token T_OR "or operator" %token T_NIN "not in operator" +%token T_REGEX_MATCH "~= operator" +%token T_REGEX_NON_MATCH "~! operator" + %token T_EQ "== operator" %token T_NE "!= operator" %token T_LT "< operator" @@ -285,7 +288,7 @@ static AstNode const* GetIntoExpression(AstNode const* node) { %left T_OR %left T_AND %nonassoc T_OUTBOUND T_INBOUND T_ANY T_ALL T_NONE -%left T_EQ T_NE T_LIKE +%left T_EQ T_NE T_LIKE T_REGEX_MATCH T_REGEX_NON_MATCH %left T_IN T_NIN %left T_LT T_GT T_LE T_GE %left T_RANGE @@ -1147,6 +1150,19 @@ operator_binary: arguments->addMember($3); $$ = parser->ast()->createNodeFunctionCall("LIKE", arguments); } + | expression T_REGEX_MATCH expression { + AstNode* arguments = parser->ast()->createNodeArray(2); + arguments->addMember($1); + arguments->addMember($3); + $$ = parser->ast()->createNodeFunctionCall("REGEX_TEST", arguments); + } + | expression T_REGEX_NON_MATCH expression { + AstNode* arguments = parser->ast()->createNodeArray(2); + arguments->addMember($1); + arguments->addMember($3); + AstNode* node = parser->ast()->createNodeFunctionCall("REGEX_TEST", arguments); + $$ = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_NOT, node); + } | expression quantifier T_EQ expression { $$ = parser->ast()->createNodeBinaryArrayOperator(NODE_TYPE_OPERATOR_BINARY_ARRAY_EQ, $1, $4, $2); } diff --git a/arangod/Aql/tokens.cpp b/arangod/Aql/tokens.cpp index 36ad178775..b3c86c9148 100644 --- a/arangod/Aql/tokens.cpp +++ b/arangod/Aql/tokens.cpp @@ -570,8 +570,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); -#define YY_NUM_RULES 97 -#define YY_END_OF_BUFFER 98 +#define YY_NUM_RULES 99 +#define YY_END_OF_BUFFER 100 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -579,35 +579,35 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[245] = +static yyconst flex_int16_t yy_accept[247] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 98, 96, 83, 84, - 40, 70, 96, 47, 96, 75, 53, 54, 45, 43, - 52, 44, 96, 46, 80, 80, 50, 38, 39, 36, - 48, 96, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 57, 58, 96, - 60, 55, 96, 56, 96, 64, 63, 64, 61, 69, - 68, 69, 69, 79, 78, 76, 79, 74, 73, 71, - 74, 87, 86, 90, 92, 91, 95, 94, 94, 95, - 83, 34, 59, 41, 51, 88, 85, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 100, 98, 85, 86, + 42, 72, 98, 49, 98, 77, 55, 56, 47, 45, + 54, 46, 98, 48, 82, 82, 52, 40, 41, 38, + 50, 98, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 59, 60, 98, + 62, 57, 98, 58, 98, 66, 65, 66, 63, 71, + 70, 71, 71, 81, 80, 78, 81, 76, 75, 73, + 76, 89, 88, 92, 94, 93, 97, 96, 96, 97, + 85, 36, 34, 61, 43, 53, 90, 87, 0, 0, - 49, 37, 33, 35, 82, 0, 0, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 15, - 59, 59, 59, 59, 14, 59, 59, 59, 59, 59, - 59, 59, 0, 42, 65, 62, 67, 66, 77, 72, - 87, 90, 89, 93, 81, 0, 81, 82, 82, 59, - 27, 13, 26, 10, 59, 59, 59, 59, 59, 1, - 59, 59, 59, 59, 2, 59, 59, 59, 12, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 82, 82, 59, 59, 11, 59, 59, 59, 59, - 59, 59, 16, 29, 59, 28, 30, 59, 59, 59, + 82, 51, 39, 35, 33, 37, 84, 0, 0, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 15, 61, 61, 61, 61, 14, 61, 61, 61, + 61, 61, 61, 61, 0, 44, 67, 64, 69, 68, + 79, 74, 89, 92, 91, 95, 83, 0, 83, 84, + 84, 61, 27, 13, 26, 10, 61, 61, 61, 61, + 61, 1, 61, 61, 61, 61, 2, 61, 61, 61, + 12, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 84, 84, 61, 61, 11, 61, 61, + 61, 61, 61, 61, 16, 29, 61, 28, 30, 61, - 59, 6, 31, 59, 59, 17, 59, 59, 59, 32, - 59, 23, 59, 59, 7, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 3, 59, 19, 59, 18, 59, - 4, 20, 22, 59, 5, 59, 25, 59, 21, 59, - 8, 24, 9, 0 + 61, 61, 61, 6, 31, 61, 61, 17, 61, 61, + 61, 32, 61, 23, 61, 61, 7, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 3, 61, 19, 61, + 18, 61, 4, 20, 22, 61, 5, 61, 25, 61, + 21, 61, 8, 24, 9, 0 } ; static yyconst YY_CHAR yy_ec[256] = @@ -625,14 +625,14 @@ static yyconst YY_CHAR yy_ec[256] = 58, 59, 60, 61, 62, 35, 63, 64, 65, 66, 67, 68, 35, 69, 70, 71, 72, 73, 74, 35, - 75, 35, 76, 77, 78, 1, 1, 1, 1, 1, + 75, 35, 76, 77, 78, 79, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 79, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 80, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -642,7 +642,7 @@ static yyconst YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst YY_CHAR yy_meta[81] = +static yyconst YY_CHAR yy_meta[82] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 4, 4, 1, @@ -651,76 +651,77 @@ static yyconst YY_CHAR yy_meta[81] = 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 1, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 1, 1, 1, 1, 1 + 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, + 1 } ; -static yyconst flex_uint16_t yy_base[268] = +static yyconst flex_uint16_t yy_base[270] = { 0, - 0, 0, 78, 79, 80, 83, 84, 85, 86, 87, - 392, 391, 92, 93, 82, 104, 392, 541, 388, 541, - 367, 541, 0, 541, 337, 541, 541, 541, 541, 541, - 541, 541, 276, 85, 82, 92, 268, 255, 247, 206, - 541, 74, 81, 0, 60, 91, 122, 73, 80, 109, - 114, 110, 127, 121, 122, 124, 134, 541, 541, 173, - 541, 541, 101, 541, 96, 541, 541, 0, 541, 541, - 541, 0, 90, 541, 541, 541, 0, 541, 541, 541, - 0, 0, 541, 0, 541, 141, 541, 541, 541, 131, - 121, 541, 0, 541, 541, 541, 541, 154, 180, 184, + 0, 0, 79, 80, 81, 84, 85, 86, 87, 88, + 398, 397, 93, 94, 83, 105, 399, 542, 395, 542, + 76, 542, 0, 542, 388, 542, 542, 542, 542, 542, + 542, 542, 378, 87, 84, 93, 373, 370, 79, 368, + 542, 88, 83, 0, 79, 94, 134, 79, 88, 127, + 119, 121, 86, 110, 128, 130, 107, 542, 542, 329, + 542, 542, 267, 542, 247, 542, 542, 0, 542, 542, + 542, 0, 205, 542, 542, 542, 0, 542, 542, 542, + 0, 0, 542, 0, 542, 254, 542, 542, 542, 133, + 234, 542, 542, 0, 542, 542, 542, 542, 84, 160, - 541, 541, 541, 541, 0, 149, 65, 0, 145, 143, - 158, 155, 153, 151, 161, 171, 172, 168, 186, 186, - 172, 182, 180, 185, 0, 179, 214, 184, 182, 205, - 188, 220, 62, 541, 541, 541, 541, 541, 541, 541, - 0, 0, 541, 541, 246, 242, 248, 0, 57, 202, - 0, 0, 0, 0, 226, 240, 226, 230, 230, 0, - 237, 240, 251, 243, 0, 254, 252, 257, 0, 252, - 264, 253, 257, 250, 254, 269, 276, 273, 273, 0, - 299, 51, 0, 278, 281, 0, 279, 294, 296, 295, - 278, 290, 0, 0, 289, 0, 0, 295, 291, 303, + 164, 542, 542, 542, 542, 542, 0, 151, 174, 0, + 149, 147, 158, 164, 163, 159, 161, 168, 170, 166, + 169, 194, 168, 178, 174, 180, 0, 175, 209, 182, + 180, 199, 186, 236, 158, 542, 542, 542, 542, 542, + 542, 542, 0, 0, 542, 542, 240, 242, 244, 0, + 73, 206, 0, 0, 0, 0, 229, 239, 228, 230, + 232, 0, 237, 239, 238, 241, 0, 252, 249, 254, + 0, 249, 260, 249, 253, 246, 248, 264, 271, 271, + 269, 0, 302, 66, 0, 274, 277, 0, 275, 284, + 293, 291, 281, 286, 0, 0, 287, 0, 0, 293, - 296, 0, 0, 296, 300, 0, 311, 316, 307, 0, - 305, 0, 309, 305, 0, 308, 325, 330, 322, 333, - 322, 342, 326, 349, 0, 349, 0, 342, 0, 349, - 0, 0, 0, 338, 0, 340, 0, 356, 0, 357, - 0, 0, 0, 541, 415, 422, 429, 436, 443, 450, - 457, 95, 461, 465, 467, 474, 481, 488, 495, 502, - 509, 513, 517, 521, 525, 529, 533 + 288, 310, 296, 0, 0, 295, 298, 0, 309, 315, + 306, 0, 304, 0, 308, 304, 0, 304, 320, 328, + 320, 327, 318, 337, 324, 342, 0, 348, 0, 340, + 0, 350, 0, 0, 0, 338, 0, 339, 0, 358, + 0, 358, 0, 0, 0, 542, 416, 423, 430, 437, + 444, 451, 458, 104, 462, 466, 468, 475, 482, 489, + 496, 503, 510, 514, 518, 522, 526, 530, 534 } ; -static yyconst flex_int16_t yy_def[268] = +static yyconst flex_int16_t yy_def[270] = { 0, - 244, 1, 245, 245, 246, 246, 247, 247, 248, 248, - 249, 249, 250, 250, 251, 251, 244, 244, 244, 244, - 244, 244, 252, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 253, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 244, 244, 255, - 244, 244, 244, 244, 244, 244, 244, 256, 244, 244, - 244, 257, 244, 244, 244, 244, 258, 244, 244, 244, - 259, 260, 244, 261, 244, 244, 244, 244, 244, 244, - 244, 244, 254, 244, 244, 244, 244, 244, 244, 244, + 246, 1, 247, 247, 248, 248, 249, 249, 250, 250, + 251, 251, 252, 252, 253, 253, 246, 246, 246, 246, + 246, 246, 254, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 255, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 246, 246, 257, + 246, 246, 246, 246, 246, 246, 246, 258, 246, 246, + 246, 259, 246, 246, 246, 246, 260, 246, 246, 246, + 261, 262, 246, 263, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 256, 246, 246, 246, 246, 246, 246, - 244, 244, 244, 244, 262, 253, 263, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 264, 255, 244, 244, 244, 244, 244, 244, 244, - 260, 261, 244, 244, 244, 244, 244, 262, 265, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 266, - 264, 265, 267, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 246, 246, 246, 246, 246, 246, 264, 255, 265, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 266, 257, 246, 246, 246, 246, 246, + 246, 246, 262, 263, 246, 246, 246, 246, 246, 264, + 267, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 268, 266, 267, 269, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 0, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244 + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 0, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246 } ; -static yyconst flex_uint16_t yy_nxt[622] = +static yyconst flex_uint16_t yy_nxt[624] = { 0, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -729,71 +730,71 @@ static yyconst flex_uint16_t yy_nxt[622] = 44, 53, 54, 55, 56, 44, 57, 44, 58, 18, 59, 60, 61, 43, 44, 45, 46, 44, 47, 48, 44, 49, 44, 50, 44, 51, 52, 44, 53, 54, - 55, 56, 44, 57, 44, 62, 63, 64, 18, 65, - 67, 67, 71, 88, 89, 71, 75, 75, 79, 79, - 80, 80, 76, 76, 85, 85, 96, 98, 106, 113, + 55, 56, 44, 57, 44, 62, 63, 64, 18, 18, + 65, 67, 67, 71, 88, 89, 71, 75, 75, 79, + 79, 80, 80, 76, 76, 85, 85, 92, 97, 99, - 93, 97, 183, 86, 86, 88, 89, 98, 183, 100, - 100, 99, 109, 133, 119, 90, 107, 110, 120, 111, - 114, 99, 91, 112, 115, 107, 113, 68, 68, 72, - 69, 69, 72, 77, 77, 81, 81, 90, 121, 99, - 109, 119, 122, 90, 110, 120, 111, 116, 114, 99, - 112, 125, 115, 123, 126, 117, 127, 143, 124, 73, - 128, 118, 73, 129, 130, 90, 121, 131, 138, 144, - 122, 145, 145, 244, 135, 116, 150, 134, 125, 151, - 123, 126, 154, 117, 127, 124, 152, 128, 118, 155, - 129, 130, 146, 156, 146, 131, 144, 147, 147, 98, + 104, 147, 147, 98, 86, 86, 88, 89, 99, 94, + 101, 101, 108, 100, 111, 129, 90, 185, 115, 112, + 121, 113, 100, 116, 185, 114, 122, 117, 68, 68, + 72, 69, 69, 72, 77, 77, 81, 81, 90, 109, + 133, 100, 111, 129, 90, 115, 112, 121, 113, 130, + 100, 116, 114, 122, 93, 117, 123, 105, 125, 118, + 124, 73, 127, 126, 73, 128, 90, 119, 133, 131, + 132, 146, 148, 120, 148, 246, 130, 149, 149, 99, + 152, 101, 101, 153, 123, 125, 154, 118, 124, 127, + 126, 156, 128, 100, 163, 119, 131, 132, 146, 157, - 107, 100, 100, 157, 150, 153, 151, 158, 159, 160, - 154, 161, 162, 99, 152, 165, 155, 166, 168, 167, - 156, 170, 171, 169, 133, 175, 176, 104, 163, 164, - 157, 179, 153, 177, 158, 159, 160, 180, 180, 161, - 162, 99, 165, 184, 166, 168, 167, 178, 170, 171, - 169, 172, 175, 176, 173, 163, 164, 174, 179, 147, - 147, 177, 185, 145, 145, 147, 147, 186, 103, 187, - 184, 180, 188, 189, 178, 99, 102, 190, 172, 191, - 192, 173, 193, 194, 174, 195, 196, 101, 197, 185, - 198, 95, 199, 200, 201, 186, 187, 202, 203, 188, + 120, 158, 109, 159, 160, 155, 161, 162, 152, 135, + 153, 167, 170, 168, 154, 169, 172, 171, 173, 156, + 164, 100, 163, 177, 178, 109, 157, 179, 158, 181, + 159, 160, 155, 161, 162, 91, 165, 166, 167, 170, + 168, 180, 169, 172, 171, 173, 174, 186, 164, 175, + 177, 178, 176, 182, 182, 179, 181, 147, 147, 149, + 149, 149, 149, 165, 166, 187, 188, 194, 180, 100, + 145, 189, 190, 174, 186, 191, 175, 192, 193, 176, + 195, 196, 197, 198, 140, 199, 200, 182, 201, 202, + 203, 204, 187, 205, 188, 194, 206, 100, 189, 190, - 189, 204, 205, 99, 190, 206, 191, 207, 192, 193, - 208, 194, 209, 195, 196, 197, 180, 180, 198, 199, - 200, 201, 213, 210, 202, 211, 203, 212, 218, 204, - 205, 214, 215, 206, 216, 207, 217, 219, 208, 220, - 209, 221, 222, 223, 94, 224, 225, 226, 227, 213, - 180, 210, 228, 211, 229, 212, 218, 230, 214, 215, - 231, 216, 232, 217, 219, 233, 220, 234, 221, 235, - 222, 223, 224, 225, 226, 227, 236, 237, 239, 228, - 238, 240, 229, 241, 242, 230, 243, 231, 92, 91, - 232, 244, 233, 83, 83, 234, 235, 244, 244, 244, + 207, 208, 191, 209, 192, 193, 210, 195, 211, 196, + 197, 198, 199, 212, 200, 201, 202, 203, 204, 182, + 182, 205, 213, 214, 206, 215, 137, 216, 207, 208, + 217, 209, 218, 219, 210, 220, 211, 221, 222, 223, + 224, 212, 225, 136, 226, 227, 228, 229, 230, 231, + 213, 214, 215, 182, 216, 232, 234, 217, 233, 218, + 219, 235, 236, 220, 221, 222, 223, 237, 224, 238, + 225, 226, 227, 228, 229, 230, 239, 231, 240, 241, + 135, 242, 243, 232, 234, 233, 244, 245, 235, 106, + 236, 103, 102, 96, 237, 95, 91, 238, 246, 83, - 244, 244, 244, 244, 236, 237, 239, 238, 240, 244, - 241, 244, 242, 244, 243, 66, 66, 66, 66, 66, - 66, 66, 70, 70, 70, 70, 70, 70, 70, 74, - 74, 74, 74, 74, 74, 74, 78, 78, 78, 78, - 78, 78, 78, 82, 82, 82, 82, 82, 82, 82, - 84, 84, 84, 84, 84, 84, 84, 87, 87, 87, - 87, 87, 87, 87, 105, 105, 105, 105, 108, 244, - 108, 108, 132, 132, 136, 244, 136, 136, 136, 136, - 136, 137, 244, 137, 137, 137, 137, 137, 139, 244, - 139, 139, 139, 139, 139, 140, 244, 140, 140, 140, + 83, 246, 246, 246, 239, 240, 246, 241, 242, 243, + 246, 246, 246, 246, 244, 245, 66, 66, 66, 66, + 66, 66, 66, 70, 70, 70, 70, 70, 70, 70, + 74, 74, 74, 74, 74, 74, 74, 78, 78, 78, + 78, 78, 78, 78, 82, 82, 82, 82, 82, 82, + 82, 84, 84, 84, 84, 84, 84, 84, 87, 87, + 87, 87, 87, 87, 87, 107, 107, 107, 107, 110, + 246, 110, 110, 134, 134, 138, 246, 138, 138, 138, + 138, 138, 139, 246, 139, 139, 139, 139, 139, 141, + 246, 141, 141, 141, 141, 141, 142, 246, 142, 142, - 140, 140, 141, 244, 141, 141, 141, 141, 141, 142, - 244, 244, 142, 142, 142, 142, 148, 244, 148, 148, - 149, 244, 149, 149, 181, 244, 181, 181, 182, 244, - 182, 182, 180, 244, 180, 180, 183, 244, 183, 183, - 17, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 142, 142, 142, 143, 246, 143, 143, 143, 143, 143, + 144, 246, 246, 144, 144, 144, 144, 150, 246, 150, + 150, 151, 246, 151, 151, 183, 246, 183, 183, 184, + 246, 184, 184, 182, 246, 182, 182, 185, 246, 185, + 185, 17, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244 + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246 } ; -static yyconst flex_int16_t yy_chk[622] = +static yyconst flex_int16_t yy_chk[624] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -803,78 +804,79 @@ static yyconst flex_int16_t yy_chk[622] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 4, 5, 15, 15, 6, 7, 8, 9, 10, - 9, 10, 7, 8, 13, 14, 34, 35, 42, 45, + 1, 3, 4, 5, 15, 15, 6, 7, 8, 9, + 10, 9, 10, 7, 8, 13, 14, 21, 34, 35, - 252, 34, 182, 13, 14, 16, 16, 36, 149, 36, - 36, 35, 43, 133, 48, 15, 107, 43, 49, 43, - 46, 36, 91, 43, 46, 42, 45, 3, 4, 5, - 3, 4, 6, 7, 8, 9, 10, 16, 50, 35, - 43, 48, 50, 15, 43, 49, 43, 47, 46, 36, - 43, 52, 46, 51, 52, 47, 53, 86, 51, 5, - 54, 47, 6, 55, 56, 16, 50, 57, 73, 90, - 50, 98, 98, 106, 65, 47, 109, 63, 52, 110, - 51, 52, 112, 47, 53, 51, 111, 54, 47, 113, - 55, 56, 99, 114, 99, 57, 90, 99, 99, 100, + 39, 99, 99, 34, 13, 14, 16, 16, 36, 254, + 36, 36, 42, 35, 43, 53, 15, 184, 45, 43, + 48, 43, 36, 46, 151, 43, 49, 46, 3, 4, + 5, 3, 4, 6, 7, 8, 9, 10, 16, 42, + 57, 35, 43, 53, 15, 45, 43, 48, 43, 54, + 36, 46, 43, 49, 21, 46, 50, 39, 51, 47, + 50, 5, 52, 51, 6, 52, 16, 47, 57, 55, + 56, 90, 100, 47, 100, 108, 54, 100, 100, 101, + 111, 101, 101, 112, 50, 51, 113, 47, 50, 52, + 51, 114, 52, 101, 121, 47, 55, 56, 90, 115, - 106, 100, 100, 115, 109, 111, 110, 116, 117, 118, - 112, 119, 120, 100, 111, 121, 113, 122, 123, 122, - 114, 124, 126, 123, 60, 128, 129, 40, 120, 120, - 115, 131, 111, 130, 116, 117, 118, 132, 132, 119, - 120, 100, 121, 150, 122, 123, 122, 130, 124, 126, - 123, 127, 128, 129, 127, 120, 120, 127, 131, 146, - 146, 130, 155, 145, 145, 147, 147, 156, 39, 157, - 150, 132, 158, 159, 130, 145, 38, 161, 127, 162, - 163, 127, 164, 166, 127, 167, 168, 37, 170, 155, - 171, 33, 172, 173, 174, 156, 157, 175, 176, 158, + 47, 116, 108, 117, 118, 113, 119, 120, 111, 135, + 112, 123, 125, 124, 113, 124, 126, 125, 128, 114, + 122, 101, 121, 130, 131, 109, 115, 132, 116, 133, + 117, 118, 113, 119, 120, 91, 122, 122, 123, 125, + 124, 132, 124, 126, 125, 128, 129, 152, 122, 129, + 130, 131, 129, 134, 134, 132, 133, 147, 147, 148, + 148, 149, 149, 122, 122, 157, 158, 165, 132, 147, + 86, 159, 160, 129, 152, 161, 129, 163, 164, 129, + 166, 168, 169, 170, 73, 172, 173, 134, 174, 175, + 176, 177, 157, 178, 158, 165, 179, 147, 159, 160, - 159, 177, 178, 145, 161, 179, 162, 184, 163, 164, - 185, 166, 187, 167, 168, 170, 181, 181, 171, 172, - 173, 174, 191, 188, 175, 189, 176, 190, 200, 177, - 178, 192, 195, 179, 198, 184, 199, 201, 185, 204, - 187, 205, 207, 208, 25, 209, 211, 213, 214, 191, - 181, 188, 216, 189, 217, 190, 200, 218, 192, 195, - 219, 198, 220, 199, 201, 221, 204, 222, 205, 223, - 207, 208, 209, 211, 213, 214, 224, 226, 230, 216, - 228, 234, 217, 236, 238, 218, 240, 219, 21, 19, - 220, 17, 221, 12, 11, 222, 223, 0, 0, 0, + 180, 181, 161, 186, 163, 164, 187, 166, 189, 168, + 169, 170, 172, 190, 173, 174, 175, 176, 177, 183, + 183, 178, 191, 192, 179, 193, 65, 194, 180, 181, + 197, 186, 200, 201, 187, 202, 189, 203, 206, 207, + 209, 190, 210, 63, 211, 213, 215, 216, 218, 219, + 191, 192, 193, 183, 194, 220, 222, 197, 221, 200, + 201, 223, 224, 202, 203, 206, 207, 225, 209, 226, + 210, 211, 213, 215, 216, 218, 228, 219, 230, 232, + 60, 236, 238, 220, 222, 221, 240, 242, 223, 40, + 224, 38, 37, 33, 225, 25, 19, 226, 17, 12, - 0, 0, 0, 0, 224, 226, 230, 228, 234, 0, - 236, 0, 238, 0, 240, 245, 245, 245, 245, 245, - 245, 245, 246, 246, 246, 246, 246, 246, 246, 247, - 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, - 248, 248, 248, 249, 249, 249, 249, 249, 249, 249, - 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, - 251, 251, 251, 251, 253, 253, 253, 253, 254, 0, - 254, 254, 255, 255, 256, 0, 256, 256, 256, 256, - 256, 257, 0, 257, 257, 257, 257, 257, 258, 0, - 258, 258, 258, 258, 258, 259, 0, 259, 259, 259, + 11, 0, 0, 0, 228, 230, 0, 232, 236, 238, + 0, 0, 0, 0, 240, 242, 247, 247, 247, 247, + 247, 247, 247, 248, 248, 248, 248, 248, 248, 248, + 249, 249, 249, 249, 249, 249, 249, 250, 250, 250, + 250, 250, 250, 250, 251, 251, 251, 251, 251, 251, + 251, 252, 252, 252, 252, 252, 252, 252, 253, 253, + 253, 253, 253, 253, 253, 255, 255, 255, 255, 256, + 0, 256, 256, 257, 257, 258, 0, 258, 258, 258, + 258, 258, 259, 0, 259, 259, 259, 259, 259, 260, + 0, 260, 260, 260, 260, 260, 261, 0, 261, 261, - 259, 259, 260, 0, 260, 260, 260, 260, 260, 261, - 0, 0, 261, 261, 261, 261, 262, 0, 262, 262, - 263, 0, 263, 263, 264, 0, 264, 264, 265, 0, - 265, 265, 266, 0, 266, 266, 267, 0, 267, 267, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 261, 261, 261, 262, 0, 262, 262, 262, 262, 262, + 263, 0, 0, 263, 263, 263, 263, 264, 0, 264, + 264, 265, 0, 265, 265, 266, 0, 266, 266, 267, + 0, 267, 267, 268, 0, 268, 268, 269, 0, 269, + 269, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244 + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[98] = +static yyconst flex_int32_t yy_rule_can_match_eol[100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, }; + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, + }; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. @@ -1376,13 +1378,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 245 ) + if ( yy_current_state >= 247 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 244 ); + while ( yy_current_state != 246 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1618,113 +1620,125 @@ YY_RULE_SETUP case 33: YY_RULE_SETUP { - return T_EQ; + return T_REGEX_MATCH; } YY_BREAK case 34: YY_RULE_SETUP { - return T_NE; + return T_REGEX_NON_MATCH; } YY_BREAK case 35: YY_RULE_SETUP { - return T_GE; + return T_EQ; } YY_BREAK case 36: YY_RULE_SETUP { - return T_GT; + return T_NE; } YY_BREAK case 37: YY_RULE_SETUP { - return T_LE; + return T_GE; } YY_BREAK case 38: YY_RULE_SETUP { - return T_LT; + return T_GT; } YY_BREAK case 39: YY_RULE_SETUP { - return T_ASSIGN; + return T_LE; } YY_BREAK case 40: YY_RULE_SETUP { - return T_NOT; + return T_LT; } YY_BREAK case 41: YY_RULE_SETUP { - return T_AND; + return T_ASSIGN; } YY_BREAK case 42: YY_RULE_SETUP { - return T_OR; + return T_NOT; } YY_BREAK case 43: YY_RULE_SETUP { - return T_PLUS; + return T_AND; } YY_BREAK case 44: YY_RULE_SETUP { - return T_MINUS; + return T_OR; } YY_BREAK case 45: YY_RULE_SETUP { - return T_TIMES; + return T_PLUS; } YY_BREAK case 46: YY_RULE_SETUP { - return T_DIV; + return T_MINUS; } YY_BREAK case 47: YY_RULE_SETUP { - return T_MOD; + return T_TIMES; } YY_BREAK case 48: YY_RULE_SETUP { - return T_QUESTION; + return T_DIV; } YY_BREAK case 49: YY_RULE_SETUP { - return T_SCOPE; + return T_MOD; } YY_BREAK case 50: YY_RULE_SETUP { - return T_COLON; + return T_QUESTION; } YY_BREAK case 51: YY_RULE_SETUP +{ + return T_SCOPE; +} + YY_BREAK +case 52: +YY_RULE_SETUP +{ + return T_COLON; +} + YY_BREAK +case 53: +YY_RULE_SETUP { return T_RANGE; } @@ -1732,43 +1746,43 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * punctuation * --------------------------------------------------------------------------- */ -case 52: +case 54: YY_RULE_SETUP { return T_COMMA; } YY_BREAK -case 53: +case 55: YY_RULE_SETUP { return T_OPEN; } YY_BREAK -case 54: +case 56: YY_RULE_SETUP { return T_CLOSE; } YY_BREAK -case 55: +case 57: YY_RULE_SETUP { return T_OBJECT_OPEN; } YY_BREAK -case 56: +case 58: YY_RULE_SETUP { return T_OBJECT_CLOSE; } YY_BREAK -case 57: +case 59: YY_RULE_SETUP { return T_ARRAY_OPEN; } YY_BREAK -case 58: +case 60: YY_RULE_SETUP { return T_ARRAY_CLOSE; @@ -1777,7 +1791,7 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * identifiers * --------------------------------------------------------------------------- */ -case 59: +case 61: YY_RULE_SETUP { /* unquoted string */ @@ -1786,7 +1800,7 @@ YY_RULE_SETUP return T_STRING; } YY_BREAK -case 60: +case 62: YY_RULE_SETUP { /* string enclosed in backticks */ @@ -1794,7 +1808,7 @@ YY_RULE_SETUP BEGIN(BACKTICK); } YY_BREAK -case 61: +case 63: YY_RULE_SETUP { /* end of backtick-enclosed string */ @@ -1805,26 +1819,26 @@ YY_RULE_SETUP return T_STRING; } YY_BREAK -case 62: +case 64: YY_RULE_SETUP { /* character escaped by backslash */ } YY_BREAK -case 63: -/* rule 63 can match eol */ +case 65: +/* rule 65 can match eol */ YY_RULE_SETUP { /* newline character inside backtick */ } YY_BREAK -case 64: +case 66: YY_RULE_SETUP { /* any character (except newline) inside backtick */ } YY_BREAK -case 65: +case 67: YY_RULE_SETUP { /* string enclosed in forwardticks */ @@ -1832,7 +1846,7 @@ YY_RULE_SETUP BEGIN(FORWARDTICK); } YY_BREAK -case 66: +case 68: YY_RULE_SETUP { /* end of forwardtick-enclosed string */ @@ -1843,20 +1857,20 @@ YY_RULE_SETUP return T_STRING; } YY_BREAK -case 67: +case 69: YY_RULE_SETUP { /* character escaped by backslash */ } YY_BREAK -case 68: -/* rule 68 can match eol */ +case 70: +/* rule 70 can match eol */ YY_RULE_SETUP { /* newline character inside forwardtick */ } YY_BREAK -case 69: +case 71: YY_RULE_SETUP { /* any character (except newline) inside forwardtick */ @@ -1865,14 +1879,14 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * strings * --------------------------------------------------------------------------- */ -case 70: +case 72: YY_RULE_SETUP { yyextra->marker(yyextra->queryString() + yyextra->offset()); BEGIN(DOUBLE_QUOTE); } YY_BREAK -case 71: +case 73: YY_RULE_SETUP { /* end of quote-enclosed string */ @@ -1883,33 +1897,33 @@ YY_RULE_SETUP return T_QUOTED_STRING; } YY_BREAK -case 72: +case 74: YY_RULE_SETUP { /* character escaped by backslash */ } YY_BREAK -case 73: -/* rule 73 can match eol */ +case 75: +/* rule 75 can match eol */ YY_RULE_SETUP { /* newline character inside quote */ } YY_BREAK -case 74: +case 76: YY_RULE_SETUP { /* any character (except newline) inside quote */ } YY_BREAK -case 75: +case 77: YY_RULE_SETUP { yyextra->marker(yyextra->queryString() + yyextra->offset()); BEGIN(SINGLE_QUOTE); } YY_BREAK -case 76: +case 78: YY_RULE_SETUP { /* end of quote-enclosed string */ @@ -1920,20 +1934,20 @@ YY_RULE_SETUP return T_QUOTED_STRING; } YY_BREAK -case 77: +case 79: YY_RULE_SETUP { /* character escaped by backslash */ } YY_BREAK -case 78: -/* rule 78 can match eol */ +case 80: +/* rule 80 can match eol */ YY_RULE_SETUP { /* newline character inside quote */ } YY_BREAK -case 79: +case 81: YY_RULE_SETUP { /* any character (except newline) inside quote */ @@ -1942,7 +1956,7 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * number literals * --------------------------------------------------------------------------- */ -case 80: +case 82: YY_RULE_SETUP { /* a numeric integer value */ @@ -1970,7 +1984,7 @@ YY_RULE_SETUP return T_INTEGER; } YY_BREAK -case 81: +case 83: YY_RULE_SETUP { /* a numeric double value */ @@ -1995,7 +2009,7 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * bind parameters * --------------------------------------------------------------------------- */ -case 82: +case 84: YY_RULE_SETUP { /* bind parameters must start with a @ @@ -2008,14 +2022,14 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * whitespace etc. * --------------------------------------------------------------------------- */ -case 83: +case 85: YY_RULE_SETUP { /* whitespace is ignored */ } YY_BREAK -case 84: -/* rule 84 can match eol */ +case 86: +/* rule 86 can match eol */ YY_RULE_SETUP { yycolumn = 0; @@ -2024,14 +2038,14 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * comments * --------------------------------------------------------------------------- */ -case 85: +case 87: YY_RULE_SETUP { BEGIN(COMMENT_SINGLE); } YY_BREAK -case 86: -/* rule 86 can match eol */ +case 88: +/* rule 88 can match eol */ YY_RULE_SETUP { /* line numbers are counted elsewhere already */ @@ -2039,38 +2053,38 @@ YY_RULE_SETUP BEGIN(INITIAL); } YY_BREAK -case 87: +case 89: YY_RULE_SETUP { /* everything else */ } YY_BREAK -case 88: +case 90: YY_RULE_SETUP { BEGIN(COMMENT_MULTI); } YY_BREAK -case 89: +case 91: YY_RULE_SETUP { BEGIN(INITIAL); } YY_BREAK -case 90: +case 92: YY_RULE_SETUP { // eat comment in chunks } YY_BREAK -case 91: +case 93: YY_RULE_SETUP { // eat the lone star } YY_BREAK -case 92: -/* rule 92 can match eol */ +case 94: +/* rule 94 can match eol */ YY_RULE_SETUP { /* line numbers are counted elsewhere already */ @@ -2080,7 +2094,7 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * special transformation for NOT IN to T_NIN * --------------------------------------------------------------------------- */ -case 93: +case 95: YY_RULE_SETUP { /* T_NOT + T_IN => T_NIN */ @@ -2088,14 +2102,14 @@ YY_RULE_SETUP return T_NIN; } YY_BREAK -case 94: -/* rule 94 can match eol */ +case 96: +/* rule 96 can match eol */ YY_RULE_SETUP { /* ignore whitespace */ } YY_BREAK -case 95: +case 97: YY_RULE_SETUP { /* found something different to T_IN */ @@ -2114,14 +2128,14 @@ case YY_STATE_EOF(NOT): return T_NOT; } YY_BREAK -case 96: +case 98: YY_RULE_SETUP { /* anything else is returned as it is */ return (int) yytext[0]; } YY_BREAK -case 97: +case 99: YY_RULE_SETUP ECHO; YY_BREAK @@ -2433,7 +2447,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 245 ) + if ( yy_current_state >= 247 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2463,11 +2477,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 245 ) + if ( yy_current_state >= 247 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 244); + yy_is_jam = (yy_current_state == 246); (void)yyg; return yy_is_jam ? 0 : yy_current_state; diff --git a/arangod/Aql/tokens.ll b/arangod/Aql/tokens.ll index 43dcda071f..cbcc6f98a4 100644 --- a/arangod/Aql/tokens.ll +++ b/arangod/Aql/tokens.ll @@ -199,6 +199,14 @@ namespace arangodb { * operators * --------------------------------------------------------------------------- */ +"=~" { + return T_REGEX_MATCH; +} + +"!~" { + return T_REGEX_NON_MATCH; +} + "==" { return T_EQ; } diff --git a/js/server/tests/aql/aql-functions-string.js b/js/server/tests/aql/aql-functions-string.js index c806d901aa..94bd013cce 100644 --- a/js/server/tests/aql/aql-functions-string.js +++ b/js/server/tests/aql/aql-functions-string.js @@ -225,8 +225,13 @@ function ahuacatlStringFunctionsTestSuite () { query = "RETURN NOOPT(V8(REGEX_TEST(@what, @re)))"; assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); + + query = "RETURN @what =~ @re"; + assertEqual(v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); + + query = "RETURN @what !~ @re"; + assertEqual(!v[2], getQueryResults(query, { what: v[0], re: v[1] })[0], v); }); - }, //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/tests/aql/aql-regex.js b/js/server/tests/aql/aql-regex.js new file mode 100644 index 0000000000..6b3ac9acf1 --- /dev/null +++ b/js/server/tests/aql/aql-regex.js @@ -0,0 +1,113 @@ +/*jshint globalstrict:false, strict:false, maxlen:5000 */ +/*global assertEqual, AQL_EXECUTE */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief tests for query language, functions +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2010-2012 triagens GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Jan Steemann +/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +var internal = require("internal"); +var jsunity = require("jsunity"); +var db = internal.db; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test suite +//////////////////////////////////////////////////////////////////////////////// + +function ahuacatlRegexTestSuite () { + var c; + + return { + +//////////////////////////////////////////////////////////////////////////////// +/// @brief set up +//////////////////////////////////////////////////////////////////////////////// + + setUp : function () { + db._drop("UnitTestsAhuacatlRegex"); + c = db._create("UnitTestsAhuacatlRegex"); + + for (var i = 0; i < 1000; ++i) { + c.insert({ _key: "test" + i }); + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief tear down +//////////////////////////////////////////////////////////////////////////////// + + tearDown : function () { + db._drop("UnitTestsAhuacatlRegex"); + c = null; + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test regex matching +//////////////////////////////////////////////////////////////////////////////// + + testRegexMatch : function () { + var values = [ + [ '^test$', 0 ], + [ '^test\\d+$', 1000 ], + [ '^test1$', 1 ], + [ '^test1', 111 ], + [ '^test1*', 1000 ], + [ '^test1+', 111 ], + [ '^test1..$', 100 ], + [ '^test1.$', 10 ], + [ '^test11.', 10 ], + [ 'test', 1000 ], + [ 'test123', 1 ], + [ 'test12', 11 ], + [ '111', 1 ], + [ '111$', 1 ], + [ '11$', 10 ], + [ '1$', 100 ] + ]; + + values.forEach(function(v) { + // test match + var query = "FOR doc IN @@collection FILTER doc._key =~ @re RETURN doc._key"; + var result = AQL_EXECUTE(query, { "@collection": c.name(), re: v[0] }).json; + assertEqual(v[1], result.length); + + // test non-match + query = "FOR doc IN @@collection FILTER doc._key !~ @re RETURN doc._key"; + result = AQL_EXECUTE(query, { "@collection": c.name(), re: v[0] }).json; + assertEqual(1000 - v[1], result.length); + }); + } + + }; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief executes the test suite +//////////////////////////////////////////////////////////////////////////////// + +jsunity.run(ahuacatlRegexTestSuite); + +return jsunity.done(); +