mirror of https://gitee.com/bigwinds/arangodb
[3.3] Bugfix: Fix `_rev` handling in `UPDATE`/`REPLACE` `WITH` clauses (#5967)
This commit is contained in:
parent
628dd917fc
commit
b91d22d97d
|
@ -1,6 +1,9 @@
|
||||||
v3.3.13 (XXXX-XX-XX)
|
v3.3.13 (XXXX-XX-XX)
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
* Bugfix: The AQL syntax variants `UPDATE/REPLACE k WITH d` now correctly take
|
||||||
|
_rev from k instead of d (when ignoreRevs is false) and ignore d._rev.
|
||||||
|
|
||||||
* put an upper bound on the number of documents to be scanned when using
|
* put an upper bound on the number of documents to be scanned when using
|
||||||
`db.<collection>.any()` in the RocksDB storage engine
|
`db.<collection>.any()` in the RocksDB storage engine
|
||||||
|
|
||||||
|
|
|
@ -660,6 +660,7 @@ AqlItemBlock* UpdateBlock::work(std::vector<AqlItemBlock*>& blocks) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string key;
|
std::string key;
|
||||||
|
std::string rev;
|
||||||
|
|
||||||
// loop over the complete block
|
// loop over the complete block
|
||||||
std::vector<bool> wasTaken;
|
std::vector<bool> wasTaken;
|
||||||
|
@ -678,7 +679,14 @@ AqlItemBlock* UpdateBlock::work(std::vector<AqlItemBlock*>& blocks) {
|
||||||
if (hasKeyVariable) {
|
if (hasKeyVariable) {
|
||||||
// separate key specification
|
// separate key specification
|
||||||
AqlValue const& k = res->getValueReference(i, keyRegisterId);
|
AqlValue const& k = res->getValueReference(i, keyRegisterId);
|
||||||
|
if (options.ignoreRevs) {
|
||||||
errorCode = extractKey(k, key);
|
errorCode = extractKey(k, key);
|
||||||
|
} else {
|
||||||
|
rev.clear();
|
||||||
|
// does nothing to rev unless k is an object that contains _rev,
|
||||||
|
// and _rev is a string.
|
||||||
|
errorCode = extractKeyAndRev(k, key, rev);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
errorCode = extractKey(a, key);
|
errorCode = extractKey(a, key);
|
||||||
}
|
}
|
||||||
|
@ -697,9 +705,18 @@ AqlItemBlock* UpdateBlock::work(std::vector<AqlItemBlock*>& blocks) {
|
||||||
keyBuilder.clear();
|
keyBuilder.clear();
|
||||||
keyBuilder.openObject();
|
keyBuilder.openObject();
|
||||||
keyBuilder.add(StaticStrings::KeyString, VPackValue(key));
|
keyBuilder.add(StaticStrings::KeyString, VPackValue(key));
|
||||||
|
if (!options.ignoreRevs && !rev.empty()) {
|
||||||
|
keyBuilder.add(StaticStrings::RevString, VPackValue(rev));
|
||||||
|
} else {
|
||||||
|
// we must never take _rev from the document if there is a key
|
||||||
|
// expression.
|
||||||
|
keyBuilder.add(StaticStrings::RevString,
|
||||||
|
VPackValue(VPackValueType::Null));
|
||||||
|
}
|
||||||
keyBuilder.close();
|
keyBuilder.close();
|
||||||
|
|
||||||
VPackCollection::merge(object, a.slice(), keyBuilder.slice(), false, false);
|
VPackCollection::merge(object, a.slice(), keyBuilder.slice(), false,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// use original slice for updating
|
// use original slice for updating
|
||||||
|
@ -1128,6 +1145,7 @@ AqlItemBlock* ReplaceBlock::work(std::vector<AqlItemBlock*>& blocks) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string key;
|
std::string key;
|
||||||
|
std::string rev;
|
||||||
|
|
||||||
// loop over the complete block
|
// loop over the complete block
|
||||||
std::vector<bool> wasTaken;
|
std::vector<bool> wasTaken;
|
||||||
|
@ -1146,7 +1164,14 @@ AqlItemBlock* ReplaceBlock::work(std::vector<AqlItemBlock*>& blocks) {
|
||||||
if (hasKeyVariable) {
|
if (hasKeyVariable) {
|
||||||
// separate key specification
|
// separate key specification
|
||||||
AqlValue const& k = res->getValueReference(i, keyRegisterId);
|
AqlValue const& k = res->getValueReference(i, keyRegisterId);
|
||||||
|
if (options.ignoreRevs) {
|
||||||
errorCode = extractKey(k, key);
|
errorCode = extractKey(k, key);
|
||||||
|
} else {
|
||||||
|
rev.clear();
|
||||||
|
// does nothing to rev unless k is an object that contains _rev,
|
||||||
|
// and _rev is a string.
|
||||||
|
errorCode = extractKeyAndRev(k, key, rev);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
errorCode = extractKey(a, key);
|
errorCode = extractKey(a, key);
|
||||||
}
|
}
|
||||||
|
@ -1165,9 +1190,18 @@ AqlItemBlock* ReplaceBlock::work(std::vector<AqlItemBlock*>& blocks) {
|
||||||
keyBuilder.clear();
|
keyBuilder.clear();
|
||||||
keyBuilder.openObject();
|
keyBuilder.openObject();
|
||||||
keyBuilder.add(StaticStrings::KeyString, VPackValue(key));
|
keyBuilder.add(StaticStrings::KeyString, VPackValue(key));
|
||||||
|
if (!options.ignoreRevs && !rev.empty()) {
|
||||||
|
keyBuilder.add(StaticStrings::RevString, VPackValue(rev));
|
||||||
|
} else {
|
||||||
|
// we must never take _rev from the document if there is a key
|
||||||
|
// expression.
|
||||||
|
keyBuilder.add(StaticStrings::RevString,
|
||||||
|
VPackValue(VPackValueType::Null));
|
||||||
|
}
|
||||||
keyBuilder.close();
|
keyBuilder.close();
|
||||||
|
|
||||||
VPackCollection::merge(object, a.slice(), keyBuilder.slice(), false, false);
|
VPackCollection::merge(object, a.slice(), keyBuilder.slice(), false,
|
||||||
|
true);
|
||||||
} else {
|
} else {
|
||||||
// Use the original slice for updating
|
// Use the original slice for updating
|
||||||
object.add(a.slice());
|
object.add(a.slice());
|
||||||
|
|
|
@ -193,6 +193,290 @@ function aqlUpdateOptionsSuite () {
|
||||||
let docs = buildSetOfDocs();
|
let docs = buildSetOfDocs();
|
||||||
db._query(q);
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateSingleWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `UPDATE {_key: @key, _rev: @rev, val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key, rev: d._rev});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateManyWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs
|
||||||
|
UPDATE {_key: doc._key, _rev: doc._rev, val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateEnumerationWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
UPDATE {_key: doc._key, _rev: doc._rev, val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function aqlUpdateWithOptionsSuite () {
|
||||||
|
|
||||||
|
return {
|
||||||
|
setUp, tearDown,
|
||||||
|
|
||||||
|
testUpdateWithSingleWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `UPDATE {_key: @key, _rev: "invalid"} WITH {val: "${invalid}"} IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
try {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
fail();
|
||||||
|
} catch (err) {
|
||||||
|
assertEqual(err.errorNum, errors.ERROR_ARANGO_CONFLICT.code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithManyWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs UPDATE {_key: doc._key, _rev: "invalid"} WITH {val: "${invalid}"} IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
try {
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
fail();
|
||||||
|
} catch (err) {
|
||||||
|
assertEqual(err.errorNum, errors.ERROR_ARANGO_CONFLICT.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithEnumerationWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
UPDATE {_key: doc._key, _rev: "invalid"} WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
try {
|
||||||
|
db._query(q);
|
||||||
|
fail();
|
||||||
|
} catch (err) {
|
||||||
|
assertEqual(err.errorNum, errors.ERROR_ARANGO_CONFLICT.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithSingleWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `UPDATE {_key: @key, _rev: "invalid"} WITH {val: "${invalid}"} IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithManyWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs UPDATE {_key: doc._key, _rev: "invalid"} WITH {val: "${invalid}"} IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithEnumerationWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
UPDATE {_key: doc._key, _rev: "invalid"} WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithSingleWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `UPDATE {_key: @key, _rev: "invalid"} WITH {val: "${invalid}"} IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithManyWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs UPDATE {_key: doc._key, _rev: "invalid"} WITH {val: "${invalid}"} IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithEnumerationWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
UPDATE {_key: doc._key, _rev: "invalid"} WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithSingleWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `UPDATE {_key: @key, _rev: @rev}
|
||||||
|
WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key, rev: d._rev});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithManyWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs
|
||||||
|
UPDATE {_key: doc._key, _rev: doc._rev}
|
||||||
|
WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithEnumerationWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
UPDATE {_key: doc._key, _rev: doc._rev}
|
||||||
|
WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function aqlUpdateWithRevOptionsSuite () {
|
||||||
|
|
||||||
|
return {
|
||||||
|
setUp, tearDown,
|
||||||
|
|
||||||
|
testUpdateWithRevSingleWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `UPDATE {_key: @key} WITH {_rev: "invalid", val: "${invalid}"} IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithRevManyWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs UPDATE {_key: doc._key} WITH {_rev: "invalid", val: "${invalid}"} IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithRevEnumerationWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
UPDATE {_key: doc._key} WITH {_rev: "invalid", val: "${invalid}"}
|
||||||
|
IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithRevSingleWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `UPDATE {_key: @key} WITH {_rev: "invalid", val: "${invalid}"} IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithRevManyWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs UPDATE {_key: doc._key} WITH {_rev: "invalid", val: "${invalid}"} IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithRevEnumerationWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
UPDATE {_key: doc._key} WITH {_rev: "invalid", val: "${invalid}"}
|
||||||
|
IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithRevSingleWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `UPDATE {_key: @key} WITH {_rev: "invalid", val: "${invalid}"} IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithRevManyWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs UPDATE {_key: doc._key} WITH {_rev: "invalid", val: "${invalid}"} IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testUpdateWithRevEnumerationWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
UPDATE {_key: doc._key} WITH {_rev: "invalid", val: "${invalid}"}
|
||||||
|
IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
validateDocsAreUpdated(docs, invalid, true);
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -305,12 +589,299 @@ function aqlReplaceOptionsSuite () {
|
||||||
let docs = buildSetOfDocs();
|
let docs = buildSetOfDocs();
|
||||||
db._query(q);
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceSingleWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `REPLACE {_key: @key, _rev: @rev, val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key, rev: d._rev});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceManyWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs
|
||||||
|
REPLACE {_key: doc._key, _rev: doc._rev, val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceEnumerationWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
REPLACE {_key: doc._key, _rev: doc._rev, val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function aqlReplaceWithOptionsSuite () {
|
||||||
|
|
||||||
|
return {
|
||||||
|
setUp, tearDown,
|
||||||
|
|
||||||
|
testReplaceWithSingleWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `REPLACE {_key: @key, _rev: "invalid"} WITH { val: "${invalid}" } IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
try {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
fail();
|
||||||
|
} catch (err) {
|
||||||
|
assertEqual(err.errorNum, errors.ERROR_ARANGO_CONFLICT.code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithManyWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs REPLACE {_key: doc._key, _rev: "invalid"} WITH { val: "${invalid}" } IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
try {
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
fail();
|
||||||
|
} catch (err) {
|
||||||
|
assertEqual(err.errorNum, errors.ERROR_ARANGO_CONFLICT.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithEnumerationWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
REPLACE {_key: doc._key, _rev: "invalid"} WITH { val: "${invalid}" }
|
||||||
|
IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
try {
|
||||||
|
db._query(q);
|
||||||
|
fail();
|
||||||
|
} catch (err) {
|
||||||
|
assertEqual(err.errorNum, errors.ERROR_ARANGO_CONFLICT.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithSingleWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `REPLACE {_key: @key, _rev: "invalid"} WITH { val: "${invalid}" } IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithManyWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs REPLACE {_key: doc._key, _rev: "invalid"} WITH { val: "${invalid}" } IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithEnumerationWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
REPLACE {_key: doc._key, _rev: "invalid"} WITH { val: "${invalid}" }
|
||||||
|
IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithSingleWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `REPLACE {_key: @key, _rev: "invalid"} WITH { val: "${invalid}" } IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithManyWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs REPLACE {_key: doc._key, _rev: "invalid"} WITH { val: "${invalid}" } IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithEnumerationWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
REPLACE {_key: doc._key, _rev: "invalid"} WITH { val: "${invalid}" }
|
||||||
|
IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithSingleWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `REPLACE {_key: @key, _rev: @rev}
|
||||||
|
WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key, rev: d._rev});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithManyWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs
|
||||||
|
REPLACE {_key: doc._key, _rev: doc._rev}
|
||||||
|
WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithEnumerationWithValidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
REPLACE {_key: doc._key, _rev: doc._rev}
|
||||||
|
WITH {val: "${invalid}"}
|
||||||
|
IN ${collectionName}
|
||||||
|
OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function aqlReplaceWithRevOptionsSuite () {
|
||||||
|
|
||||||
|
return {
|
||||||
|
setUp, tearDown,
|
||||||
|
|
||||||
|
testReplaceWithRevSingleWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `REPLACE {_key: @key} WITH { _rev: "invalid", val: "${invalid}" } IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithRevManyWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs REPLACE {_key: doc._key} WITH { _rev: "invalid", val: "${invalid}" } IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithRevEnumerationWithInvalidRev : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
REPLACE {_key: doc._key} WITH { _rev: "invalid", val: "${invalid}" }
|
||||||
|
IN ${collectionName} OPTIONS {ignoreRevs: false}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithRevSingleWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `REPLACE {_key: @key} WITH { _rev: "invalid", val: "${invalid}" } IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithRevManyWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs REPLACE {_key: doc._key} WITH { _rev: "invalid", val: "${invalid}" } IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithRevEnumerationWithInvalidRevIgnore : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
REPLACE {_key: doc._key} WITH { _rev: "invalid", val: "${invalid}" }
|
||||||
|
IN ${collectionName} OPTIONS {ignoreRevs: true}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithRevSingleWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `REPLACE {_key: @key} WITH { _rev: "invalid", val: "${invalid}" } IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs(1);
|
||||||
|
for (let d of docs) {
|
||||||
|
db._query(q, {key: d._key});
|
||||||
|
}
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithRevManyWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN @docs REPLACE {_key: doc._key} WITH { _rev: "invalid", val: "${invalid}" } IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs(10);
|
||||||
|
db._query(q, {docs: [...docs]});
|
||||||
|
|
||||||
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
testReplaceWithRevEnumerationWithInvalidRevDefault : function () {
|
||||||
|
const invalid = genInvalidValue();
|
||||||
|
let q = `FOR doc IN ${collectionName}
|
||||||
|
REPLACE {_key: doc._key} WITH { _rev: "invalid", val: "${invalid}" }
|
||||||
|
IN ${collectionName}`;
|
||||||
|
let docs = buildSetOfDocs();
|
||||||
|
db._query(q);
|
||||||
|
|
||||||
validateDocsAreUpdated(docs, invalid, true);
|
validateDocsAreUpdated(docs, invalid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief test suite
|
/// @brief test suite
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -687,7 +1258,11 @@ function aqlUpsertOptionsSuite () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
jsunity.run(aqlUpdateOptionsSuite);
|
jsunity.run(aqlUpdateOptionsSuite);
|
||||||
|
jsunity.run(aqlUpdateWithOptionsSuite);
|
||||||
|
jsunity.run(aqlUpdateWithRevOptionsSuite);
|
||||||
jsunity.run(aqlReplaceOptionsSuite);
|
jsunity.run(aqlReplaceOptionsSuite);
|
||||||
|
jsunity.run(aqlReplaceWithOptionsSuite);
|
||||||
|
jsunity.run(aqlReplaceWithRevOptionsSuite);
|
||||||
jsunity.run(aqlRemoveOptionsSuite);
|
jsunity.run(aqlRemoveOptionsSuite);
|
||||||
jsunity.run(aqlUpsertOptionsSuite);
|
jsunity.run(aqlUpsertOptionsSuite);
|
||||||
return jsunity.done();
|
return jsunity.done();
|
||||||
|
|
Loading…
Reference in New Issue