8000 Projections from Prefix Values (#20351) · trooso/arangodb@325c058 · GitHub
[go: up one dir, main page]

Skip to content

Commit 325c058

Browse files
author
Lars Maier
authored
Projections from Prefix Values (arangodb#20351)
* Added projections for prefix values. * Remove comment.
1 parent 303bddf commit 325c058

File tree

4 files changed

+73
-12
lines changed

4 files changed

+73
-12
lines changed

arangod/ClusterEngine/ClusterIndex.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,10 @@ ClusterIndex::ClusterIndex(IndexId id, LogicalCollection& collection,
9393
_prefixFields =
< 10000 /td>
9494
Index::parseFields(info.get(StaticStrings::IndexPrefixFields),
9595
/*allowEmpty*/ true, /*allowExpansion*/ false);
96-
_coveredFields =
96+
_coveredFields = Index::mergeFields(
97+
_prefixFields,
9798
Index::parseFields(info.get(StaticStrings::IndexStoredValues),
98-
/*allowEmpty*/ true, /*allowExpansion*/ false);
99+
/*allowEmpty*/ true, /*allowExpansion*/ false));
99100
}
100101

101102
// check for "estimates" attribute

arangod/RocksDBEngine/RocksDBZkdIndex.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,24 @@ class RocksDBZkdIndexIterator final : public IndexIterator {
219219
bool nextCoveringImpl(CoveringCallback const& callback,
220220
uint64_t limit) override {
221221
struct CoveringData : IndexIteratorCoveringData {
222-
explicit CoveringData(velocypack::Slice data) : _data(data) {}
223-
VPackSlice at(size_t i) const override { return _data.at(i); }
222+
CoveringData(VPackSlice prefixValues, VPackSlice storedValues)
223+
: _storedValues(storedValues),
224+
_prefixValuesLength(prefixValues.length()),
225+
_prefixValues(prefixValues) {}
226+
VPackSlice at(size_t i) const override {
227+
if (i < _prefixValuesLength) {
228+
return _prefixValues.at(i);
229+
}
230+
return _storedValues.at(i - _prefixValuesLength);
231+
}
224232
bool isArray() const noexcept override { return true; }
225-
velocypack::ValueLength length() const override { return _data.length(); }
233+
velocypack::ValueLength length() const override {
234+
return _prefixValuesLength + _storedValues.length();
235+
}
226236

227-
velocypack::Slice _data;
237+
velocypack::Slice _storedValues;
238+
std::size_t _prefixValuesLength;
239+
velocypack::Slice _prefixValues;
228240
};
229241
return findNext(
230242
[&](rocksdb::Slice key, rocksdb::Slice value) {
@@ -243,7 +255,14 @@ class RocksDBZkdIndexIterator final : public IndexIterator {
243255
return RocksDBValue::indexStoredValues(value);
244256
}
245257
});
246-
CoveringData coveringData{storedValues};
258+
auto prefixValues = std::invoke([&] {
259+
if constexpr (hasPrefix) {
260+
return RocksDBKey::indexedVPack(key);
261+
} else {
262+
return VPackSlice::emptyArraySlice();
263+
}
264+
});
265+
CoveringData coveringData{prefixValues, storedValues};
247266
std::ignore = callback(documentId, coveringData);
248267
},
249268
limit);

arangod/RocksDBEngine/RocksDBZkdIndex.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ class RocksDBZkdIndexBase : public RocksDBIndex {
4343

4444
std::vector<std::vector<basics::AttributeName>> const& coveredFields()
4545
const override {
46-
// The index only covers stored values
47-
return _storedValues;
46+
return _coveredFields;
4847
}
4948
std::vector<std::vector<basics::AttributeName>> const& prefixFields()
5049
const noexcept {

tests/js/client/aql/aql-optimizer-zkdindex-prefix-fields.js

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,18 @@ const db = arangodb.db;
2828
const aql = arangodb.aql;
2929
const {assertTrue, assertFalse, assertEqual} = jsunity.jsUnity.assertions;
3030
const _ = require("lodash");
31+
const normalize = require("@arangodb/aql-helper").normalizeProjections;
3132

3233
function optimizerRuleZkd2dIndexTestSuite() {
3334
const colName = 'UnitTestZkdIndexCollection';
3435
let col;
3536

3637
return {
3738

39+
tearDown: function () {
40+
db[colName].drop();
41+
},
42+
3843
testSimplePrefix: function () {
3944
col = db._create(colName);
4045
col.ensureIndex({
@@ -62,7 +67,6 @@ function optimizerRuleZkd2dIndexTestSuite() {
6267
assertEqual(result.length, 3);
6368
assertEqual(_.uniq(result.map(([a, b]) => b)), ["foo"]);
6469
assertEqual(result.map(([a, b]) => a).sort(), [5, 6, 7]);
65-
col.drop();
6670
},
6771

6872
testMultiPrefix: function () {
@@ -94,8 +98,46 @@ function optimizerRuleZkd2dIndexTestSuite() {
9498
assertEqual(_.uniq(result.map(([a, b, c]) => b)), ["foo"]);
9599
assertEqual(_.uniq(result.map(([a, b, c]) => c)), [-2]);
96100
assertEqual(result.map(([a, b, c]) => a).sort(), [5, 6, 7]);
97-
col.drop();
98-
}
101+
},
102+
103+
testProjections: function () {
104+
col = db._create(colName);
105+
col.ensureIndex({
106+
type: 'zkd',
107+
name: 'zkdIndex',
108+
fields: ['x', 'y'],
109+
fieldValueTypes: 'double',
110+
storedValues: ["z"],
111+
prefixFields: ["stringValue", "value"],
112+
});
113+
114+
db._query(aql`
115+
FOR str IN ["foo", "bar", "baz"]
116+
FOR v IN [1, 19, -2]
117+
FOR i IN 1..100
118+
INSERT {x: i, y: i, z: i, stringValue: str, value: v} INTO ${col}
119+
`);
120+
121+
const query = aql`
122+
FOR doc IN ${col}
123+
FILTER doc.x >= 5 && doc.y <= 7 && doc.stringValue == "foo" && doc.value == -2
124+
return [doc.z, doc.stringValue, doc.value]
125+
`;
126+
127+
const res = db._createStatement({query: query.query, bindVars: query.bindVars}).explain();
128+
const indexNodes = res.plan.nodes.filter(n => n.type === "IndexNode");
129+
assertEqual(indexNodes.length, 1);
130+
const index = indexNodes[0];
131+
assertTrue(index.indexCoversProjections, true);
132+
assertEqual(normalize(index.projections), normalize(["z", "stringValue", "value"]));
133+
134+
const result = db._createStatement({query: query.query, bindVars: query.bindVars}).execute().toArray();
135+
for (const [a, b, c] of result) {
136+
assertEqual(b, "foo");
137+
assertEqual(c, -2);
138+
assertTrue(5 <= a && a <= 7);
139+
}
140+
},
99141

100142
};
101143
}

0 commit comments

Comments
 (0)
0