Remove unique from label-prop index

Summary: Remove unique feature from label-property index

Reviewers: ipaljak, mferencevic, vkasljevic

Reviewed By: mferencevic

Subscribers: tsabolcec, pullbot

Differential Revision: https://phabricator.memgraph.io/D2045
This commit is contained in:
Matija Santl 2019-05-13 17:06:16 +02:00
parent 1f93edaa88
commit f2cc41fa59
32 changed files with 111 additions and 372 deletions

View File

@ -147,7 +147,7 @@ class WorkerAccessor final : public GraphDbAccessor {
WorkerAccessor(Worker *db, tx::TransactionId tx_id)
: GraphDbAccessor(*db, tx_id) {}
void BuildIndex(storage::Label, storage::Property, bool) override {
void BuildIndex(storage::Label, storage::Property) override {
// TODO: Rethink BuildIndex API or inheritance. It's rather strange that a
// derived type blocks this functionality.
LOG(FATAL) << "BuildIndex invoked on worker.";

View File

@ -132,10 +132,8 @@ EdgeAccessor GraphDbAccessor::FindEdge(gid::Gid gid, bool current_state) {
}
void GraphDbAccessor::BuildIndex(storage::Label label,
storage::Property property,
bool unique) {
storage::Property property) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
if (unique) throw utils::NotYetImplemented("Distributed unique index");
db_.storage().index_build_tx_in_progress_.access().insert(transaction_.id_);
// on function exit remove the create index transaction from

View File

@ -467,8 +467,7 @@ class GraphDbAccessor {
* @param label - label to build for
* @param property - property to build for
*/
virtual void BuildIndex(storage::Label label, storage::Property property,
bool);
virtual void BuildIndex(storage::Label label, storage::Property property);
/// Deletes the index responisble for (label, property).
/// At the moment this isn't implemented in distributed.

View File

@ -115,9 +115,7 @@ void DumpEdge(std::ostream *os, GraphDbAccessor *dba,
void DumpIndexKey(std::ostream *os, GraphDbAccessor *dba,
const LabelPropertyIndex::Key &key) {
*os << "CREATE ";
if (key.unique_) *os << "UNIQUE ";
*os << "INDEX ON :" << dba->LabelName(key.label_) << "("
*os << "CREATE INDEX ON :" << dba->LabelName(key.label_) << "("
<< dba->PropertyName(key.property_) << ");";
}

View File

@ -138,11 +138,11 @@ EdgeAccessor GraphDbAccessor::FindEdge(gid::Gid gid, bool current_state) {
}
void GraphDbAccessor::BuildIndex(storage::Label label,
storage::Property property, bool unique) {
storage::Property property) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
// Create the index
const LabelPropertyIndex::Key key(label, property, unique);
const LabelPropertyIndex::Key key(label, property);
if (db_->storage().label_property_index_.CreateIndex(key) == false) {
throw IndexExistsException(
"Index is either being created by another transaction or already "
@ -155,9 +155,6 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
dba.PopulateIndex(key);
dba.EnableIndex(key);
dba.Commit();
} catch (const ConstraintViolationException &) {
db_->storage().label_property_index_.DeleteIndex(key);
throw;
} catch (const tx::TransactionEngineError &e) {
db_->storage().label_property_index_.DeleteIndex(key);
throw TransactionException(e.what());
@ -171,18 +168,15 @@ void GraphDbAccessor::EnableIndex(const LabelPropertyIndex::Key &key) {
// reason.
wal().Emplace(database::StateDelta::BuildIndex(
transaction_id(), key.label_, LabelName(key.label_), key.property_,
PropertyName(key.property_), key.unique_));
PropertyName(key.property_)));
}
void GraphDbAccessor::PopulateIndex(const LabelPropertyIndex::Key &key) {
for (auto vertex : Vertices(key.label_, false)) {
if (vertex.PropsAt(key.property_).type() == PropertyValue::Type::Null)
continue;
if (!db_->storage().label_property_index_.UpdateOnLabelProperty(
vertex.address(), vertex.current_)) {
throw ConstraintViolationException(
"Index couldn't be created due to constraint violation!");
}
db_->storage().label_property_index_.UpdateOnLabelProperty(vertex.address(),
vertex.current_);
}
}
@ -300,12 +294,7 @@ void GraphDbAccessor::UpdateOnAddLabel(storage::Label label,
throw ConstraintViolationException(e.what());
}
if (!db_->storage().label_property_index_.UpdateOnLabel(label, vlist_ptr,
vertex)) {
throw ConstraintViolationException(
"Node couldn't be updated due to index constraint violation!");
}
db_->storage().label_property_index_.UpdateOnLabel(label, vlist_ptr, vertex);
db_->storage().labels_index_.Update(label, vlist_ptr, vertex);
}
@ -330,11 +319,8 @@ void GraphDbAccessor::UpdateOnAddProperty(
throw ConstraintViolationException(e.what());
}
if (!db_->storage().label_property_index_.UpdateOnProperty(
property, vertex_accessor.address(), vertex)) {
throw ConstraintViolationException(
"Node couldn't be updated due to unique index violation!");
}
db_->storage().label_property_index_.UpdateOnProperty(
property, vertex_accessor.address(), vertex);
}
void GraphDbAccessor::UpdateOnRemoveProperty(
@ -552,9 +538,8 @@ std::vector<std::string> GraphDbAccessor::IndexInfo() const {
}
for (LabelPropertyIndex::Key key :
db_->storage().label_property_index_.Keys()) {
info.emplace_back(fmt::format(":{}({}){}", LabelName(key.label_),
PropertyName(key.property_),
key.unique_ ? " unique" : ""));
info.emplace_back(fmt::format(":{}({})", LabelName(key.label_),
PropertyName(key.property_)));
}
return info;
}

View File

@ -411,8 +411,7 @@ class GraphDbAccessor {
* @param label - label to build for
* @param property - property to build for
*/
void BuildIndex(storage::Label label, storage::Property property,
bool unique);
void BuildIndex(storage::Label label, storage::Property property);
/// Deletes the index responisble for (label, property).
///

View File

@ -138,11 +138,11 @@ EdgeAccessor GraphDbAccessor::FindEdge(gid::Gid gid, bool current_state) {
}
void GraphDbAccessor::BuildIndex(storage::Label label,
storage::Property property, bool unique) {
storage::Property property) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
// Create the index
const LabelPropertyIndex::Key key(label, property, unique);
const LabelPropertyIndex::Key key(label, property);
if (db_->storage().label_property_index_.CreateIndex(key) == false) {
throw IndexExistsException(
"Index is either being created by another transaction or already "
@ -155,9 +155,6 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
dba.PopulateIndex(key);
dba.EnableIndex(key);
dba.Commit();
} catch (const ConstraintViolationException &) {
db_->storage().label_property_index_.DeleteIndex(key);
throw;
} catch (const tx::TransactionEngineError &e) {
db_->storage().label_property_index_.DeleteIndex(key);
throw TransactionException(e.what());
@ -170,18 +167,15 @@ void GraphDbAccessor::EnableIndex(const LabelPropertyIndex::Key &key) {
// built at this point even if this DBA's transaction aborts for some reason.
raft()->Emplace(database::StateDelta::BuildIndex(
transaction_id(), key.label_, LabelName(key.label_), key.property_,
PropertyName(key.property_), key.unique_));
PropertyName(key.property_)));
}
void GraphDbAccessor::PopulateIndex(const LabelPropertyIndex::Key &key) {
for (auto vertex : Vertices(key.label_, false)) {
if (vertex.PropsAt(key.property_).type() == PropertyValue::Type::Null)
continue;
if (!db_->storage().label_property_index_.UpdateOnLabelProperty(
vertex.address(), vertex.current_)) {
throw ConstraintViolationException(
"Index couldn't be created due to constraint violation!");
}
db_->storage().label_property_index_.UpdateOnLabelProperty(vertex.address(),
vertex.current_);
}
}
@ -210,11 +204,7 @@ void GraphDbAccessor::UpdateLabelIndices(storage::Label label,
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
auto *vlist_ptr = vertex_accessor.address();
if (!db_->storage().label_property_index_.UpdateOnLabel(label, vlist_ptr,
vertex)) {
throw ConstraintViolationException(
"Node couldn't be updated due to index constraint violation!");
}
db_->storage().label_property_index_.UpdateOnLabel(label, vlist_ptr, vertex);
db_->storage().labels_index_.Update(label, vlist_ptr, vertex);
}
@ -222,11 +212,8 @@ void GraphDbAccessor::UpdatePropertyIndex(
storage::Property property, const RecordAccessor<Vertex> &vertex_accessor,
const Vertex *const vertex) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
if (!db_->storage().label_property_index_.UpdateOnProperty(
property, vertex_accessor.address(), vertex)) {
throw ConstraintViolationException(
"Node couldn't be updated due to index constraint violation!");
}
db_->storage().label_property_index_.UpdateOnProperty(
property, vertex_accessor.address(), vertex);
}
int64_t GraphDbAccessor::VerticesCount() const {
@ -427,9 +414,8 @@ std::vector<std::string> GraphDbAccessor::IndexInfo() const {
}
for (LabelPropertyIndex::Key key :
db_->storage().label_property_index_.Keys()) {
info.emplace_back(fmt::format(":{}({}){}", LabelName(key.label_),
PropertyName(key.property_),
key.unique_ ? " unique" : ""));
info.emplace_back(fmt::format(":{}({})", LabelName(key.label_),
PropertyName(key.property_)));
}
return info;
}

View File

@ -418,8 +418,7 @@ class GraphDbAccessor {
* @param label - label to build for
* @param property - property to build for
*/
void BuildIndex(storage::Label label, storage::Property property,
bool unique);
void BuildIndex(storage::Label label, storage::Property property);
/// Deletes the index responisble for (label, property).
///

View File

@ -142,12 +142,10 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
auto label = *it++;
RETURN_IF_NOT(it != index_value.end());
auto property = *it++;
RETURN_IF_NOT(it != index_value.end());
auto unique = *it++;
RETURN_IF_NOT(label.IsString() && property.IsString() && unique.IsBool());
RETURN_IF_NOT(label.IsString() && property.IsString());
recovery_data->indexes.emplace_back(
IndexRecoveryData{label.ValueString(), property.ValueString(),
/*create = */ true, unique.ValueBool()});
/*create = */ true});
}
// Read a list of unique constraints
@ -450,7 +448,7 @@ void RecoverWal(const fs::path &durability_dir, database::GraphDb *db,
} else {
recovery_data->indexes.emplace_back(
IndexRecoveryData{delta.label_name, delta.property_name,
/*create = */ true, delta.unique});
/*create = */ true});
}
break;
}
@ -537,7 +535,7 @@ void RecoverIndexes(database::GraphDb *db,
auto label = dba.Label(index.label);
auto property = dba.Property(index.property);
if (index.create) {
dba.BuildIndex(label, property, index.unique);
dba.BuildIndex(label, property);
} else {
dba.DeleteIndex(label, property);
}

View File

@ -17,7 +17,7 @@ namespace fs = std::filesystem;
namespace durability {
// Snapshot layout is described in durability/version.hpp
static_assert(durability::kVersion == 10,
static_assert(durability::kVersion == 11,
"Wrong snapshot version, please update!");
namespace {
@ -50,7 +50,6 @@ bool Encode(const fs::path &snapshot_file, database::GraphDb &db,
for (const auto &key : dba.GetIndicesKeys()) {
index_vec.emplace_back(dba.LabelName(key.label_));
index_vec.emplace_back(dba.PropertyName(key.property_));
index_vec.emplace_back(key.unique_);
}
encoder.WriteList(index_vec);
}

View File

@ -103,14 +103,12 @@ StateDelta StateDelta::RemoveEdge(tx::TransactionId tx_id, gid::Gid edge_id) {
StateDelta StateDelta::BuildIndex(tx::TransactionId tx_id, storage::Label label,
const std::string &label_name,
storage::Property property,
const std::string &property_name,
bool unique) {
const std::string &property_name) {
StateDelta op(StateDelta::Type::BUILD_INDEX, tx_id);
op.label = label;
op.label_name = label_name;
op.property = property;
op.property_name = property_name;
op.unique = unique;
return op;
}
@ -202,7 +200,6 @@ void StateDelta::Encode(
encoder.WriteString(label_name);
encoder.WriteInt(property.Id());
encoder.WriteString(property_name);
encoder.WriteBool(unique);
break;
case Type::DROP_INDEX:
encoder.WriteInt(label.Id());
@ -305,7 +302,6 @@ std::optional<StateDelta> StateDelta::Decode(
DECODE_MEMBER(label_name, ValueString)
DECODE_MEMBER_CAST(property, ValueInt, storage::Property)
DECODE_MEMBER(property_name, ValueString)
DECODE_MEMBER(unique, ValueBool)
break;
case Type::DROP_INDEX:
DECODE_MEMBER_CAST(label, ValueInt, storage::Label)

View File

@ -45,8 +45,7 @@ cpp<#
(value "PropertyValue" :initval "PropertyValue::Null")
(label "storage::Label")
(label-name "std::string")
(check-empty :bool)
(unique :bool))
(check-empty :bool))
(:documentation
"Describes single change to the database state. Used for durability (WAL).
@ -71,7 +70,7 @@ in StateDeltas.")
remove-label ;; vertex_id, label, label_name
remove-vertex ;; vertex_id, check_empty
remove-edge ;; edge_id
build-index ;; label, label_name, property, property_name, unique
build-index ;; label, label_name, property, property_name
drop-index ;; label, label_name, property, property_name
build-unique_constraint ;; label, label_name, properties, property_names
drop-unique_constraint ;; label, label_name, properties, property_names
@ -128,7 +127,7 @@ omitted in the comment."))
static StateDelta BuildIndex(tx::TransactionId tx_id, storage::Label label,
const std::string &label_name,
storage::Property property,
const std::string &property_name, bool unique);
const std::string &property_name);
static StateDelta DropIndex(tx::TransactionId tx_id, storage::Label label,
const std::string &label_name,
storage::Property property,

View File

@ -15,7 +15,7 @@ constexpr std::array<uint8_t, 4> kSnapshotMagic{{'M', 'G', 's', 'n'}};
constexpr std::array<uint8_t, 4> kWalMagic{{'M', 'G', 'w', 'l'}};
// The current default version of snapshot and WAL encoding / decoding.
constexpr int64_t kVersion{10};
constexpr int64_t kVersion{11};
// Snapshot format (version 10):
// 1) Magic number + snapshot version

View File

@ -71,12 +71,10 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
auto label = *it++;
RETURN_IF_NOT(it != index_value.end());
auto property = *it++;
RETURN_IF_NOT(it != index_value.end());
auto unique = *it++;
RETURN_IF_NOT(label.IsString() && property.IsString() && unique.IsBool());
RETURN_IF_NOT(label.IsString() && property.IsString());
recovery_data->indexes.emplace_back(
IndexRecoveryData{label.ValueString(), property.ValueString(),
/*create = */ true, unique.ValueBool()});
/*create = */ true});
}
auto dba = db->Access();
@ -162,7 +160,7 @@ void RecoverIndexes(database::GraphDb *db,
auto label = dba.Label(index.label);
auto property = dba.Property(index.property);
if (index.create) {
dba.BuildIndex(label, property, index.unique);
dba.BuildIndex(label, property);
} else {
dba.DeleteIndex(label, property);
}

View File

@ -17,7 +17,7 @@ namespace fs = std::filesystem;
namespace durability {
// Snapshot layout is described in durability/version.hpp
static_assert(durability::kVersion == 8,
static_assert(durability::kVersion == 9,
"Wrong snapshot version, please update!");
namespace {
@ -38,7 +38,6 @@ bool Encode(const fs::path &snapshot_file, database::GraphDb &db,
for (const auto &key : dba.GetIndicesKeys()) {
index_vec.emplace_back(dba.LabelName(key.label_));
index_vec.emplace_back(dba.PropertyName(key.property_));
index_vec.emplace_back(key.unique_);
}
encoder.WriteList(index_vec);
}

View File

@ -103,14 +103,12 @@ StateDelta StateDelta::RemoveEdge(tx::TransactionId tx_id, gid::Gid edge_id) {
StateDelta StateDelta::BuildIndex(tx::TransactionId tx_id, storage::Label label,
const std::string &label_name,
storage::Property property,
const std::string &property_name,
bool unique) {
const std::string &property_name) {
StateDelta op(StateDelta::Type::BUILD_INDEX, tx_id);
op.label = label;
op.label_name = label_name;
op.property = property;
op.property_name = property_name;
op.unique = unique;
return op;
}
@ -182,7 +180,6 @@ void StateDelta::Encode(
encoder.WriteString(label_name);
encoder.WriteInt(property.Id());
encoder.WriteString(property_name);
encoder.WriteBool(unique);
break;
case Type::DROP_INDEX:
encoder.WriteInt(label.Id());
@ -264,7 +261,6 @@ std::optional<StateDelta> StateDelta::Decode(
DECODE_MEMBER(label_name, ValueString)
DECODE_MEMBER_CAST(property, ValueInt, storage::Property)
DECODE_MEMBER(property_name, ValueString)
DECODE_MEMBER(unique, ValueBool)
break;
case Type::DROP_INDEX:
DECODE_MEMBER_CAST(label, ValueInt, storage::Label)
@ -337,8 +333,7 @@ void StateDelta::Apply(GraphDbAccessor &dba) const {
break;
}
case Type::BUILD_INDEX: {
dba.BuildIndex(dba.Label(label_name), dba.Property(property_name),
unique);
dba.BuildIndex(dba.Label(label_name), dba.Property(property_name));
break;
}
case Type::DROP_INDEX: {

View File

@ -38,8 +38,7 @@ cpp<#
(value "PropertyValue" :initval "PropertyValue::Null")
(label "storage::Label")
(label-name "std::string")
(check-empty :bool)
(unique :bool))
(check-empty :bool))
(:documentation
"Describes single change to the database state. Used for state communication
over network in HA.
@ -65,7 +64,7 @@ in StateDeltas.")
remove-label ;; vertex_id, label, label_name
remove-vertex ;; vertex_id, check_empty
remove-edge ;; edge_id
build-index ;; label, label_name, property, property_name, unique
build-index ;; label, label_name, property, property_name
drop-index ;; label, label_name, property, property_name
no-op ;; no-op state delta required by Raft protocol
)
@ -122,7 +121,7 @@ omitted in the comment.")
static StateDelta BuildIndex(tx::TransactionId tx_id, storage::Label label,
const std::string &label_name,
storage::Property property,
const std::string &property_name, bool unique);
const std::string &property_name);
static StateDelta DropIndex(tx::TransactionId tx_id, storage::Label label,
const std::string &label_name,
storage::Property property,

View File

@ -14,9 +14,9 @@ namespace durability {
constexpr std::array<uint8_t, 6> kSnapshotMagic{{'M', 'G', 'H', 'A', 's', 'n'}};
// The current default version of snapshot and WAL encoding / decoding.
constexpr int64_t kVersion{8};
constexpr int64_t kVersion{9};
// Snapshot format (version 8):
// Snapshot format (version 9):
// 1) Magic number + snapshot version
//
// 2) A list of label+property indices.

View File

@ -547,22 +547,24 @@ Callback HandleIndexQuery(IndexQuery *index_query,
Callback callback;
switch (index_query->action_) {
case IndexQuery::Action::CREATE:
case IndexQuery::Action::CREATE_UNIQUE:
#ifdef MG_SINGLE_NODE
throw QueryRuntimeException(
"Unique index is not supported, use unique constraint instead ");
#else
throw QueryRuntimeException("Unique index is not supported");
#endif
case IndexQuery::Action::CREATE:
callback.fn = [action, label, properties, db_accessor,
invalidate_plan_cache] {
try {
CHECK(properties.size() == 1);
db_accessor->BuildIndex(label, properties[0],
action == IndexQuery::Action::CREATE_UNIQUE);
db_accessor->BuildIndex(label, properties[0]);
invalidate_plan_cache();
} catch (const database::ConstraintViolationException &e) {
throw QueryRuntimeException(e.what());
} catch (const database::IndexExistsException &e) {
if (action == IndexQuery::Action::CREATE_UNIQUE) {
throw QueryRuntimeException(e.what());
}
// Otherwise ignore creating an existing index.
// Ignore creating an existing index.
} catch (const database::TransactionException &e) {
throw QueryRuntimeException(e.what());
}

View File

@ -38,14 +38,10 @@ class LabelPropertyIndex {
public:
const storage::Label label_;
const storage::Property property_;
bool unique_{false};
Key(storage::Label label, storage::Property property)
: label_(label), property_(property) {}
Key(storage::Label label, storage::Property property, bool unique)
: label_(label), property_(property), unique_(unique) {}
// Comparison operators - we need them to keep this sorted inside skiplist.
bool operator<(const Key &other) const {
if (this->label_ != other.label_) return this->label_ < other.label_;
@ -77,37 +73,16 @@ class LabelPropertyIndex {
*/
void DeleteIndex(const Key &key) { indices_.access().remove(key); }
/** NOTE: All update methods aren't supporting the case where two threads
* try to update the index with the same value. If both of them conclude that
* the insert is valid, one will insert first and that makes the second insert
* invalid if the unique constraint set.
*/
/**
* @brief - Updates all indexes which should contain this vertex.
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in vlist)
*/
bool UpdateOnLabelProperty(mvcc::VersionList<Vertex> *const vlist,
void UpdateOnLabelProperty(mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
const auto &labels = vertex->labels_;
// We need to check if the given vertex can be inserted in all indexes
auto access = indices_.access();
for (auto &index : access) {
if (!index.first.unique_) continue;
// Vertex has the given label
if (std::find(labels.begin(), labels.end(), index.first.label_) ==
labels.end())
continue;
auto prop = vertex->properties_.at(index.first.property_);
if (prop.type() != PropertyValue::Type::Null) {
if (!CheckUniqueConstraint(*index.second, prop, vlist, vertex)) {
return false;
}
}
}
for (auto &index : access) {
for (auto &index : indices_.access()) {
// Vertex has the given label
if (std::find(labels.begin(), labels.end(), index.first.label_) ==
labels.end())
@ -117,7 +92,6 @@ class LabelPropertyIndex {
Insert(*index.second, prop, vlist, vertex);
}
}
return true;
}
/**
@ -128,23 +102,11 @@ class LabelPropertyIndex {
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in vlist)
*/
bool UpdateOnLabel(storage::Label label,
void UpdateOnLabel(storage::Label label,
mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
// We need to check if the given vertex can be inserted in all indexes
auto access = indices_.access();
for (auto &index : access) {
if (!index.first.unique_) continue;
if (index.first.label_ != label) continue;
auto prop = vertex->properties_.at(index.first.property_);
if (prop.type() != PropertyValue::Type::Null) {
if (!CheckUniqueConstraint(*index.second, prop, vlist, vertex)) {
return false;
}
}
}
for (auto &index : access) {
for (auto &index : indices_.access()) {
if (index.first.label_ != label) continue;
auto prop = vertex->properties_.at(index.first.property_);
if (prop.type() != PropertyValue::Type::Null) {
@ -152,7 +114,6 @@ class LabelPropertyIndex {
Insert(*index.second, prop, vlist, vertex);
}
}
return true;
}
/**
@ -163,28 +124,11 @@ class LabelPropertyIndex {
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in vlist)
*/
bool UpdateOnProperty(storage::Property property,
void UpdateOnProperty(storage::Property property,
mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
const auto &labels = vertex->labels_;
// We need to check if the given vertex can be inserted in all indexes
auto access = indices_.access();
for (auto &index : access) {
if (!index.first.unique_) continue;
if (index.first.property_ != property) continue;
if (std::find(labels.begin(), labels.end(), index.first.label_) !=
labels.end()) {
// Label exists and vertex should be added to skiplist.
if (!CheckUniqueConstraint(*index.second,
vertex->properties_.at(property), vlist,
vertex)) {
return false;
}
}
}
for (auto &index : access) {
for (auto &index : indices_.access()) {
if (index.first.property_ != property) continue;
if (std::find(labels.begin(), labels.end(), index.first.label_) !=
labels.end()) {
@ -192,7 +136,6 @@ class LabelPropertyIndex {
Insert(*index.second, vertex->properties_.at(property), vlist, vertex);
}
}
return true;
}
/**
@ -526,35 +469,6 @@ class LabelPropertyIndex {
const Vertex *const record_{nullptr};
};
/**
* @brief - Check if an insert is valid due to the unique constraint
* @param index - into which index to add
* @param value - value which to add
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in
* vlist)
* @param unique - unique constraint on index
* @return bool - true if valid, false otherwise
*/
bool CheckUniqueConstraint(SkipList<IndexEntry> &index,
const PropertyValue &value,
mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
auto access = index.access();
auto it = access.find_or_larger(IndexEntry{value, nullptr, nullptr});
// If not found.
if (it == access.end()) {
return true;
}
// If not equal.
if (IndexEntry::Less(it->value_, value) ||
IndexEntry::Less(value, it->value_)) {
return true;
}
return vlist->cypher_id() == it->vlist_->cypher_id();
}
/**
* @brief - Insert value, vlist, vertex into corresponding index (key) if
* the index exists.
@ -563,12 +477,10 @@ class LabelPropertyIndex {
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in
* vlist)
* @param unique - unique constraint on index
*/
void Insert(SkipList<IndexEntry> &index, const PropertyValue &value,
mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
// Property exists and vertex should be added to skiplist.
index.access().insert(IndexEntry{value, vlist, vertex});
}

View File

@ -38,14 +38,10 @@ class LabelPropertyIndex {
public:
const storage::Label label_;
const storage::Property property_;
bool unique_{false};
Key(storage::Label label, storage::Property property)
: label_(label), property_(property) {}
Key(storage::Label label, storage::Property property, bool unique)
: label_(label), property_(property), unique_(unique) {}
// Comparison operators - we need them to keep this sorted inside skiplist.
bool operator<(const Key &other) const {
if (this->label_ != other.label_) return this->label_ < other.label_;
@ -75,41 +71,18 @@ class LabelPropertyIndex {
/**
* Returns if it succeeded in deleting the index and freeing the index memory
*/
void DeleteIndex(const Key &key) {
indices_.access().remove(key);
}
/** NOTE: All update methods aren't supporting the case where two threads
* try to update the index with the same value. If both of them conclude that
* the insert is valid, one will insert first and that makes the second insert
* invalid if the unique constraint set.
*/
void DeleteIndex(const Key &key) { indices_.access().remove(key); }
/**
* @brief - Updates all indexes which should contain this vertex.
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in vlist)
*/
bool UpdateOnLabelProperty(mvcc::VersionList<Vertex> *const vlist,
void UpdateOnLabelProperty(mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
const auto &labels = vertex->labels_;
// We need to check if the given vertex can be inserted in all indexes
auto access = indices_.access();
for (auto &index : access) {
if (!index.first.unique_) continue;
// Vertex has the given label
if (std::find(labels.begin(), labels.end(), index.first.label_) ==
labels.end())
continue;
auto prop = vertex->properties_.at(index.first.property_);
if (prop.type() != PropertyValue::Type::Null) {
if (!CheckUniqueConstraint(*index.second, prop, vlist, vertex)) {
return false;
}
}
}
for (auto &index : access) {
for (auto &index : indices_.access()) {
// Vertex has the given label
if (std::find(labels.begin(), labels.end(), index.first.label_) ==
labels.end())
@ -119,7 +92,6 @@ class LabelPropertyIndex {
Insert(*index.second, prop, vlist, vertex);
}
}
return true;
}
/**
@ -130,23 +102,11 @@ class LabelPropertyIndex {
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in vlist)
*/
bool UpdateOnLabel(storage::Label label,
void UpdateOnLabel(storage::Label label,
mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
// We need to check if the given vertex can be inserted in all indexes
auto access = indices_.access();
for (auto &index : access) {
if (!index.first.unique_) continue;
if (index.first.label_ != label) continue;
auto prop = vertex->properties_.at(index.first.property_);
if (prop.type() != PropertyValue::Type::Null) {
if (!CheckUniqueConstraint(*index.second, prop, vlist, vertex)) {
return false;
}
}
}
for (auto &index : access) {
for (auto &index : indices_.access()) {
if (index.first.label_ != label) continue;
auto prop = vertex->properties_.at(index.first.property_);
if (prop.type() != PropertyValue::Type::Null) {
@ -154,7 +114,6 @@ class LabelPropertyIndex {
Insert(*index.second, prop, vlist, vertex);
}
}
return true;
}
/**
@ -165,28 +124,11 @@ class LabelPropertyIndex {
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in vlist)
*/
bool UpdateOnProperty(storage::Property property,
void UpdateOnProperty(storage::Property property,
mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
const auto &labels = vertex->labels_;
// We need to check if the given vertex can be inserted in all indexes
auto access = indices_.access();
for (auto &index : access) {
if (!index.first.unique_) continue;
if (index.first.property_ != property) continue;
if (std::find(labels.begin(), labels.end(), index.first.label_) !=
labels.end()) {
// Label exists and vertex should be added to skiplist.
if (!CheckUniqueConstraint(*index.second,
vertex->properties_.at(property), vlist,
vertex)) {
return false;
}
}
}
for (auto &index : access) {
for (auto &index : indices_.access()) {
if (index.first.property_ != property) continue;
if (std::find(labels.begin(), labels.end(), index.first.label_) !=
labels.end()) {
@ -194,7 +136,6 @@ class LabelPropertyIndex {
Insert(*index.second, vertex->properties_.at(property), vlist, vertex);
}
}
return true;
}
/**
@ -528,35 +469,6 @@ class LabelPropertyIndex {
const Vertex *const record_{nullptr};
};
/**
* @brief - Check if an insert is valid due to the unique constraint
* @param index - into which index to add
* @param value - value which to add
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in
* vlist)
* @param unique - unique constraint on index
* @return bool - true if valid, false otherwise
*/
bool CheckUniqueConstraint(SkipList<IndexEntry> &index,
const PropertyValue &value,
mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
auto access = index.access();
auto it = access.find_or_larger(IndexEntry{value, nullptr, nullptr});
// If not found.
if (it == access.end()) {
return true;
}
// If not equal.
if (IndexEntry::Less(it->value_, value) ||
IndexEntry::Less(value, it->value_)) {
return true;
}
return vlist->cypher_id() == it->vlist_->cypher_id();
}
/**
* @brief - Insert value, vlist, vertex into corresponding index (key) if
* the index exists.
@ -565,12 +477,10 @@ class LabelPropertyIndex {
* @param vlist - pointer to vlist entry to add
* @param vertex - pointer to vertex record entry to add (contained in
* vlist)
* @param unique - unique constraint on index
*/
void Insert(SkipList<IndexEntry> &index, const PropertyValue &value,
mvcc::VersionList<Vertex> *const vlist,
const Vertex *const vertex) {
// Property exists and vertex should be added to skiplist.
index.access().insert(IndexEntry{value, vlist, vertex});
}

View File

@ -93,7 +93,7 @@ static auto CreateIndexedVertices(int index_count, int vertex_count,
database::GraphDb &db) {
auto label = db.Access().Label("label");
auto prop = db.Access().Property("prop");
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
auto dba = db.Access();
for (int vi = 0; vi < vertex_count; ++vi) {
for (int index = 0; index < index_count; ++index) {

View File

@ -20,7 +20,7 @@ int main(int argc, char *argv[]) {
// This makes sure we update the explorer when we bump the snapshot version.
// Snapshot layout is described in durability/version.hpp
static_assert(durability::kVersion == 10,
static_assert(durability::kVersion == 11,
"Wrong snapshot version, please update!");
fs::path snapshot_path(FLAGS_snapshot_file);

View File

@ -43,7 +43,6 @@ struct DatabaseState {
struct IndexKey {
std::string label;
std::string property;
bool is_unique;
};
std::set<Vertex> vertices;
@ -70,9 +69,7 @@ bool operator<(const DatabaseState::Edge &first,
bool operator<(const DatabaseState::IndexKey &first,
const DatabaseState::IndexKey &second) {
if (first.label != second.label) return first.label < second.label;
if (first.property != second.property)
return first.property < second.property;
return first.is_unique < second.is_unique;
return first.property < second.property;
}
bool operator==(const DatabaseState::Vertex &first,
@ -89,8 +86,7 @@ bool operator==(const DatabaseState::Edge &first,
bool operator==(const DatabaseState::IndexKey &first,
const DatabaseState::IndexKey &second) {
return first.label == second.label && first.property == second.property &&
first.is_unique == second.is_unique;
return first.label == second.label && first.property == second.property;
}
bool operator==(const DatabaseState &first, const DatabaseState &second) {
@ -196,8 +192,8 @@ class DatabaseEnvironment {
// Capture all indices
std::set<DatabaseState::IndexKey> indices;
for (const auto &key : dba.GetIndicesKeys()) {
indices.insert({dba.LabelName(key.label_),
dba.PropertyName(key.property_), key.unique_});
indices.insert(
{dba.LabelName(key.label_), dba.PropertyName(key.property_)});
}
return {vertices, edges, indices};
@ -357,12 +353,12 @@ TEST(DumpTest, IndicesKeys) {
DatabaseEnvironment db;
db.CreateVertex({"Label1", "Label2"}, {{"prop", PropertyValue(10)}}, false);
db.Execute("CREATE INDEX ON :Label1(prop);");
db.Execute("CREATE UNIQUE INDEX ON :Label2(prop);");
db.Execute("CREATE INDEX ON :Label2(prop);");
auto dba = db.Access();
CypherDumpGenerator dump(&dba);
EXPECT_EQ(DumpNext(&dump), "CREATE INDEX ON :Label1(prop);");
EXPECT_EQ(DumpNext(&dump), "CREATE UNIQUE INDEX ON :Label2(prop);");
EXPECT_EQ(DumpNext(&dump), "CREATE INDEX ON :Label2(prop);");
EXPECT_EQ(DumpNext(&dump), kCreateInternalIndex);
EXPECT_EQ(DumpNext(&dump),
"CREATE (:__mg_vertex__:Label1:Label2 {__mg_id__: 0, prop: 10});");
@ -403,7 +399,7 @@ TEST(DumpTest, CheckStateSimpleGraph) {
db.CreateEdge(w, z, "Knows", {{"how", "school"}});
db.CreateEdge(w, z, "Likes", {{"how", "very much"}});
// Create few indices
db.Execute("CREATE UNIQUE INDEX ON :Person(name);");
db.Execute("CREATE INDEX ON :Person(name);");
db.Execute("CREATE INDEX ON :Person(unexisting_property);");
const auto &db_initial_state = db.GetState();

View File

@ -87,7 +87,7 @@ TEST_F(DistributedDynamicWorker, IndexExistsOnNewWorker) {
label = dba->Label("label");
property = dba->Property("property");
dba->BuildIndex(label, property, false);
dba->BuildIndex(label, property);
EXPECT_TRUE(dba->LabelPropertyIndexExists(label, property));
EXPECT_EQ(CountIterable(dba->Vertices(label, property, false)), 100);
}
@ -159,7 +159,7 @@ TEST_F(DistributedDynamicWorker, IndexExistsOnNewWorkerAfterRecovery) {
label = dba->Label("label");
property = dba->Property("property");
dba->BuildIndex(label, property, false);
dba->BuildIndex(label, property);
EXPECT_TRUE(dba->LabelPropertyIndexExists(label, property));
}

View File

@ -144,7 +144,7 @@ TEST_F(DistributedGraphDb, BuildIndexDistributed) {
{
auto dba = master().Access();
dba->BuildIndex(label, property, false);
dba->BuildIndex(label, property);
EXPECT_TRUE(dba->LabelPropertyIndexExists(label, property));
EXPECT_EQ(CountIterable(dba->Vertices(label, property, false)), 100);
}
@ -191,7 +191,7 @@ TEST_F(DistributedGraphDb, BuildIndexConcurrentInsert) {
std::this_thread::sleep_for(0.5s);
{
auto dba = master().Access();
dba->BuildIndex(label, property, false);
dba->BuildIndex(label, property);
EXPECT_TRUE(dba->LabelPropertyIndexExists(label, property));
}

View File

@ -52,7 +52,7 @@ class DbGenerator {
void BuildIndex(int seq_number) {
dba_.BuildIndex(Label(seq_number % kLabelCount),
Property(seq_number % kPropertyCount), false);
Property(seq_number % kPropertyCount));
}
EdgeAccessor RandomEdge(bool remove_from_ids = false) {
@ -376,7 +376,7 @@ TEST_F(Durability, WalEncoding) {
auto e0 = dba.InsertEdge(v0, v1, dba.EdgeType("et0"));
ASSERT_EQ(e0.gid(), gid0);
e0.PropsSet(dba.Property("p0"), std::vector<PropertyValue>{1, 2, 3});
dba.BuildIndex(dba.Label("l1"), dba.Property("p1"), false);
dba.BuildIndex(dba.Label("l1"), dba.Property("p1"));
dba.DeleteIndex(dba.Label("l1"), dba.Property("p1"));
dba.Commit();
@ -430,7 +430,6 @@ TEST_F(Durability, WalEncoding) {
EXPECT_EQ(deltas[8].type, Type::BUILD_INDEX);
EXPECT_EQ(deltas[8].label_name, "l1");
EXPECT_EQ(deltas[8].property_name, "p1");
EXPECT_EQ(deltas[8].unique, false);
EXPECT_EQ(deltas[9].type, Type::TRANSACTION_COMMIT);
// The next two deltas are the DeleteIndex internal transactions.
@ -469,7 +468,7 @@ TEST_F(Durability, SnapshotEncoding) {
e0.PropsSet(dba.Property("p0"), std::vector<PropertyValue>{1, 2, 3});
auto e1 = dba.InsertEdge(v2, v1, dba.EdgeType("et1"));
ASSERT_EQ(e1.gid(), gid1);
dba.BuildIndex(dba.Label("l1"), dba.Property("p1"), false);
dba.BuildIndex(dba.Label("l1"), dba.Property("p1"));
dba.Commit();
MakeSnapshot(db);
}
@ -501,10 +500,9 @@ TEST_F(Durability, SnapshotEncoding) {
ASSERT_TRUE(dv.IsList());
// Label property indices.
decoder.ReadValue(&dv);
ASSERT_EQ(dv.ValueList().size(), 3);
ASSERT_EQ(dv.ValueList().size(), 2);
EXPECT_EQ(dv.ValueList()[0].ValueString(), "l1");
EXPECT_EQ(dv.ValueList()[1].ValueString(), "p1");
EXPECT_EQ(dv.ValueList()[2].ValueBool(), false);
// Unique constraints
decoder.ReadValue(&dv);
@ -943,7 +941,7 @@ TEST_F(Durability, UniqueIndexRecoverySnapshotAndWal) {
auto label = dba.Label("A");
auto property = dba.Property("x");
dba.BuildIndex(label, property, true);
dba.BuildIndex(label, property);
auto v0 = dba.InsertVertex();
v0.add_label(label);
@ -987,7 +985,7 @@ TEST_F(Durability, UniqueIndexRecoveryWal) {
auto label = dba.Label("A");
auto property = dba.Property("x");
dba.BuildIndex(label, property, true);
dba.BuildIndex(label, property);
auto v0 = dba.InsertVertex();
v0.add_label(label);

View File

@ -19,7 +19,7 @@ TEST(GraphDbTest, GarbageCollectIndices) {
};
auto label = dba.Label("label");
auto property = dba.Property("property");
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
commit();
auto vertex = dba.InsertVertex();

View File

@ -104,7 +104,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuild) {
AddVertex(0);
Commit();
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
Commit();
EXPECT_EQ(dba.VerticesCount(label, property), 1);
@ -112,8 +112,8 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuild) {
// confirm there is a differentiation of indexes based on (label, property)
auto label2 = dba.Label("label2");
auto property2 = dba.Property("property2");
dba.BuildIndex(label2, property, false);
dba.BuildIndex(label, property2, false);
dba.BuildIndex(label2, property);
dba.BuildIndex(label, property2);
Commit();
EXPECT_EQ(dba.VerticesCount(label, property), 1);
@ -122,7 +122,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuild) {
}
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexDelete) {
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
Commit();
EXPECT_TRUE(dba.LabelPropertyIndexExists(label, property));
@ -133,12 +133,12 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyIndexDelete) {
}
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuildTwice) {
dba.BuildIndex(label, property, false);
EXPECT_THROW(dba.BuildIndex(label, property, false), utils::BasicException);
dba.BuildIndex(label, property);
EXPECT_THROW(dba.BuildIndex(label, property), utils::BasicException);
}
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexCount) {
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
EXPECT_EQ(dba.VerticesCount(label, property), 0);
EXPECT_EQ(Count(dba.Vertices(label, property, true)), 0);
for (int i = 0; i < 14; ++i) AddVertex(0);
@ -159,7 +159,7 @@ TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
try {
// This could either pass or throw.
dba.BuildIndex(dba.Label("l" + std::to_string(index)),
dba.Property("p" + std::to_string(index)), false);
dba.Property("p" + std::to_string(index)));
// If it throws, make sure the exception is right.
} catch (const database::TransactionException &e) {
// Nothing to see here, move along.
@ -186,7 +186,7 @@ TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
x, testing::AllOf(testing::Ge(center - 2), testing::Le(center + 2)));
TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
// add some vertices without the property
for (int i = 0; i < 20; i++) AddVertex();
@ -230,7 +230,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
#undef EXPECT_WITH_MARGIN
TEST_F(GraphDbAccessorIndex, LabelPropertyValueIteration) {
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
Commit();
// insert 10 verties and and check visibility
@ -243,7 +243,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueIteration) {
}
TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
Commit();
std::vector<PropertyValue> expected_property_value(50, 0);
@ -371,7 +371,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
class GraphDbAccessorIndexRange : public GraphDbAccessorIndex {
protected:
void SetUp() override {
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
for (int i = 0; i < 100; i++) AddVertex(i / 10);
ASSERT_EQ(Count(dba.Vertices(false)), 0);
@ -450,29 +450,3 @@ TEST_F(GraphDbAccessorIndexRange, RangeInterationIncompatibleTypes) {
EXPECT_EQ(Count(Vertices(nullopt, Inclusive(1000.0))), 100);
EXPECT_EQ(Count(Vertices(Inclusive(0.0), nullopt)), 100);
}
TEST_F(GraphDbAccessorIndex, UniqueConstraintViolationOnInsert) {
dba.BuildIndex(label, property, true);
Commit();
AddVertex(0);
EXPECT_THROW(AddVertex(0), database::ConstraintViolationException);
}
TEST_F(GraphDbAccessorIndex, UniqueConstraintViolationOnBuild) {
AddVertex(0);
AddVertex(0);
Commit();
EXPECT_THROW(dba.BuildIndex(label, property, true),
database::ConstraintViolationException);
}
TEST_F(GraphDbAccessorIndex, UniqueConstraintUpdateProperty) {
dba.BuildIndex(label, property, true);
AddVertex(0);
auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(label);
vertex_accessor.PropsSet(property, 10);
EXPECT_THROW(vertex_accessor.PropsSet(property, 0),
database::ConstraintViolationException);
}

View File

@ -39,7 +39,7 @@ class QueryCostEstimator : public ::testing::Test {
void SetUp() {
// create the index in the current db accessor and then swap it to a new one
dba.BuildIndex(label, property, false);
dba.BuildIndex(label, property);
dba = db.Access();
}

View File

@ -1594,7 +1594,7 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
vertex.PropsSet(prop, value);
}
dba.Commit();
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
}
auto dba = db.Access();
ASSERT_EQ(14, CountIterable(dba.Vertices(false)));
@ -1659,7 +1659,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
string_vertex.add_label(label);
string_vertex.PropsSet(prop, "string");
dba.Commit();
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
}
auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
@ -1696,7 +1696,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
}
dba.Commit();
}
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
// MATCH (m), (n :label {prop: m})
@ -1724,7 +1724,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
}
dba.Commit();
}
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
// MATCH (m), (n :label {prop: m})
@ -1775,7 +1775,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
vertex_with_prop.add_label(label);
vertex_with_prop.PropsSet(prop, 42);
dba.Commit();
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
}
auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
@ -1809,7 +1809,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeNull) {
vertex_with_prop.add_label(label);
vertex_with_prop.PropsSet(prop, 42);
dba.Commit();
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
}
auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
@ -1839,7 +1839,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
v.add_label(label);
v.PropsSet(prop, 2);
dba.Commit();
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
}
auto dba = db.Access();
EXPECT_EQ(1, CountIterable(dba.Vertices(false)));
@ -1879,7 +1879,7 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
dba.Commit();
}
db.Access().BuildIndex(label, prop, false);
db.Access().BuildIndex(label, prop);
// Make sure there are `vertex_count` vertices
{

View File

@ -20,7 +20,7 @@
#include "utils/timer.hpp"
// Snapshot layout is described in durability/version.hpp
static_assert(durability::kVersion == 10,
static_assert(durability::kVersion == 11,
"Wrong snapshot version, please update!");
bool ValidateNotEmpty(const char *flagname, const std::string &value) {