8000 Feature/aql subquery splicing with gather (#10341) · arangodb/arangodb@7a57a72 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7a57a72

Browse files
goedderzmchacki
authored andcommitted
Feature/aql subquery splicing with gather (#10341)
Allow Splicing with GATHER nodes
1 parent bd1316b commit 7a57a72

Some content is hidden

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

56 files changed

+742
-330
lines changed

arangod/Aql/Aggregator.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "Aggregator.h"
2525

2626
#include "Aql/AqlValue.h"
27+
#include "Aql/AqlValueMaterializer.h"
2728
#include "Basics/VelocyPackHelper.h"
2829
#include "Transaction/Context.h"
2930
#include "Transaction/Helpers.h"

arangod/Aql/AqlItemBlock.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include "Aql/SharedAqlItemBlockPtr.h"
3434
#include "Basics/StaticStrings.h"
3535
#include "Basics/VelocyPackHelper.h"
36+
#include "Transaction/Context.h"
37+
#include "Transaction/Methods.h"
3638

3739
#include <velocypack/Iterator.h>
3840
#include <velocypack/velocypack-aliases.h>
@@ -566,7 +568,7 @@ SharedAqlItemBlockPtr AqlItemBlock::steal(std::vector<size_t> const& chosen,
566568
/// corresponding position
567569
/// "raw": List of actual values, positions 0 and 1 are always null
568570
/// such that actual indices start at 2
569-
void AqlItemBlock::toVelocyPack(transaction::Methods* trx, VPackBuilder& result) const {
571+
void AqlItemBlock::toVelocyPack(velocypack::Options const* const trxOptions, VPackBuilder& result) const {
570572
TRI_ASSERT(result.isOpenObject());
571573
VPackOptions options(VPackOptions::Defaults);
572574
options.buildUnindexedArrays = true;
@@ -650,7 +652,7 @@ void AqlItemBlock::toVelocyPack(transaction::Methods* trx, VPackBuilder& result)
650652

651653
if (it == table.end()) {
652654
currentState = Next;
653-
a.toVelocyPack(trx, raw, false);
655+
a.toVelocyPack(trxOptions, raw, false);
654656
table.try_emplace(a, pos++);
655657
} else {
656658
currentState = Positional;
@@ -699,28 +701,29 @@ void AqlItemBlock::toVelocyPack(transaction::Methods* trx, VPackBuilder& result)
699701
result.add("raw", raw.slice());
700702
}
701703

702-
void AqlItemBlock::rowToSimpleVPack(size_t const row, transaction::Methods* trx, arangodb::velocypack::Builder& builder) const {
704+
void AqlItemBlock::rowToSimpleVPack(size_t const row, velocypack::Options const* options, arangodb::velocypack::Builder& builder) const {
703705
VPackArrayBuilder rowBuilder{&builder};
704706

705707
if (isShadowRow(row)) {
706-
getShadowRowDepth(row).toVelocyPack(trx, *rowBuilder, false);
708+
getShadowRowDepth(row).toVelocyPack(options, *rowBuilder, false);
707709
} else {
708-
AqlValue{AqlValueHintNull{}}.toVelocyPack(trx, *rowBuilder, false);
710+
AqlValue{AqlValueHintNull{}}.toVelocyPack(options, *rowBuilder, false);
709711
}
710712
for (RegisterId reg = 0; reg < getNrRegs(); ++reg) {
711-
getValueReference(row, reg).toVelocyPack(trx, *rowBuilder, false);
713+
getValueReference(row, reg).toVelocyPack(options, *rowBuilder, false);
712714
}
713715
}
714716

715-
void AqlItemBlock::toSimpleVPack(transaction::Methods* trx, arangodb::velocypack::Builder& builder) const {
717+
void AqlItemBlock::toSimpleVPack(velocypack::Options const* options,
718+
arangodb::velocypack::Builder& builder) const {
716719
VPackObjectBuilder block{&builder};
717720
block->add("nrItems", VPackValue(size()));
718721
block->add("nrRegs", VPackValue(getNrRegs()));
719722
block->add(VPackValue("matrix"));
720723
{
721724
VPackArrayBuilder matrixBuilder{block.builder};
722725
for (size_t row = 0; row < size(); ++row) {
723-
rowToSimpleVPack(row, trx, *matrixBuilder.builder);
726+
rowToSimpleVPack(row, options, *matrixBuilder.builder);
724727
}
725728
}
726729
}

arangod/Aql/AqlItemBlock.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ class AqlItemBlock {
208208

209209
/// @brief toJson, transfer a whole AqlItemBlock to Json, the result can
210210
/// be used to recreate the AqlItemBlock via the Json constructor
211-
void toVelocyPack(transaction::Methods* trx, arangodb::velocypack::Builder&) const;
211+
void toVelocyPack(velocypack::Options const*, arangodb::velocypack::Builder&) const;
212212

213213
/// @brief Creates a human-readable velocypack of the block. Adds an object
214214
/// `{nrItems, nrRegs, matrix}` to the builder.
@@ -217,9 +217,9 @@ class AqlItemBlock {
217217
// (of length nrRegs+1 (sic)). The first entry contains the shadow row depth,
218218
// or `null` for data rows. The entries with indexes 1..nrRegs contain the
219219
// registers 0..nrRegs-1, respectively.
220-
void toSimpleVPack(transaction::Methods* trx, arangodb::velocypack::Builder&) const;
220+
void toSimpleVPack(velocypack::Options const*, arangodb::velocypack::Builder&) const;
221221

222-
void rowToSimpleVPack(size_t row, transaction::Methods* trx,
222+
void rowToSimpleVPack(size_t row, velocypack::Options const*,
223223
velocypack::Builder& builder) const;
224224

225225
/// @brief test if the given row is a shadow row and conveys subquery

arangod/Aql/AqlValue.cpp

Lines changed: 33 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
#include <velocypack/StringRef.h>
4141
#include <velocypack/velocypack-aliases.h>
4242

43-
#include <array>
44-
4543
using namespace arangodb;
4644
using namespace arangodb::aql;
4745

@@ -933,7 +931,7 @@ v8::Handle<v8::Value> AqlValue::toV8(v8::Isolate* isolate, transaction::Methods*
933931
}
934932

935933
/// @brief materializes a value into the builder
936-
void AqlValue::toVelocyPack(transaction::Methods* trx, arangodb::velocypack::Builder& builder,
934+
void AqlValue::toVelocyPack(VPackOptions const* options, arangodb::velocypack::Builder& builder,
937935
bool resolveExternals) const {
938936
switch (type()) {
939937
case VPACK_SLICE_POINTER:
@@ -949,7 +947,7 @@ void AqlValue::toVelocyPack(transaction::Methods* trx, arangodb::velocypack::Bui
949947
bool const sanitizeCustom = true;
950948
arangodb::basics::VelocyPackHelper::sanitizeNonClientTypes(
951949
slice(), VPackSlice::noneSlice(), builder,
952-
trx->transactionContextPtr()->getVPackOptions(), sanitizeExternals,
950+
options, sanitizeExternals,
953951
sanitizeCustom);
954952
} else {
955953
builder.add(slice());
@@ -961,7 +959,7 @@ void AqlValue::toVelocyPack(transaction::Methods* trx, arangodb::velocypack::Bui
961959
for (auto const& it : *_data.docvec) {
962960
size_t const n = it->size();
963961
for (size_t i = 0; i < n; ++i) {
964-
it->getValueReference(i, 0).toVelocyPack(trx, builder, resolveExternals);
962+
it->getValueReference(i, 0).toVelocyPack(options, builder, resolveExternals);
965963
}
966964
}
967965
builder.close();
@@ -980,8 +978,13 @@ void AqlValue::toVelocyPack(transaction::Methods* trx, arangodb::velocypack::Bui
980978
}
981979
}
982980

981+
void AqlValue::toVelocyPack(transaction::Methods* trx, arangodb::velocypack::Builder& builder,
982+
bool resolveExternals) const {
983+
toVelocyPack(trx->transactionContextPtr()->getVPackOptions(), builder, resolveExternals);
984+
}
985+
983986
/// @brief materializes a value into the builder
984-
AqlValue AqlValue::materialize(transaction::Methods* trx, bool& hasCopied,
987+
AqlValue AqlValue::materialize(VPackOptions const* options, bool& hasCopied,
985988
bool resolveExternals) const {
986989
switch (type()) {
987990
case VPACK_INLINE:
@@ -997,7 +1000,7 @@ AqlValue AqlValue::materialize(transaction::Methods* trx, bool& hasCopied,
9971000
ConditionalDeleter<VPackBuffer<uint8_t>> deleter(shouldDelete);
9981001
std::shared_ptr<VPackBuffer<uint8_t>> buffer(new VPackBuffer<uint8_t>, deleter);
9991002
VPackBuilder builder(buffer);
1000-
toVelocyPack(trx, builder, resolveExternals);
1003+
toVelocyPack(options, builder, resolveExternals);
10011004
hasCopied = true;
10021005
return AqlValue(buffer.get(), shouldDelete);
10031006
}
@@ -1008,6 +1011,11 @@ AqlValue AqlValue::materialize(transaction::Methods* trx, bool& hasCopied,
10081011
return AqlValue();
10091012
}
10101013

1014+
AqlValue AqlValue::materialize(transaction::Methods* trx, bool& hasCopied,
1015+
bool resolveExternals) const {
1016+
return materialize(trx->transactionContextPtr()->getVPackOptions(), hasCopied, resolveExternals);
1017+
}
1018+
10111019
/// @brief clone a value
10121020
AqlValue AqlValue::clone() const {
10131021
switch (type()) {
@@ -1173,23 +1181,24 @@ AqlValue AqlValue::CreateFromBlocks(transaction::Methods* trx,
11731181
}
11741182

11751183
/// @brief comparison for AqlValue objects
1176-
int AqlValue::Compare(transaction::Methods* trx, AqlValue const& left,
1184+
int AqlValue::Compare(velocypack::Options const* options, AqlValue const& left,
11771185
AqlValue const& right, bool compareUtf8) {
11781186
AqlValue::AqlValueType const leftType = left.type();
11791187
AqlValue::AqlValueType const rightType = right.type();
11801188

11811189
if (leftType != rightType) {
1190+
// TODO implement this case more efficiently
11821191
if (leftType == RANGE || rightType == RANGE || leftType == DOCVEC || rightType == DOCVEC) {
11831192
// range|docvec against x
1184-
transaction::BuilderLeaser leftBuilder(trx);
1185-
left.toVelocyPack(trx, *leftBuilder.get(), false);
1193+
VPackBuilder leftBuilder;
1194+
left.toVelocyPack(options, leftBuilder, false);
11861195

1187-
transaction::BuilderLeaser rightBuilder(trx);
1188-
right.toVelocyPack(trx, *rightBuilder.get(), false);
1196+
VPackBuilder rightBuilder;
1197+
right.toVelocyPack(options, rightBuilder, false);
11891198

1190-
return arangodb::basics::VelocyPackHelper::compare(
1191-
leftBuilder->slice(), rightBuilder->slice(), compareUtf8,
1192-
trx->transactionContextPtr()->getVPackOptions());
1199+
return arangodb::basics::VelocyPackHelper::compare(leftBuilder.slice(),
1200+
rightBuilder.slice(),
1201+
compareUtf8, options);
11931202
}
11941203
// fall-through to other types intentional
11951204
}
@@ -1201,9 +1210,8 @@ int AqlValue::Compare(transaction::Methods* trx, AqlValue const& left,
12011210
case VPACK_SLICE_POINTER:
12021211
case VPACK_MANAGED_SLICE:
12031212
case VPACK_MANAGED_BUFFER: {
1204-
return arangodb::basics::VelocyPackHelper::compare(
1205-
left.slice(), right.slice(), compareUtf8,
1206-
trx->transactionContextPtr()->getVPackOptions());
1213+
return arangodb::basics::VelocyPackHelper::compare(left.slice(), right.slice(),
1214+
compareUtf8, options);
12071215
}
12081216
case DOCVEC: {
12091217
// use lexicographic ordering of AqlValues regardless of block,
@@ -1232,7 +1240,7 @@ int AqlValue::Compare(transaction::Methods* trx, AqlValue const& left,
12321240
AqlValue const& rval =
12331241
right._data.docvec->at(rblock)->getValueReference(ritem, 0);
12341242

1235-
int cmp = Compare(trx, lval, rval, compareUtf8);
1243+
int cmp = Compare(options, lval, rval, compareUtf8);
12361244

12371245
if (cmp != 0) {
12381246
return cmp;
@@ -1280,6 +1288,11 @@ int AqlValue::Compare(transaction::Methods* trx, AqlValue const& left,
12801288
return 0;
12811289
}
12821290

1291+
int AqlValue::Compare(transaction::Methods* trx, AqlValue const& left,
1292+
AqlValue const& right, bool compareUtf8) {
1293+
return Compare(trx->transactionContextPtr()->getVPackOptions(), left, right, compareUtf8);
1294+
}
1295+
12831296
AqlValue::AqlValue(std::vector<arangodb::aql::SharedAqlItemBlockPtr>* docvec) noexcept {
12841297
TRI_ASSERT(docvec != nullptr);
12851298
_data.docvec = docvec;
@@ -1610,68 +1623,8 @@ AqlValueGuard::~AqlValueGuard() {
16101623
}
16111624

16121625
void AqlValueGuard::steal() { _destroy = false; }
1613-
AqlValue& AqlValueGuard::value() { return _value; }
1614-
AqlValueMaterializer::AqlValueMaterializer(transaction::Methods* trx)
1615-
: trx(trx), materialized(), hasCopied(false) {}
1616-
AqlValueMaterializer::AqlValueMaterializer(AqlValueMaterializer const& other)
1617-
: trx(other.trx), materialized(other.materialized), hasCopied(other.hasCopied) {
1618-
if (other.hasCopied) {
1619-
// copy other's slice
1620-
materialized = other.materialized.clone();
1621-
}
1622-
}
16231626

1624-
AqlValueMaterializer& AqlValueMaterializer::operator=(AqlValueMaterializer const& other) {
1625-
if (this != &other) {
1626-
TRI_ASSERT(trx == other.trx); // must be from same transaction
1627-
trx = other.trx; // to shut up cppcheck
1628-
if (hasCopied) {
1629-
// destroy our own slice
1630-
materialized.destroy();
1631-
hasCopied = false;
1632-
}
1633-
// copy other's slice
1634-
materialized = other.materialized.clone();
1635-
hasCopied = other.hasCopied;
1636-
}
1637-
return *this;
1638-
}
1639-
1640-
AqlValueMaterializer::AqlValueMaterializer(AqlValueMaterializer&& other) noexcept
1641-
: trx(other.trx), materialized(other.materializ 10000 ed), hasCopied(other.hasCopied) {
1642-
// reset other
1643-
other.hasCopied = false;
1644-
// cppcheck-suppress *
1645-
other.materialized = AqlValue();
1646-
}
1647-
1648-
AqlValueMaterializer& AqlValueMaterializer::operator=(AqlValueMaterializer&& other) noexcept {
1649-
if (this != &other) {
1650-
TRI_ASSERT(trx == other.trx); // must be from same transaction
1651-
trx = other.trx; // to shut up cppcheck
1652-
if (hasCopied) {
1653-
// destroy our own slice
1654-
materialized.destroy();
1655-
}
1656-
// reset other
1657-
materialized = other.materialized;
1658-
hasCopied = other.hasCopied;
1659-
other.materialized = AqlValue();
1660-
}
1661-
return *this;
1662-
}
1663-
1664-
AqlValueMaterializer::~AqlValueMaterializer() {
1665-
if (hasCopied) {
1666-
materialized.destroy();
1667-
}
1668-
}
1669-
1670-
arangodb::velocypack::Slice AqlValueMaterializer::slice(AqlValue const& value,
1671-
bool resolveExternals) {
1672-
materialized = value.materialize(trx, hasCopied, resolveExternals);
1673-
return materialized.slice();
1674-
}
1627+
AqlValue& AqlValueGuard::value() { return _value; }
16751628

16761629
size_t std::hash<arangodb::aql::AqlValue>::operator()(arangodb::aql::AqlValue const& x) const
16771630
noexcept {

arangod/Aql/AqlValue.h

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace velocypack {
4747
template <typename T>
4848
class Buffer;
4949
class Builder;
50+
struct Options;
5051
class Slice;
5152
class StringRef;
5253
}
@@ -329,11 +330,12 @@ struct AqlValue final {
329330
v8::Handle<v8::Value> toV8(v8::Isolate* isolate, transaction::Methods*) const;
330331

331332
/// @brief materializes a value into the builder
332-
void toVelocyPack(transaction::Methods*, arangodb::velocypack::Builder& builder,
333-
bool resolveExternals) const;
333+
void toVelocyPack(velocypack::Options const*, arangodb::velocypack::Builder&, bool resolveExternals) const;
334+
void toVelocyPack(transaction::Methods*, arangodb::velocypack::Builder&, bool resolveExternals) const;
334335

335336
/// @brief materialize a value into a new one. this expands docvecs and
336337
/// ranges
338+
AqlValue materialize(velocypack::Options const*, bool& hasCopied, bool resolveExternals) const;
337339
AqlValue materialize(transaction::Methods*, bool& hasCopied, bool resolveExternals) const;
338340

339341
/// @brief return the slice for the value
@@ -364,6 +366,8 @@ struct AqlValue final {
364366
arangodb::aql::RegisterId);
365367

366368
/// @brief compare function for two values
369+
static int Compare(velocypack::Options const*, AqlValue const& left,
370+
AqlValue const& right, bool useUtf8);
367371
static int Compare(transaction::Methods*, AqlValue const& left,
368372
AqlValue const& right, bool useUtf8);
369373

@@ -399,28 +403,6 @@ class AqlValueGuard {
399403
bool _destroy;
400404
};
401405

402-
struct AqlValueMaterializer {
403-
explicit AqlValueMaterializer(transaction::Methods* trx);
404-
405-
AqlValueMaterializer(AqlValueMaterializer const& other);
406-
407-
// cppcheck-suppress operatorEqVarError
408-
AqlValueMaterializer& operator=(AqlValueMaterializer const& other);
409-
410-
AqlValueMaterializer(AqlValueMaterializer&& other) noexcept;
411-
412-
// cppcheck-suppress operatorEqVarError
413-
AqlValueMaterializer& operator=(AqlValueMaterializer&& other) noexcept;
414-
415-
~AqlValueMaterializer();
416-
417-
arangodb::velocypack::Slice slice(AqlValue const& value, bool resolveExternals);
418-
419-
transaction::Methods* trx;
420-
AqlValue materialized;
421-
bool hasCopied;
422-
};
423-
424406
static_assert(sizeof(AqlValue) == 16, "invalid AqlValue size");
425407

426408
} // namespace aql

0 commit comments

Comments
 (0)
0