backend/actions/unique_index.cc (39 lines of code) (raw):

// // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "backend/actions/unique_index.h" #include "backend/actions/action.h" #include "backend/actions/context.h" #include "backend/actions/ops.h" #include "backend/datamodel/key_range.h" #include "backend/storage/iterator.h" #include "common/errors.h" #include "absl/status/status.h" #include "zetasql/base/status_macros.h" namespace google { namespace spanner { namespace emulator { namespace backend { UniqueIndexVerifier::UniqueIndexVerifier(const Index* index) : index_(index) {} absl::Status UniqueIndexVerifier::Verify(const ActionContext* ctx, const InsertOp& op) const { if (!index_->is_unique()) { return absl::OkStatus(); } // Prefix key from the index data table. Key index_key = op.key.Prefix(index_->key_columns().size()); // Find all entries for the the given index key. ZETASQL_ASSIGN_OR_RETURN(std::unique_ptr<StorageIterator> itr, ctx->store()->Read(index_->index_data_table(), KeyRange::Prefix(index_key), {})); if (!itr->Next()) { return error::Internal( absl::StrCat("Missing entry for index: ", index_->Name(), " key: ", index_key.DebugString())); } if (itr->Next()) { // Return an error for multiple entries. return error::UniqueIndexConstraintViolation(index_->Name(), index_key.DebugString()); } ZETASQL_RETURN_IF_ERROR(itr->Status()); return absl::OkStatus(); } } // namespace backend } // namespace emulator } // namespace spanner } // namespace google