Skip to content
Permalink
Browse files

Fix the same name tag and edge in same space #598 (#652)

* Fix the same name tag and edge in same space #598

* Fix show tags or edges have many same tags or edge #650

* Address dutor's comment

* Rebase upstream

* Modify default install path
  • Loading branch information...
laura-ding authored and dutor committed Aug 2, 2019
1 parent 1a5b693 commit 0e3150c8d78a9816ea9158a945adda2c2a09b341
@@ -7,7 +7,7 @@
version=""
rpmbuilddir=""

prefix="/usr/local"
prefix="/usr/local/nebula"
bindir="$prefix/bin"
datadir="$prefix/scripts"
sysconfdir="$prefix/etc"
@@ -54,9 +54,6 @@ fi
echo "current version is [ $rpm_version ], release is [$rpm_release]"
echo "current rpmbuild is [ $rpmbuilddir ]"

# because of use the static third-party lib, the rpmbuild can't check the file in rpm packet, so change the check to warnning
sudo sed -i 's/^%__check_files/#&/' /usr/lib/rpm/macros

# modify nebula.spec's version
sed -i "s/@VERSION@/$rpm_version/g" nebula.spec
sed -i "s/@RELEASE@/$rpm_release/g" nebula.spec
@@ -19,7 +19,6 @@ BuildRequires: make
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libtool
BuildRequires: bison
BuildRequires: unzip
BuildRequires: readline
BuildRequires: ncurses
@@ -41,16 +40,6 @@ make -j2
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}

# After install, if config file is non-existent, copy default config file
%post
daemons=(metad graphd storaged)
for daemon in ${daemons[@]}
do
if [[ ! -f %{_install_dir}/etc/nebula-${daemon}.conf ]]; then
cp %{_install_dir}/etc/nebula-${daemon}.conf.default %{_install_dir}/etc/nebula-${daemon}.conf
fi
done

%package metad
Summary: nebula meta server daemon
Group: Applications/Databases
@@ -92,18 +81,37 @@ Group: Applications/Databases
%attr(0644,root,root) %{_sysconfdir}/nebula-metad.conf.default
%attr(0755,root,root) %{_datadir}/nebula-metad.service

# After install, if config file is non-existent, copy default config file
%post metad
if [[ ! -f %{_install_dir}/etc/nebula-metad.conf ]]; then
cp %{_install_dir}/etc/nebula-metad.conf.default %{_install_dir}/etc/nebula-metad.conf
fi


# graphd rpm include files
%files graphd
%attr(0755,root,root) %{_bindir}/nebula-graphd
%attr(0644,root,root) %config%{_sysconfdir}/nebula-graphd.conf.default
%attr(0755,root,root) %{_datadir}/nebula-graphd.service

%post graphd
if [[ ! -f %{_install_dir}/etc/nebula-graphd.conf ]]; then
cp %{_install_dir}/etc/nebula-graphd.conf.default %{_install_dir}/etc/nebula-graphd.conf
fi


# storaged rpm include files
%files storaged
%attr(0755,root,root) %{_bindir}/nebula-storaged
%attr(0644,root,root) %config%{_sysconfdir}/nebula-storaged.conf.default
%attr(0755,root,root) %{_datadir}/nebula-storaged.service

%post storaged
if [[ ! -f %{_install_dir}/etc/nebula-storaged.conf ]]; then
cp %{_install_dir}/etc/nebula-storaged.conf.default %{_install_dir}/etc/nebula-storaged.conf
fi


%files nebula
%attr(0755,root,root) %{_bindir}/nebula
%attr(0644,root,root) %{_resourcesdir}/completion.json
@@ -116,7 +124,7 @@ Group: Applications/Databases

%debug_package

# missing third-part ids
# missing not found ids
%undefine _missing_build_ids_terminate_build

