8000 Merge remote-tracking branch 'origin/devel' into feature/upgrade-rocksdb · arangodb/arangodb@b2832c3 · GitHub
[go: up one dir, main page]

Skip to content

Commit b2832c3

Browse files
committed
Merge remote-tracking branch 'origin/devel' into feature/upgrade-rocksdb
* origin/devel: Feature/aql subquery execution block impl execute implementation batch sub queries (#11318) Fix isAdminUser. (#11326) Bug fix/fixes 20200318 (#11319) updated CHANGELOG Feature/out of search in range (#11324) fix "fix" for collection figures (#11323)
2 parents d1e2bfc + 096dd9b commit b2832c3

File tree

99 files changed

+2428
-797
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+2428
-797
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ devel
33

44
* Upgraded bundled RocksDB library to version 6.8.0.
55

6+
* Added AQL function `IN_RANGE`.
7+
68
* Added startup option `--ssl.prefer-http1-in-alpn` to optionally let the
79
server prefer HTTP/1.1 over HTTP/2 in ALPN protocol negotiations.
810

arangod/Actions/RestActionHandler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "RestActionHandler.h"
2525

2626
#include "Actions/actions.h"
27+
#include "Basics/StaticStrings.h"
2728
#include "Basics/StringUtils.h"
2829
#include "Statistics/RequestStatistics.h"
2930
#include "VocBase/vocbase.h"
@@ -40,7 +41,7 @@ RestActionHandler::RestActionHandler(application_features::ApplicationServer& se
4041

4142
RestStatus RestActionHandler::execute() {
4243
// check the request path
43-
if (_request->databaseName() == TRI_VOC_SYSTEM_DATABASE) {
44+
if (_request->databaseName() == StaticStrings::SystemDatabase) {
4445
if (StringUtils::isPrefix(_request->requestPath(), "/_admin/aardvark")) {
4546
RequestStatistics::SET_IGNORE(_statistics);
4647
}

arangod/Agency/MoveShard.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ bool MoveShard::start(bool&) {
217217
}
218218

219219
// Check that the toServer is not locked:
220+
// cppcheck-suppress *
220221
if (auto const& [jobId, has] = _snapshot.hasAsString(blockedServersPrefix + _to); has) {
221222
LOG_TOPIC("de054", DEBUG, Logger::SUPERVISION)
222223
<< "server " << _to << " is currently locked by " << jobId

arangod/Aql/AllRowsFetcher.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ std::pair<ExecutionState, AqlItemMatrix const*> AllRowsFetcher::fetch F438 AllRows() {
6161
}
6262

6363
std::tuple<ExecutionState, SkipResult, AqlItemBlockInputMatrix> AllRowsFetcher::execute(AqlCallStack& stack) {
64-
if (!stack.isRelevant()) {
65-
auto [state, skipped, block] = _dependencyProxy->execute(stack);
66-
return {state, skipped, AqlItemBlockInputMatrix{block}};
67-
}
6864
TRI_ASSERT(stack.peek().getOffset() == 0);
6965
TRI_ASSERT(!stack.peek().needsFullCount());
7066
// We allow a 0 hardLimit for bypassing

arangod/Aql/AqlCall.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,16 @@ struct AqlCall {
5151

5252
AqlCall() = default;
5353
// Replacements for struct initialization
54+
// cppcheck-suppress *
5455
explicit constexpr AqlCall(size_t offset, Limit softLimit = Infinity{},
5556
Limit hardLimit = Infinity{}, bool fullCount = false)
5657
: offset{offset}, softLimit{softLimit}, hardLimit{hardLimit}, fullCount{fullCount} {}
5758

5859
enum class LimitType { SOFT, HARD };
60+
// cppcheck-suppress *
5961
constexpr AqlCall(size_t offset, bool fullCount, Infinity)
6062
: offset{offset}, softLimit{Infinity{}}, hardLimit{Infinity{}}, fullCount{fullCount} {}
63+
// cppcheck-suppress *
6164
constexpr AqlCall(size_t offset, bool fullCount, size_t limit, LimitType limitType)
6265
: offset{offset},
6366
softLimit{limitType == LimitType::SOFT ? Limit{limit} : Limit{Infinity{}}},

arangod/Aql/AqlCallList.cpp

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
////////////////////////////////////////////////////////////////////////////////
2+
/// DISCLAIMER
3+
///
4+
/// Copyright 2019 ArangoDB GmbH, Cologne, Germany
5+
///
6+
/// Licensed under the Apache License, Version 2.0 (the "License");
7+
/// you may not use this file except in compliance with the License.
8 10000 +
/// You may obtain a copy of the License at
9+
///
10+
/// http://www.apache.org/licenses/LICENSE-2.0
11+
///
12+
/// Unless required by applicable law or agreed to in writing, software
13+
/// distributed under the License is distributed on an "AS IS" BASIS,
14+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
/// See the License for the specific language governing permissions and
16+
/// limitations under the License.
17+
///
18+
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
///
20+
/// @author Michael Hackstein
21+
////////////////////////////////////////////////////////////////////////////////
22+
23+
#include "AqlCallList.h"
24+
25+
#include "Basics/StaticStrings.h"
26+
#include "Basics/voc-errors.h"
27+
#include "Containers/Enumerate.h"
28+
#include "Logger/LogMacros.h"
29+
#include "Logger/Logger.h"
30+
31+
#include <velocypack/Builder.h>
32+
#include <velocypack/Collection.h>
33+
#include <velocypack/Slice.h>
34+
#include <velocypack/velocypack-aliases.h>
35+
36+
#include <iostream>
37+
#include <map>
38+
#include <string_view>
39+
40+
using namespace arangodb;
41+
using namespace arangodb::aql;
42+
43+
namespace {
44+
// hack for MSVC
45+
auto getStringView(VPackSlice slice) -> std::string_view {
46+
velocypack::StringRef ref = slice.stringRef();
47+
return std::string_view(ref.data(), ref.size());
48+
}
49+
} // namespace
50+
51+
AqlCallList::AqlCallList(AqlCall const& call) : _specificCalls{call} {}
52+
53+
AqlCallList::AqlCallList(AqlCall const& specificCall, AqlCall const& defaultCall)
54+
: _specificCalls{specificCall}, _defaultCall{defaultCall} {}
55+
56+
[[nodiscard]] auto AqlCallList::popNextCall() -> AqlCall {
57+
TRI_ASSERT(hasMoreCalls());
58+
if (!_specificCalls.empty()) {
59+
// We only implemented for a single given call.
60+
TRI_ASSERT(_specificCalls.size() == 1);
61+
auto res = _specificCalls.back();
62+
_specificCalls.pop_back();
63+
return res;
64+
}
65+
TRI_ASSERT(_defaultCall.has_value());
66+
return _defaultCall.value();
67+
}
68+
69+
[[nodiscard]] auto AqlCallList::peekNextCall() const -> AqlCall const& {
70+
TRI_ASSERT(hasMoreCalls());
71+
if (!_specificCalls.empty()) {
72+
// We only implemented for a single given call.
73+
TRI_ASSERT(_specificCalls.size() == 1);
74+
return _specificCalls.back();
75+
}
76+
TRI_ASSERT(_defaultCall.has_value());
77+
return _defaultCall.value();
78+
}
79+
80+
[[nodiscard]] auto AqlCallList::hasMoreCalls() const noexcept -> bool {
81+
return !_specificCalls.empty() || _defaultCall.has_value();
82+
}
83+
84+
[[nodiscard]] auto AqlCallList::modifyNextCall() -> AqlCall& {
85+
TRI_ASSERT(hasMoreCalls());
86+
if (_specificCalls.empty()) {
87+
TRI_ASSERT(_defaultCall.has_value());
88+
// We need to emplace a copy of defaultCall into the specific calls
89+
// This can then be modified and eventually be consumed
90+
_specificCalls.emplace_back(_defaultCall.value());
91+
}
92+
return _specificCalls.back();
93+
}
94+
95+
auto AqlCallList::fromVelocyPack(VPackSlice slice) -> ResultT<AqlCallList> {
96+
if (ADB_UNLIKELY(!slice.isObject())) {
97+
using namespace std::string_literals;
98+
return Result(TRI_ERROR_TYPE_ERROR,
99+
"When deserializating AqlCallList: Expected object, got "s +
100+
slice.typeName());
101+
}
102+
103+
auto expectedPropertiesFound = std::map<std::string_view, bool>{};
104+
expectedPropertiesFound.emplace(StaticStrings::AqlCallListSpecific, false);
105+
expectedPropertiesFound.emplace(StaticStrings::AqlCallListDefault, false);
106+
107+
auto const readSpecific = [](velocypack::Slice slice) -> ResultT<std::vector<AqlCall>> {
108+
if (ADB_UNLIKELY(!slice.isArray())) {
109+
auto message = std::string{"When deserializating AqlCall: When reading " +
110+
StaticStrings::AqlCallListSpecific +
111+
": "
112+
"Unexpected type "};
113+
message += slice.typeName();
114+
return Result(TRI_ERROR_TYPE_ERROR, std::move(message));
115+
}
116+
std::vector<AqlCall> res;
117+
res.reserve(slice.length());
118+
for (auto const& c : VPackArrayIterator(slice)) {
119+
auto maybeAqlCall = AqlCall::fromVelocyPack(c);
120+
if (ADB_UNLIKELY(maybeAqlCall.fail())) {
121+
auto message = std::string{"When deserializing AqlCallList: entry "};
122+
message += std::to_string(res.size());
123+
message += ": ";
124+
message += std::move(maybeAqlCall).errorMessage();
125+
return Result(TRI_ERROR_TYPE_ERROR, std::move(message));
126+
}
127+
res.emplace_back(maybeAqlCall.get());
128+
}
129+
return res;
130+
};
131+
132+
auto const readDefault = [](velocypack::Slice slice) -> ResultT<std::optional<AqlCall>> {
133+
if (ADB_UNLIKELY(!slice.isObject() && !slice.isNull())) {
134+
auto message =
135+
std::string{"When deserializating AqlCallList: When reading " +
136+
StaticStrings::AqlCallListDefault +
137+
": "
138+
"Unexpected type "};
139+
message += slice.typeName();
140+
return Result(TRI_ERROR_TYPE_ERROR, std::move(message));
141+
}
142+
if (slice.isNull()) {
143+
return {std::nullopt};
144+
}
145+
auto maybeAqlCall = AqlCall::fromVelocyPack(slice);
146+
if (ADB_UNLIKELY(maybeAqlCall.fail())) {
147+
auto message = std::string{"When deserializing AqlCallList: default "};
148+
message += std::move(maybeAqlCall).errorMessage();
149+
return Result(TRI_ERROR_TYPE_ERROR, std::move(message));
150+
}
151+
return {std::move(maybeAqlCall.get())};
152+
};
153+
154+
AqlCallList result{AqlCall{}};
155+
156+
for (auto const it : velocypack::ObjectIterator(slice)) {
157+
auto const keySlice = it.key;
158+
if (ADB_UNLIKELY(!keySlice.isString())) {
159+
return Result(TRI_ERROR_TYPE_ERROR,
160+
"When deserializating AqlCallList: Key is not a string");
161+
}
162+
auto const key = getStringView(keySlice);
163+
164+
if (auto propIt = expectedPropertiesFound.find(key);
165+
ADB_LIKELY(propIt != expectedPropertiesFound.end())) {
166+
if (ADB_UNLIKELY(propIt->second)) {
167+
return Result(
168+
TRI_ERROR_TYPE_ERROR,
169+
"When deserializating AqlCallList: Encountered duplicate key");
170+
}
171+
propIt->second = true;
172+
}
173+
174+
if (key == StaticStrings::AqlCallListSpecific) {
175+
auto maybeCalls = readSpecific(it.value);
176+
if (maybeCalls.fail()) {
177+
return std::move(maybeCalls).result();
178+
}
179+
result._specificCalls = maybeCalls.get();
180+
} else if (key == StaticStrings::AqlCallListDefault) {
181+
auto maybeCall = readDefault(it.value);
182+
if (maybeCall.fail()) {
183+
return std::move(maybeCall).result();
184+
}
185+
result._defaultCall = maybeCall.get();
186+
} else {
187+
LOG_TOPIC("c30c1", WARN, Logger::AQL)
188+
<< "When deserializating AqlCallList: Encountered unexpected key " << key;
189+
// If you run into this assertion during rolling upgrades after adding a
190+
// new attribute, remove it in the older version.
191+
TRI_ASSERT(false);
192+
}
193+
}
194+
195+
for (auto const& it : expectedPropertiesFound) {
196+
if (ADB_UNLIKELY(!it.second)) {
197+
auto message = std::string{"When deserializating AqlCall: missing key "};
198+
message += it.first;
199+
return Result(TRI_ERROR_TYPE_ERROR, std::move(message));
200+
}
201+
}
202+
203+
return result;
204+
}
205+
206+
auto AqlCallList::toVelocyPack(VPackBuilder& builder) const -> void {
207+
// We need to have something that is serializable
208+
TRI_ASSERT(hasMoreCalls());
209+
builder.openObject();
210+
builder.add(VPackValue(StaticStrings::AqlCallListSpecific));
211+
212+
{
213+
builder.openArray();
214+
for (auto const& call : _specificCalls) {
215+
call.toVelocyPack(builder);
216+
}
217+
builder.close();
218+
}
219+
builder.add(VPackValue(StaticStrings::AqlCallListDefault));
220+
if (_defaultCall.has_value()) {
221+
_defaultCall.value().toVelocyPack(builder);
222+
} else {
223+
builder.add(VPackSlice::nullSlice());
224+
}
225+
226+
builder.close();
227+
}
228+
229+
auto AqlCallList::toString() const -> std::string {
230+
auto stream = std::stringstream{};
231+
stream << *this;
232+
return stream.str();
233+
}
234+
235+
bool arangodb::aql::operator==(AqlCallList const& left, AqlCallList const& right) {
236+
if (left._specificCalls.size() != right._specificCalls.size()) {
237+
return false;
238+
}
239+
// Sorry call does not implement operator!=
240+
if (!(left._defaultCall == right._defaultCall)) {
241+
return false;
242+
}
243+
for (auto const& [index, call] : enumerate(left._specificCalls)) {
244+
if (!(call == right._specificCalls[index])) {
245+
return false;
246+
}
247+
}
248+
return true;
249+
}
250+
251+
auto arangodb::aql::operator<<(std::ostream& out, AqlCallList const& list) -> std::ostream& {
252+
out << "specific: [ ";
253+
for (auto const& [index, call] : enumerate(list._specificCalls)) {
254+
if (index > 0) {
255+
out << ", ";
256+
}
257+
out << call;
258+
}
259+
out << " ]";
260+
if (list._defaultCall.has_value()) {
261+
out << " default: " << list._defaultCall.value();
262+
}
263+
return out;
264+
}

0 commit comments

Comments
 (0)
0