diff --git a/arangod/Aql/ModificationBlocks.cpp b/arangod/Aql/ModificationBlocks.cpp index 3fa2cb81bf..a44bdbd40e 100644 --- a/arangod/Aql/ModificationBlocks.cpp +++ b/arangod/Aql/ModificationBlocks.cpp @@ -588,6 +588,10 @@ AqlItemBlock* UpdateBlock::work(std::vector& blocks) { VPackSlice toUpdate = object.slice(); + if (toUpdate.isNone()) { + continue; + } + // fetch old revision OperationResult opRes = _trx->update(_collection->name, toUpdate, options); if (!isMultiple) { @@ -649,6 +653,16 @@ AqlItemBlock* UpdateBlock::work(std::vector& blocks) { UpsertBlock::UpsertBlock(ExecutionEngine* engine, UpsertNode const* ep) : ModificationBlock(engine, ep) {} +bool UpsertBlock::isShardKeyError(VPackSlice const slice) const { + TRI_ASSERT(_isDBServer); + + if (_usesDefaultSharding) { + return false; + } + + return slice.hasKey(StaticStrings::KeyString); +} + /// @brief the actual work horse for inserting data AqlItemBlock* UpsertBlock::work(std::vector& blocks) { size_t const count = countBlocksRows(blocks); @@ -758,8 +772,12 @@ AqlItemBlock* UpsertBlock::work(std::vector& blocks) { AqlValue const& insertDoc = res->getValueReference(i, insertRegisterId); VPackSlice toInsert = insertDoc.slice(); if (toInsert.isObject()) { - insertBuilder.add(toInsert); - insRows.emplace_back(dstRow); + if (_isDBServer && isShardKeyError(toInsert)) { + errorCode = TRI_ERROR_CLUSTER_MUST_NOT_SPECIFY_KEY; + } else { + insertBuilder.add(toInsert); + insRows.emplace_back(dstRow); + } } else { errorCode = TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID; } @@ -983,6 +1001,10 @@ AqlItemBlock* ReplaceBlock::work(std::vector& blocks) { } VPackSlice toUpdate = object.slice(); + + if (toUpdate.isNone()) { + continue; + } // fetch old revision OperationResult opRes = _trx->replace(_collection->name, toUpdate, options); if (!isMultiple) { diff --git a/arangod/Aql/ModificationBlocks.h b/arangod/Aql/ModificationBlocks.h index 3e50259096..ceb6fb719f 100644 --- a/arangod/Aql/ModificationBlocks.h +++ b/arangod/Aql/ModificationBlocks.h @@ -126,6 +126,9 @@ class UpsertBlock : public ModificationBlock { protected: /// @brief the actual work horse for updating data AqlItemBlock* work(std::vector&) override final; + + private: + bool isShardKeyError(arangodb::velocypack::Slice const) const; }; } // namespace arangodb::aql