%changelog
@@ -164,13 +164,19 @@ void ShowExecutor::showTags() {
std::vector<std::string> header{"Name"};
resp_->set_column_names(std::move(header));

std::set<std::string> uniqueTags;
for (auto &tag : value) {
uniqueTags.emplace(tag.get_tag_name());
}

for (auto &item : uniqueTags) {
std::vector<cpp2::ColumnValue> row;
row.resize(1);
row[0].set_str(tag.get_tag_name());
row[0].set_str(item);
rows.emplace_back();
rows.back().set_columns(std::move(row));
}

resp_->set_rows(std::move(rows));
DCHECK(onFinish_);
onFinish_();
@@ -204,10 +210,15 @@ void ShowExecutor::showEdges() {
std::vector<std::string> header{"Name"};
resp_->set_column_names(std::move(header));

std::set<std::string> uniqueEdges;
for (auto &edge : value) {
uniqueEdges.emplace(edge.get_edge_name());
}

for (auto &item : uniqueEdges) {
std::vector<cpp2::ColumnValue> row;
row.resize(1);
row[0].set_str(edge.get_edge_name());
row[0].set_str(item);
rows.emplace_back();
rows.back().set_columns(std::move(row));
}
@@ -264,6 +264,18 @@ TEST_F(SchemaTest, metaCommunication) {
};
ASSERT_TRUE(verifyResult(resp, expected));
}
{
cpp2::ExecutionResponse resp;
std::string query = "SHOW TAGS";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
std::vector<uniform_tuple_t<std::string, 1>> expected{
{"tag1"},
{"person"},
{"upper"},
};
ASSERT_TRUE(verifyResult(resp, expected));
}
// Test create edge without prop
{
cpp2::ExecutionResponse resp;
@@ -367,7 +379,6 @@ TEST_F(SchemaTest, metaCommunication) {
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
std::vector<uniform_tuple_t<std::string, 1>> expected{
{"edge1"},
{"edge1"},
{"buy"},
{"education"},
@@ -726,65 +737,51 @@ TEST_F(SchemaTest, TTLtest) {
// Edge ttl test
{
cpp2::ExecutionResponse resp;
std::string query = "CREATE EDGE person(name string, email string, "
"age int, gender string, row_timestamp timestamp)";
std::string query = "CREATE EDGE work(number string, start_time timestamp)"
"ttl_duration = 100, ttl_col = start_time";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
// TODO(YT) Use show create edge test
{
cpp2::ExecutionResponse resp;
std::string query = "DESCRIBE EDGE person";
std::string query = "DESCRIBE EDGE work";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
std::vector<uniform_tuple_t<std::string, 2>> expected{
{"name", "string"},
{"email", "string"},
{"age", "int"},
{"gender", "string"},
{"row_timestamp", "timestamp"},
{"number", "string"},
{"start_time", "timestamp"},
};
ASSERT_TRUE(verifyResult(resp, expected));
}
// TODO(YT) Use show create edge test
{
cpp2::ExecutionResponse resp;
std::string query = "CREATE EDGE man(name string, email string, "
"age int, gender string, row_timestamp timestamp)"
"ttl_duration = 100, ttl_col = row_timestamp";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
// TODO(YT) Use show create edge test
{
// Disable implicit ttl mode
cpp2::ExecutionResponse resp;
std::string query = "CREATE EDGE woman(name string, email string, "
"age int, gender string, row_timestamp timestamp)"
std::string query = "CREATE EDGE work1(number string, start_time timestamp)"
"ttl_duration = 100";
auto code = client->execute(query, resp);
ASSERT_NE(cpp2::ErrorCode::SUCCEEDED, code);
}
{
// Disable when ttl_col is not an integer column or a timestamp column
cpp2::ExecutionResponse resp;
std::string query = "CREATE EDGE woman(name string, email string, "
"age int, gender string, row_timestamp timestamp)"
std::string query = "CREATE EDGE work2(number string, start_time timestamp)"
"ttl_col = name";
auto code = client->execute(query, resp);
ASSERT_NE(cpp2::ErrorCode::SUCCEEDED, code);
}
{
cpp2::ExecutionResponse resp;
std::string query = "CREATE EDGE woman(name string, email string, "
"age int, gender string, row_timestamp timestamp)"
"ttl_duration = -100, ttl_col = row_timestamp";
std::string query = "CREATE EDGE work2(name string, number string, start_time timestamp)"
"ttl_duration = -100, ttl_col = start_time";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
// TODO(YT) Use show create edge
{
cpp2::ExecutionResponse resp;
std::string query = "CREATE EDGE only_ttl_col(name string, email string, "
std::string query = "CREATE EDGE edge_only_ttl_col(name string, email string, "
"age int, gender string, row_timestamp timestamp)"
"ttl_col = row_timestamp";
auto code = client->execute(query, resp);
@@ -793,15 +790,15 @@ TEST_F(SchemaTest, TTLtest) {
// TODO(YT) Use show create edge
{
cpp2::ExecutionResponse resp;
std::string query = "ALTER EDGE woman "
"ttl_duration = 50, ttl_col = row_timestamp";
std::string query = "ALTER EDGE work2 "
"ttl_duration = 50, ttl_col = start_time";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
// TODO(YT) Use show create edge
{
cpp2::ExecutionResponse resp;
std::string query = "ALTER EDGE woman "
std::string query = "ALTER EDGE work2 "
"Drop (name) ttl_duration = 200";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
@@ -810,39 +807,38 @@ TEST_F(SchemaTest, TTLtest) {
{
// Failed when alter tag to set ttl_col on not integer and timestamp column
cpp2::ExecutionResponse resp;
std::string query = "ALTER EDGE woman "
"ttl_col = email";
std::string query = "ALTER EDGE work2 "
"ttl_col = number";
auto code = client->execute(query, resp);
ASSERT_NE(cpp2::ErrorCode::SUCCEEDED, code);
}
// TODO(YT) Use show create edge
{
// When the column is as TTL column, droping column failed
cpp2::ExecutionResponse resp;
std::string query = "ALTER EDGE woman "
"Drop (row_timestamp)";
std::string query = "ALTER EDGE work2 "
"Drop (start_time)";
auto code = client->execute(query, resp);
ASSERT_NE(cpp2::ErrorCode::SUCCEEDED, code);
}
// TODO(YT) Use show create edge
{
// First remove TTL property, then drop column
cpp2::ExecutionResponse resp;
std::string query = "ALTER EDGE woman "
"ttl_col = age";
std::string query = "ALTER EDGE work2 CHANGE(number int) "
"ttl_col = number";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
// TODO(YT) Use show create edge
{
cpp2::ExecutionResponse resp;
std::string query = "ALTER EDGE woman "
"drop (row_timestamp)";
std::string query = "ALTER EDGE work2 "
"Drop (start_time)";
auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
}
// TODO(YT) Use show create edge

{
cpp2::ExecutionResponse resp;
std::string query = "DROP SPACE default_space";
@@ -11,24 +11,25 @@ namespace go nebula.meta
include "common.thrift"

enum ErrorCode {
SUCCEEDED = 0,
SUCCEEDED = 0,

// RPC Failure
E_DISCONNECTED = -1,
E_FAIL_TO_CONNECT = -2,
E_RPC_FAILURE = -3,
E_DISCONNECTED = -1,
E_FAIL_TO_CONNECT = -2,
E_RPC_FAILURE = -3,

E_LEADER_CHANGED = -11,
E_LEADER_CHANGED = -11,

// Operation Failure
E_NO_HOSTS = -21,
E_EXISTED = -22,
E_NOT_FOUND = -23,
E_INVALID_HOST = -24,
E_UNSUPPORTED = -25,
E_NOT_DROP = -26,
E_NO_HOSTS = -21,
E_EXISTED = -22,
E_NOT_FOUND = -23,
E_INVALID_HOST = -24,
E_UNSUPPORTED = -25,
E_NOT_DROP = -26,
E_BALANCER_RUNNING = -27,
E_CONFIG_IMMUTABLE = -28,
E_CONFLICT = -29,

// KV Failure
E_STORE_FAILURE = -31,
@@ -334,6 +334,8 @@ Status MetaClient::handleResponse(const RESP& resp) {
return Status::Error("no hosts!");
case cpp2::ErrorCode::E_CONFIG_IMMUTABLE:
return Status::CfgImmutable();
case cpp2::ErrorCode::E_CONFLICT:
return Status::Error("conflict!");
case cpp2::ErrorCode::E_LEADER_CHANGED: {
HostAddr leader(resp.get_leader().get_ip(), resp.get_leader().get_port());
{
@@ -11,6 +11,21 @@ namespace meta {

void CreateEdgeProcessor::process(const cpp2::CreateEdgeReq& req) {
CHECK_SPACE_ID_AND_RETURN(req.get_space_id());
{
// if there is an tag of the same name
// TODO: there exists race condition, we should address it in the future
folly::SharedMutex::ReadHolder rHolder(LockUtils::tagLock());
auto conflictRet = getTagId(req.get_space_id(), req.get_edge_name());
if (conflictRet.ok()) {
LOG(ERROR) << "Failed to create edge `" << req.get_edge_name()
<< "': some tag with the same name already exists.";
resp_.set_id(to(conflictRet.value(), EntryType::EDGE));
resp_.set_code(cpp2::ErrorCode::E_CONFLICT);
onFinished();
return;
}
}

folly::SharedMutex::WriteHolder wHolder(LockUtils::edgeLock());
auto ret = getEdgeType(req.get_space_id(), req.get_edge_name());
if (ret.ok()) {
@@ -19,6 +34,7 @@ void CreateEdgeProcessor::process(const cpp2::CreateEdgeReq& req) {
onFinished();
return;
}

std::vector<kvstore::KV> data;
EdgeType edgeType = autoIncrementId();
data.emplace_back(MetaServiceUtils::indexEdgeKey(req.get_space_id(), req.get_edge_name()),

0 comments on commit 0e3150c

Please sign in to comment.
You can’t perform that action at this time.