From 6e8e93bffac8a4728f7f9543df867060f4567a66 Mon Sep 17 00:00:00 2001 From: dutor <440396+dutor@users.noreply.github.com> Date: Mon, 13 May 2019 11:16:27 +0800 Subject: [PATCH] Support IP:Port semantically (#356) * Support IP:Port semantically * Address @dangleptr's comments * Fixed stupid compiling error --- src/graph/test/SchemaTest.cpp | 4 ++-- src/parser/AdminSentences.cpp | 6 ++++-- src/parser/AdminSentences.h | 21 ++++++++++----------- src/parser/parser.yy | 29 +++++++++++++++++++++-------- src/parser/scanner.lex | 9 +++++++++ src/parser/test/CMakeLists.txt | 10 +++++++++- src/parser/test/ParserTest.cpp | 4 ++-- src/parser/test/ScannerTest.cpp | 2 ++ 8 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/graph/test/SchemaTest.cpp b/src/graph/test/SchemaTest.cpp index 083408144de..20501e9620a 100644 --- a/src/graph/test/SchemaTest.cpp +++ b/src/graph/test/SchemaTest.cpp @@ -31,7 +31,7 @@ TEST_F(SchemaTest, metaCommunication) { ASSERT_NE(nullptr, client); { cpp2::ExecutionResponse resp; - std::string query = "ADD HOSTS(\"127.0.0.1:1000\", \"127.0.0.1:1100\")"; + std::string query = "ADD HOSTS 127.0.0.1:1000, 127.0.0.1:1100"; auto code = client->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } @@ -243,7 +243,7 @@ TEST_F(SchemaTest, metaCommunication) { } { cpp2::ExecutionResponse resp; - std::string query = "REMOVE HOSTS(\"127.0.0.1:1000\", \"127.0.0.1:1100\")"; + std::string query = "REMOVE HOSTS 127.0.0.1:1000, 127.0.0.1:1100"; auto code = client->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); } diff --git a/src/parser/AdminSentences.cpp b/src/parser/AdminSentences.cpp index 84f7d725fb7..5cd41a43ac2 100644 --- a/src/parser/AdminSentences.cpp +++ b/src/parser/AdminSentences.cpp @@ -31,8 +31,10 @@ std::string ShowSentence::toString() const { std::string HostList::toString() const { std::string buf; buf.reserve(256); - for (auto &host : hostStrs_) { - buf += *host; + for (auto &host : hosts_) { + buf += network::NetworkUtils::intToIPv4(host->first); + buf += ":"; + buf += std::to_string(host->second); buf += ","; } buf.resize(buf.size() - 1); diff --git a/src/parser/AdminSentences.h b/src/parser/AdminSentences.h index 51f8d81dcb5..fd117697431 100644 --- a/src/parser/AdminSentences.h +++ b/src/parser/AdminSentences.h @@ -58,24 +58,23 @@ inline std::ostream& operator<<(std::ostream &os, ShowSentence::ShowType type) { class HostList final { public: - void addHost(std::string *hoststr) { - hostStrs_.emplace_back(hoststr); + void addHost(HostAddr *addr) { + hosts_.emplace_back(addr); } std::string toString() const; - std::vector toHosts() const { + std::vector hosts() const { std::vector result; - result.resize(hostStrs_.size()); - auto getHostAddr = [] (const auto &ptr) { - return network::NetworkUtils::toHostAddr(folly::trimWhitespace(*(ptr.get()))); - }; - std::transform(hostStrs_.begin(), hostStrs_.end(), result.begin(), getHostAddr); + result.reserve(hosts_.size()); + for (auto &host : hosts_) { + result.emplace_back(*host); + } return result; } private: - std::vector> hostStrs_; + std::vector> hosts_; }; @@ -90,7 +89,7 @@ class AddHostsSentence final : public Sentence { } std::vector hosts() const { - return hosts_->toHosts(); + return hosts_->hosts(); } std::string toString() const override; @@ -111,7 +110,7 @@ class RemoveHostsSentence final : public Sentence { } std::vector hosts() const { - return hosts_->toHosts(); + return hosts_->hosts(); } std::string toString() const override; diff --git a/src/parser/parser.yy b/src/parser/parser.yy index c04ef5447c0..9f0cc254e7c 100644 --- a/src/parser/parser.yy +++ b/src/parser/parser.yy @@ -61,6 +61,7 @@ class GraphScanner; nebula::EdgeList *edge_list; nebula::ArgumentList *argument_list; nebula::HostList *host_list; + nebula::HostAddr *host_item; nebula::SpaceOptList *space_opt_list; nebula::SpaceOptItem *space_opt_item; nebula::AlterTagOptList *alter_tag_opt_list; @@ -94,7 +95,7 @@ class GraphScanner; /* token type specification */ %token BOOL -%token INTEGER +%token INTEGER IPV4 %token DOUBLE %token STRING VARIABLE LABEL @@ -130,12 +131,13 @@ class GraphScanner; %type update_item %type edge_list %type host_list +%type host_item %type space_opt_list %type space_opt_item %type alter_tag_opt_list %type alter_tag_opt_item -%type ttl_spec +%type ttl_spec port %type column_spec %type column_spec_list @@ -850,27 +852,27 @@ show_sentence ; add_hosts_sentence - : KW_ADD KW_HOSTS L_PAREN host_list R_PAREN { + : KW_ADD KW_HOSTS host_list { auto sentence = new AddHostsSentence(); - sentence->setHosts($4); + sentence->setHosts($3); $$ = sentence; } ; remove_hosts_sentence - : KW_REMOVE KW_HOSTS L_PAREN host_list R_PAREN { + : KW_REMOVE KW_HOSTS host_list { auto sentence = new RemoveHostsSentence(); - sentence->setHosts($4); + sentence->setHosts($3); $$ = sentence; } ; host_list - : STRING { + : host_item { $$ = new HostList(); $$->addHost($1); } - | host_list COMMA STRING { + | host_list COMMA host_item { $$ = $1; $$->addHost($3); } @@ -879,6 +881,17 @@ host_list } ; +host_item + : IPV4 COLON port { + $$ = new nebula::HostAddr(); + $$->first = $1; + $$->second = $3; + } + /* TODO(dutor) Support hostname and IPv6 */ + ; + +port : INTEGER { $$ = $1; } + create_space_sentence : KW_CREATE KW_SPACE LABEL L_PAREN space_opt_list R_PAREN { auto sentence = new CreateSpaceSentence($3); diff --git a/src/parser/scanner.lex b/src/parser/scanner.lex index 1ab4072ad25..9f846ff6ea7 100644 --- a/src/parser/scanner.lex +++ b/src/parser/scanner.lex @@ -96,6 +96,7 @@ LABEL ([a-zA-Z][_a-zA-Z0-9]*) DEC ([0-9]) HEX ([0-9a-fA-F]) OCT ([0-7]) +IP_OCTET ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) %% @@ -226,6 +227,14 @@ OCT ([0-7]) } return TokenType::LABEL; } +{IP_OCTET}(\.{IP_OCTET}){3} { + uint32_t octets[4] = {0}; + sscanf(yytext, "%i.%i.%i.%i", &octets[3], &octets[2], &octets[1], &octets[0]); + // The bytes order conforms to the one used in NetworkUtils + uint32_t ipv4 = (octets[3] << 24) | (octets[2] << 16) | (octets[1] << 8) | octets[0]; + yylval->intval = ipv4; + return TokenType::IPV4; + } 0[Xx]{HEX}+ { int64_t val = 0; sscanf(yytext, "%lx", &val); diff --git a/src/parser/test/CMakeLists.txt b/src/parser/test/CMakeLists.txt index 8713210a2f7..473ad25a3ec 100644 --- a/src/parser/test/CMakeLists.txt +++ b/src/parser/test/CMakeLists.txt @@ -3,6 +3,8 @@ add_executable( ParserTest.cpp $ $ + $ + $ ) nebula_link_libraries( parser_test @@ -17,6 +19,8 @@ add_executable( ScannerTest.cpp $ $ + $ + $ ) nebula_link_libraries( scanner_test @@ -33,6 +37,8 @@ add_executable( ExpressionTest.cpp $ $ + $ + $ ) nebula_link_libraries( expression_test @@ -45,8 +51,10 @@ nebula_add_test(expression_test) add_executable( expression_encode_decode_bm ExpressionEncodeDecodeBenchmark.cpp - $ $ + $ + $ + $ ) nebula_link_libraries( expression_encode_decode_bm diff --git a/src/parser/test/ParserTest.cpp b/src/parser/test/ParserTest.cpp index 7cf1bb34b4a..d8ad1457b0d 100644 --- a/src/parser/test/ParserTest.cpp +++ b/src/parser/test/ParserTest.cpp @@ -368,7 +368,7 @@ TEST(Parser, Find) { TEST(Parser, AdminOperation) { { GQLParser parser; - std::string query = "add hosts (\"127.0.0.1:1000\", \"127.0.0.1:9000\")"; + std::string query = "add hosts 127.0.0.1:1000, 127.0.0.1:9000"; auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } @@ -380,7 +380,7 @@ TEST(Parser, AdminOperation) { } { GQLParser parser; - std::string query = "remove hosts (\"127.0.0.1:1000\", \"127.0.0.1:9000\")"; + std::string query = "remove hosts 127.0.0.1:1000, 127.0.0.1:9000"; auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } diff --git a/src/parser/test/ScannerTest.cpp b/src/parser/test/ScannerTest.cpp index 8860cf7f5cf..ecc4db75cdb 100644 --- a/src/parser/test/ScannerTest.cpp +++ b/src/parser/test/ScannerTest.cpp @@ -332,6 +332,8 @@ TEST(Scanner, Basic) { CHECK_SEMANTIC_VALUE("+123.456", TokenType::DOUBLE, 123.456), CHECK_SEMANTIC_VALUE("-123.456", TokenType::DOUBLE, -123.456), + CHECK_SEMANTIC_VALUE("127.0.0.1", TokenType::IPV4, 0x7F000001), + CHECK_SEMANTIC_VALUE("\"Hello\"", TokenType::STRING, "Hello"), CHECK_SEMANTIC_VALUE("\"Hello\\\\\"", TokenType::STRING, "Hello\\"), CHECK_SEMANTIC_VALUE("\"He\\nllo\"", TokenType::STRING, "He\nllo"),