From 23eed20de2d934689a22510f173b272559c2a6cb Mon Sep 17 00:00:00 2001 From: dutor <440396+dutor@users.noreply.github.com> Date: Tue, 2 Jul 2019 14:00:30 +0800 Subject: [PATCH] Fixed unary minus integer bug and support to take function call as vid (#429) * Fixed unary minus integer bug and support to take function call as vid * Fixed crash when a non-existing column referenced in PIPE * Addressed @laura-ding's comment * minor fixes * add test for unary minus * Address comments * Addressed @CPWstatic's comments --- src/common/filter/Expressions.h | 2 +- src/common/filter/test/ExpressionTest.cpp | 2 + src/graph/GoExecutor.cpp | 43 ++++++--- src/graph/InsertEdgeExecutor.cpp | 25 +++++- src/graph/InsertVertexExecutor.cpp | 10 ++- src/graph/InterimResult.cpp | 6 +- src/graph/InterimResult.h | 3 +- src/graph/test/YieldTest.cpp | 2 +- src/parser/Clauses.cpp | 20 ++++- src/parser/Clauses.h | 50 +++++++---- src/parser/MutateSentences.cpp | 20 ++--- src/parser/MutateSentences.h | 80 +++++++++-------- src/parser/parser.yy | 104 ++++++++++++++-------- src/parser/scanner.lex | 10 +-- src/parser/test/ParserTest.cpp | 13 ++- src/parser/test/ScannerTest.cpp | 7 +- 16 files changed, 257 insertions(+), 140 deletions(-) diff --git a/src/common/filter/Expressions.h b/src/common/filter/Expressions.h index f4ebfdc7e8d..6ec7866c44c 100644 --- a/src/common/filter/Expressions.h +++ b/src/common/filter/Expressions.h @@ -281,7 +281,7 @@ class Expression { }; -// $_.any_prop_name +// $-.any_prop_name or $- class InputPropertyExpression final : public Expression { public: InputPropertyExpression() { diff --git a/src/common/filter/test/ExpressionTest.cpp b/src/common/filter/test/ExpressionTest.cpp index 7582d006520..efb74ce36e7 100644 --- a/src/common/filter/test/ExpressionTest.cpp +++ b/src/common/filter/test/ExpressionTest.cpp @@ -141,7 +141,9 @@ TEST_F(ExpressionTest, LiteralContantsArithmetic) { TEST_EXPR(16 + 4 + 2, 22, Int); + TEST_EXPR(16+4+2, 22, Int); TEST_EXPR(16 - 4 - 2, 10, Int); + TEST_EXPR(16-4-2, 10, Int); TEST_EXPR(16 - (4 - 2), 14, Int); TEST_EXPR(16 * 4 * 2, 128, Int); TEST_EXPR(16 / 4 / 2, 2, Int); diff --git a/src/graph/GoExecutor.cpp b/src/graph/GoExecutor.cpp index 1087e758a4b..d640d00daa2 100644 --- a/src/graph/GoExecutor.cpp +++ b/src/graph/GoExecutor.cpp @@ -56,6 +56,7 @@ Status GoExecutor::prepare() { } while (false); if (!status.ok()) { + LOG(ERROR) << "Preparing failed: " << status; return status; } @@ -105,9 +106,7 @@ Status GoExecutor::prepareFrom() { if (clause == nullptr) { LOG(FATAL) << "From clause shall never be null"; } - if (!clause->isRef()) { - starts_ = clause->srcNodeList()->nodeIds(); - } else { + if (clause->isRef()) { auto *expr = clause->ref(); if (expr->isInputExpression()) { auto *iexpr = static_cast(expr); @@ -120,6 +119,24 @@ Status GoExecutor::prepareFrom() { // No way to happen except memory corruption LOG(FATAL) << "Unknown kind of expression"; } + break; + } + + auto vidList = clause->vidList(); + for (auto *expr : vidList) { + status = expr->prepare(); + if (!status.ok()) { + break; + } + auto value = expr->eval(); + if (!Expression::isInt(value)) { + status = Status::Error("Vertex ID should be of type integer"); + break; + } + starts_.push_back(Expression::asInt(value)); + } + if (!status.ok()) { + break; } } while (false); return status; @@ -208,22 +225,26 @@ Status GoExecutor::setupStarts() { if (!starts_.empty()) { return Status::OK(); } + const auto *inputs = inputs_.get(); // Take one column from a variable if (varname_ != nullptr) { - auto *varinput = ectx()->variableHolder()->get(*varname_); - if (varinput == nullptr) { + auto *varInputs = ectx()->variableHolder()->get(*varname_); + if (varInputs == nullptr) { return Status::Error("Variable `%s' not defined", varname_->c_str()); } - starts_ = varinput->getVIDs(*colname_); - return Status::OK(); + DCHECK(inputs == nullptr); + inputs = varInputs; } // No error happened, but we are having empty inputs - if (inputs_ == nullptr) { + if (inputs == nullptr) { return Status::OK(); } - // Take one column from the input of the pipe - DCHECK(colname_ != nullptr); - starts_ = inputs_->getVIDs(*colname_); + + auto result = inputs->getVIDs(*colname_); + if (!result.ok()) { + return std::move(result).status(); + } + starts_ = std::move(result).value(); return Status::OK(); } diff --git a/src/graph/InsertEdgeExecutor.cpp b/src/graph/InsertEdgeExecutor.cpp index ed515c4910e..415b885d737 100644 --- a/src/graph/InsertEdgeExecutor.cpp +++ b/src/graph/InsertEdgeExecutor.cpp @@ -67,9 +67,27 @@ StatusOr> InsertEdgeExecutor::prepareEdges() { auto index = 0; for (auto i = 0u; i < rows_.size(); i++) { auto *row = rows_[i]; - auto src = row->srcid(); - auto dst = row->dstid(); - auto rank = row->rank(); + auto status = row->srcid()->prepare(); + if (!status.ok()) { + return status; + } + auto v = row->srcid()->eval(); + if (!Expression::isInt(v)) { + return Status::Error("Vertex ID should be of type integer"); + } + auto src = Expression::asInt(v); + status = row->dstid()->prepare(); + if (!status.ok()) { + return status; + } + v = row->dstid()->eval(); + if (!Expression::isInt(v)) { + return Status::Error("Vertex ID should be of type integer"); + } + auto dst = Expression::asInt(v); + + int64_t rank = row->rank(); + auto expressions = row->values(); // Now default value is unsupported @@ -121,6 +139,7 @@ StatusOr> InsertEdgeExecutor::prepareEdges() { in.__isset.props = true; } } + return edges; } diff --git a/src/graph/InsertVertexExecutor.cpp b/src/graph/InsertVertexExecutor.cpp index 3cf1ba5aa7c..979a15e953f 100644 --- a/src/graph/InsertVertexExecutor.cpp +++ b/src/graph/InsertVertexExecutor.cpp @@ -80,7 +80,15 @@ StatusOr> InsertVertexExecutor::prepareVertic std::vector vertices(rows_.size()); for (auto i = 0u; i < rows_.size(); i++) { auto *row = rows_[i]; - auto id = row->id(); + auto status = row->id()->prepare(); + if (!status.ok()) { + return status; + } + auto v = row->id()->eval(); + if (!Expression::isInt(v)) { + return Status::Error("Vertex ID should be of type integer"); + } + auto id = Expression::asInt(v); auto expressions = row->values(); std::vector values; diff --git a/src/graph/InterimResult.cpp b/src/graph/InterimResult.cpp index 4a77f91a180..c3eba96272d 100644 --- a/src/graph/InterimResult.cpp +++ b/src/graph/InterimResult.cpp @@ -22,7 +22,7 @@ InterimResult::InterimResult(std::vector vids) { } -std::vector InterimResult::getVIDs(const std::string &col) const { +StatusOr> InterimResult::getVIDs(const std::string &col) const { if (!vids_.empty()) { DCHECK(rsReader_ == nullptr); return vids_; @@ -33,7 +33,9 @@ std::vector InterimResult::getVIDs(const std::string &col) const { while (iter) { VertexID vid; auto rc = iter->getVid(col, vid); - CHECK(rc == ResultType::SUCCEEDED); + if (rc != ResultType::SUCCEEDED) { + return Status::Error("Column `%s' not found", col.c_str()); + } result.emplace_back(vid); ++iter; } diff --git a/src/graph/InterimResult.h b/src/graph/InterimResult.h index bf81509c8f5..4b14ca82256 100644 --- a/src/graph/InterimResult.h +++ b/src/graph/InterimResult.h @@ -8,6 +8,7 @@ #define GRAPH_INTERIMRESULT_H_ #include "base/Base.h" +#include "base/StatusOr.h" #include "dataman/RowSetReader.h" #include "dataman/RowSetWriter.h" #include "dataman/SchemaWriter.h" @@ -36,7 +37,7 @@ class InterimResult final { return rsReader_->schema(); } - std::vector getVIDs(const std::string &col) const; + StatusOr> getVIDs(const std::string &col) const; std::vector getRows() const; // TODO(dutor) iterating interfaces on rows and columns diff --git a/src/graph/test/YieldTest.cpp b/src/graph/test/YieldTest.cpp index a3d3f7d0b42..1ff743da88b 100644 --- a/src/graph/test/YieldTest.cpp +++ b/src/graph/test/YieldTest.cpp @@ -40,7 +40,7 @@ TEST_F(YieldTest, Basic) { } { cpp2::ExecutionResponse resp; - std::string query = "YIELD 1 + 1"; + std::string query = "YIELD 1+1"; auto code = client->execute(query, resp); ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); std::vector> expected{ diff --git a/src/parser/Clauses.cpp b/src/parser/Clauses.cpp index 9983ddf6fcf..e2b2f912bfd 100644 --- a/src/parser/Clauses.cpp +++ b/src/parser/Clauses.cpp @@ -21,6 +21,7 @@ std::string StepClause::toString() const { return buf; } + std::string SourceNodeList::toString() const { std::string buf; buf.reserve(256); @@ -34,14 +35,27 @@ std::string SourceNodeList::toString() const { return buf; } +std::string VertexIDList::toString() const { + std::string buf; + buf.reserve(256); + for (auto &expr : vidList_) { + buf += expr->toString(); + buf += ","; + } + if (!buf.empty()) { + buf.resize(buf.size() - 1); + } + return buf; +} + std::string FromClause::toString() const { std::string buf; buf.reserve(256); buf += "FROM "; - if (!isRef_) { - buf += srcNodeList_->toString(); - } else { + if (isRef()) { buf += ref_->toString(); + } else { + buf += vidList_->toString(); } return buf; } diff --git a/src/parser/Clauses.h b/src/parser/Clauses.h index 6f2e7cdf268..97b651633e1 100644 --- a/src/parser/Clauses.h +++ b/src/parser/Clauses.h @@ -51,40 +51,56 @@ class SourceNodeList final { }; -class FromClause final { + +class VertexIDList final { public: - explicit FromClause(SourceNodeList *srcNodeList) { - srcNodeList_.reset(srcNodeList); - isRef_ = false; + void add(Expression *expr) { + vidList_.emplace_back(expr); } - explicit FromClause(Expression *expr) { - ref_.reset(expr); - isRef_ = true; + std::vector vidList() const { + std::vector result; + result.reserve(vidList_.size()); + for (auto &expr : vidList_) { + result.push_back(expr.get()); + } + return result; } - void setSourceNodeList(SourceNodeList *srcNodeList) { - srcNodeList_.reset(srcNodeList); + std::string toString() const; + +private: + std::vector> vidList_; +}; + + +class FromClause final { +public: + explicit FromClause(VertexIDList *vidList) { + vidList_.reset(vidList); } - SourceNodeList* srcNodeList() const { - return srcNodeList_.get(); + explicit FromClause(Expression *ref) { + ref_.reset(ref); } - Expression* ref() const { - return ref_.get(); + auto vidList() const { + return vidList_->vidList(); } - bool isRef() const { - return isRef_; + auto isRef() const { + return ref_ != nullptr; + } + + auto ref() const { + return ref_.get(); } std::string toString() const; private: - std::unique_ptr srcNodeList_; + std::unique_ptr vidList_; std::unique_ptr ref_; - bool isRef_{false}; }; diff --git a/src/parser/MutateSentences.cpp b/src/parser/MutateSentences.cpp index c35cca47cde..b3baac56fbc 100644 --- a/src/parser/MutateSentences.cpp +++ b/src/parser/MutateSentences.cpp @@ -69,7 +69,7 @@ std::string ValueList::toString() const { std::string VertexRowItem::toString() const { std::string buf; buf.reserve(256); - buf += std::to_string(id_); + buf += id_->toString(); buf += ":"; buf += "("; buf += values_->toString(); @@ -107,9 +107,9 @@ std::string EdgeRowItem::toString() const { std::string buf; buf.reserve(256); - buf += std::to_string(srcid_); + buf += srcid_->toString(); buf += "->"; - buf += std::to_string(dstid_); + buf += dstid_->toString(); if (rank_ != 0) { buf += "@"; buf += std::to_string(rank_); @@ -185,7 +185,7 @@ std::string UpdateVertexSentence::toString() const { buf += "OR INSERT "; } buf += "VERTEX "; - buf += std::to_string(vid_); + buf += vid_->toString(); buf += " SET "; buf += updateItems_->toString(); if (whereClause_ != nullptr) { @@ -209,9 +209,9 @@ std::string UpdateEdgeSentence::toString() const { buf += "OR INSERT "; } buf += "EDGE "; - buf += std::to_string(srcid_); + buf += srcid_->toString(); buf += "->"; - buf += std::to_string(dstid_); + buf += dstid_->toString(); buf += " SET "; buf += updateItems_->toString(); if (whereClause_ != nullptr) { @@ -230,7 +230,7 @@ std::string DeleteVertexSentence::toString() const { std::string buf; buf.reserve(256); buf += "DELETE VERTEX "; - buf += srcNodeList_->toString(); + buf += vidList_->toString(); if (whereClause_ != nullptr) { buf += " "; buf += whereClause_->toString(); @@ -241,10 +241,10 @@ std::string DeleteVertexSentence::toString() const { std::string EdgeList::toString() const { std::string buf; buf.reserve(256); - for (auto edge : edges_) { - buf += std::to_string(edge.first); + for (auto &edge : edges_) { + buf += edge.first->toString(); buf += "->"; - buf += std::to_string(edge.second); + buf += edge.second->toString(); buf += ","; } if (!buf.empty()) { diff --git a/src/parser/MutateSentences.h b/src/parser/MutateSentences.h index de3f57b2b67..04cfeea5916 100644 --- a/src/parser/MutateSentences.h +++ b/src/parser/MutateSentences.h @@ -101,13 +101,13 @@ class ValueList final { class VertexRowItem final { public: - VertexRowItem(int64_t id, ValueList *values) { - id_ = id; + VertexRowItem(Expression *id, ValueList *values) { + id_.reset(id); values_.reset(values); } - int64_t id() const { - return id_; + Expression* id() const { + return id_.get(); } std::vector values() const { @@ -117,7 +117,7 @@ class VertexRowItem final { std::string toString() const; private: - int64_t id_; + std::unique_ptr id_; std::unique_ptr values_; }; @@ -185,28 +185,28 @@ class InsertVertexSentence final : public Sentence { class EdgeRowItem final { public: - EdgeRowItem(int64_t srcid, int64_t dstid, ValueList *values) { - srcid_ = srcid; - dstid_ = dstid; + EdgeRowItem(Expression *srcid, Expression *dstid, ValueList *values) { + srcid_.reset(srcid); + dstid_.reset(dstid); values_.reset(values); } - EdgeRowItem(int64_t srcid, int64_t dstid, int64_t rank, ValueList *values) { - srcid_ = srcid; - dstid_ = dstid; + EdgeRowItem(Expression *srcid, Expression *dstid, int64_t rank, ValueList *values) { + srcid_.reset(srcid); + dstid_.reset(dstid); rank_ = rank; values_.reset(values); } - int64_t srcid() const { - return srcid_; + auto srcid() const { + return srcid_.get(); } - int64_t dstid() const { - return dstid_; + auto dstid() const { + return dstid_.get(); } - int64_t rank() const { + auto rank() const { return rank_; } @@ -217,9 +217,9 @@ class EdgeRowItem final { std::string toString() const; private: - int64_t srcid_{0}; - int64_t dstid_{0}; - int64_t rank_{0}; + std::unique_ptr srcid_; + std::unique_ptr dstid_; + int64_t rank_; std::unique_ptr values_; }; @@ -326,8 +326,8 @@ class UpdateVertexSentence final : public Sentence { insertable_ = insertable; } - void setVid(int64_t vid) { - vid_ = vid; + void setVid(Expression *vid) { + vid_.reset(vid); } void setUpdateList(UpdateList *items) { @@ -346,7 +346,7 @@ class UpdateVertexSentence final : public Sentence { private: bool insertable_{false}; - int64_t vid_{0}; + std::unique_ptr vid_; std::unique_ptr updateItems_; std::unique_ptr whereClause_; std::unique_ptr yieldClause_; @@ -359,12 +359,12 @@ class UpdateEdgeSentence final : public Sentence { insertable_ = insertable; } - void setSrcId(int64_t srcid) { - srcid_ = srcid; + void setSrcId(Expression *srcid) { + srcid_.reset(srcid); } - void setDstId(int64_t dstid) { - dstid_ = dstid; + void setDstId(Expression *dstid) { + dstid_.reset(dstid); } void setRank(int64_t rank) { @@ -387,23 +387,24 @@ class UpdateEdgeSentence final : public Sentence { private: bool insertable_{false}; - int64_t srcid_{0}; - int64_t dstid_{0}; + std::unique_ptr srcid_; + std::unique_ptr dstid_; int64_t rank_{0}; std::unique_ptr updateItems_; std::unique_ptr whereClause_; std::unique_ptr yieldClause_; }; + class DeleteVertexSentence final : public Sentence { public: - explicit DeleteVertexSentence(SourceNodeList *srcNodeList) { - srcNodeList_.reset(srcNodeList); + explicit DeleteVertexSentence(VertexIDList *vidList) { + vidList_.reset(vidList); kind_ = Kind::kDeleteVertex; } - const SourceNodeList* srcNodeLists() const { - return srcNodeList_.get(); + auto vidList() const { + return vidList_->vidList(); } void setWhereClause(WhereClause *clause) { @@ -417,26 +418,29 @@ class DeleteVertexSentence final : public Sentence { std::string toString() const override; private: - std::unique_ptr srcNodeList_; - std::unique_ptr whereClause_; + std::unique_ptr vidList_; + std::unique_ptr whereClause_; }; + class EdgeList final { public: - void addEdge(int64_t srcid, int64_t dstid) { - edges_.emplace_back(std::make_pair(srcid, dstid)); + void addEdge(Expression *srcid, Expression *dstid) { + edges_.emplace_back(srcid, dstid); } - const std::vector>& edges() const { + const auto& edges() const { return edges_; } std::string toString() const; private: - std::vector> edges_; + using EdgeItem = std::pair, std::unique_ptr>; + std::vector edges_; }; + class DeleteEdgeSentence final : public Sentence { public: explicit DeleteEdgeSentence(EdgeList *edgeList) { diff --git a/src/parser/parser.yy b/src/parser/parser.yy index 6a35875b522..34f4e3e0087 100644 --- a/src/parser/parser.yy +++ b/src/parser/parser.yy @@ -42,7 +42,7 @@ class GraphScanner; nebula::ColumnType type; nebula::StepClause *step_clause; nebula::FromClause *from_clause; - nebula::SourceNodeList *src_node_list; + nebula::VertexIDList *vid_list; nebula::OverClause *over_clause; nebula::WhereClause *where_clause; nebula::YieldClause *yield_clause; @@ -97,7 +97,7 @@ class GraphScanner; %token KW_ORDER KW_ASC /* symbols */ %token L_PAREN R_PAREN L_BRACKET R_BRACKET L_BRACE R_BRACE COMMA -%token PIPE OR AND LT LE GT GE EQ NE ADD SUB MUL DIV MOD NOT NEG ASSIGN +%token PIPE OR AND LT LE GT GE EQ NE PLUS MINUS MUL DIV MOD NOT NEG ASSIGN %token DOT COLON SEMICOLON L_ARROW R_ARROW AT %token ID_PROP TYPE_PROP SRC_ID_PROP DST_ID_PROP RANK_PROP INPUT_REF DST_REF SRC_REF @@ -111,18 +111,19 @@ class GraphScanner; %type expression logic_or_expression logic_and_expression %type relational_expression multiplicative_expression additive_expression %type unary_expression primary_expression equality_expression -%type ref_expression %type src_ref_expression %type dst_ref_expression %type input_ref_expression %type var_ref_expression %type alias_ref_expression +%type vid_ref_expression +%type vid %type function_call_expression %type argument_list %type type_spec %type step_clause %type from_clause -%type id_list +%type vid_list %type over_clause %type where_clause %type yield_clause @@ -152,7 +153,7 @@ class GraphScanner; %type order_factor %type order_factors -%type port +%type port unary_integer rank %type column_spec %type column_spec_list @@ -251,6 +252,10 @@ input_ref_expression : INPUT_REF DOT LABEL { $$ = new InputPropertyExpression($3); } + | INPUT_REF { + // To reference the `id' column implicitly + $$ = new InputPropertyExpression(new std::string("id")); + } ; src_ref_expression @@ -311,10 +316,10 @@ argument_list unary_expression : primary_expression { $$ = $1; } - | ADD primary_expression { + | PLUS primary_expression { $$ = new UnaryExpression(UnaryExpression::PLUS, $2); } - | SUB primary_expression { + | MINUS primary_expression { $$ = new UnaryExpression(UnaryExpression::NEGATE, $2); } | NOT primary_expression { @@ -349,10 +354,10 @@ multiplicative_expression additive_expression : multiplicative_expression { $$ = $1; } - | additive_expression ADD multiplicative_expression { + | additive_expression PLUS multiplicative_expression { $$ = new ArithmeticExpression($1, ArithmeticExpression::ADD, $3); } - | additive_expression SUB multiplicative_expression { + | additive_expression MINUS multiplicative_expression { $$ = new ArithmeticExpression($1, ArithmeticExpression::SUB, $3); } ; @@ -429,33 +434,52 @@ step_clause ; from_clause - : KW_FROM id_list { - auto from = new FromClause($2); - $$ = from; + : KW_FROM vid_list { + $$ = new FromClause($2); } - | KW_FROM ref_expression { - auto from = new FromClause($2); - $$ = from; + | KW_FROM vid_ref_expression { + $$ = new FromClause($2); } ; -ref_expression - : input_ref_expression { +vid_list + : vid { + $$ = new VertexIDList(); + $$->add($1); + } + | vid_list COMMA vid { $$ = $1; + $$->add($3); } - | var_ref_expression { + ; + +vid + : unary_integer { + $$ = new PrimaryExpression($1); + } + | function_call_expression { $$ = $1; } + ; -id_list - : INTEGER { - auto list = new SourceNodeList(); - list->addNodeId($1); - $$ = list; +unary_integer + : PLUS INTEGER { + $$ = $2; + } + | MINUS INTEGER { + $$ = -$2; } - | id_list COMMA INTEGER { + | INTEGER { + $$ = $1; + } + ; + +vid_ref_expression + : input_ref_expression { + $$ = $1; + } + | var_ref_expression { $$ = $1; - $$->addNodeId($3); } ; @@ -542,7 +566,7 @@ create_schema_prop_list ; create_schema_prop_item - : KW_TTL_DURATION ASSIGN INTEGER { + : KW_TTL_DURATION ASSIGN unary_integer { // Less than or equal to 0 means infinity, so less than 0 is equivalent to 0 if ($3 < 0) { $3 = 0; @@ -623,7 +647,7 @@ alter_schema_prop_list ; alter_schema_prop_item - : KW_TTL_DURATION ASSIGN INTEGER { + : KW_TTL_DURATION ASSIGN unary_integer { // Less than or equal to 0 means infinity, so less than 0 is equivalent to 0 if ($3 < 0) { $3 = 0; @@ -838,7 +862,7 @@ vertex_row_list ; vertex_row_item - : INTEGER COLON L_PAREN value_list R_PAREN { + : vid COLON L_PAREN value_list R_PAREN { $$ = new VertexRowItem($1, $4); } ; @@ -887,16 +911,18 @@ edge_row_list ; edge_row_item - : INTEGER R_ARROW INTEGER COLON L_PAREN value_list R_PAREN { + : vid R_ARROW vid COLON L_PAREN value_list R_PAREN { $$ = new EdgeRowItem($1, $3, $6); } - | INTEGER R_ARROW INTEGER AT INTEGER COLON L_PAREN value_list R_PAREN { + | vid R_ARROW vid AT rank COLON L_PAREN value_list R_PAREN { $$ = new EdgeRowItem($1, $3, $5, $8); } ; +rank: unary_integer { $$ = $1; }; + update_vertex_sentence - : KW_UPDATE KW_VERTEX INTEGER KW_SET update_list where_clause yield_clause { + : KW_UPDATE KW_VERTEX vid KW_SET update_list where_clause yield_clause { auto sentence = new UpdateVertexSentence(); sentence->setVid($3); sentence->setUpdateList($5); @@ -904,7 +930,7 @@ update_vertex_sentence sentence->setYieldClause($7); $$ = sentence; } - | KW_UPDATE KW_OR KW_INSERT KW_VERTEX INTEGER KW_SET update_list where_clause yield_clause { + | KW_UPDATE KW_OR KW_INSERT KW_VERTEX vid KW_SET update_list where_clause yield_clause { auto sentence = new UpdateVertexSentence(); sentence->setInsertable(true); sentence->setVid($5); @@ -933,7 +959,7 @@ update_item ; update_edge_sentence - : KW_UPDATE KW_EDGE INTEGER R_ARROW INTEGER + : KW_UPDATE KW_EDGE vid R_ARROW vid KW_SET update_list where_clause yield_clause { auto sentence = new UpdateEdgeSentence(); sentence->setSrcId($3); @@ -943,7 +969,7 @@ update_edge_sentence sentence->setYieldClause($9); $$ = sentence; } - | KW_UPDATE KW_OR KW_INSERT KW_EDGE INTEGER R_ARROW INTEGER + | KW_UPDATE KW_OR KW_INSERT KW_EDGE vid R_ARROW vid KW_SET update_list where_clause yield_clause { auto sentence = new UpdateEdgeSentence(); sentence->setInsertable(true); @@ -954,7 +980,7 @@ update_edge_sentence sentence->setYieldClause($11); $$ = sentence; } - | KW_UPDATE KW_EDGE INTEGER R_ARROW INTEGER AT INTEGER + | KW_UPDATE KW_EDGE vid R_ARROW vid AT rank KW_SET update_list where_clause yield_clause { auto sentence = new UpdateEdgeSentence(); sentence->setSrcId($3); @@ -965,7 +991,7 @@ update_edge_sentence sentence->setYieldClause($11); $$ = sentence; } - | KW_UPDATE KW_OR KW_INSERT KW_EDGE INTEGER R_ARROW INTEGER AT INTEGER KW_SET + | KW_UPDATE KW_OR KW_INSERT KW_EDGE vid R_ARROW vid AT rank KW_SET update_list where_clause yield_clause { auto sentence = new UpdateEdgeSentence(); sentence->setInsertable(true); @@ -980,7 +1006,7 @@ update_edge_sentence ; delete_vertex_sentence - : KW_DELETE KW_VERTEX id_list where_clause { + : KW_DELETE KW_VERTEX vid_list where_clause { auto sentence = new DeleteVertexSentence($3); sentence->setWhereClause($4); $$ = sentence; @@ -988,11 +1014,11 @@ delete_vertex_sentence ; edge_list - : INTEGER R_ARROW INTEGER { + : vid R_ARROW vid { $$ = new EdgeList(); $$->addEdge($1, $3); } - | edge_list COMMA INTEGER R_ARROW INTEGER { + | edge_list COMMA vid R_ARROW vid { $$ = $1; $$->addEdge($3, $5); } diff --git a/src/parser/scanner.lex b/src/parser/scanner.lex index ce35dfdd71c..57e5d0e3124 100644 --- a/src/parser/scanner.lex +++ b/src/parser/scanner.lex @@ -195,8 +195,8 @@ IP_OCTET ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) ";" { return TokenType::SEMICOLON; } "@" { return TokenType::AT; } -"+" { return TokenType::ADD; } -"-" { return TokenType::SUB; } +"+" { return TokenType::PLUS; } +"-" { return TokenType::MINUS; } "*" { return TokenType::MUL; } "/" { return TokenType::DIV; } "%" { return TokenType::MOD; } @@ -260,9 +260,9 @@ IP_OCTET ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) yylval->intval = val; return TokenType::INTEGER; } -[+-]?{DEC}+ { yylval->intval = ::atoll(yytext); return TokenType::INTEGER; } -[+-]?{DEC}+\.{DEC}* { yylval->doubleval = ::atof(yytext); return TokenType::DOUBLE; } -[+-]?{DEC}*\.{DEC}+ { yylval->doubleval = ::atof(yytext); return TokenType::DOUBLE; } +{DEC}+ { yylval->intval = ::atoll(yytext); return TokenType::INTEGER; } +{DEC}+\.{DEC}* { yylval->doubleval = ::atof(yytext); return TokenType::DOUBLE; } +{DEC}*\.{DEC}+ { yylval->doubleval = ::atof(yytext); return TokenType::DOUBLE; } \${LABEL} { yylval->strval = new std::string(yytext + 1, yyleng - 1); return TokenType::VARIABLE; } diff --git a/src/parser/test/ParserTest.cpp b/src/parser/test/ParserTest.cpp index ce47143547a..3ce0d998dcc 100644 --- a/src/parser/test/ParserTest.cpp +++ b/src/parser/test/ParserTest.cpp @@ -364,6 +364,13 @@ TEST(Parser, InsertVertex) { auto result = parser.parse(query); ASSERT_FALSE(result.ok()) << result.status(); } + { + GQLParser parser; + std::string query = "INSERT VERTEX person(name,age,married,salary,create_time) " + "VALUES -12345:(\"dutor\", 30, true, 3.14, 1551331900)"; + auto result = parser.parse(query); + ASSERT_TRUE(result.ok()) << result.status(); + } } TEST(Parser, UpdateVertex) { @@ -408,7 +415,7 @@ TEST(Parser, InsertEdge) { { GQLParser parser; std::string query = "INSERT EDGE transfer(amount, time) " - "VALUES 12345->54321:(3.75, 1537408527)"; + "VALUES 12345->-54321:(3.75, 1537408527)"; auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } @@ -424,7 +431,7 @@ TEST(Parser, InsertEdge) { { GQLParser parser; std::string query = "INSERT EDGE NO OVERWRITE transfer(amount, time) " - "VALUES 12345->54321:(3.75, 1537408527)"; + "VALUES -12345->54321:(3.75, 1537408527)"; auto result = parser.parse(query); ASSERT_TRUE(result.ok()) << result.status(); } @@ -438,7 +445,7 @@ TEST(Parser, InsertEdge) { { GQLParser parser; std::string query = "INSERT EDGE NO OVERWRITE transfer(amount, time) " - "VALUES 12345->54321@1537408527:(3.75, 1537408527)"; + "VALUES 12345->-54321@1537408527:(3.75, 1537408527)"; 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 b5dbe737ca6..7eb038fd797 100644 --- a/src/parser/test/ScannerTest.cpp +++ b/src/parser/test/ScannerTest.cpp @@ -109,8 +109,8 @@ TEST(Scanner, Basic) { CHECK_SEMANTIC_TYPE(",", TokenType::COMMA), CHECK_SEMANTIC_TYPE(":", TokenType::COLON), CHECK_SEMANTIC_TYPE(";", TokenType::SEMICOLON), - CHECK_SEMANTIC_TYPE("+", TokenType::ADD), - CHECK_SEMANTIC_TYPE("-", TokenType::SUB), + CHECK_SEMANTIC_TYPE("+", TokenType::PLUS), + CHECK_SEMANTIC_TYPE("-", TokenType::MINUS), CHECK_SEMANTIC_TYPE("*", TokenType::MUL), CHECK_SEMANTIC_TYPE("/", TokenType::DIV), CHECK_SEMANTIC_TYPE("%", TokenType::MOD), @@ -343,15 +343,12 @@ TEST(Scanner, Basic) { CHECK_SEMANTIC_VALUE("label123", TokenType::LABEL, "label123"), CHECK_SEMANTIC_VALUE("123", TokenType::INTEGER, 123), - CHECK_SEMANTIC_VALUE("-123", TokenType::INTEGER, -123), CHECK_SEMANTIC_VALUE("0x123", TokenType::INTEGER, 0x123), CHECK_SEMANTIC_VALUE("0xdeadbeef", TokenType::INTEGER, 0xdeadbeef), CHECK_SEMANTIC_VALUE("0123", TokenType::INTEGER, 0123), CHECK_SEMANTIC_VALUE("123.", TokenType::DOUBLE, 123.), CHECK_SEMANTIC_VALUE(".123", TokenType::DOUBLE, 0.123), CHECK_SEMANTIC_VALUE("123.456", TokenType::DOUBLE, 123.456), - 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),